AI Agent 关键技术详解:从 Function Calling 到 Guardrails 的工程栈

作者:Codex 整理时间:2026-04-24 10:24:56 CST 来源:参考 AI Agent 全景指南:从基础认知到工程化落地 第五章“关键技术”扩写 主题:系统介绍支撑 AI Agent 能力落地的关键技术栈,包括 Function Calling、MCP、RAG 与向量库、结构化输出、状态管理、Guardrails、Planning、Memory、Observability 与 Evaluation。文章重点不是罗列术语,而是解释这些技术分别解决什么工程问题、如何组合成生产级 Agent 系统,以及它们之间的边界与误区。

一、先看整体:Agent 技术栈解决的不是“更聪明”,而是“可行动、可恢复、可治理”

讨论 Agent 关键技术时,最容易掉进一个误区:

把 Agent 的能力全部归因于大模型本身。

模型当然是核心。没有模型的语言理解、推理、代码生成、计划生成能力,Agent 很难成立。 但从工程系统角度看,Agent 的可用性并不只来自模型,而来自一组围绕模型建立起来的技术栈。

这些技术栈分别回答不同问题:

  • 模型如何把“想做什么”变成程序能执行的动作
  • 系统如何把外部工具、数据源、业务系统接给模型
  • Agent 如何获得超出参数记忆之外的知识
  • 输出如何稳定变成 JSON、表单、命令、计划或 API 入参
  • 多轮任务如何保持状态、失败后如何恢复
  • 高风险动作如何被权限、策略、审计与人工确认约束
  • 任务执行过程如何被观测、评估、回放和持续改进

所以,Agent 的关键技术不是一堆孤立名词,而是一套运行支撑系统:

如果把 Agent 看成一个任务推进系统,那么大模型更像“决策与生成核心”,而这些关键技术共同构成“运行时外骨骼”。 没有这层外骨骼,模型可以回答问题,却很难稳定执行任务;可以偶尔演示成功,却很难长期运行在真实业务环境里。

这一点非常重要。 真正的 Agent 工程化,不是让 Prompt 写得更玄,而是让模型的每次判断都能进入系统化流程:

  • 输入有上下文和权限边界
  • 决策有结构化表达
  • 调用有路由、校验和审计
  • 检索有证据和来源
  • 状态有持久化和恢复点
  • 输出有 schema 和业务验证
  • 风险有策略门禁和人工接管
  • 结果有评测与可观测数据

下面逐项展开。

二、Function Calling:让模型把“意图”变成可执行的结构化动作

Function Calling,也常被放在更宽泛的 Tool Calling 体系里理解。 它解决的核心问题是:

模型输出不能只是一段自然语言,而要能表达“我要调用哪个函数,以及参数是什么”。

在普通对话中,模型可能这样回答:

“我需要查询订单 12345 的物流状态。”

这句话人能看懂,但程序不能稳定执行。 Function Calling 则要求模型输出类似这样的结构化意图:

{
  "name": "query_order_shipping",
  "arguments": {
    "order_id": "12345"
  }
}

这一步的意义非常大。 因为一旦模型能稳定输出函数名和参数,Agent 就可以把语言推理和程序执行接起来。

1. Function Calling 不是“模型真的执行了函数”

这是一个常见误解。

Function Calling 本身并不等于模型在执行函数。 更准确地说,它让模型产生一个结构化调用请求,然后由 Agent Runtime 或应用后端决定:

  • 这个函数是否存在
  • 当前用户是否有权限调用
  • 参数是否符合 schema
  • 是否需要二次确认
  • 是否进入队列异步执行
  • 执行结果如何返回给模型继续推理

也就是说,模型负责提出动作意图,系统负责执行动作。

这层分工非常关键。 如果把执行权直接交给模型,而没有运行时校验和权限边界,就会把“生成错误”升级为“动作错误”。

2. Function Calling 的典型链路

一次可靠的 Function Calling 通常包括这些步骤:

  1. 系统把可用函数、参数 schema、使用约束告诉模型。
  2. 模型根据任务判断是否需要调用工具。
  3. 模型输出函数名和参数。
  4. Runtime 校验函数名、参数类型、必填字段、权限和业务规则。
  5. Runtime 执行函数,得到结构化结果或错误。
  6. Runtime 把结果作为观察反馈交给模型。
  7. 模型基于反馈继续规划、重试、解释或结束任务。

它的真正价值不是“能调用一个 API”,而是把模型动作意图纳入了程序协议

3. 工程上要特别注意的点

Function Calling 落地时,最容易踩这些坑:

  • 工具描述太含糊,导致模型选错工具
  • 参数 schema 太宽松,导致下游系统收到脏数据
  • 工具返回值没有结构,导致模型无法可靠继续推理
  • 缺少权限判断,导致模型能请求不该请求的动作
  • 缺少幂等控制,重试时重复扣费、重复下单、重复发消息
  • 缺少错误分类,模型不知道该重试、换工具还是终止

