一个提示词。一个按钮。一套完整部署的系统。这就是 2026 年的 AI 工程化

@0xWast3
英语2天前 · 2026年7月15日
129K
111
15
20
263

TL;DR

这是一份关于生成式应用架构的综合指南,详细介绍了 AI Agents 如何利用 Claude 和 Obsidian 构建、部署并管理完整的软件系统。

六个月前,这需要一个后端开发人员、一个 DevOps 工程师和两周时间。今天,它只需要一句话和 Claude。以下是完整的架构——以及为什么大多数开发者还没有意识到这一点。

大多数人对 AI 的心智模型是错误的。

他们认为:AI 助手 → 你提问 → 它回答。

2026 年的现实:AI Agent → 你描述一个系统 → 它构建、部署并将该系统连接到你的环境。不是原型。不是代码片段。而是一个正在运行的应用程序。

这种转变有一个名字:生成式应用架构。而使其成为现实的工具栈——Claude + Obsidian + MCP——现在任何人都可以使用。

1. 生成式应用架构的真正含义

传统软件开发:

text
1想法 → 规格 → 设计 → 前端开发 → 后端开发
2→ 数据库设置 → API 集成 → 测试 → 部署
3时长:数周。成本:数千美元。

生成式应用架构:

text
1想法 → 提示词 → 运行中的系统
2时长:数分钟。成本:API Token。

AI Agent 不仅会编写代码。它会在底层运行一个完整的 Agentic 循环:

第 1 步 - 任务分解

你抽象的请求(“为一家洗车店构建一个 CRM 系统”)会被分解成数十个原子子任务:数据库模式、UI 组件、通知逻辑、认证流程、API 端点。

第 2 步 - 通过 MCP 进行环境映射

通过模型上下文协议,Agent 可以立即理解它可以访问哪些工具——你的文件系统、已安装的包、正在运行的服务、可用的 API。

第 3 步 - 迭代构建与测试

Agent 编写代码,执行它,捕获编译错误,修复它们,并重新测试——自主完成——直到系统成功运行。

第 4 步 - 上下文感知部署

输出不是包含代码的文本文件。而是一个实时的本地环境或一个可部署的 Web 应用程序。

这就是一个辅助开发者的工具与一个完全取代构建流程的系统之间的区别。

2. Claude 作为引擎——三种部署模式

模式 1 - Claude Artifacts

从提示词到运行中应用程序的最快路径。当你要求 Claude 构建某些东西时,它会打开一个交互式 Artifact 窗口,并实时组装、编译和运行一个完整的 Web 应用程序——React、HTML、JavaScript——你可以看着它完成。

你可以在 Artifact 内部与运行的应用程序交互,用自然语言迭代它,并导出完整的归档文件。

一个能生成生产级金融追踪器的提示词:

text
1构建一个个人财务管理应用程序,包含:
2
3功能:
4- 交易记录(添加/编辑/删除,带分类)
5- 月度预算视图(带进度条)
6- 加密货币投资组合追踪器(从 CoinGecko API 拉取实时价格)
7- 实时更新的净资产计算
8- 深色模式切换
9
10技术要求:
11- 单文件 React 应用程序
12- 仅使用 useState + useEffect(无外部状态管理)
13- 使用 Tailwind CSS 进行样式设计
14- 从公共 API 获取数据(无需认证)
15- 移动端响应式
16
17数据:
18- 在会话之间持久化到 localStorage
19- 将交易导出为 CSV
20
21输出:完整的、可立即部署的自包含应用程序。

Claude Artifacts 返回的内容——一个完整的 React 应用程序:

javascript
1import { useState, useEffect } from "react";
2
3const CATEGORIES = ["Housing","Food","Transport","Entertainment","Health","Savings","Income","Crypto","Other"];
4const CRYPTO_IDS = { BTC: "bitcoin", ETH: "ethereum", SOL: "solana" };
5
6export default function FinanceTracker() {
7 const [transactions, setTransactions] = useState(() =>
8 JSON.parse(localStorage.getItem("transactions") || "[]")
9 );
10 const [cryptoPrices, setCryptoPrices] = useState({});
11 const [form, setForm] = useState({ description:"", amount:"", category:"Other", type:"expense", date:"" });
12 const [darkMode, setDarkMode] = useState(false);
13
14 useEffect(() => {
15 const ids = Object.values(CRYPTO_IDS).join(",");
16 fetch(`https://api.coingecko.com/api/v3/simple/price?ids=${ids}&vs_currencies=usd`)
17 .then(r => r.json())
18 .then(data => {
19 const prices = {};
20 Object.entries(CRYPTO_IDS).forEach(([sym, id]) => { prices[sym] = data[id]?.usd || 0; });
21 setCryptoPrices(prices);
22 });
23 }, []);
24
25 useEffect(() => {
26 localStorage.setItem("transactions", JSON.stringify(transactions));
27 }, [transactions]);
28
29 const addTransaction = () => {
30 if (!form.description || !form.amount) return;
31 setTransactions(prev => [...prev, { ...form, id: Date.now(), amount: parseFloat(form.amount),
32 date: form.date || new Date().toISOString().split("T")[0] }]);
33 setForm({ description:"", amount:"", category:"Other", type:"expense", date:"" });
34 };
35
36 const totalIncome = transactions.filter(t => t.type === "income").reduce((s,t) => s + t.amount, 0);
37 const totalExpenses = transactions.filter(t => t.type === "expense").reduce((s,t) => s + t.amount, 0);
38 const netWorth = totalIncome - totalExpenses;
39
40 const bg = darkMode ? "#0D0D0D" : "#F9F7F4";
41 const card = darkMode ? "#1A1A1A" : "#FFF";
42 const text = darkMode ? "#F0F0F0" : "#1A1A1A";
43 const border = darkMode ? "#2A2A2A" : "#E8E8E8";
44
45 return (
46 <div style={{ minHeight:"100vh", background:bg, color:text, fontFamily:"system-ui, sans-serif" }}>
47 <div style={{ maxWidth:800, margin:"0 auto", padding:"24px 16px" }}>
48
49 <div style={{ display:"flex", justifyContent:"space-between", marginBottom:24 }}>
50 <div>
51 <h1 style={{ fontSize:22, fontWeight:500, margin:0 }}>Finance Tracker</h1>
52 <p style={{ margin:"4px 0 0", fontSize:13, color: netWorth >= 0 ? "#22C55E" : "#EF4444" }}>
53 Net worth: ${netWorth.toFixed(2)}
54 </p>
55 </div>
56 <button onClick={() => setDarkMode(!darkMode)}
57 style={{ padding:"8px 14px", borderRadius:8, border:`1px solid ${border}`,
58 background:card, color:text, cursor:"pointer" }}>
59 {darkMode ? "Light" : "Dark"}
60 </button>
61 </div>
62
63 <div style={{ display:"grid", gridTemplateColumns:"1fr 1fr", gap:10, marginBottom:20 }}>
64 {[["Income","#22C55E",totalIncome],["Expenses","#EF4444",totalExpenses]].map(([label,color,val]) => (
65 <div key={label} style={{ background:card, border:`1px solid ${border}`, borderRadius:10, padding:14 }}>
66 <p style={{ margin:0, fontSize:12, color:"#999" }}>{label}</p>
67 <p style={{ margin:"4px 0 0", fontSize:20, fontWeight:600, color }}>${val.toFixed(2)}</p>
68 </div>
69 ))}
70 </div>
71
72 <div style={{ background:card, border:`1px solid ${border}`, borderRadius:10, padding:16, marginBottom:20 }}>
73 <div style={{ display:"grid", gridTemplateColumns:"2fr 1fr 1fr", gap:8, marginBottom:8 }}>
74 <input placeholder="Description" value={form.description}
75 onChange={e => setForm(p => ({ ...p, description: e.target.value }))}
76 style={{ padding:"9px 12px", borderRadius:8, border:`1px solid ${border}`, background:bg, color:text, fontSize:13 }} />
77 <input type="number" placeholder="Amount" value={form.amount}
78 onChange={e => setForm(p => ({ ...p, amount: e.target.value }))}
79 style={{ padding:"9px 12px", borderRadius:8, border:`1px solid ${border}`, background:bg, color:text, fontSize:13 }} />
80 <select value={form.type} onChange={e => setForm(p => ({ ...p, type: e.target.value }))}
81 style={{ padding:"9px 12px", borderRadius:8, border:`1px solid ${border}`, background:bg, color:text, fontSize:13 }}>
82 <option value="expense">Expense</option>
83 <option value="income">Income</option>
84 </select>
85 </div>
86 <div style={{ display:"grid", gridTemplateColumns:"2fr auto", gap:8 }}>
87 <select value={form.category} onChange={e => setForm(p => ({ ...p, category: e.target.value }))}
88 style={{ padding:"9px 12px", borderRadius:8, border:`1px solid ${border}`, background:bg, color:text, fontSize:13 }}>
89 {CATEGORIES.map(c => <option key={c}>{c}</option>)}
90 </select>
91 <button onClick={addTransaction}
92 style={{ padding:"9px 20px", borderRadius:8, background:"#E8692A",
93 color:"#fff", border:"none", cursor:"pointer", fontSize:13, fontWeight:500 }}>
94 Add
95 </button>
96 </div>
97 </div>
98
99 <div style={{ background:card, border:`1px solid ${border}`, borderRadius:10, overflow:"hidden" }}>
100 <p style={{ margin:0, padding:"12px 16px", borderBottom:`1px solid ${border}`, fontSize:13, fontWeight:500 }}>
101 Transactions ({transactions.length})
102 </p>
103 {transactions.slice().reverse().map(t => (
104 <div key={t.id} style={{ display:"flex", justifyContent:"space-between",
105 alignItems:"center", padding:"11px 16px", borderBottom:`1px solid ${border}` }}>
106 <div>
107 <p style={{ margin:0, fontSize:13, fontWeight:500 }}>{t.description}</p>
108 <p style={{ margin:"2px 0 0", fontSize:12, color:"#999" }}>{t.category} · {t.date}</p>
109 </div>
110 <span style={{ fontSize:14, fontWeight:600, color: t.type==="income" ? "#22C55E" : "#EF4444" }}>
111 {t.type==="income" ? "+" : "-"}${t.amount.toFixed(2)}
112 </span>
113 </div>
114 ))}
115 </div>
116 </div>
117 </div>
118 );
119}

