找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

2273

积分

0

好友

318

主题
发表于 昨天 02:30 | 查看: 4| 回复: 0

AI Agent组合原子化工具示意图

软件智能体(AI Agents)现在已经迈入了能够可靠工作的新阶段。以 Claude Code 为代表的项目证明,只要赋予一个大语言模型访问 Bash 和文件系统的权限,并让它在一个自主循环中运行直至达成目标,它就能完成复杂的多步骤任务。

这里存在一个深刻的洞见:一个优秀的编程 Agent,本质上就是一个优秀的通用 Agent。 支撑 Claude Code 重构代码库的同一套架构,同样可以用来整理你的文件、管理阅读列表,或者自动化你的工作流。

通过 Claude Code SDKGoogle 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_filesread_file 等工具,并结合自身的判断力来组合执行。你只需描述结果,Agent 负责在循环中将其实现。

涌现能力 (Emergent Capability)

原则: Agent 可以完成你从未显式设计过的任务。

这是 Agent-native 架构的飞轮效应:

  1. 你构建了原子工具和平权能力。
  2. 用户提出了一个你从未预料到的需求。
  3. Agent 通过组合现有工具,尝试完成任务(可能成功,也可能失败并揭示工具缺口)。
  4. 你观察这些模式,添加领域工具或优化 Prompt 来补强能力。
  5. 重复上述过程。

验证你的 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_filessearch_notes 工具
删除笔记 delete_filedelete_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),它们主要带来三方面价值:

  1. 词汇表 (Vocabulary): create_note 这样的工具本身就在“教育”Agent,在你的系统中“笔记”是什么概念,如何创建。
  2. 护栏 (Guardrails): 某些操作(如删除)可能需要额外的确认步骤,这些验证逻辑不应完全交给 Agent 判断。
  3. 效率 (Efficiency): 将高频、固定的操作序列打包成一个工具,可以提升执行速度并降低 LLM 的调用成本。

领域工具的设计规则: 它应该代表用户视角下的一个 概念性动作。它可以包含必要的机械验证(如参数格式检查),但 绝不能包含“做什么”或“是否做”的业务判断 —— 这属于 Prompt 和 Agent 判断力的范畴。同时,默认应保持底层原语可用,不要为了封装而关闭 Agent 的底层权限,除非出于明确的安全考虑。

升级成为代码 (Graduating to Code)

有些操作会因为性能或可靠性原因,需要从“由 Agent 动态编排”升级为“预写的优化代码”。

  1. 阶段 1: Agent 在循环中使用原子原语(灵活性最高,用于验证概念)。
  2. 阶段 2: 添加封装好的领域工具(执行更快,但仍由 Agent 决定何时调用)。
  3. 阶段 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 应该动态注入一个上下文模块,例如:

  • 可用资源 (Available Data):
    ## Available Data
    - 12 notes in /notes
    - 3 active projects in /projects
    - User preferences at /preferences.md
  • 能力 (Capabilities): 描述它能使用哪些工具,能达成什么目标(如:创建、搜索、整理笔记)。
  • 最近活动 (Recent Activity): 用户上一步做了什么,Agent 上一步执行了什么结果。

文件 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_filesread_fileanalyze_contentmove_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 架构为我们打开了一扇通向全新可能的大门。如果让你用这种架构重新设计你最熟悉的一个应用(比如待办清单、邮件客户端或知识库工具),你会希望它获得哪些以前无法实现的“涌现能力”?




上一篇:基于Electron与React构建:本地化微信聊天记录分析导出工具WeFlow详解
下一篇:Markdown简史:从博客诞生到编程世界与AI时代的通用语
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2026-1-16 00:55 , Processed in 0.271156 second(s), 39 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2025 云栈社区.

快速回复 返回顶部 返回列表