所以,Function Calling 最好被看成一个接口设计问题,而不是 Prompt 技巧问题。

一个好工具通常需要具备:

  • 清晰的名称
  • 明确的用途说明
  • 收敛的参数 schema
  • 可机器解析的返回结构
  • 稳定的错误码
  • 权限与审计策略
  • 幂等键或事务边界

工具越像“给模型用的内部 API”,Agent 越稳定。

三、MCP:把外部能力标准化接入 Agent 的协议层

Function Calling 解决的是“模型如何表达调用意图”。 MCP 进一步解决的是另一个问题:

大量外部工具、数据源、文件系统、数据库和服务,如何以统一方式暴露给 AI 应用。

MCP 的全称是 Model Context Protocol。 它可以理解为一种面向 AI 应用的连接协议,用来把外部上下文和能力接入模型应用。

更直白地说:

Function Calling 像是模型递出一张“我想调用这个工具”的申请单;MCP 像是 Agent 应用和各种外部工具之间的一套标准插座、插头和通讯规约。

如果没有 MCP,每个 Agent 应用都要自己写:

  • 怎么连接订单系统
  • 怎么连接文件系统
  • 怎么连接数据库
  • 怎么连接浏览器
  • 怎么连接 GitHub、Slack、Notion、Jira
  • 怎么描述这些工具给模型看
  • 怎么把调用参数传过去
  • 怎么把结果再交还给模型

这些事情本质上都很像,但如果每个应用各写一遍,就会出现大量重复适配代码。

MCP 的作用,就是把这些外部能力包成一个个 MCP Server,再让 AI 应用通过 MCP Client 用统一协议去发现和调用它们。按照 MCP 官方架构说明,一个 AI 应用通常通过 MCP Client 连接一个或多个 MCP Server,而 Server 可以暴露 tools、resources、prompts 等能力。

这意味着,Agent 不必为每一个外部系统单独写一套模型适配逻辑。 它可以通过统一协议发现和调用能力:

  • tools:可执行动作,例如查询数据库、读文件、调用业务 API
  • resources:可读取上下文,例如文件内容、数据库记录、配置项
  • prompts:可复用提示模板或任务入口
  • lifecycle:连接初始化、能力发现、更新通知、会话管理

1. 一个具体例子:查询订单状态

假设用户对一个客服 Agent 说:

帮我查一下订单 12345 现在到哪里了。

如果只看 Function Calling,模型可能输出:

{
  "name": "query_order_shipping",
  "arguments": {
    "order_id": "12345"
  }
}

这一步只说明:模型判断自己需要调用 query_order_shipping 这个工具。

但问题是:

这个工具从哪里来? 它的 schema 是谁提供的? 真实的订单系统在内网、数据库还是第三方 API? 不同 Agent 应用都要重复写一遍订单系统适配吗?

MCP 处理的就是这些问题。

一条更完整的链路大概是:

  1. 客服 Agent 启动时,MCP Client 连接 order-mcp-server
  2. Agent 通过 MCP 向这个 Server 询问:“你有哪些 tools、resources、prompts?”
  3. order-mcp-server 返回工具清单,其中包括 query_order_shipping,以及它的参数 schema、说明和返回结构。
  4. Agent Runtime 把这个工具注册成模型可见的 tool。
  5. 用户提出查询订单的请求。
  6. 模型通过 Function Calling 生成 query_order_shipping({ "order_id": "12345" })
  7. Tool Router 校验权限、参数和风险后,把这次调用交给 MCP Client。
  8. MCP Client 用 MCP 协议把调用请求发给 order-mcp-server
  9. order-mcp-server 再去调用真实的订单数据库或物流 API。
  10. Server 把结构化结果返回给 MCP Client。
  11. Agent Runtime 把结果作为观察反馈交给模型。
  12. 模型再把结果解释成用户能读懂的话。

所以 MCP 并不是让模型“直接连数据库”。 它更像是在模型应用和真实系统之间加了一层标准化的能力适配层:

用户请求
  -> 模型判断要做什么
  -> Function Calling 产出工具调用意图
  -> Runtime / Tool Router 校验和路由
  -> MCP Client 发起标准协议调用
  -> MCP Server 访问真实系统
  -> 结果返回给模型继续推理

这也是为什么 MCP 听起来像“协议”,但在工程里很具体: 它实际负责工具发现、能力描述、参数传递、资源读取、调用返回、连接生命周期等环节。

2. MCP、Tool Router 和模型决策的关系

理解 MCP 时,最容易混淆的是三件事:

用户一句话
  -> 模型理解意图
  -> 选择工具集合
  -> 选择具体 function
  -> 填参数
  -> 执行

这里面至少有三层角色:

  • MCP:工具供给层
  • Tool Router:调度层
  • LLM:最终的工具选择和参数生成者

