文章 / AI实践

Building Effective Agents|构建有效的智能体

3,725 字 阅读约 9 分钟
目录 ▾

Building Effective Agents|构建有效的智能体 【翻译+总结】

原文链接:Building Effective AI Agents \ Anthropic

更新说明: 本文所描述的许多工具生态,自 2024 年 12 月以来已经发生变化。关于 Anthropic 当前采用的方法,请参阅 How we built Claude Managed Agents 以及 Managed Agents documentation。

过去一年里,我们与来自不同行业的数十个团队合作,共同构建大型语言模型(LLM)智能体。

我们反复观察到一个现象:

最成功的实现,并没有使用复杂的框架(Framework)或专门的库(Specialized Libraries)。相反,它们往往建立在简单、可组合(Composable)的模式之上。

在本文中,我们将分享与客户合作以及亲自构建 Agent 过程中获得的经验,并为开发者提供一些关于如何构建有效 Agent 的实用建议。


一、什么是 Agent?

“Agent”可以有很多种定义。

一些客户将 Agent 定义为一种完全自主的系统:它可以在较长时间内独立运行,并使用各种工具完成复杂任务。

另一些客户则使用 Agent 这个词来描述更加规定式(Prescriptive)的实现,也就是按照预先定义好的工作流执行任务。

在 Anthropic,我们将这些不同形式统称为:

Agentic Systems(智能体系统)

但在架构层面,我们会特别区分两类系统。

Workflows

Workflows 是通过预先定义好的代码路径(Predefined Code Paths)来编排 LLM 和工具的系统。

Agents

Agents 则是由 LLM 动态决定自己的执行过程以及工具使用方式的系统。

也就是说,LLM 自己掌握“如何完成任务”的控制权。

译者注:

这是全文最重要的定义之一。

Workflow 和 Agent 的核心区别并不是“简单 vs 复杂”,而是:谁拥有执行路径的控制权?

Workflow

程序决定下一步
    ↓
调用 LLM / Tool
    ↓
程序继续决定下一步
Agent

LLM 判断当前状态
    ↓
决定下一步 Action
    ↓
调用 Tool
    ↓
获得 Environment Feedback
    ↓
LLM 再次决定

二、什么时候应该使用 Agent?什么时候不应该?

在构建 LLM 应用时,我们建议:

尽可能寻找最简单的解决方案,只在确实有必要的时候增加复杂度。

这甚至可能意味着完全不构建 Agentic System。

Agentic Systems 通常是在用:

更高 Latency
+
更高 Cost
        ↓
换取
        ↓
更好的 Task Performance

因此,需要认真判断这种权衡什么时候才真正值得。

当确实需要增加复杂度时:

Workflow 更适合定义明确的任务,因为它能够提供更好的:

  • Predictability(可预测性)
  • Consistency(一致性)

而当任务需要:

  • Flexibility(灵活性)
  • Model-driven Decision-making(模型驱动决策)

并且需要规模化运行时,Agent 往往更加合适。

但对于很多应用来说:

优化一次 LLM 调用,再结合 Retrieval 和 In-context Examples,通常已经足够。

译者注:

Anthropic 隐含给出了一个非常重要的复杂度阶梯:

Single LLM Call
        ↓
LLM + Retrieval / Tools
        ↓
Workflow
        ↓
Agent

原则是:

上一层能解决问题
        ↓
不要进入下一层

三、什么时候以及如何使用 Framework?

目前已经有很多 Framework 可以帮助开发者更加容易地实现 Agentic Systems,例如:

  • Claude Agent SDK
  • AWS Strands Agents SDK
  • Rivet
  • Vellum

这些 Framework 可以简化很多标准的底层工作,例如:

  • 调用 LLM
  • 定义 Tools
  • 解析 Tool Calls
  • 将多个 LLM Call 串联起来

因此,它们能够帮助开发者快速开始。

但是 Framework 往往也会引入额外的抽象层(Abstraction Layers)。

你的代码
   ↓
Framework
   ↓
Prompt 构造
   ↓
LLM API
   ↓
