
软件智能体(AI Agents)现在已经迈入了能够可靠工作的新阶段。以 Claude Code 为代表的项目证明,只要赋予一个大语言模型访问 Bash 和文件系统的权限,并让它在一个自主循环中运行直至达成目标,它就能完成复杂的多步骤任务。
这里存在一个深刻的洞见:一个优秀的编程 Agent,本质上就是一个优秀的通用 Agent。 支撑 Claude Code 重构代码库的同一套架构,同样可以用来整理你的文件、管理阅读列表,或者自动化你的工作流。
通过 Claude Code SDK、Google ADK 等框架,这种能力变得触手可及。你可以构建一种全新的应用:其功能不再是你预先写死的代码,而是你描述的 结果(Outcome) —— 由一个装备了工具的 Agent,在循环中自主实现。
这开启了一个全新的领域:软件开始像 Claude Code 一样工作,但应用场景远超编程。这就是 Anthropic 与 Dan Shipper 联合倡导的最新架构理念 —— Agent-native Architecture(智能体原生架构)。在云栈社区这样的技术论坛中,关于这种前沿架构的讨论也日益增多。本文将深入拆解其核心原则与工程实践,为你勾勒这一范式的清晰图景。
核心原则
要构建真正的 Agent-native 应用,需要遵循以下 5 大核心原则:
平权 (Parity)
原则: 用户通过 UI 能做的任何事,Agent 必须能通过工具(Tools)完成。
这是整个架构的基石。没有平权,其他一切都无从谈起。你必须确保 Agent 拥有一套完整的工具集,能够覆盖 UI 的所有交互能力。
一个简单的测试方法是:随机挑选一个 UI 上的操作动作,然后问自己:Agent 能通过调用工具完成这个动作吗?这是验证这一原则的黄金标准。
颗粒度 (Granularity)
原则: 工具应该是 原子级(Atomic) 的原语。功能特性(Features)是由 Agent 在循环中通过组合工具达成的结果。
工具是提供基本能力的最小单元。而一个具体的功能特性,则是通过 Prompt 描述的一个目标结果,由 Agent 动态组合多个原子工具来实现。
如何判断颗粒度是否正确?问自己:要改变软件的行为,你是通过修改 Prompt,还是重构代码?如果是前者,说明你的工具设计对了。
可组合性 (Composability)
原则: 拥有了原子工具和平权能力,你可以仅通过编写新的 Prompt 来创造新功能。
例如,你想要一个“每周回顾”功能?这只需要一个 Prompt:
“检查本周修改过的文件。总结关键变更。基于未完成项和截止日期,建议下周的三个优先级事项。”
Agent 会自动调用 list_files、read_file 等工具,并结合自身的判断力来组合执行。你只需描述结果,Agent 负责在循环中将其实现。
涌现能力 (Emergent Capability)
原则: Agent 可以完成你从未显式设计过的任务。
这是 Agent-native 架构的飞轮效应:
- 你构建了原子工具和平权能力。
- 用户提出了一个你从未预料到的需求。
- Agent 通过组合现有工具,尝试完成任务(可能成功,也可能失败并揭示工具缺口)。
- 你观察这些模式,添加领域工具或优化 Prompt 来补强能力。
- 重复上述过程。
验证你的 Agent 是否具备涌现能力,就看看它能否处理其领域内的开放式请求。
随时间进化 (Improvement over time)
原则: Agent-native 应用通过积累上下文和优化 Prompt 而变得更好,无需重新发版。
与传统软件不同,Agent-native 应用可以通过以下方式自我进化:
- 积累上下文: 状态通过上下文文件(Context Files)在多个会话间持久化。
- 开发者级优化: 你推送更新的系统级 Prompt,所有用户立即受益。
- 用户级定制: 用户可以根据自己的习惯和工作流,修改本地 Prompt。
这种持续进化的能力,是 人工智能 应用区别于传统软件的关键特征之一。
实践中的原则
理解了原则,我们来看看如何将它们落地到具体的工程实践中。
解决“平权”问题
想象一个笔记应用。用户通过语音或聊天框说:“总结我关于这次会议的笔记,并标记为紧急。”
如果 UI 能做(点击“标记为紧急”按钮),但 Agent 没有对应的工具(例如 tag_note),Agent 就会在执行链中卡住。
修正方案: 建立一张 能力映射表(Capability Map)。
| 用户动作 |
Agent 实现方式 |
| 创建笔记 |
write_file 到笔记目录,或专用 create_note 工具 |
| 标记为紧急 |
update_file 修改元数据,或 tag_note 工具 |
| 搜索笔记 |
search_files 或 search_notes 工具 |
| 删除笔记 |
delete_file 或 delete_note 工具 |
将平权作为一条工程纪律: 每当添加一个 UI 功能时,都要同步问自己:Agent 能通过工具达成这个结果吗?如果不能,立即添加或规划相应的原子工具。
解决“颗粒度”问题:原子化 vs 捆绑逻辑
核心认知是:Agent 追求的是通过 判断力(Judgment) 来达成结果,而不是执行一段写死的、死板的指令序列。
- ❌ 错误做法(捆绑逻辑):
- 工具:
classify_and_organize_files(files)
- 问题:如何分类、如何组织的决策逻辑被写死在了工具代码里(充满了if-else)。要改变行为,必须重构这个工具的代码,灵活性极差。
- ✅ 正确做法(原子化):
- 工具:
read_file, write_file, move_file, bash
- Prompt:“整理下载文件夹,将图片、文档、压缩包分别移动到对应的子目录中...”
- 优势:Agent 负责观察文件内容、做出分类决策、并组合调用原子工具来完成整理。要改变行为(比如按日期而非类型整理),只需修改 Prompt。Agent 拥有了根据上下文灵活调整的自主权。
演进路线:从原语到领域工具
启动项目时,一个有效的策略是:一开始只提供最纯粹的原语(如 Bash 命令、基础的文件读写操作)。这能最快地验证架构可行性,并暴露出 Agent 在实际运作中真正需要的工具模式。
当模式开始涌现后,再有意识地添加 领域工具(Domain Tools),它们主要带来三方面价值:
- 词汇表 (Vocabulary):
create_note 这样的工具本身就在“教育”Agent,在你的系统中“笔记”是什么概念,如何创建。
- 护栏 (Guardrails): 某些操作(如删除)可能需要额外的确认步骤,这些验证逻辑不应完全交给 Agent 判断。
- 效率 (Efficiency): 将高频、固定的操作序列打包成一个工具,可以提升执行速度并降低 LLM 的调用成本。
领域工具的设计规则: 它应该代表用户视角下的一个 概念性动作。它可以包含必要的机械验证(如参数格式检查),但 绝不能包含“做什么”或“是否做”的业务判断 —— 这属于 Prompt 和 Agent 判断力的范畴。同时,默认应保持底层原语可用,不要为了封装而关闭 Agent 的底层权限,除非出于明确的安全考虑。
升级成为代码 (Graduating to Code)
有些操作会因为性能或可靠性原因,需要从“由 Agent 动态编排”升级为“预写的优化代码”。
- 阶段 1: Agent 在循环中使用原子原语(灵活性最高,用于验证概念)。
- 阶段 2: 添加封装好的领域工具(执行更快,但仍由 Agent 决定何时调用)。
- 阶段 3: 针对已经明确、稳定的热点路径,用高度优化的代码实现(速度极快,结果确定)。
关键注意点: 即使某个操作用代码实现了,Agent 仍应保留 直接触发该优化代码 的能力。同时,系统最好也保留 回退到使用底层原语 的能力,以处理优化代码覆盖不到的边缘情况。
架构模式:文件即通用接口
为什么 Claude Code 如此依赖文件系统?因为 Bash + Filesystem 是迄今为止最经受考验、最通用的 Agent 接口。
- 已知的: Agent(基于训练数据)天生就理解
cat, grep, mv, ls 等命令。
- 可检查的: 用户和开发者都能直接查看、编辑、移动文件。没有黑盒,一切状态透明。
- 可移植的: 导出、备份、迁移数据变得极其简单,就是拷贝文件夹。
- 自文档化: 像
/projects/acme/notes/ 这样的路径结构本身就携带了丰富的语义,比 SELECT * FROM notes WHERE project_id=‘acme’ 这样的查询更容易被 Agent 理解和运用。
实体作用域目录
这是一种推荐的文件结构组织模式:
{entity_type}/{entity_id}/
├── primary content (主内容,如 .md, .txt)
├── metadata (元数据,如 .json, .yaml)
└── related materials (相关素材,如图片、日志)
例如:Research/books/{bookId}/ 目录下可能包含书籍的全文、阅读笔记、引用来源以及 Agent 处理该书时生成的日志。
context.md 模式
Agent 需要知道它正在处理什么、能做什么。系统 Prompt 应该动态注入一个上下文模块,例如:
文件 vs 数据库
如何选择存储方式?这是一个经典的 后端 & 架构 设计决策。
- 用文件存储: 用户需要直接读写的内容(笔记、文档)、配置文件、Agent 生成的内容、大段文本。
- 用数据库存储: 需要高频更新和复杂查询的结构化数据、临时会话状态、具有强关系的数据模型。
冲突处理建议: 采用 共享工作空间(Shared Workspace) 模式。让 Agent 和用户在同一个数据空间内协作,而不是为 Agent 创建隔离的沙盒。这自然带来了并发写入的问题,需要通过简单的策略处理,例如“最后写入获胜(Last-write-wins)”或轻量级的文件锁。
成功标准与反模式
在构建 Agent-native 应用时,我们很容易不自觉地滑回传统的、确定性的软件工程思维。以下是需要警惕的具体 反模式:
Agent 作为路由器
- 反模式: Agent 的唯一工作就是分析用户意图,然后像一个路由开关一样,调用一个预先写死的
run_workflow_X() 函数。
- 问题: 你把 Agent 的智能降级成了复杂的
if/else 语句。如果用户需求稍微偏离预设路径(例如:“运行工作流A,但跳过第二步”),系统就会崩溃。
- 正确姿势: Agent 应该负责 执行,而不仅仅是路由。它应该拥有组成该工作流的所有原子工具,并根据实时情况自主决定调用哪些工具以及调用的顺序。
“请求/响应”思维
- 反模式: 将 Agent 视为一个高级 API:输入一个请求,期望它直接输出一个完美的结果。
- 问题: 这完全丢失了 主循环(Master Loop) 的核心价值。真正的 Agent 是 追求结果(Outcome) 的。它可能会尝试、失败、分析错误、调整策略、再尝试,循环往复直到达成目标或放弃。
- 正确姿势: 给 Agent 一个目标,让它在一个循环中自主运行,并相信它能处理过程中出现的意外。
防御性工具设计
- 反模式: 由于习惯了防御性编程,把工具的输入参数限制得非常严格(例如,只允许几个枚举值,添加多层校验)。
- 问题: 虽然安全,但也扼杀了 涌现能力。Agent 无法以你未曾预料的方式创造性地使用工具。
- 正确姿势: 默认保持工具的开放性。除非有明确的安全风险(例如执行
rm -rf /),否则应允许 Agent 传入任何它基于判断认为合理的参数。
工作流形状的工具
- 反模式: 创建一个名为
analyze_and_organize_files(directory) 的工具,把“分析”和“组织”的逻辑都打包进去。
- 问题: 你把 “判断逻辑” 捆绑进了工具实现里。要改变文件组织方式(比如从按类型改为按日期),必须重写这个工具的代码。
- 正确姿势: 拆解为
list_files、read_file、analyze_content、move_file 等原子工具。让 Agent 在运行时读取文件内容后,再决定如何分析和移动它们。
“幸福路径”思维
- 反模式: 在工具代码里写死了对所有已知边缘情况的处理逻辑(例如
if error_code == 500: retry(3))。
- 问题: 如果代码替 Agent 处理了一切,那 Agent 就退化成了一个无脑的调用器。
- 正确姿势: Agent-native 架构允许 用 Agent 的判断力来处理边缘情况。如果工具返回 500 错误,Agent 可以自行决定是立即重试、还是先检查网络连接、或是通知用户并等待指示。
成功的终极测试
想验证你构建的是否是一个真正的 Agent-native 应用?尝试这个测试:
在你的应用领域内,描述一个你想要达成的结果,但这个结果对应的功能你从未专门开发过。
然后,看看你的 Agent 能否通过在一个循环中自主运行,组合现有的原子工具,最终搞定它?如果能,那么恭喜,你走在了正确的道路上。
小结:把判断力还给 Agent
当我们深入探讨 Agent-native 时,其本质是一场关于 “控制权移交” 的深刻变革。
在传统软件工程中,我们追求确定性,试图用代码穷尽所有逻辑分支。而在 Agent-native 的世界里,我们学会了 放手。我们不再编写死板的“执行步骤”,而是提供灵活的“能力原语”。我们把 “如何做(How)” 的判断力,从僵化的代码中剥离出来,归还给了具有认知能力的 Agent。
- 平权 赋予了 Agent 与用户同等的行动能力。
- 颗粒度 为 Agent 提供了自由组合与创造的空间。
- 涌现 则让我们见证了软件超越预设设计的可能性。
这绝不意味着代码变得不再重要。恰恰相反,代码的角色发生了根本性转变——从 “指挥官” 变成了 “军火库”。开发者的核心任务是锻造精良、可靠的武器(工具),而 Agent 则负责在前线,根据瞬息万变的战况(上下文),灵活运用这些武器达成战略目标。
这,或许就是智能时代软件架构正在演进的方向。
参考链接:https://every.to/guides/agent-native
Agent-native 架构为我们打开了一扇通向全新可能的大门。如果让你用这种架构重新设计你最熟悉的一个应用(比如待办清单、邮件客户端或知识库工具),你会希望它获得哪些以前无法实现的“涌现能力”?