这就是完整的应用程序。一个提示词。在 Claude Artifacts 中即时运行。

模式 2 - Claude + MCP(本地部署)

MCP(模型上下文协议)让 Claude 能够直接访问你的本地环境。一个提示词不仅生成代码——它还会在你的硬盘上创建文件夹,通过终端安装包,编写配置文件,并启动一个本地服务器。

将 Claude 连接到你的文件系统的 MCP 配置:

json
1{
2 "mcpServers": {
3 "filesystem": {
4 "command": "npx",
5 "args": [
6 "-y",
7 "@modelcontextprotocol/server-filesystem",
8 "/Users/yourname/Projects"
9 ]
10 },
11 "terminal": {
12 "command": "npx",
13 "args": ["-y", "@modelcontextprotocol/server-terminal"]
14 },
15 "sqlite": {
16 "command": "npx",
17 "args": [
18 "-y",
19 "@modelcontextprotocol/server-sqlite",
20 "--db-path",
21 "/Users/yourname/Projects/app.db"
22 ]
23 }
24 }
25}

有了这个激活的配置,一个简单的提示词:

text
1为一家洗车业务构建并部署一个本地 CRM 系统。
2
3在 ~/Projects/carwash-crm/ 创建项目。
4自动安装依赖。
5设置 SQLite 数据库,包含以下表:
6- customers(姓名,电话,邮箱,车辆,备注)
7- visits(客户 ID,日期,服务,价格,状态)
8- staff(姓名,角色,排班)
9
10构建一个 Web 界面,包含:
11- 客户搜索和个人资料
12- 每位客户的访问历史
13- 月度收入仪表盘
14- 短信提醒系统(Twilio 集成,仅配置)
15
16完成后启动开发服务器。
17准备好后报告 localhost URL。

