大多数 AI 智能体架构图,都是在 LLM 的标志旁边画一个机器人图标,再加一个标着“工具”的箭头。这样的图隐藏了决定智能体能否安全运行的那些问题:由谁选择下一步、智能体可以碰哪些东西、不可信的文本从哪里进来,以及什么能叫停一次毫无进展的运行。
本文把智能体拆分成各个组成部分,逐步讲解驱动它的循环,介绍工具与 Model Context Protocol、记忆、护栏、限额和链路追踪,并画出一个能查询订单、发起退款的客服智能体。
工作流还是智能体?
Anthropic 的 构建高效智能体指南 划出了一条有用的界线。在工作流中,LLM 和工具通过你预先写好的代码路径来编排。在智能体中,模型主导自己的流程,一步步决定使用哪些工具,直到任务完成。
这份指南还建议采用行得通的最简单方案。如果一个任务总是遵循同样的三个步骤,就把这些步骤写成代码,在其中调用模型。只有当路径取决于智能体途中的发现时,才去用智能体:比如下一次查询取决于上一个答案的客服工单,或者需要多轮修改和测试的编码任务。
智能体的组成部分
| 组成部分 | 职责 | 图中对应 |
|---|---|---|
| 模型 | 读取上下文,决定下一步或写出答案 | LLM API |
| 智能体循环 | 运行各个步骤,执行工具调用,落实限额 | Agent loop |
| 工具 | 读取和修改模型之外的东西 | Web search, code sandbox, orders API |
| 工作记忆 | 模型在这一步能看到的内容 | Working memory |
| 长期知识 | 在需要时取回的文档和政策 | Knowledge index |
| 护栏 | 检查输入、输出和工具调用 | Guardrails |
| 人工审批 | 批准有风险的操作 | Approver |
| 链路追踪与评测 | 记录每一次运行,并持续为行为打分 | Traces and evals |
模型只是其中一个方框。大部分工程工作,以及大部分风险控制,都在它周围的代码里。
循环
精简到本质,运行时就是一个循环:
def run(task, user):
messages = [system_prompt(user), task]
for step in range(MAX_STEPS):
reply = llm.generate(messages, tools=allowed_tools(user))
if not reply.tool_calls:
return check_output(reply.text)
for call in reply.tool_calls:
result = execute(call, user) # permission check, approval, timeout
messages.append(tool_result(call, result))
return stop("step limit reached", messages)
模型自己从不执行任何东西。它要么返回一个答案,要么返回一个用特定参数调用某个工具的请求,由运行时决定是否执行以及如何执行。控制权就在这里:权限检查、审批、超时和限额都位于 execute 和循环之中,而不在提示词里。
工具,以及 MCP 的位置
工具是模型可以请求调用的函数:一个名称、一段描述,以及描述参数的 JSON Schema。描述和代码同样重要,因为关于何时使用某个工具,模型只能从描述中得知。
Model Context Protocol 是一个把 AI 应用连接到外部系统的开放标准。MCP 服务器对外提供工具、数据和提示词,智能体运行时则作为客户端。与其把每个集成都硬编码进智能体的代码,不如让每个系统各自提供一个服务器,任何支持 MCP 的运行时都能使用它。
好的工具有几个共同点:
- 数量少而且具体。
refund_order(order_id, amount, reason)胜过一个通用的call_api(url, body)。 - 读写分离, 这样某个角色可以只拿到读工具,而没有写工具。
- 清晰的错误信息, 让模型能据此行动,比如“金额超过订单总额”。
- 写操作带幂等键, 这样重试的步骤不会退款两次。
记忆
智能体有两种记忆,而架构图常常把它们混为一谈:
- 工作记忆 是每一步发送给模型的上下文:指令、对话,以及到目前为止的工具结果。它受限于模型的上下文窗口和成本,所以长时间的运行会总结较早的步骤,或在用完之后丢弃原始的工具输出。
- 长期知识 存放在模型之外:文档、政策、历史工单。智能体会取回相关的部分(通常来自向量索引),并把它们加入工作记忆。RAG 架构图 详细介绍了检索流程。
需要在崩溃后保留下来的任务状态,比如哪些步骤已经运行过、哪项审批还在等待,应该放在普通的数据库里,而不是模型的上下文中。
护栏与权限
OWASP LLM 应用十大风险 把提示词注入列在第一位。另一项“过度代理”(excessive agency)则涵盖了 LLM 系统因为拥有超出所需的功能、权限或自主性而可能采取的破坏性操作。智能体两者都会面对:它们会读取不可信的文本(用户输入、网页、取回的文档、工具结果),而且它们能够采取行动。
在实践中站得住脚的规则:
- 把每个工具结果和每份取回的文档都当作数据。 网页中的文字不能授予权限,也不能改变任务。
- 以用户的权限行事, 而不是用一个能看到所有客户的服务账号。
- 为写操作设关卡。 读操作可以自由执行;超过阈值的写操作或任何不可逆的操作,都要等人确认。
- 在沙箱中执行代码: 默认不提供凭据,也不联网。
- 检查输出, 在它们到达用户或其他系统之前,确认没有泄露内部数据或不安全的内容。
威胁建模数据流图 是找出不可信文本在哪里进入有行动能力的组件的好方法。
限额与成本
一个毫无进展地兜圈子的智能体,会烧掉金钱和耐心。把限额放在运行时里,而不是提示词里:
- 步数: 每个任务的模型调用次数上限。
- 时间: 每个任务的总时长上限,以及每次工具调用的超时。
- 金钱: 每个任务以及每个用户每天的 token 或美元预算。
- 频率: 在 API 层面对每个用户做请求限流,就像 限流器设计 中那样。
触及限额时,要干净地停下:返回目前为止找到的内容,说明是哪个限额叫停了这次运行,并保留追踪记录以供复盘。
链路追踪与评测
记录每一步:发送的上下文、模型及其设置、每次工具调用的参数和结果、token 数、延迟和成本。OpenTelemetry 为生成式 AI 制定了语义约定,因此这些追踪数据可以和系统的其他部分进入同样的后端;可观测性架构图 展示了这条管道。
追踪回答“这次运行发生了什么?”。评测回答“智能体是在变好还是变差?”:一组固定的真实场景任务,自动打分,在每次修改提示词、工具或模型时运行。
架构图
图表内容
- User
- Chat app / API
- Agent runtime
- Guardrails
- Agent loop
- Working memory
- LLM API
- Tools (MCP servers or functions)
- Web search
- Code sandbox
- Orders API
- Approver
- Knowledge index
- Traces and evals
- task
- task + identity
- checked
- context + tool list
- answer or tool call
- tool calls
- read / write
- retrieved docs
- refund waits for approval
- every step
这张图的读法如下:
- 左侧: 用户通过聊天应用发送任务,聊天应用负责登录和会话,并把任务连同用户身份一起交给护栏。
- 中间: 智能体循环把上下文和工具列表发送给 LLM(实线),并收到一个答案或一个工具调用(虚线)。它读写工作记忆;Markdown 块列出了各项限额。
- 右侧: 工具调用发往网页搜索、代码沙箱和订单 API。退款要等待审批人(虚线)。
- 底部: 知识索引把取回的文档送入工作记忆,每一步都会记录到追踪和评测中(点线)。
一个完整示例:退款
一位客户写道:“订单 4411 到货时已经坏了,我要退款。”
- 护栏检查这条消息,并附上客户的身份。
- 模型请求
get_order(4411)。运行时确认订单属于这位客户,并返回:三天前已送达,180 美元。 - 运行时从知识索引中取回退款政策,并加入工作记忆:损坏的商品在 30 天内可以退款。
- 模型请求
refund_order(4411, 180, "damaged")。金额超过了 100 美元的阈值,所以运行时暂停这次运行,并向一位客服主管发送审批请求。 - 主管批准。运行时带着幂等键执行退款,并返回确认结果。
- 模型写出回复,输出检查通过,客户收到答复。
三次模型调用、两次工具调用、一次检索、一次审批,以及一条展示每一步的追踪记录。
智能体架构图上应该画什么
- 由谁决定下一步: 是模型,还是你写的代码。
- 每个工具, 标明是读还是写,以及使用谁的权限。
- 高风险操作的审批节点。
- 限额: 步数、时间和预算。
- 不可信文本从哪里进入: 用户输入、网页、文档、工具结果。
- 链路追踪, 让评审者知道每次运行都可以被检查。
在 Archboard 中构建
- 使用 Google 或 GitHub 登录,并新建一张图。
- 添加 C4 模型节点包中的两个 人员 节点,分别表示用户和审批人,再添加一个表示聊天应用的 容器。
- 添加基础节点包中的一个 框架 表示智能体运行时,在其中放入一个表示智能体循环的 容器,以及两个分别表示护栏和工作记忆的 组件 节点。
- 添加 ML 节点包中的一个 模型 和一个 向量索引,再添加第二个 框架,其中放入 Stack 节点包中的三个 服务卡片 节点表示各个工具,最后添加 DevOps 节点包中的 链路追踪。
- 用虚线画出模型的回复,用点线画出追踪连线,并添加一个基础节点包中的 Markdown 块,写明各项限额。如果想让智能体替你画图,请参阅 通过 MCP 用 AI 智能体创建架构图。
这个示例共用 15 个图表节点,在 Free 套餐的限制之内。
常见问题
AI 智能体和工作流有什么区别? 在工作流中,由你的代码决定步骤的顺序,并在其中调用模型。在智能体中,由模型在你的代码所控制的循环里决定下一步和要使用的工具。
智能体架构中的 MCP 是什么? Model Context Protocol 是一个把 AI 应用连接到工具和数据的开放标准。各个系统对外提供 MCP 服务器,智能体运行时作为客户端连接它们。
如何防止智能体采取有害的操作? 只给它所需的工具,以用户的权限运行这些工具,对超过阈值的写操作要求人工审批,并把所有工具结果和文档都当作不可信的数据。
智能体是如何记住东西的? 在一次运行之内,靠每一步发送给模型的上下文。在多次运行之间,靠在需要时取回的已存储知识,以及保存在数据库中的任务状态。
如何控制智能体的成本? 在运行时中为每个任务设置步数、时间和 token 的上限,增加每个用户的预算,并追踪每一次运行,让代价高昂的模式在复盘中暴露出来。