它们的关系不是互相替代,而是上下游协作:

MCP Server 提供工具
  -> Tool Router 裁剪候选工具集合
  -> LLM 在候选工具里选择 function 并填参数
  -> Runtime / MCP Client 执行调用

更准确地说:

MCP 提供工具,Router 缩小工具空间,LLM 完成最终选择和参数填充。

MCP Server 可以理解为工具仓库。 比如在银行场景里,可以有多个 MCP Server:

CRM MCP Server
  - query_customer
  - query_customer_assets
  - query_customer_tags

Product MCP Server
  - recommend_product
  - query_product_risk_level

Marketing MCP Server
  - generate_campaign_copy
  - query_customer_segment

这些 MCP Server 的职责是把能力标准化暴露出来。 它们通常不负责判断“当前用户问题到底该用哪个工具”。

Tool Router 则是调度层。 它的职责不是执行真实业务动作,而是在工具全集里先做一次裁剪。

例如用户说:

查一下张三的客户资产。

Router 可以先筛掉无关能力:

候选工具:
  - CRM.query_customer
  - CRM.query_customer_assets

过滤掉:
  - File.read_pdf
  - Browser.search
  - Product.recommend_product

然后模型只需要在一个更小、更相关的候选集合里选择具体 function。

这件事非常重要。 因为模型不是“精确知道工具”,而是在基于工具名称、description、参数 schema、上下文提示做语义匹配和概率选择。工具越多、描述越相似、干扰项越多,误选概率就越高。

在复杂系统中,模型不应该直接面对所有真实 API。 中间通常需要一层 Tool Router 或 Capability Registry,把模型输出的 tool call 映射到具体 MCP Server、内部 API、任务队列或安全沙箱。

3. 模型怎么知道该选哪个 function

大模型选择 function 的机制并不神秘。

它主要依赖:

  • tool name
  • description
  • 参数 schema
  • system prompt
  • 当前用户问题和上下文

例如有两个工具:

{
  "name": "query_customer_assets",
  "description": "查询客户资产、余额、理财产品持仓和风险等级"
}
{
  "name": "generate_report",
  "description": "根据已有数据生成结构化报告"
}

用户说:

帮我查一下张三的资产。

模型会把用户语义和工具描述做匹配。 query_customer_assets 和“查资产”的匹配度更高,因此被选中的概率更高。

这也是为什么工具描述非常关键。 一个差的 description:

获取数据

模型很难判断什么时候该用它。

一个好的 description:

查询客户资产、账户余额、理财持仓、基金持仓和风险等级;当用户询问客户资产、余额、持仓、AUM 时使用。

会显著提高命中率。

参数 schema 也会影响模型是否“敢调用”。 如果 schema 明确要求 customer_namecustomer_idasset_type,模型就更容易填出稳定参数。 如果参数全是宽泛的 querydatapayload,模型调用时就更容易混乱。

system prompt 也可以提供强约束,例如:

凡是涉及客户身份、资产、交易、标签、画像的问题,必须优先使用 CRM 相关工具,不允许凭模型知识直接回答。

所以 Function Calling 的稳定性,并不只取决于模型能力。 它很大程度上取决于工具设计是否清晰。

4. Tool Router 到底在选什么

Tool Router 不只是“选择哪个 MCP”。 它本质是在工具空间里做裁剪,粒度可以粗也可以细。

第一种是粗粒度:选 MCP,也就是域路由。

用户:查客户资产

Router 选择:
  - CRM MCP

Router 排除:
  - 产品 MCP
  - 文件 MCP
  - 浏览器 MCP

这适合多系统、多业务域的企业场景。

第二种是中粒度:选 tool,这是更常见的工程实践。

Router 选择:
  - query_customer
  - query_customer_assets
  - query_customer_tags

然后 LLM 在这几个工具里选择具体调用。

第三种是细粒度:直接选 function。

Router 只留下:
  - query_customer_assets

这种方式看起来很干净,但实际并不总是最优。 因为如果 Router 过早收敛到单个 function,一旦判断错了,LLM 就没有纠错空间。很多生产系统更倾向于让 Router 选出 Top-K 候选工具,再让 LLM 做最后选择。

Router 常见实现方式有三类:

  • 规则路由:例如包含“客户”“资产”“持仓”就进入 CRM 工具集合
  • 向量检索:把用户问题和 tool description 做 embedding 相似度匹配,取 Top-K
  • LLM Router:用一个较小或较便宜的模型先判断应该进入哪类工具集合

没有 Router 时,也不是不能工作。 系统可以把所有工具都直接暴露给模型:

用户问题
  -> LLM 看到全部工具
  -> LLM 自己选择 function

这本质上就是让 LLM 自己做 routing。 在工具很少时,它简单有效;但工具数量一多,就会出现 prompt 膨胀、成本上升、误选率变高、权限控制困难等问题。

