构建高效的 AI Agent¶
原文发布于 2024 年 12 月 19 日,作者 Erik Schluntz 和 Barry Zhang
引言¶
最成功的 Agent 实现并不依赖复杂框架,而是建立在简单、可组合的模式之上。 过去一年,我们与数十个跨行业团队合作构建了基于 LLM 的 Agent。一个关键发现是:最成功的实现并没有使用复杂的框架或专门的库,而是依赖简单、可组合的模式。
本文将分享我们在与客户合作以及自身构建 Agent 过程中积累的经验,为开发者提供构建高效 Agent 的实用指南。相关代码示例可参考 cookbook。
什么是 Agent?¶
"Agent"一词含义广泛,我们将其划分为"工作流"和"Agent"两类。 "Agent"可以指代多种不同的系统。我们将这些变体统称为 Agentic 系统,并在其中区分两大类:
| 类型 | 定义 | 特点 |
|---|---|---|
| 工作流(Workflows) | LLM 和工具通过预定义的代码路径进行编排 | 可预测、一致性强 |
| Agent | LLM 动态主导自身的流程和工具使用,自主决定如何完成任务 | 灵活、自适应 |
下文将详细介绍这两类 Agentic 系统的构建方式。
何时使用(以及何时不使用)Agent¶
核心原则:尽可能寻找最简单的方案,只在必要时增加复杂度。 Agentic 系统往往需要用延迟和成本换取更好的任务表现。更复杂不等于更好。
- 工作流为定义明确的任务提供可预测性和一致性
- Agent适用于需要灵活性和模型驱动决策的场景
- 对于许多应用来说,单次 LLM 调用配合检索和上下文示例通常就已足够
何时以及如何使用框架¶
框架有助于快速起步,但务必理解底层代码。 目前市面上有多种 Agent 框架:
| 框架 | 类型 |
|---|---|
| Claude Agent SDK | 代码 SDK |
| Strands Agents SDK (AWS) | 代码 SDK |
| Rivet | 拖放式 GUI 工作流构建器 |
| Vellum | GUI 工具,用于构建和测试复杂工作流 |
这些框架简化了标准底层任务(调用 LLM、定义和解析工具、链式调用等),但它们通常会创建额外的抽象层,遮蔽底层的 prompt 和响应,导致调试困难。
建议:
- 先直接使用 LLM API——很多模式只需几行代码即可实现
- 如果使用框架,确保理解底层代码
- 对底层运作的错误假设是客户出错的常见原因
构建模块、工作流和 Agent¶
构建模块:增强型 LLM¶
Agent 系统的基本构建模块是一个配备了增强能力的 LLM。 当代模型能够主动使用检索、工具和记忆等能力——自主生成搜索查询、选择合适的工具、决定保留哪些信息。

实现关键:
1. 根据具体用例定制能力
2. 确保 LLM 有一个简单、文档完善的接口
Model Context Protocol(MCP)是一种标准化的工具接口实现方式,详见构建 MCP 客户端。
工作流:Prompt 链式调用(Prompt Chaining)¶
将任务分解为固定的步骤序列,前一步的输出作为后一步的输入。 可以在中间步骤添加程序化检查("门控")来验证过程是否正确。

适用场景: 任务可以清晰地分解为固定的子任务时。目标是用延迟换取更高的准确率——让每次 LLM 调用处理更简单的任务。
示例:
- 先生成营销文案,再翻译成其他语言
- 先写文档大纲,检查是否符合标准,再基于大纲撰写正文
工作流:路由(Routing)¶
对输入进行分类,将其导向专门的后续处理流程。 这实现了关注点分离,并支持构建更专门化的 prompt。否则,针对一类输入的优化可能损害对其他输入的处理效果。

适用场景: 复杂任务存在明显不同的类别,分开处理效果更好。
示例:
- 将客服查询(通用问题、退款、技术支持)路由到不同流程
- 简单问题路由到 Claude Haiku 4.5 等小模型,困难问题路由到 Claude Sonnet 4.5 等大模型
工作流:并行化(Parallelization)¶
多个 LLM 同时处理任务,再将输出程序化聚合。 有两种变体:
| 变体 | 说明 |
|---|---|
| 分段(Sectioning) | 将任务拆分为独立的子任务并行执行 |
| 投票(Voting) | 对同一任务运行多次以获得多样化输出 |

适用场景: 子任务可以并行执行以提升速度,或者需要多个视角/尝试以提高置信度。对于复杂任务,让每个考量点由单独的 LLM 调用处理通常效果更好。
分段示例:
- 护栏系统:一个模型处理用户查询,另一个模型筛查不当内容——这比让同一个 LLM 同时处理护栏和核心响应效果更好
- 自动化评估:每个 LLM 调用评估不同的性能维度
投票示例:
- 使用多个不同 prompt 审查代码漏洞
- 使用多个 prompt 和投票阈值评估内容合规性
工作流:编排者-工作者(Orchestrator-Workers)¶
中央 LLM 动态分解任务,委派给工作者 LLM,并综合它们的结果。 与并行化的关键区别在于灵活性——子任务不是预定义的,而是由编排者根据具体输入动态确定的。

适用场景: 复杂任务中无法预测所需的子任务时。
示例:
- 编码产品对多个文件进行复杂修改
- 搜索任务从多个来源收集和分析信息
工作流:评估者-优化器(Evaluator-Optimizer)¶
一个 LLM 生成响应,另一个提供评估和反馈,形成循环。 类似于人类作者的迭代写作过程。