Tool Call
   ↓
Framework Runtime

抽象层越多,你越可能看不到:

模型到底收到了什么?
模型到底返回了什么?
Tool Call 到底如何产生?
History 如何被拼接?
失败是在哪一层发生的?

这会让 Debugging 变得更加困难。

Framework 还可能诱使开发者加入原本并不需要的复杂度,而一个更加简单的实现可能已经足够。

因此,我们建议开发者:

一开始直接使用 LLM API。

很多常见 Agent Pattern 实际上只需要几行代码就能够实现。

如果确实使用 Framework,也应该确保:

你理解 Framework 底层到底在做什么。


四、Building Blocks、Workflows 与 Agents

接下来,我们会介绍在生产环境中经常看到的一些 Agentic System Pattern。

整体复杂度是逐步增加的:

Augmented LLM
      ↓
Prompt Chaining
      ↓
Routing
      ↓
Parallelization
      ↓
Orchestrator-Workers
      ↓
Evaluator-Optimizer
      ↓
Autonomous Agent

这里并不是说后面的模式一定“更高级”。

而是:

控制逻辑更动态
+
系统复杂度更高
+
模型拥有更多决策空间

五、Building Block:Augmented LLM

Agentic System 最基本的构建模块,是一个经过增强的 LLM。

也就是:

Augmented LLM(增强型 LLM)

典型结构:

             ┌──────── Retrieval
             │
User → LLM ──┼──────── Tools
             │
             └──────── Memory

可以简单理解为:

LLM
+
Retrieval
+
Tools
+
Memory
=
Augmented LLM

现在的模型已经能够主动使用这些能力,例如:

自己生成 Search Query
        ↓
选择合适的 Tool
        ↓
获取外部信息
        ↓
判断哪些信息应该保留

在实现这些能力时,我们建议重点关注两个问题。

第一:针对具体 Use Case 定制能力

不要只是因为某个能力存在就接入。

需要根据实际业务场景设计:

Retrieval
Tool
Memory
Context

第二:为 LLM 提供简单且文档清晰的接口

LLM 是否能够可靠地使用这些能力,很大程度上取决于接口本身是否容易理解。

译者注:

可以把 Augmented LLM 看成整个 Agent 系统的“原子能力”。

后面的 Workflow 和 Agent,本质上是在解决:

这些能力怎么组织?
        +
什么时候调用?
        +
由谁决定调用?

六、Workflow:Prompt Chaining

**Prompt Chaining(提示链)**将一个任务拆解成一系列连续步骤。

每一次 LLM Call 都处理上一次 LLM Call 的输出。

Task
 ↓
LLM 1
 ↓
Output 1
 ↓
LLM 2
 ↓
Output 2
 ↓
LLM 3
 ↓
Final Result

还可以在中间加入程序化检查:

LLM 1
  ↓
Output
  ↓
 Gate
 /   \
通过   不通过
 ↓      ↓
LLM 2  Retry / Reject / Human

什么时候适合 Prompt Chaining?

当任务可以非常容易、清晰地拆解成固定子任务时,这种 Workflow 非常合适。

核心权衡是:

更多 LLM Calls
      ↓
更高 Latency
      ↓
每一步任务更简单
      ↓
整体 Accuracy 可能更高

示例

生成营销文案
    ↓
翻译成目标语言

或者:

生成 Outline
    ↓
检查 Outline
    ↓
满足要求?
  /      \
否        是
↓         ↓
修改      撰写全文

译者注:

Prompt Chaining 真正重要的不只是“串起来”,而是:

中间步骤可以加入确定性的 Gate。


七、Workflow:Routing

**Routing(路由)**首先对输入进行分类,然后把输入发送到专门的后续任务。

                ┌→ General QA Workflow
                │
Input → Router ─┼→ Refund Workflow
                │
                └→ Technical Support Workflow

这样可以实现:

Separation of Concerns(关注点分离)

不同类型的问题可以使用不同的:

Prompt
Model
Tool
Workflow
Policy

什么时候适合 Routing?