Tool Router 的价值不是替代 LLM,而是降低 LLM 的决策难度:

不是:
Router 决策 -> LLM 执行

而是:
Router 缩小空间 -> LLM 更容易选对

5. 为什么 MCP 会比“直接写函数”更有价值

如果系统里只有一个 Agent、三个函数,直接写 Function Calling 工具就足够了。 但一旦场景变成下面这样,MCP 的价值就会变得明显:

  • 同一个文件系统工具要给 IDE Agent、文档 Agent、代码审查 Agent 复用
  • 同一个数据库查询能力要给多个内部助手使用
  • 同一个 GitHub 能力既要给 Chatbot 用,也要给命令行 Agent 用
  • 工具能力需要被统一版本化、禁用、审计和授权
  • 新增一个外部系统时,希望接入一次,多处可用

这时 MCP Server 就像一个可复用的能力模块。 工具开发者只要把能力按 MCP 暴露出来,不同 AI 应用就可以通过 MCP Client 接入,而不是每个应用都重新写一套适配。

也就是说:

Function Calling 让一次调用变得结构化;MCP 让一批外部能力变得可发现、可复用、可治理。

6. 以银行 + OpenClaw 为例

如果把这套结构放到银行企微助手或 OpenClaw 这类 Agent 平台里,一个更合理的链路是:

企微用户
  -> Agent / OpenClaw
  -> Tool Router
  -> MCP Client
  -> CRM MCP / 产品 MCP / 营销 MCP
  -> 真实业务系统

其中:

  • OpenClaw 负责承载 Agent 会话、上下文、模型调用和运行时编排
  • Tool Router 负责根据用户问题、权限、业务域筛选候选工具
  • MCP Client 负责按 MCP 协议连接不同 MCP Server
  • MCP Server 负责把 CRM、产品、营销等系统能力标准化暴露出来
  • LLM 负责在候选工具里选择具体 function,并生成结构化参数

例如:

用户:帮我看看张三适合推荐什么理财产品。

一条可能的执行链路是:

  1. Router 先判断这是客户画像 + 产品推荐任务。
  2. Router 选出 CRM 和产品相关工具。
  3. LLM 先调用 query_customer_assets 查询客户资产。
  4. LLM 再调用 query_customer_risk_profile 查询风险等级。
  5. LLM 调用 recommend_product 获取候选产品。
  6. Guardrails 检查推荐是否符合适当性、权限和合规要求。
  7. Agent 生成面向客户经理的推荐解释。

这里 MCP 不负责“想出推荐策略”。 它负责让 CRM、产品、营销这些外部能力以统一方式被 Agent 调用。真正的任务推进,是 Router、LLM、Runtime、Guardrails 和业务系统协作完成的。

7. MCP 的工程价值

MCP 的价值不只是“连接工具更方便”。 它更重要的意义在于标准化和治理:

  • 统一工具发现方式
  • 统一资源读取方式
  • 统一提示模板复用方式
  • 降低不同模型应用接入同一工具生态的成本
  • 让工具能力可以被版本化、治理和审计
  • 让权限、日志、审批、沙箱策略更容易集中管理

当一个组织里有多个 Agent、多个 IDE 插件、多个内部自动化助手时,如果每个系统都手写一套工具接入方式,长期会非常混乱。 MCP 这类协议层的意义,就是把“模型接工具”从一次性集成变成可复用基础设施。

如果要做企业级 Agent,通常需要三件套:

  • Tool Router:控制工具规模,避免把全部工具一次性塞给模型
  • Tool 描述标准化:提高模型选中正确工具的概率
  • Tool 分层和拆域:按 CRM、产品、营销、风控、文件、浏览器等领域拆 MCP Server

8. MCP 的风险边界

但 MCP 也不是银弹。

它让工具接入更容易,也意味着风险面扩大。 一个 MCP Server 一旦暴露了文件、数据库、浏览器、Shell、内部系统等能力,就必须考虑:

  • Server 是否可信
  • 工具描述是否可能被污染
  • 参数是否可能触发越权操作
  • 工具返回内容是否可能注入恶意指令
  • 多个工具组合后是否形成数据外泄路径
  • 是否有用户确认、权限隔离和审计日志

因此,MCP 最好被放进“能力市场 + 权限系统 + 审计系统 + 沙箱系统”的组合里理解。 它解决连接问题,但不自动解决信任问题。

四、RAG 与向量库:让 Agent 基于外部知识行动,而不是只依赖模型参数

RAG 的全称是 Retrieval-Augmented Generation,即检索增强生成。 它解决的核心问题是:

模型的参数记忆不等于当前、完整、可信的业务知识。

一个 Agent 如果只依赖模型训练时学到的内容,会遇到很多限制:

  • 不知道企业内部文档
  • 不知道最新政策、价格、合同、工单状态
  • 不知道用户当前上传的文件
  • 不知道某个项目仓库里的真实代码
  • 难以给出可追溯证据