Claude 通过 MCP 端到端地执行这个任务——创建目录结构,安装 Node 包,编写数据库模式,构建 UI,并启动服务器。你会得到一个 localhost URL。

模式 3 - 包含公司标准的 Claude Projects

将你的 UI 工具包、设计令牌、API 文档和安全要求一次性上传到 Claude Project。之后 Claude 生成的每个系统都会自动符合你的内部技术栈。

text
1[Claude Project 上下文包含:]
2- design-system.md(颜色、排版、间距)
3- api-standards.md(认证模式、错误代码)
4- security-policy.md(输入验证规则、CORS 配置)
5- stack.md(React 18,TypeScript,Tailwind,Prisma,PostgreSQL)
6
7提示词:
8"构建一个带有邮箱验证功能的客户注册表单,
9并在提交时自动创建 Notion 数据库条目。"
10
11输出:与你技术栈完全匹配的生产级代码——
12无需任何清理工作。

3. Obsidian 作为 AI 指挥中心

2026 年的 Obsidian 不再是一个笔记应用。它是一个个人 AI 指挥中心,你积累的知识库成为你构建的每个系统的上下文层。

架构转变:你的知识库不再是存储空间。它变成了 RAG(检索增强生成)——一个 AI Agent 在执行任何任务之前都会查询的活态知识库。

实现这一功能的插件栈:

Smart Connections - 索引你的整个知识库,并在每次 AI 调用时发送相关笔记作为上下文。

Obsidian Copilot - 将你的知识库直接连接到 Claude API。配置一次:

javascript
1
2 "provider": "anthropic",
3 "model": "claude-opus-4-8",
4 "apiKey": "YOUR_ANTHROPIC_KEY",
5 "systemPrompt": "你是一位系统架构师。你可以访问用户完整的知识库作为上下文。在构建系统时,请参考他们现有的笔记、过去的决策和既定的模式。输出:可工作的代码 + Obsidian 文件结构。",
6 "contextWindow": {
7 "includeActiveFile": true,
8 "includeLinkedFiles": true,
9 "includeRecentFiles": 10,
10 "includeFolders": ["Projects", "Systems", "Decisions"]
11 }
12}

Canvas 作为系统设计界面

一个提示词就能创建一个交互式 Obsidian Canvas,Claude 在其中以连接的块的形式布局整个系统架构。

text
1Obsidian Canvas 中的提示词:
2"为我的 Twitter 账号设计一个内容生产管线。
3我每周发布 3 篇文章并管理 5 个赞助交易。
4请参考我现有的内容日历笔记。"
5
6输出:Canvas 包含以下连接块:
7→ 内容构思(从你的兴趣笔记中提取)
8→ 草稿 → 审核 → 发布工作流
9→ 赞助商追踪(带截止日期提醒)
10→ 分析仪表盘
11→ 自动跨平台发布逻辑
12→ 每个块都链接到相关的 Obsidian 文件

Claude 生成的作为结构化文件的 Canvas 输出:

json
1{
2 "nodes": [
3 {
4 "id": "ideation",
5 "type": "file",
6 "file": "Systems/ContentPipeline/Ideation.md",
7 "x": 0, "y": 0, "width": 300, "height": 200,
8 "color": "1"
9 },
10 {
11 "id": "draft",
12 "type": "file",
13 "file": "Systems/ContentPipeline/Draft.md",
14 "x": 400, "y": 0, "width": 300, "height": 200,
15 "color": "3"
16 },
17 {
18 "id": "sponsors",
19 "type": "file",
20 "file": "Systems/ContentPipeline/SponsorTracker.md",
21 "x": 0, "y": 300, "width": 300, "height": 200,
22 "color": "5"
23 },
24 {
25 "id": "analytics",
26 "type": "file",
27 "file": "Systems/ContentPipeline/Analytics.md",
28 "x": 400, "y": 300, "width": 300, "height": 200,
29 "color": "6"
30 }
31 ],
32 "edges": [
33 {
34 "id": "e1",
35 "fromNode": "ideation", "fromSide": "right",
36 "toNode": "draft", "toSide": "left",
37 "label": "approved concepts"
38 },
39 {
40 "id": "e2",
41 "fromNode": "sponsors", "fromSide": "right",
42 "toNode": "draft", "toSide": "bottom",
43 "label": "brief integration"
44 }
45 ]
46}

4. 使用本地 LLM 实现完全隐私

对于敏感数据——客户系统、财务工具、内部工具——你可以通过本地模型而不是云 API 进行路由。零数据离开你的机器。

bash
1# 安装 Ollama
2curl -fsSL https://ollama.com/install.sh | sh
3
4# 拉取一个适合编码的模型
5ollama pull llama3.2:latest
6# 或者为了更强的代码生成能力:
7ollama pull qwen2.5-coder:32b
8
9# 启动本地服务器
10ollama serve
11# 运行在 localhost:11434

配置 Obsidian Copilot 使用本地端点:

javascript
1{
2 "provider": "ollama",
3 "model": "qwen2.5-coder:32b",
4 "baseUrl": "http://localhost:11434",
5 "systemPrompt": "你是一位本地系统构建者,可以通过 MCP 访问用户的文件系统。构建完整的、可工作的系统。除非有明确指令,否则绝不将数据发送到外部 API。"
6}

本地模型 + MCP 桥接:

python
1import requests
2import json
3from pathlib import Path
4from watchdog.observers import Observer
5from watchdog.events import FileSystemEventHandler
6
7OBSIDIAN_INBOX = Path.home() / "Obsidian" / "AI-Inbox"
8PROJECTS_DIR = Path.home() / "Projects"
9OLLAMA_URL = "http://localhost:11434/api/generate"
10
11class InboxWatcher(FileSystemEventHandler):
12 """
13 监视 Obsidian AI-Inbox 文件夹。
14 当出现新的 .md 文件时,将其视为构建提示。
15 传递给本地 LLM -> 通过 MCP 执行 -> 报告结果。
16 """
17
18 def on_created(self, event):
19 if not event.src_path.endswith(".md"):
20 return
21
22 prompt_file = Path(event.src_path)
23 prompt = prompt_file.read_text()
24
25 print(f"[Inbox] 新提示: {prompt_file.name}")
26 self.execute_prompt(prompt, prompt_file.stem)
27
28 def execute_prompt(self, prompt: str, project_name: str):
29 response = requests.post(OLLAMA_URL, json={
30 "model": "qwen2.5-coder:32b",
31 "prompt": f"""你是一位系统构建者。
32 构建此系统: {prompt}
33
34 输出一个包含以下内容的 JSON 计划:
35 {{
36 "project_dir": "相对路径",
37 "files": [
38 {{"path": "相对路径", "content": "文件内容"}}
39 ],
40 "commands": ["npm install", "等等"],
41 "summary": "构建了什么"
42 }}""",
43 "stream": False
44 })
45
46 plan = json.loads(response.json()["response"])
47 project_dir = PROJECTS_DIR / plan["project_dir"]
48 project_dir.mkdir(parents=True, exist_ok=True)
49
50 for file_spec in plan["files"]:
51 file_path = project_dir / file_spec["path"]
52 file_path.parent.mkdir(parents=True, exist_ok=True)
53 file_path.write_text(file_spec["content"])
54 print(f"[构建] 创建: {file_path}")
55
56 result_file = OBSIDIAN_INBOX / f"{project_name}-result.md"
57 result_file.write_text(
58 f"# 构建完成: {project_name}\n\n"
59 f"**位置:** {project_dir}\n\n"
60 f"**摘要:** {plan['summary']}\n\n"
61 f"**创建的文件数:** {len(plan['files'])}\n"
62 )
63 print(f"[完成] 结果已写入 Obsidian")
64
65if __name__ == "__main__":
66 OBSIDIAN_INBOX.mkdir(exist_ok=True)
67 observer = Observer()
68 observer.schedule(InboxWatcher(), str(OBSIDIAN_INBOX), recursive=False)
69 observer.start()
70 print(f"[监视中] {OBSIDIAN_INBOX}")
71
72 try:
73 while True:
74 import time; time.sleep(1)
75 except KeyboardInterrupt:
76 observer.stop()
77 observer.join()