当一个复杂任务存在明显不同的类别,并且不同类别最好分别处理时,Routing 非常有效。

前提是:

Classification 能够比较准确地完成。

分类可以由:

Rules
Traditional Classifier
LLM

完成。

模型 Routing 示例

User Question
     ↓
   Router
   /    \
简单     复杂
 ↓        ↓
Haiku   Sonnet

这样可以在:

Cost
Performance
Latency

之间进行权衡。

译者注:

Routing 并不等于 LLM Routing。

更合理的生产结构往往是:

Input
  ↓
Rules 能确定?
 /          \
是           否
↓            ↓
Rule Route   LLM Routing
                ↓
            仍不确定?
             /     \
            否      是
            ↓       ↓
        Workflow  Unknown/Human

LLM Routing 真正擅长的通常是:

模糊输入
+
非结构化信息
+
多信号综合
+
规则难以穷举的长尾情况

八、Workflow:Parallelization

有些任务可以让多个 LLM 同时执行,然后通过程序聚合结果。

这种 Workflow 称为:

Parallelization(并行化)

主要有两种形式。

1. Sectioning

将任务拆成多个相互独立的子任务,并行执行。

                  ┌→ Worker A:安全检查
                  │
Task → Fan-out ───┼→ Worker B:事实检查
                  │
                  ├→ Worker C:格式检查
                  │
                  └→ Worker D:质量检查
                          ↓
                       Fan-in
                          ↓
                     Final Result

2. Voting

让多个 LLM 执行相同任务,再聚合结果。

                 ┌→ LLM 1 → Result A
                 │
Same Task ───────┼→ LLM 2 → Result B
                 │
                 └→ LLM 3 → Result C
                           ↓
                          Vote
                           ↓
                      Final Decision

什么时候适合 Parallelization?

主要有两个目标:

目标 1:Speed
独立任务并行执行

目标 2:Confidence
多个 Perspective / Attempt

译者注:

对后端开发而言,可以直接类比:

fan-out
   ↓
workers
   ↓
fan-in

真正困难的通常不是并发本身,而是:

Timeout
Partial Failure
Retry
Result Conflict
Aggregation
Cancellation
Overall Budget

九、Workflow:Orchestrator-Workers

在 Orchestrator-Workers Workflow 中:

一个中央 LLM 动态拆解任务;

然后把子任务分配给 Worker;

最后综合结果。

Complex Task
     ↓
Orchestrator LLM
     ↓
动态拆解 Subtasks
     ↓
 ┌──────┬──────┬──────┐
 ↓      ↓      ↓      ↓
W1     W2     W3     W4
 └──────┴──────┴──────┘
         ↓
      Synthesis
         ↓
    Final Result

与 Parallelization 的关键区别

Parallelization:

Task
 ↓
程序提前知道:
A / B / C 三个任务
 ↓
并行执行

Orchestrator-Workers:

Task
 ↓
Orchestrator 分析
 ↓
“这个任务需要 A、C、F、G”
 ↓
动态创建 Worker Tasks

也就是说:

Parallelization
≈ Static DAG
Orchestrator-Workers
≈ Dynamic DAG Generation

Coding 示例

用户:

修复这个 GitHub Issue

系统一开始并不知道:

要改几个文件?
哪些文件?
每个文件改什么?
是否需要补测试?
是否需要改配置?

这些 Subtasks 必须在运行过程中动态确定。


十、Workflow:Evaluator-Optimizer

在 Evaluator-Optimizer Workflow 中:

一个 LLM 负责生成;

另一个 LLM 负责评估和反馈;

然后循环改进。

Generator
   ↓
 Draft
   ↓
Evaluator
   ↓
Feedback
   ↓
Generator
   ↓
Revision
   ↓
Evaluator
   ↓
...

最终需要明确的停止条件:

Evaluator
   ↓
达到标准?
 /      \
是       否
↓        ↓
Stop   Revision

什么时候适合?

必须至少满足两个条件。

条件一:存在明确 Evaluation Criteria

也就是说:

“更好”能够被定义

条件二:Feedback 能真正产生改进

Draft
 ↓