RAG 的思路是: 在生成答案或执行任务之前,先从外部知识库检索相关资料,再把检索结果作为上下文交给模型。

1. RAG 不等于向量库

很多人会把 RAG 简化成“把文档丢进向量库”。 这只是 RAG 的一小部分。

完整的 RAG 至少包括两条链路:

离线入库链路:

  • 文档收集
  • 解析清洗
  • 权限和来源标注
  • Chunk 切分
  • Embedding 向量化
  • 索引构建
  • 版本更新
  • 召回评测

在线查询链路:

  • 用户问题理解
  • 查询改写
  • 多路召回
  • 重排
  • 上下文压缩
  • 引用生成
  • 不足证据判断
  • 再检索或拒答

向量库只是其中的索引和召回基础设施。 RAG 真正的难点,往往在知识治理和检索质量。

2. 向量库解决什么

向量库的核心能力,是把文本、图片、代码片段等内容转成向量后,支持相似度检索。 这使系统可以根据语义相近程度找到相关内容,而不只依赖关键词匹配。

在 Agent 中,向量库常用于:

  • 检索企业知识库
  • 检索历史对话和任务记忆
  • 检索代码片段
  • 检索错误案例和解决方案
  • 检索相似工单、合同、政策条款

但向量检索也有边界:

  • 语义相似不等于事实正确
  • 召回相关不等于回答充分
  • Chunk 命中不等于证据完整
  • 权限过滤不能只靠模型遵守
  • 旧文档、重复文档、冲突文档会污染结果

因此,生产级 RAG 通常会结合:

  • 向量检索
  • 关键词检索
  • 元数据过滤
  • 权限过滤
  • Reranker 重排
  • Query Rewrite
  • Context Compression
  • 引用与证据校验
  • 离线评测集

3. Agentic RAG:Agent 参与检索决策

普通 RAG 往往是固定流程: 用户问题进来,系统检索 TopK 文档,然后模型回答。

Agentic RAG 更进一步: 由 Agent 决定是否检索、检索什么、是否需要再检索、是否需要调用不同数据源。

例如,一个研发 Agent 处理“这个接口为什么报错”时,可能会依次检索:

  • 当前报错日志
  • 相关代码文件
  • 最近提交记录
  • API 文档
  • 已知故障案例
  • 监控指标

如果第一次检索证据不足,它还可以改写查询、扩大范围、切换检索工具,甚至提出需要用户提供更多信息。

这就是 Agentic RAG 和普通 RAG 的差异: 检索不再是固定前处理步骤,而变成任务闭环中的一个可决策动作。

五、Memory:Agent 的记忆不是“把聊天记录越存越多”

Memory 常被讲得很神秘,好像 Agent 只要有记忆就会变得更像人。 但工程上要冷静一点:

Agent 的 Memory 本质上是可检索、可更新、可治理的任务上下文资产。

它不应该只是无限追加聊天记录。 如果把所有历史都塞进上下文,系统会很快遇到:

  • 成本失控
  • 噪声变多
  • 隐私风险
  • 过期信息干扰
  • 模型注意力被稀释

更合理的做法,是把 Memory 分层。

1. 短期记忆

短期记忆服务于当前任务。 它保存的是当前会话或当前 run 里的临时信息:

  • 用户刚才给出的目标
  • 当前执行到第几步
  • 已调用过哪些工具
  • 工具返回了什么结果
  • 当前有哪些待确认问题
  • 哪些尝试已经失败

短期记忆通常和 Session State、Run Context 放在一起。

2. 长期记忆

长期记忆服务于跨任务复用。 它保存的是相对稳定、未来可能再次使用的信息:

  • 用户偏好
  • 项目背景
  • 常用工具
  • 历史决策
  • 业务规则
  • 已验证的解决方案

长期记忆需要强治理。 不是所有信息都应该自动写入长期记忆,更不是所有长期记忆都应该在每次任务中默认加载。

至少要考虑:

  • 哪些信息可以记
  • 谁授权记
  • 什么时候过期
  • 如何删除
  • 如何避免敏感信息进入模型上下文
  • 如何处理记忆冲突

3. 情景记忆

对工程型 Agent 来说,还有一类非常重要的记忆:情景记忆。 它记录的是任务过程中的关键决策与失败经验:

  • 为什么选择这个方案
  • 哪个测试失败过
  • 哪个工具调用超时
  • 哪个文件不能修改
  • 哪个用户约束必须遵守
  • 哪次修复被验证有效

这类记忆对长任务尤其重要。 它让 Agent 不必在上下文压缩后重新踩坑,也方便人类接手任务。

六、结构化输出:让模型输出从“可读”变成“可消费”

如果说 Function Calling 让模型能表达动作意图,那么结构化输出让模型的普通回答也能被程序稳定消费。

它解决的问题是:

模型输出不能只适合人眼阅读,还要适合下游系统解析。

例如,客服 Agent 处理一封邮件后,不能只输出:

“这个客户比较着急,应该尽快回复。”

更可用的输出可能是:

{
  "priority": "high",
  "intent": "refund_request",
  "sentiment": "angry",
  "deadline": "2026-04-25",
  "needs_human_review": true,
  "suggested_action": "route_to_refund_specialist"
}

这样下游系统才能自动:

  • 排序
  • 分派
  • 触发工作流
  • 进入审批
  • 生成报表
  • 进入评测样本

1. JSON Mode、Structured Outputs 和 Function Calling 的区别

不同平台叫法会不同,但概念上可以这样区分:

  • JSON Mode:要求模型输出合法 JSON,但不一定严格符合业务 schema。
  • Structured Outputs:要求输出匹配指定 schema,例如字段、类型、枚举、必填项。
  • Function Calling:要求模型选择工具,并以结构化参数表达调用意图。

它们都在解决“模型输出不稳定”的问题,但使用场景不同。

如果你要模型返回一个最终报告的结构化摘要,适合 Structured Outputs。 如果你要模型调用一个外部函数,适合 Function Calling。 如果你只是希望结果至少是 JSON,JSON Mode 可能够用,但工程约束较弱。

2. 结构化输出不是万能保险

结构化输出能提高格式稳定性,但它不保证语义一定正确。 例如:

{
  "risk_level": "low"
}

这个 JSON 可能格式完全正确,但风险判断可能是错的。

所以结构化输出后面还需要:

  • 业务规则校验
  • 数值范围校验
  • 引用证据校验
  • 权限校验
  • 人工复核
  • 离线评测

也就是说,schema 解决的是“形状正确”,不自动解决“内容正确”。

七、Guardrails:把能力边界、风险边界和业务边界做成系统约束

Agent 越能行动,Guardrails 越重要。 因为普通问答系统答错了,主要风险是信息错误;Agent 做错了,可能直接造成外部世界的状态变化。

Guardrails 解决的是:

哪些输入、输出、工具调用和动作应该被允许,哪些应该被拦截、降级、确认或终止。

1. Guardrails 不只是安全审查

很多人一听 Guardrails,就只想到内容安全。 但在 Agent 系统里,Guardrails 至少包括四类:

输入 Guardrails:

  • 是否包含恶意指令
  • 是否包含越权请求
  • 是否包含敏感信息
  • 是否试图覆盖系统规则

输出 Guardrails:

  • 是否泄露隐私
  • 是否生成不合规内容
  • 是否缺少必要免责声明
  • 是否与证据矛盾

工具调用 Guardrails:

  • 是否允许调用该工具
  • 参数是否越界
  • 是否需要用户确认
  • 是否触发限流或成本上限
  • 是否可能造成不可逆动作

业务 Guardrails:

  • 是否违反业务规则
  • 是否绕过审批流程
  • 是否满足交付质量门槛
  • 是否需要人工复核

这些边界最好不要只写在 Prompt 里。 Prompt 可以提醒模型,但真正的系统约束应该放在运行时、策略引擎、权限系统和审计系统里。

2. Guardrails 的常见动作

Guardrails 不一定只有“允许”和“拒绝”两种结果。 生产系统里更常见的是多级处理:

  • allow:直接允许
  • repair:要求模型修复格式或补充字段
  • retry:换策略重试
  • redact:脱敏后继续
  • downgrade:降级为只读或建议模式
  • confirm:要求用户确认
  • escalate:转人工审批
  • abort:终止任务
  • rollback:撤销已执行动作

真正好用的 Guardrails,是能根据风险等级选择不同控制动作。

例如:

  • 查询公开文档:直接允许
  • 查询内部文档:检查用户权限
  • 发送邮件:先生成草稿,等待确认
  • 修改数据库:需要审批和事务回滚
  • 删除生产数据:默认禁止或强人工审批

3. Guardrails 要可审计

如果系统只是“悄悄拦截”,后续很难改进。 每次 Guardrails 命中都应该记录:

  • 命中了哪条规则
  • 输入和输出摘要是什么
  • 当前用户和权限是什么
  • 触发了什么处理动作
  • 是否被人工放行
  • 最终结果如何

这些记录会变成 Agent 持续迭代的重要数据。 它们能告诉你:是规则太松、太严,还是模型总在某些任务上不稳定。

八、Planning 与 Reflection:让 Agent 能拆任务,也能判断自己是否走偏

Planning 解决的是“怎么把目标拆成步骤”。 Reflection 解决的是“执行后如何检查自己是否需要修正”。

这两个能力经常被讲成模型智能本身,但工程上最好把它们系统化。

1. Planning 的作用

Agent 面对开放目标时,通常不能一步完成。 例如:

“帮我分析这个项目为什么 CI 失败,并修好。”