适用场景: 有明确的评估标准,且迭代改进能带来可衡量的价值。两个适用信号:
1. LLM 的响应在获得明确反馈后能够改善
2. LLM 能够提供这样的反馈
示例:
- 文学翻译:评估者对语言细微差异提出批评
- 复杂搜索任务:需要多轮搜索和分析
Agent¶
当 LLM 的能力足以理解复杂输入、进行推理规划、可靠地使用工具并从错误中恢复时,Agent 便在生产环境中涌现。 Agent 从人类用户的指令或交互式讨论开始。一旦任务明确,Agent 就会独立规划和运作,可能在需要更多信息或判断时回到人类那里。
执行过程中,关键是让 Agent 在每一步都能从环境获取"真实信息(ground truth)"。Agent 可以在检查点或遇到阻碍时暂停等待人类反馈。
实现方式: 通常就是 LLM 在循环中基于环境反馈使用工具。因此,清晰周到地设计工具集及其文档至关重要。

适用场景: 开放式问题,无法预测所需步骤数量,无法硬编码固定路径。需要对 Agent 的决策有一定程度的信任。
注意事项: 自主性意味着更高的成本和错误累积的风险。建议在沙盒环境中进行充分测试,并设置适当的护栏。
示例:
- 解决 SWE-bench 任务的编码 Agent(涉及多文件编辑)
- computer use 参考实现——Claude 使用计算机完成任务
组合与定制这些模式¶
这些是常见的模式,开发者可以根据不同用例进行塑造和组合。 成功的关键是衡量性能并迭代实现。只在复杂度明确能改善结果时才增加复杂度。
总结¶
在 LLM 领域取得成功的关键不是构建最复杂的系统,而是为你的需求构建正确的系统。
推荐路径:
1. 从简单 prompt 开始
2. 通过全面评估进行优化
3. 只在简单方案不够时才引入多步 Agent 系统
实现 Agent 的三大核心原则:
| 原则 | 说明 |
|---|---|
| 简单性 | 保持 Agent 设计的简洁 |
| 透明性 | 明确展示 Agent 的规划步骤 |
| 工具文档与测试 | 精心打造 Agent-计算机接口(ACI) |
框架有助于快速入门,但进入生产环境时,不要犹豫去减少抽象层,用基础组件构建。
附录 1:Agent 的实践应用¶
两个最具实际价值的应用领域展示了 Agent 最佳适用条件:需要对话与行动结合、有明确成功标准、能形成反馈循环、有人类监督。
A. 客户支持¶
客户支持是开放式 Agent 的天然适用场景:
| 维度 | 优势 |
|---|---|
| 对话流 | 支持交互自然遵循对话模式,同时需要访问外部信息 |
| 工具集成 | 可拉取客户数据、订单历史、知识库文章 |
| 操作执行 | 退款、更新工单等可程序化处理 |
| 成功衡量 | 可通过用户定义的解决方案明确衡量 |
一些公司通过"按成功解决收费"的定价模式验证了其商业可行性。
B. 编码 Agent¶
软件开发展现了 LLM 的巨大潜力,能力从代码补全演进到自主问题解决:
| 维度 | 优势 |
|---|---|
| 可验证性 | 代码方案可通过自动化测试验证 |
| 反馈循环 | Agent 可利用测试结果迭代 |
| 问题定义 | 问题空间定义明确且结构化 |
| 质量度量 | 输出质量可客观衡量 |
在 Anthropic 的实现中,Agent 可以在 SWE-bench Verified 基准测试中解决真实的 GitHub issue。但人类审核对于确保方案符合更广泛的系统需求仍然至关重要。
附录 2:工具的 Prompt 工程¶
工具定义和规范应该获得与整体 prompt 同等程度的 prompt 工程关注。 Tools 使 Claude 能够通过 API 中的结构和定义与外部服务交互(参见 tool use API 文档)。
同一个操作可以有多种规范方式(例如文件编辑可用 diff 或重写整个文件;结构化输出可用 markdown 或 JSON)。某些格式对 LLM 来说比其他格式难得多:
- 写 diff 需要在写新代码之前就知道 chunk header 的行数
- JSON 需要对换行符和引号进行额外转义
工具格式建议¶
| 建议 | 说明 |
|---|---|
| 充足的思考 token | 给模型足够的 token 来"思考",避免写到一半陷入死角 |
| 自然格式 | 保持格式接近模型在互联网文本中自然遇到的形式 |
| 零格式开销 | 确保没有格式"开销",如准确的行数统计或字符串转义 |
好的 ACI(Agent-计算机接口)设计指南¶
经验法则:想想在人机接口(HCI)上投入了多少精力,计划在 Agent-计算机接口(ACI)上投入同样多的精力。
| 原则 | 详细说明 |
|---|---|
| 换位思考 | 站在模型的角度——仅凭描述和参数,工具用法是否明显?好的工具定义应包含示例用法、边界情况、输入格式要求,以及与其他工具的明确边界 |
| 直观命名 | 修改参数名称或描述使其更直观——把它想象成为团队中的初级开发者编写一份优秀的 docstring |
| 充分测试 | 在 workbench 中运行大量示例输入,观察模型犯的错误,并不断迭代 |
| 防呆设计(Poka-yoke) | 修改参数设计使犯错更加困难 |
实践案例¶
在 SWE-bench 的工作中,我们花在优化工具上的时间实际上比优化整体 prompt 还多。我们发现模型在离开根目录后使用相对文件路径时会犯错。解决方案是将工具改为始终要求绝对路径——模型使用这种方式后表现完美。