具体 Feedback
 ↓
Revision
 ↓
指标明显提升

而不是:

Draft
 ↓
“可以更好”
 ↓
换一种说法
 ↓
继续换一种说法

译者注:

Evaluator-Optimizer 最关键的问题是:

什么时候停止?

需要提前设计:

Quality Threshold
Maximum Iterations
No Improvement Detection
Token Budget
Time Budget

十一、Agents

随着 LLM 在以下能力上不断成熟:

  • 理解复杂输入
  • Reasoning
  • Planning
  • Reliable Tool Use
  • Error Recovery

Agent 开始逐渐进入生产环境。

Agent 最基本的执行机制可以表示为:

Human Request
     ↓
Understand Task
     ↓
Plan / Decide
     ↓
Choose Action
     ↓
Call Tool
     ↓
Environment
     ↓
Observation
     ↓
Update Understanding
     ↓
Decide Next Action
     ↓
    ...

也就是:

Decide
  ↓
Act
  ↓
Observe
  ↓
Decide
  ↓
Act
  ↓
Observe
  ↓
...

Ground Truth

Agent 在执行过程中非常重要的一件事情是:

不断从 Environment 获得 Ground Truth。

例如:

Tool Call Result
Code Execution Result
Database Result
API Response
Test Result
File State
Browser State

于是 Agent 不应该只是:

LLM 思考
   ↓
LLM 再思考
   ↓
LLM 认为完成了

而应该是:

LLM 判断
   ↓
真实 Action
   ↓
Environment 返回真实结果
   ↓
LLM 根据真实结果继续判断

Agent 为什么需要 Stop Conditions?

因为 Agent 可能运行很多 Turn。

如果没有约束:

判断
 ↓
调用工具
 ↓
失败
 ↓
再调用
 ↓
换一个工具
 ↓
继续尝试
 ↓
...

可能无限运行。

因此通常需要:

Max Iterations
Max Tool Calls
Max Model Calls
Deadline
Token Budget
Cost Budget
No-progress Detection
Human Checkpoint

译者注:

Agent 最小实现虽然简单,但生产级 Agent 真正困难的是外围 Runtime。

              ┌── Permissions
              ├── Tool Schema
              ├── Context
              ├── Budget
LLM Loop ─────┼── Timeout
              ├── Retry
              ├── Guardrails
              ├── Stop Conditions
              └── Eval

十二、组合和定制这些 Pattern

这些 Building Blocks 并不是规定式架构。

它们只是生产环境中经常出现的 Pattern。

实际系统完全可能是:

Input
 ↓
Routing
 ↓
Parallel Evidence Collection
 ↓
Prompt Chaining
 ↓
证据够吗?
 /      \
是       否
↓        ↓
Report   Agent Investigation
           ↓
        More Tools
           ↓
        New Evidence
           ↓
        Evaluator
           ↓
        Final Report

因此重点不是:

“我要选哪一个 Pattern?”

而是:

这个问题的哪一部分
适合什么控制方式?

最终原则仍然是:

增加复杂度
    ↓
必须能够证明
    ↓
Outcome 改善

十三、总结

在 LLM 领域取得成功,并不是构建最复杂、最先进的系统。

真正重要的是:

构建最适合自己需求的系统。

可以将 Anthropic 的整体思想浓缩为:

Start Simple
    ↓
Measure
    ↓
Identify Failure Cases
    ↓
Add Only Necessary Complexity
    ↓
Measure Again

在实现 Agent 时,有三个核心原则。

1. Simplicity

能用简单方案解决
        ↓
不要引入复杂 Agent

2. Transparency

Agent 做了什么?
为什么调用这个 Tool?
得到了什么 Observation?
为什么继续?
为什么停止?

这些过程应该尽可能可观察。

3. ACI

认真设计:

Agent-Computer Interface

包括:

Tool Name
Tool Description
Parameters
Return Schema
Error Semantics
Permissions
Examples
Edge Cases

附录 1:Agents in Practice

Anthropic 与客户合作的过程中发现,有两个领域特别适合 AI Agent。

