name: 智能体原生架构 description: 构建以智能体为一等公民的应用程序。在涉及设计自主智能体、创建 MCP 工具、实现自修改系统或构建功能由智能体在循环中操作实现结果的应用时使用此技能。
<why_now>
为什么现在
软件代理现在工作可靠。Claude Code 证明了,一个具有访问 bash 和文件工具的 LLM,在循环中操作直到实现目标,可以自主完成复杂的多步骤任务。
令人惊讶的发现:一个真正优秀的编码代理实际上是一个真正优秀的通用代理。 让 Claude Code 重构代码库的相同架构可以让一个代理组织您的文件、管理您的阅读列表或自动化您的工作流程。
Claude Code SDK 使这变得可访问。您可以构建应用程序,其中功能不是您编写的代码——它们是您描述的结果,由具有工具的代理实现,在循环中操作直到达到结果。
这开辟了一个新领域:以 Claude Code 方式工作的软件,应用于远超出编码的类别。 </why_now>
<core_principles>
核心原则
1. 对等性
用户通过用户界面可以做的任何事情,代理都应该能够通过工具实现。
这是基本原则。没有它,一切都无关紧要。
想象您构建了一个笔记应用,具有创建、组织和标记笔记的漂亮界面。用户要求代理:“创建一条总结我会议的笔记,并标记为紧急。”
如果您构建了创建笔记的用户界面,但没有代理能力做同样的事,代理就会卡住。它可能会道歉或请求澄清问题,但它无法帮助——即使这个操作对人类使用界面来说是微不足道的。
修复方法: 确保代理具有工具(或工具组合)可以完成用户界面可以做的任何事情。
这不是关于创建用户界面按钮到工具的一对一映射。而是关于确保代理可以实现相同的结果。有时这是一个单一工具(create_note)。有时是组合原语(write_file 到笔记目录,并具有适当的格式)。
纪律: 当添加任何用户界面功能时,问:代理能实现这个结果吗?如果不能,添加必要的工具或原语。
能力映射有帮助:
| 用户操作 | 代理如何实现 |
|---|---|
| 创建笔记 | write_file 到笔记目录,或 create_note 工具 |
| 将笔记标记为紧急 | update_file 元数据,或 tag_note 工具 |
| 搜索笔记 | search_files 或 search_notes 工具 |
| 删除笔记 | delete_file 或 delete_note 工具 |
测试: 选择用户在用户界面中可以执行的任何操作。向代理描述它。它能实现结果吗?
2. 粒度
倾向于原子原语。功能是由代理在循环中操作直到达到结果而实现的成果。
工具是原始能力:读取文件、写入文件、运行 bash 命令、存储记录、发送通知。
一个功能不是您编写的函数。它是您在提示中描述的结果,由具有工具并在循环中操作直到达到结果的代理实现。
较少粒度(限制代理):
工具:classify_and_organize_files(files)
→ 您编写了决策逻辑
→ 代理执行您的代码
→ 要改变行为,您重构
更多粒度(赋予代理权力):
工具:read_file, write_file, move_file, list_directory, bash
提示:“组织用户的下载文件夹。分析每个文件,根据内容和最近性确定适当位置,并将它们移动到那里。”
代理:在循环中操作—读取文件、做出判断、移动事物、检查结果—直到文件夹被组织好。
→ 代理做出决策
→ 要改变行为,您编辑提示
关键转变: 代理以判断力追求结果,而不是执行编排好的序列。它可能会遇到意外的文件类型、调整其方法或请求澄清问题。循环继续直到结果实现。
您的工具越原子,代理使用它们就越灵活。如果您将决策逻辑捆绑到工具中,您就把判断力移回了代码。
测试: 要改变功能行为,您是编辑文本还是重构代码?
3. 可组合性
有了原子工具和对等性,您只需编写新提示就可以创建新功能。
这是前两个原则的回报。当您的工具是原子的且代理可以做用户可以做的任何事情时,新功能只是新提示。
想要一个“每周回顾”功能,总结活动并建议优先级吗?那是一个提示:
“回顾本周修改的文件。总结关键变化。基于未完成项目和临近截止日期,建议下周三个优先级。”
代理使用 list_files、read_file 和其判断力来完成这个。您没有编写每周回顾代码。您描述了一个结果,代理在循环中操作直到实现。
这对开发者和用户都有效。 您可以通过添加提示来发布新功能。用户可以通过修改提示或创建自己的来定制行为。“当我说‘归档这个’时,总是将它移到我的行动文件夹并标记为紧急”成为一个用户级提示,扩展了应用程序。
约束: 这只有在工具足够原子以以您未预期的方式组合,且代理与用户对等时才有效。如果工具编码了太多逻辑,或代理无法访问关键能力,组合就会崩溃。
测试: 您能通过编写新提示部分来添加新功能,而不添加新代码吗?
4. 涌现能力
代理可以实现您未明确设计的事情。
当工具是原子的、保持对等性且提示可组合时,用户会要求代理做您从未预料到的事情。而且通常,代理可以解决它。
“交叉参考我的会议笔记和我的任务列表,告诉我我承诺了什么但还没有安排。”
您没有构建“承诺追踪器”功能。但如果代理可以读取笔记、读取任务并推理它们—在循环中操作直到有答案—它就可以完成这个。
这揭示了潜在需求。 与其猜测用户想要什么功能,您观察他们要求代理做什么。当模式出现时,您可以用特定领域的工具或专用提示来优化它们。但您不必预期它们—您发现了它们。
飞轮效应:
- 用原子工具和对等性构建
- 用户要求您未预料到的事情
- 代理组合工具来实现它们(或失败,揭示差距)
- 您观察被请求的模式
- 添加领域工具或提示以使常见模式高效
- 重复
这改变了您构建产品的方式。您不是试图预先想象每个功能。您正在创建一个有能力的基金会,并从涌现的事物中学习。
测试: 给代理一个与您领域相关的开放式请求。它能想出合理的方法,在循环中操作直到成功吗?如果它只是说“我没有那个功能”,您的架构就太受限了。
5. 随时间改进
智能体原生应用程序通过累积上下文和提示精炼而变得更好。
与传统软件不同,智能体原生应用程序无需发布代码即可改进:
累积上下文: 代理可以跨会话维护状态—存在什么、用户做了什么、什么有效、什么无效。代理读取和更新的 context.md 文件是第一层。更复杂的方法涉及结构化记忆和学习偏好。
多级提示精炼:
- 开发者级别: 您发布更新提示,改变所有用户的代理行为
- 用户级别: 用户为其工作流程定制提示
- 代理级别: 代理基于反馈修改自己的提示(高级)
自修改(高级): 代理可以编辑自己的提示甚至自己的代码。对于生产用例,考虑添加安全护栏—批准门、自动检查点以回滚、健康检查。这是趋势所在。
改进机制仍在被发现。上下文和提示精炼是已验证的。自修改正在涌现。清楚的是:该架构支持以传统软件不具备的方式变得更好。
测试: 应用程序在使用一个月后比第一天更好吗,即使没有代码更改? </core_principles>
<intake>
您需要智能体原生架构的哪个方面帮助?
- 设计架构 - 从头计划新的智能体原生系统
- 文件与工作空间 - 使用文件作为通用接口,共享工作空间模式
- 工具设计 - 构建原始工具、动态能力发现、CRUD 完整性
- 领域工具 - 知道何时添加领域工具与保持原语
- 执行模式 - 完成信号、部分完成、上下文限制
- 系统提示 - 在提示中定义代理行为、判断标准
- 上下文注入 - 将运行时应用状态注入代理提示
- 行动对等性 - 确保代理可以做用户可以做的所有事情
- 自修改 - 使代理安全地自我进化
- 产品设计 - 渐进式披露、潜在需求、批准模式
- 移动模式 - iOS 存储、后台执行、检查点/恢复
- 测试 - 测试智能体原生应用的能力和对等性
- 重构 - 使现有代码更智能体原生
在继续之前等待响应。 </intake>
<routing>
| 响应 | 行动 |
|---|---|
| 1, “design”, “architecture”, “plan” | 阅读 architecture-patterns.md,然后应用下面的架构检查清单 |
| 2, “files”, “workspace”, “filesystem” | 阅读 files-universal-interface.md 和 shared-workspace-architecture.md |
| 3, “tool”, “mcp”, “primitive”, “crud” | 阅读 mcp-tool-design.md |
| 4, “domain tool”, “when to add” | 阅读 from-primitives-to-domain-tools.md |
| 5, “execution”, “completion”, “loop” | 阅读 agent-execution-patterns.md |
| 6, “prompt”, “system prompt”, “behavior” | 阅读 system-prompt-design.md |
| 7, “context”, “inject”, “runtime”, “dynamic” | 阅读 dynamic-context-injection.md |
| 8, “parity”, “ui action”, “capability map” | 阅读 action-parity-discipline.md |
| 9, “self-modify”, “evolve”, “git” | 阅读 self-modification.md |
| 10, “product”, “progressive”, “approval”, “latent demand” | 阅读 product-implications.md |
| 11, “mobile”, “ios”, “android”, “background”, “checkpoint” | 阅读 mobile-patterns.md |
| 12, “test”, “testing”, “verify”, “validate” | 阅读 agent-native-testing.md |
| 13, “review”, “refactor”, “existing” | 阅读 refactoring-to-prompt-native.md |
阅读参考后,将这些模式应用到用户的具体上下文中。 </routing>
<architecture_checklist>
架构审查检查清单
设计智能体原生系统时,在实现前验证这些:
核心原则
- [ ] 对等性: 每个用户界面操作都有对应的代理能力
- [ ] 粒度: 工具是原语;功能是提示定义的结果
- [ ] 可组合性: 新功能可以通过提示单独添加
- [ ] 涌现能力: 代理可以处理您领域中的开放式请求
工具设计
- [ ] 动态与静态: 对于外部 API,代理应具有完全访问权限,使用动态能力发现
- [ ] CRUD 完整性: 每个实体都有创建、读取、更新和删除
- [ ] 原语而非工作流: 工具启用能力,不编码业务逻辑
- [ ] API 作为验证器: 当 API 验证时使用
z.string()输入,而不是z.enum()
文件与工作空间
- [ ] 共享工作空间: 代理和用户在相同数据空间工作
- [ ] context.md 模式: 代理读取/更新上下文文件以累积知识
- [ ] 文件组织: 实体作用域目录,具有一致命名
代理执行
- [ ] 完成信号: 代理有明确的
complete_task工具(非启发式检测) - [ ] 部分完成: 多步任务跟踪进度以恢复
- [ ] 上下文限制: 从一开始就为有界上下文设计
上下文注入
- [ ] 可用资源: 系统提示包括存在什么(文件、数据、类型)
- [ ] 可用能力: 系统提示用用户词汇记录工具
- [ ] 动态上下文: 长时间会话刷新上下文(或提供
refresh_context工具)
用户界面集成
- [ ] 代理 → 用户界面: 代理更改反映在用户界面中(共享服务、文件监视或事件总线)
- [ ] 无静默操作: 代理写入立即触发用户界面更新
- [ ] 能力发现: 用户可以学习代理能做什么
移动(如果适用)
- [ ] 检查点/恢复: 优雅处理 iOS 应用暂停
- [ ] iCloud 存储: iCloud 优先,多设备同步本地回退
- [ ] 成本意识: 模型层级选择(Haiku/Sonnet/Opus)
设计架构时,在您的计划中明确解决每个复选框。 </architecture_checklist>
<quick_start>
快速开始:构建智能体原生功能
步骤 1:定义原子工具
const tools = [
tool("read_file", "读取任何文件", { path: z.string() }, ...),
tool("write_file", "写入任何文件", { path: z.string(), content: z.string() }, ...),
tool("list_files", "列出目录", { path: z.string() }, ...),
tool("complete_task", "信号任务完成", { summary: z.string() }, ...),
];
步骤 2:在系统提示中编写行为
## 您的责任
当被要求组织内容时,您应该:
1. 读取现有文件以理解结构
2. 分析什么组织合理
3. 使用您的工具创建/移动文件
4. 使用您的判断关于布局和格式
5. 完成后调用 complete_task
您决定结构。使它好。
步骤 3:让代理在循环中工作
const result = await agent.run({
prompt: userMessage,
tools: tools,
systemPrompt: systemPrompt,
// 代理循环直到调用 complete_task
});
</quick_start>
<reference_index>
参考文件
所有参考在 references/ 中:
核心模式:
- architecture-patterns.md - 事件驱动、统一编排器、代理到用户界面
- files-universal-interface.md - 为什么文件、组织模式、context.md
- mcp-tool-design.md - 工具设计、动态能力发现、CRUD
- from-primitives-to-domain-tools.md - 何时添加领域工具、过渡到代码
- agent-execution-patterns.md - 完成信号、部分完成、上下文限制
- system-prompt-design.md - 功能作为提示、判断标准
智能体原生纪律:
- dynamic-context-injection.md - 运行时上下文、注入什么
- action-parity-discipline.md - 能力映射、对等工作流
- shared-workspace-architecture.md - 共享数据空间、用户界面集成
- product-implications.md - 渐进式披露、潜在需求、批准
- agent-native-testing.md - 测试结果、对等性测试
平台特定:
- mobile-patterns.md - iOS 存储、检查点/恢复、成本意识
- self-modification.md - 基于 Git 的进化、护栏
- refactoring-to-prompt-native.md - 迁移现有代码 </reference_index>
<anti_patterns>
反模式
常见的非完全智能体原生方法
这些不一定是错的—它们可能适合您的用例。但值得认识到与此文档描述的架构不同。
代理作为路由器 — 代理找出用户想要什么,然后调用正确的函数。代理的智能用于路由,而不是行动。这可以工作,但您只使用了代理能做的一小部分。
先构建应用,再添加代理 — 您以传统方式构建功能(作为代码),然后将其暴露给代理。代理只能做您功能已经做的事。您不会获得涌现能力。
请求/响应思维 — 代理获取输入,做一件事,返回输出。这错过了循环:代理获取要实现的结果,操作直到完成,沿途处理意外情况。
防御性工具设计 — 您过度约束工具输入,因为您习惯于防御性编程。严格的枚举、每层验证。这是安全的,但它阻止代理做您未预料到的事情。
代码中的快乐路径,代理只执行 — 传统软件在代码中处理边缘情况—您编写当 X 出错时发生什么的逻辑。智能体原生让代理用判断处理边缘情况。如果您的代码处理所有边缘情况,代理只是调用者。
具体反模式
主要错误:代理执行您的代码而不是解决问题
// 错误 - 您编写了工作流,代理只执行它
tool("process_feedback", async ({ message }) => {
const category = categorize(message); // 您的代码决定
const priority = calculatePriority(message); // 您的代码决定
await store(message, category, priority); // 您的代码编排
if (priority > 3) await notify(); // 您的代码决定
});
// 正确 - 代理找出如何处理反馈
tools: store_item, send_message // 原语
prompt: “基于可操作性评重要性 1-5,存储反馈,如果 >= 4 则通知”
工作流形状的工具 — analyze_and_organize 将判断捆绑到工具中。将其分解为原语并让代理组合它们。
上下文饥饿 — 代理不知道应用中存在什么资源。
用户:“在我的 feed 中写些关于 Catherine the Great 的内容”
代理:“什么 feed?我不理解您指的是什么系统。”
修复:将可用资源、能力和词汇注入系统提示。
孤立用户界面操作 — 用户可以通过用户界面做某事,但代理无法实现。修复:保持对等性。
静默操作 — 代理更改状态但用户界面不更新。修复:使用共享数据存储与反应性绑定,或文件系统监视。
启发式完成检测 — 通过启发式检测代理完成(连续迭代没有工具调用,检查预期输出文件)。这是脆弱的。修复:要求代理通过 complete_task 工具明确信号完成。
动态 API 的静态工具映射 — 为 50 个 API 端点构建 50 个工具,而 discover + access 模式会更灵活。
// 错误 - 每个 API 类型都需要硬编码工具
tool("read_steps", ...)
tool("read_heart_rate", ...)
tool("read_sleep", ...)
// 当添加葡萄糖追踪时...需要代码更改
// 正确 - 动态能力发现
tool("list_available_types", ...) // 发现可用内容
tool("read_health_data", { dataType: z.string() }, ...) // 访问任何类型
不完整的 CRUD — 代理可以创建但不能更新或删除。
// 用户:“删除那条日志条目”
// 代理:“我没有那个工具”
tool("create_journal_entry", ...) // 缺失:更新、删除
修复:每个实体都需要完整的 CRUD。
沙箱隔离 — 代理在与用户分开的数据空间中工作。
Documents/
├── user_files/ ← 用户的空间
└── agent_output/ ← 代理的空间(隔离)
修复:使用共享工作空间,双方操作相同文件。
无理由的关卡 — 领域工具是做某事的唯一方式,而您无意限制访问。默认是开放的。除非有特定原因,否则保持原语可用。
人为能力限制 — 出于模糊的安全担忧而不是特定风险,限制代理能做什么。仔细考虑限制能力。代理通常应该能做用户可以做的事情。 </anti_patterns>
<success_criteria>
成功标准
当您构建了智能体原生应用程序时:
架构
- [ ] 代理可以实现用户通过用户界面可以实现的任何事情(对等性)
- [ ] 工具是原子原语;领域工具是快捷方式,不是关卡(粒度)
- [ ] 新功能可以通过编写新提示添加(可组合性)
- [ ] 代理可以实现您未明确设计的事情(涌现能力)
- [ ] 改变行为意味着编辑提示,而不是重构代码
实现
- [ ] 系统提示包括关于应用状态的动态上下文
- [ ] 每个用户界面操作都有对应的代理工具(行动对等性)
- [ ] 代理工具在系统提示中用用户词汇记录
- [ ] 代理和用户在相同数据空间工作(共享工作空间)
- [ ] 代理操作立即反映在用户界面中
- [ ] 每个实体都有完整的 CRUD(创建、读取、更新、删除)
- [ ] 代理明确信号完成(无启发式检测)
- [ ] context.md 或等效用于累积知识
产品
- [ ] 简单请求立即工作,没有学习曲线
- [ ] 高级用户可以将系统推向意外方向
- [ ] 您通过观察用户要求代理做什么来学习用户想要什么
- [ ] 批准要求匹配风险和可逆性
移动(如果适用)
- [ ] 检查点/恢复处理应用中断
- [ ] iCloud 优先存储,本地回退
- [ ] 后台执行明智使用可用时间
- [ ] 模型层级匹配任务复杂性
最终测试
向代理描述一个在您应用程序领域内但您未构建特定功能的结果。
它能找出如何实现它,在循环中操作直到成功吗?
如果 yes,您构建了智能体原生的东西。
如果它说“我没有那个功能”—您的架构仍然太受限。 </success_criteria>