AI Agent 生产环境落地手册:架构、评估与成本控制
一个客服 Agent 在预发环境跑了两周,人工评审通过率 88%。上线第五天,财务发现模型账单是预算的 4 倍,日志里同一个失败的订单查询工具被重试了 3000 多次。模型没换,代码没改。问题出在架构、评估、成本这三块各自设计,没一起设计。
下面按五个部分展开,每部分都给可执行的判断标准和配置项,不给概念定义。
一、技术栈分层与 MCP / A2A 选型
先把 Agent 系统拆成七层,每层单独决定用什么。混在一起讨论,最后一定变成框架之争。
| 层 | 职责 | 常见选择 |
|---|---|---|
| 模型接入 | 多模型调用、限流、密钥托管、区域合规 | 官方 SDK、LiteLLM、云厂商模型网关 |
| 编排 | 状态流转、循环控制、中断恢复、人工介入 | LangGraph、OpenAI Agents SDK、Google ADK、自研状态机 |
| 工具协议 | 工具接入的标准化 | MCP |
| Agent 互联 | 跨进程、跨团队、跨厂商调用 | A2A |
| 记忆与检索 | 会话、偏好、文档检索 | Redis、Postgres + pgvector、Milvus |
| 评估与可观测 | trace、数据集、打分、成本归集 | Langfuse、LangSmith、Arize Phoenix、OpenTelemetry |
| 执行隔离 | 跑代码、访问网络时的隔离 | E2B、gVisor、Firecracker、受限容器 |
MCP 解决的是什么
MCP(Model Context Protocol)由 Anthropic 在 2024 年 11 月开源,走 JSON-RPC 2.0。传输有两种:本地进程用 stdio,远程服务用 Streamable HTTP(2025-03-26 规范版本引入,替换了早期的 HTTP+SSE)。规范用日期做版本号,接入前先确认对方实现的是哪一版,别假设向后兼容。
服务端提供三类原语:tools(可调用动作)、resources(可读数据)、prompts(预置模板)。客户端侧提供 sampling、roots、elicitation。实际项目里 90% 的时间花在 tools 上,resources 和 prompts 用得少。
MCP 的价值在复用:一个订单查询 MCP Server 写完,Claude Desktop、IDE 插件、你自己的 Agent 都能挂。如果只有一个宿主,直接写函数调用更省事。
A2A 解决的是什么
A2A 由 Google 在 2025 年 4 月发布,同年 6 月捐给 Linux Foundation。核心是 Agent Card,放在 /.well-known/agent-card.json,描述这个 Agent 能做什么、需要什么鉴权、支持哪些输入输出模式。早期路径是 agent.json,换成 agent-card.json 之后不少项目还在用旧路径,对接时两边都要看。任务有明确的生命周期状态,长任务可以中途查询进度。
选型判断只有一条:你能不能改对方的实现。
- 一个 Agent 挂多个内部工具 → 上 MCP,别碰 A2A。
- 多个团队各自维护 Agent,互相调用且你改不了对方 → A2A。
- 两者不冲突。A2A 暴露出去的 Agent,内部照样用 MCP 挂工具。
远程 MCP Server 的鉴权,规范里走的是 OAuth 2.1 相关流程,各家宿主支持进度不一致。上线前实测一遍授权码流程能不能走通,别等联调时才发现宿主只支持静态 token。
二、任务分解、工具调用、记忆与权限
任务分解:能写 if/else 的别交给模型
判断标准很直接:一个流程里超过一半的步骤你能写成确定性代码,就该画成图,而不是交给自由循环的 ReAct。
以退款处理为例:
- 校验订单状态、支付渠道、时间窗——代码做,模型不参与。
- 命中规则引擎的条目——直接返回结论,结束。
- 规则未覆盖——调模型给建议,同时把不确定性标记出来。
- 金额超过阈值——进人工审批队列,暂停执行。
- 执行退款——幂等接口,带幂等键。
用 LangGraph 的话,这张图就是 StateGraph 里的几个节点加条件边;自研就是一个显式状态机加持久化 checkpoint,进程重启能续上。
工具调用:schema 写不好,后面全是补丁
- 参数 description 要写单位、格式、枚举。别写「日期」,写「YYYY-MM-DD,UTC 时区」。
- 返回值必须截断。把 200KB 的 HTML 塞回上下文,一次调用就能烧掉几万 token。工具层先做结构化摘要,只回必要字段。
- 读操作超时可以重试;写操作超时不能盲目重试,先查状态再决定。重试要设上限,加指数退避和抖动。
- 单个 Agent 暴露给模型的工具数量,我的经验值是不超过 15 个。超过之后命名要分组,或者做两级路由:先让模型选工具类别,再选具体工具。
记忆分四层,别都塞进向量库
| 类型 | 存什么 | 放哪 | 读写时机 |
|---|---|---|---|
| 会话上下文 | 当前对话、工具结果 | Redis / 内存,TTL 分钟到小时级 | 每轮 |
| 用户偏好 | 语言、渠道、历史工单 | Postgres / KV,长期 | 会话开始时读 |
| 语义记忆 | 文档、历史工单 | 向量库,带来源 ID 和时间戳 | 检索时 |
| 程序性记忆 | 提示词、规则、few-shot | Git 版本库 | 发布时 |
权限:Agent 不能拿人的长期凭证
| 动作类型 | 凭证 | 审批 | 审计 |
|---|---|---|---|
| 只读查询 | 短期 token、只读角色 | 无 | 记录参数与结果摘要 |
| 内部写(建工单) | 短期 token、限定资源范围 | 无 | 全量记录 |
| 外部写(发邮件、调第三方) | 短期 token、域名白名单 | 首次人工确认 | 全量记录并发通知 |
| 资金、删除、权限变更 | 不直接授予 | 必须人工,双人复核 | 全量记录加告警 |
三、评估集、可观测性与红队测试
评估集分层,判分能用代码就用代码
| 层 | 样本量级 | 判分方式 |
|---|---|---|
| 工具调用正确性 | 200–500 | 参数精确匹配、规则判定 |
| 多步任务完成 | 100–300 | 最终状态断言加关键路径检查 |
| 端到端业务 | 50–200 | 人工打分加业务指标 |
| 安全 | 100+ | 红队用例,规则判定为主 |
触发回归的时机:改提示词、换模型版本、加工具、改工具 schema。上线用影子流量,新旧版本并行跑,比对关键指标再切流量。
可观测性:trace 结构和必记字段
trace 结构用 OpenTelemetry 的 GenAI 语义约定,一次 Agent 运行对应一个 trace,每次模型调用和工具调用各一个 span。这套属性名在近几个版本里改过(gen_ai.system 后来重命名过),实现时锁定 semconv 版本,别自动升级。
每个 span 必记:
- 模型名与版本、提示词版本号
- 输入输出 token 数、首 token 延迟、总延迟
- 工具名、参数、返回摘要、重试次数
- 估算成本、会话 ID、租户 ID
红队清单
- 间接提示注入:把指令藏在检索文档、网页、工具返回里
- 工具越权:构造参数让 Agent 访问未授权资源(如用 tenant_id 遍历)
- 数据外泄:诱导把内部数据发到外部 URL 或邮件地址
- 循环与成本爆炸:构造让 Agent 反复重试的输入
- 提示词泄露:套出系统提示和内部工具清单
- 记忆投毒:往长期记忆写脏数据,影响后续所有会话
- 审批绕过:伪造「已审批」上下文直接执行写操作
四、云上部署与成本优化
托管还是自建
| 维度 | 托管平台 | 自建 K8s 加沙箱 |
|---|---|---|
| 上线速度 | 快,几小时能跑通 | 慢,网络和隔离都要自己搭 |
| 网络 | 出网受限,接内网要专门打通 | 完全可控 |
| 隔离 | 平台提供 | 自己选 E2B、gVisor、Firecracker |
| 成本模型 | 按调用或按运行时长 | 按机器,空闲也在付费 |
| 平台绑定 | 中到高 | 低 |
成本项拆开看
| 成本项 | 主要驱动 | 可以做的事 |
|---|---|---|
| 模型 token | 上下文长度、步数、输出长度 | 上下文裁剪、工具结果截断、按任务路由到小模型 |
| 缓存 | 稳定前缀的重复率 | 把系统提示和工具定义放最前面,启用 prompt caching |
| 工具与第三方 API | 调用次数、单价 | 结果缓存、批处理、失败不盲目重试 |
| 向量库 | 存储量加查询 QPS | 分层索引、按 TTL 清理旧文档 |
| 可观测平台 | trace 数量与保留期 | 采样:错误和高风险全量存,成功样本按比例 |
| 沙箱算力 | 单次运行时长 | 空闲回收、限制单次运行上限 |
硬性限制写在配置里,别写在文档里
- 单次 Agent 运行的
max_steps和 token 上限 - 单租户、单会话的日配额和熔断阈值
- 成本告警按小时环比,超阈值自动降级到小模型或转人工
- 重试上限,且只对幂等读操作重试
五、失败模式与公开案例
七种常见的翻车方式
| 失败模式 | 现象 | 根因 | 处理 |
|---|---|---|---|
| 重试风暴 | 账单暴涨,同一工具被反复调用 | 代码层没设重试上限 | 工具层做超时与熔断,重试只给读操作 |
| 工具描述含糊 | 模型调错参数或调错工具 | 参数 description 没写单位和格式 | 补 description,加正例反例 |
| 记忆污染 | 越用越差,跨会话串味 | 无差别写入长期记忆 | 白名单写入、TTL、来源标记 |
| 评估集漂移 | 离线分高,线上投诉多 | 评估集是早期构造的,没跟真实分布 | 每月从线上采样补充 |
| 上下文爆炸 | 长会话后期延迟和成本双高 | 全量历史回灌 | 摘要加关键信息结构化,辅以检索 |
| 权限过宽 | 一次注入就能删数据 | Agent 复用了人的长期 token | 短期凭证、最小权限、写操作审批 |
| 只看成功率 | 成功率高但单任务成本不可接受 | 没有单任务成本指标 | 把成本纳入评估指标 |
公开可查的落地路径
公开报道里,Klarna 在 2024 年讲过 AI 客服承接了大量重复咨询,2025 年 CEO 又表示会回补一部分人工客服岗位。具体数字各家报道有出入,这里只取方向。这个来回说明一件事:把 Agent 放进生产是可逆的过程,先用人工兜底、逐步放权,比一次性把决策权交出去稳。
两条相对稳的路径:
一条是把 Agent 放在已有工单系统里做辅助,检索、起草、填字段,人保留最终提交动作。风险低,见效快,评估集也好造。
另一条是低风险、高频、结果可验证的场景直接自动执行,比如密码重置、物流查询。前提是回滚容易,出错成本可接受。
高风险场景,比如退款、改配置、发给外部客户的内容,先走审批队列。等评估集里这类任务的样本量到几百条、判分稳定之后,再考虑放权。
上手先做两件事
不用重写架构。挑一个已经在跑的流程:
- 把工具失败的重试次数从无上限改成有上限,只对幂等读操作重试。
- 把单次运行的
max_steps和 token 上限写进配置,超限直接终止并告警。
参考文档以官方为准:modelcontextprotocol.io、github.com/a2aproject/A2A、opentelemetry.io 的 GenAI 语义约定、langfuse.com 文档。协议版本和价格随时会变,本文数字请以各官方页面当前内容核对。