将一个包含构建提示的 .md 文件放入你的 Obsidian AI-Inbox 文件夹。桥接器会拾取它,通过本地模型路由,在你的 Projects 文件夹中构建系统,并将完成通知写回 Obsidian。

5. 完整工作流——从想法到已部署的系统

text
1第 1 步 - 输入
2在 Obsidian 的 AI 面板上,写下:
3"带加密货币集成和月度预算追踪的个人财务系统。"
4点击生成。
5
6第 2 步 - 上下文组装
7Smart Connections 插件扫描你的知识库。
8找到你过去 3 个月的财务笔记。
9将它们作为上下文发送给 Claude API。
10
11第 3 步 - 架构设计
12Claude (Opus 4.8) 设计系统:
13- 数据库模式
14- UI 组件
15- API 集成
16- 文件结构
17
18第 4 步 - 构建
19Claude (Sonnet 5) 通过 MCP 实现:
20- 创建 ~/Projects/finance-tracker/
21- 安装依赖
22- 编写所有文件
23- 在 localhost:3000 启动开发服务器
24
25第 5 步 - 结果
26Obsidian 创建文件夹:Finance System/
27内部包含:链接的仪表盘、配置笔记,
28以及一个指向正在运行的应用程序的直接链接。

从第 1 步到应用程序运行的总时间:4-12 分钟。

这种转变的意义

这不是一种更快的编码方式。

这是想法与执行之间的一种不同关系。

过去,你能构建什么受限于技术技能和时间。一个非开发者无法构建 CRM。一个独立开发者无法同时构建五个系统。一个团队无法在数小时而非数周内交付。

这三个约束都已不复存在。

新的约束是思维的清晰度——精确描述你需要什么、理解什么是好的输出、并对其进行迭代的能力。这是一种思维技能,而非技术技能。

生成式应用架构不会让开发者变得过时。它让系统化思考的能力——在构建之前推理你需要什么——比编写实现它的代码的能力变得更有价值。

工具栈就在这里。模型能力已经足够。剩下的唯一变量是,你是正在用它来构建,还是在阅读关于那些正在构建的人的文章。

本文描述了截至 2026 年 7 月 Claude、Obsidian 和 MCP 中可用的功能。具体的插件版本和 API 配置可能会发生变化。在实施前,请务必核实当前的文档。

感谢阅读。

二次创作

使用 YouMind 创作爆款文章

收集素材、拆解爆点、生成视觉资产、撰写内容,并在一个 AI 工作空间里完成分发。

了解 YouMind
写给创作者

把你的 Markdown 变成干净的 𝕏 文章

图片上传、表格、代码块,往 𝕏 上手动重排太痛苦。YouMind 把整篇 Markdown 一键转成干净、可直接发布的 𝕏 文章草稿。

试试 Markdown 转 𝕏

更多可拆解样本

近期爆款文章

探索更多爆款文章