它们共同具有:

Conversation
+
Action
+
Clear Success Criteria
+
Feedback Loop
+
Human Oversight

A. Customer Support

Customer Support 天然符合 Agent 模型。

用户提出问题
    ↓
Agent 理解需求
    ↓
查询 Customer Data
    ↓
查询 Order History
    ↓
查询 Knowledge Base
    ↓
决定 Action
    ↓
Refund / Update Ticket / Reply
    ↓
确认问题是否解决

它的重要优势是:

Success 可以比较明确地衡量。


B. Coding Agents

Coding Agent 也是一个非常典型的 Agent 场景。

Issue
 ↓
理解代码
 ↓
定位文件
 ↓
修改代码
 ↓
运行 Tests
 ↓
失败?
 /   \
是    否
↓     ↓
继续改  Human Review

Coding Agent 特别适合 Agent Loop,是因为它天然存在大量 Ground Truth:

Compiler
Tests
Linter
Runtime
Git Diff
File System

这让 Agent 能够形成非常清晰的 Feedback Loop。


附录 2:Prompt Engineering Your Tools

无论构建哪种 Agentic System,Tools 都很可能是重要组成部分。

Tool 本质上是:

LLM
 ↓
Tool Interface
 ↓
External System / API
 ↓
Tool Result
 ↓
LLM

Anthropic 强调:

Tool Definition 和 Tool Specification 应该获得与整体 Prompt 同等程度的工程投入。


Tool Format 的选择

同一个动作可能存在多种表达方式。

例如修改文件:

方案 A:
生成 Diff

方案 B:
重写整个文件

对传统程序而言,两者可能可以无损转换。

但对 LLM 而言:

格式复杂度
≠
生成难度相同

例如 JSON 中写代码:

需要处理:
newline escaping
quote escaping
nested structure

Markdown 则更加自然。

因此 Tool Format 应该遵循:

自然
+
低格式负担
+
低出错概率

ACI:Agent-Computer Interface

可以把 Tool Design 类比成人类世界的 HCI。

Human
 ↓
HCI
 ↓
Computer

对应 Agent:

Agent
 ↓
ACI
 ↓
Computer / Environment

好的 ACI 应该让模型:

知道什么时候使用这个 Tool
知道什么时候不能使用
知道每个参数是什么意思
知道返回结果代表什么
知道失败后怎么办

Poka-yoke:防错设计

Anthropic 特别强调:

不要只告诉模型:

“请小心,不要犯错。”

更好的方法是:

重新设计 Tool
    ↓
让错误本身更难发生

例如:

Before

edit_file(
    path="../src/a.py"
)

Agent 更容易因为当前目录变化而出错。

改成:

After

edit_file(
    absolute_path="/repo/src/a.py"
)

从接口层面消除一类错误。

这就是:

Poka-yoke / Mistake-proofing。


最终学习框架

整篇文章最终可以压缩成下面这套判断逻辑:

真实问题
   ↓
Single LLM Call 能解决吗?
   ├─ Yes → 使用最简单方案
   │
   └─ No
       ↓
固定路径能提前定义吗?
       ├─ Yes
       │    ↓
       │  Workflow
       │    ├─ Prompt Chaining
       │    ├─ Routing
       │    ├─ Parallelization
       │    ├─ Orchestrator-Workers
       │    └─ Evaluator-Optimizer
       │
       └─ No
            ↓
执行路径是否依赖运行时 Observation?
            ├─ No → 继续优化 Workflow
            │
            └─ Yes
                 ↓
               Agent
                 ↓
       Decide → Act → Observe
            ↑            ↓
            └────────────┘

而无论使用哪一种架构,外围始终需要:

Tool Design
Context
Permissions
Budget
Timeout
Guardrails
Error Recovery
Stopping Conditions
Eval
Human Oversight

最终原则不是:

Build the most advanced Agent

而是:

Build the simplest system
that reliably solves the problem.

即:

构建能够可靠解决问题的最简单系统。

易浅小站

EACHEN STUDIO / ARTICLE END

关于作者 →
RELATED / 3