作者: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 通常包括这些步骤:
- 系统把可用函数、参数 schema、使用约束告诉模型。
- 模型根据任务判断是否需要调用工具。
- 模型输出函数名和参数。
- Runtime 校验函数名、参数类型、必填字段、权限和业务规则。
- Runtime 执行函数,得到结构化结果或错误。
- Runtime 把结果作为观察反馈交给模型。
- 模型基于反馈继续规划、重试、解释或结束任务。
它的真正价值不是“能调用一个 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 处理的就是这些问题。
一条更完整的链路大概是:
- 客服 Agent 启动时,MCP Client 连接
order-mcp-server。 - Agent 通过 MCP 向这个 Server 询问:“你有哪些 tools、resources、prompts?”
order-mcp-server返回工具清单,其中包括query_order_shipping,以及它的参数 schema、说明和返回结构。- Agent Runtime 把这个工具注册成模型可见的 tool。
- 用户提出查询订单的请求。
- 模型通过 Function Calling 生成
query_order_shipping({ "order_id": "12345" })。 - Tool Router 校验权限、参数和风险后,把这次调用交给 MCP Client。
- MCP Client 用 MCP 协议把调用请求发给
order-mcp-server。 order-mcp-server再去调用真实的订单数据库或物流 API。- Server 把结构化结果返回给 MCP Client。
- Agent Runtime 把结果作为观察反馈交给模型。
- 模型再把结果解释成用户能读懂的话。
所以 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_name、customer_id、asset_type,模型就更容易填出稳定参数。 如果参数全是宽泛的 query、data、payload,模型调用时就更容易混乱。
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,并生成结构化参数
例如:
用户:帮我看看张三适合推荐什么理财产品。
一条可能的执行链路是:
- Router 先判断这是客户画像 + 产品推荐任务。
- Router 选出 CRM 和产品相关工具。
- LLM 先调用
query_customer_assets查询客户资产。 - LLM 再调用
query_customer_risk_profile查询风险等级。 - LLM 调用
recommend_product获取候选产品。 - Guardrails 检查推荐是否符合适当性、权限和合规要求。
- 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 架构通常是这样的:
- 用户输入目标,系统生成 Run Context。
- Planner 生成初始任务图。
- Memory 和 RAG 提供相关上下文。
- 模型根据上下文生成下一步动作或结构化输出。
- Function Calling 表达工具调用意图。
- Tool Router 校验权限、参数、风险和路由。
- MCP 或内部工具层执行真实动作。
- 执行结果写入 Event Log 和 State Store。
- Evaluator 或 Reflection 判断是否继续、重试、修复或结束。
- Guardrails 在输入、输出、工具调用和交付前持续介入。
- Observability 系统记录 trace、metrics、logs。
- 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 从演示走向工程化落地的关键。