这类任务需要先拆解:

  • 读取报错日志
  • 定位失败测试
  • 搜索相关代码
  • 判断失败原因
  • 修改代码
  • 运行测试
  • 总结变更

Planning 的价值,是把开放目标变成可执行步骤。 但计划不能太僵。真实任务中,工具结果常常会改变下一步。

所以生产级 Planning 更像“可动态更新的任务图”,而不是一次性生成的 TODO 列表。

2. Reflection 的作用

Reflection 常被翻译为反思。 在 Agent 里,它更像执行后的自检机制:

  • 当前结果是否满足目标
  • 工具调用是否失败
  • 输出是否符合 schema
  • 证据是否充分
  • 是否需要再检索
  • 是否需要回滚
  • 是否应该请用户确认

但 Reflection 也不能完全靠模型自说自话。 更可靠的方式是结合外部信号:

  • 测试是否通过
  • API 是否返回成功
  • schema 是否校验通过
  • 业务规则是否通过
  • 人工审核是否通过
  • 评测指标是否下降

也就是说,Reflection 最好不是“模型感觉自己对了”,而是“模型结合可验证信号判断下一步”。

九、状态管理:让 Agent 知道自己在哪里、做过什么、还能不能恢复

状态管理是很多 Agent 原型最容易忽略的部分。 在简单 Demo 里,状态可能只是聊天上下文。 但在真实系统里,Agent 的状态至少包括:

  • 当前任务目标
  • 当前计划
  • 已完成步骤
  • 待执行步骤
  • 工具调用记录
  • 外部系统返回值
  • 中间产物
  • 用户确认记录
  • 错误与重试历史
  • 权限与环境信息

这些内容如果只放在模型上下文里,会非常脆弱:

  • 上下文窗口有限
  • 历史会被压缩
  • 任务中断后难以恢复
  • 多 Agent 协作时难以共享
  • 审计与调试困难

因此,生产级 Agent 需要显式状态管理。

1. Session State

Session State 保存会话级信息。 例如用户当前选择了哪个项目、偏好什么输出格式、最近确认了什么约束。

它适合短期使用,但不应该无限期沉淀。

2. Run State

Run State 保存一次任务执行过程。 例如任务图、步骤状态、工具调用结果、错误记录、产物路径。

它是 Agent 能恢复运行的关键。 如果任务跑到一半失败,系统应该知道从哪里继续,而不是从头再来。

3. Checkpoint

Checkpoint 是状态管理里非常重要的一层。 它记录任务在关键节点的快照。

例如:

  • 已经完成需求分析
  • 已经生成代码补丁
  • 已经通过单元测试
  • 已经等待用户确认
  • 已经提交外部系统

有了 Checkpoint,系统才能支持:

  • 失败恢复
  • 人工接手
  • 回滚
  • 重放
  • 长任务暂停后继续

4. Event Log

Event Log 记录每一次关键事件:

  • 模型输入摘要
  • 模型输出摘要
  • 工具调用
  • 工具结果
  • Guardrails 命中
  • 用户确认
  • 任务状态变化
  • 异常和重试

它是调试、审计、评测和产品改进的基础。

如果没有 Event Log,Agent 出错后只能靠猜。 如果有 Event Log,至少可以回放它当时为什么那么做。

十、Observability:让 Agent 的运行过程可以被看见

普通后端系统需要可观测性,Agent 系统更需要。 因为 Agent 的问题往往不是单点异常,而是多因素链路问题:

  • 模型选错工具
  • 工具返回结果不完整
  • RAG 召回证据错误
  • Prompt 引导不足
  • schema 校验失败
  • Guardrails 误拦截
  • 用户权限不足
  • 某个外部 API 变慢

如果没有可观测性,工程团队很难回答:

  • 这次任务为什么失败
  • 哪个步骤最慢
  • 哪个工具最容易报错
  • 哪类问题最耗 token
  • 哪条策略经常误伤
  • 哪个版本上线后质量下降

1. Traces

Trace 记录一次任务从入口到结束的调用链。 对 Agent 来说,一条 Trace 可能包括:

  • 用户请求
  • 规划步骤
  • 模型调用
  • RAG 检索
  • 工具调用
  • 外部 API
  • Guardrails 校验
  • 最终输出

Trace 的价值是把一次复杂任务串起来。

2. Metrics

Metrics 关注可聚合指标。 例如:

  • 成功率
  • 平均延迟
  • P95 延迟
  • 平均 token 成本
  • 工具调用次数
  • 格式校验失败率
  • 用户确认率
  • 人工接管率
  • Guardrails 命中率

这些指标能帮助团队判断系统是否真的在变好。

3. Logs

Logs 记录结构化事件。 对于 Agent,日志最好不要只写自然语言,而要包含:

  • run_id
  • trace_id
  • user_id 或匿名标识
  • tool_name
  • policy_id
  • error_code
  • model_version
  • prompt_version
  • schema_version

这些字段决定了后续能不能定位问题。

十一、Evaluation:Agent 不是上线后才知道好不好

Evaluation 是 Agent 工程化里的另一根主梁。 没有评测,系统只能凭感觉迭代。

Agent 的评测不能只看最终回答是否流畅。 它应该覆盖任务推进过程。

1. 输出质量评测

例如:

  • 答案是否正确
  • 是否引用了证据
  • 是否遗漏关键点
  • 是否产生幻觉
  • 是否符合格式
  • 是否符合语气要求

2. 工具调用评测

例如:

  • 是否选择了正确工具
  • 参数是否正确
  • 是否少调用或多调用
  • 是否正确处理错误
  • 是否遵守权限规则

3. 任务成功评测

例如:

  • 是否完成用户目标
  • 是否通过测试
  • 是否生成可用产物
  • 是否满足业务验收标准
  • 是否在成本和时间预算内完成

4. 安全与治理评测

例如:

  • 是否拒绝越权请求
  • 是否泄露敏感信息
  • 是否执行危险动作
  • 是否正确触发人工确认
  • 是否有完整审计记录

评测的难点在于,Agent 的输出不是单一文本。 它可能包含计划、工具调用、文件修改、数据库操作、外部系统状态变化。 所以评测也应该从“文本评测”升级为“过程评测”。

十二、这些技术如何组合成一套可落地架构

把上面的技术放在一起,一个比较稳的 Agent 架构通常是这样的:

  1. 用户输入目标,系统生成 Run Context。
  2. Planner 生成初始任务图。
  3. Memory 和 RAG 提供相关上下文。
  4. 模型根据上下文生成下一步动作或结构化输出。
  5. Function Calling 表达工具调用意图。
  6. Tool Router 校验权限、参数、风险和路由。
  7. MCP 或内部工具层执行真实动作。
  8. 执行结果写入 Event Log 和 State Store。
  9. Evaluator 或 Reflection 判断是否继续、重试、修复或结束。
  10. Guardrails 在输入、输出、工具调用和交付前持续介入。
  11. Observability 系统记录 trace、metrics、logs。
  12. Evaluation 系统用真实样本持续回归测试。

这套链路的目标不是把系统搞复杂,而是把风险显性化。

简单任务可以只用其中一部分。 例如一个只读问答助手,可能只需要 RAG、结构化输出和基础日志。 但一个能发邮件、改代码、下订单、操作数据库的 Agent,就必须认真设计工具权限、状态恢复、审计、Guardrails 和人工确认。

十三、常见误区:不要把技术名词当作能力本身

最后把几个常见误区集中说清。

误区一:接了工具就是 Agent

不是。

接工具只是让模型有了可调用能力。 Agent 还需要目标管理、状态、反馈、规划、验证和治理。

误区二:用了 RAG 就不会幻觉

不是。

RAG 只能提供外部证据。 如果召回错了、证据不足、模型误读了、引用缺失了,仍然会出现错误。

误区三:结构化输出等于内容正确

不是。

结构化输出只能提高格式稳定性。 内容正确还需要业务校验、证据校验和评测。

误区四:Guardrails 写在 Prompt 里就够了

不够。

Prompt 是软约束,运行时策略、权限系统、审计和人工确认才是硬约束。

误区五:Memory 越多越好

不是。

记忆越多,噪声、隐私、冲突和成本也越高。 Memory 的关键是筛选、过期、权限和检索,而不是无限保存。

误区六:Observability 是上线后再补的

最好不要。

Agent 的行为链路复杂,如果一开始没有 run_id、trace_id、tool call log、prompt version 和 schema version,后面出问题很难复盘。

最后总结:Agent 的关键技术,本质上是在给模型补上工程系统能力

AI Agent 之所以不同于普通 Chatbot,不是因为它更会聊天,而是因为它能围绕目标推进任务。

但任务推进不是凭空发生的。 它依赖一整套技术栈:

  • Function Calling 让模型能表达动作意图
  • MCP 让外部能力能被统一接入
  • RAG 与向量库让 Agent 能基于外部知识行动
  • Memory 让任务上下文能被选择性保留和复用
  • 结构化输出让结果能被程序稳定消费
  • Guardrails 让风险边界能被系统约束
  • Planning 与 Reflection 让任务能动态拆解和修正
  • 状态管理让长任务能恢复、回放和交接
  • Observability 让过程可见
  • Evaluation 让质量可测

如果只看模型,Agent 像一个聪明的大脑。 但如果看完整技术栈,Agent 更像一个有神经系统、执行系统、记忆系统、免疫系统和监控系统的工程体。

真正成熟的 Agent,不是“什么都能自动做”,而是:

知道自己能做什么,知道什么时候该调用什么能力,知道失败后如何恢复,也知道哪些事情必须停下来等待验证。

这才是 Agent 从演示走向工程化落地的关键。

参考资料