暗无天日

=============>DarkSun的个人博客

读:AI Agent 生产化——一份从原型到上线的速查清单

引子:四个一上规模就坏的东西

在笔记本上写个 Agent 原型不难。调几个 API、试几个 prompt,一个周末就能搞定。但把这个原型交给真实用户、承受真实流量、处理真实数据,问题就一个个冒出来了。原文总结了四类最常见的断裂点,它们几乎总是结伴出现。

状态

原型可以把所有东西放内存。但生产环境有并行会话、重启、崩溃的情况。两个用户可能互相拿到对方的上下文,进程重启就把进行到一半的任务丢掉了。

密钥

API key 硬编码或放在 .env 文件里跟着代码库到处跑。一旦泄露或需要轮换,就有停服风险。

信任

Agent 可以不加校验地调用任何工具、传任何参数。恶意输入能骗它调用删除接口,参数类型不匹配会让工具作用于错误的资源。

可观测性

原型阶段可以靠 print 调试。上线后 Agent 开始给出略显古怪的答案,用户投诉了才会被发现。

三种架构模式

写第一行路由之前就要选好架构。后期切换意味着同时重构状态管理、测试和追踪。

ReAct(思考→行动→观察→重复) :适合步骤不固定、工具选项多的场景。容易陷入无限循环,需要设置步数预算,中间过程不好追踪。

Plan and Execute(先定计划再逐步执行) :适合步骤可预测的长周期任务。问题是一旦环境中途变化,计划就过时了。

Multi-Agent(专业 Agent 通过协调器互相交接) :适合需要清晰角色分离的复杂工作流。一旦多个 Agent 互相传递任务、失败重试、读写共享上下文,就需要编排层管理协调。否则状态不可追踪,失败几乎无法复现。

配置和治理

动手写 Agent 逻辑之前,先把配置管好。模型版本用什么、密钥放哪里、工具开关怎么控——这些基础设施不先搭好,Agent 逻辑写得再漂亮也用不起来。

模型版本放在配置里 。改模型就像改数据库连接字符串:更新配置、重启服务,不涉及修改代码 。这样才能在不触发发布流程的情况下回滚降级的模型、按合规要求切换供应商、在低环境跑更便宜的模型。

Feature Flag (功能开关)让你不改代码就能控制 Agent 行为,比如启用新工具或切换模型版本。新功能可以先对部分用户开放,出问题可以用 kill switch(紧急关闭开关)立即禁用某个工具。工具开关和模型开关要分开管理,因为它们的风险级别和审批要求不同。

环境晋升机制 :每个 Agent 在到达生产环境之前,应该先依次经过本地开发、staging(预发布)等环境,逐级验证通过后才能晋升到下一环。每个关卡都是发现问题的最佳时机,自动化检查会阻止未稳定的构建继续往上走。

状态、内存与安全

短期记忆 vs 长期记忆

Agent 系统中的"记忆"有两个不同含义。持久化太少 Agent 无法完成多轮任务,持久化太多带来合规风险和检索延迟。

原则:大部分任务用上下文窗口或带 TTL(Time To Live,自动过期时间)的缓存就够了。不要一开始就上长期记忆。当你确实需要时,要准备的不仅是一个数据库,还包括 schema、索引策略、检索机制、删除路径和经过法务审核的保留策略。

方面 短期记忆 长期记忆
范围 当前会话 跨会话持久化
适用场景 单轮和多步任务 用户偏好、历史决策、语义检索
何时清除 会话结束 显式删除或按策略
关键需求 TTL 或窗口管理 Schema、索引、保留策略、删除路径
示例工具 Redis with TTL、LangGraph checkpoints 向量数据库如 Chroma

Checkpoint 机制

一个 20 步的任务可能在 14 步失败。没有 checkpoint 就得全部重来。每完成一个关键步骤就把 Agent 状态写入持久化存储,带上步骤 ID 和时间戳。重启时从最新的 checkpoint 恢复继续执行。

六个 Agent 特有安全威胁

Agent 处理外部世界的内容并据此行动,这带来了常规安全检查表覆盖不到的六个威胁:

  1. Prompt 注入 :工具输出中的恶意内容改写 Agent 的指令。办法:所有外部内容都当作不可信,进入上下文之前先做无害化处理。
  2. 工具错误调用 :Agent 用错误参数调用工具,或远超预期地频繁调用。办法:对参数做严格的 schema 校验(规定参数的类型和取值范围),每次运行设置步骤数和调用次数上限。
  3. 数据泄露 :Agent 通过输出或外部 API 调用泄漏敏感数据。办法:对输出做过滤,给容器设置网络出口白名单。
  4. 权限提升 :Agent 访问超出自身角色的工具或资源。办法:运行时用白名单机制(不是黑名单)控制每个角色能调用的工具,每次调用记录审计日志。
  5. 失控执行 :Agent 陷入无限循环或调用数百次工具。办法:设置步骤数、tokens 数和挂钟时间(wall-clock time,实际经过的时间)三项硬限制。
  6. LLM 生成异常代码 :Agent 执行的代码可能访问意外的资源。办法:在沙箱中运行所有生成的代码,不给网络访问,文件系统设为只读。

Guardrails

安全护栏要加在平台层面,而不是靠 prompt 指令。平台层面的限制 Agent 绕不开——即使攻击者通过 prompt 注入骗过了 Agent,平台仍然能拦住越权操作。每个 Agent 角色需要一份声明式的、版本控制的 whitelist,指明它能调用哪些工具、读哪些数据、传哪些参数。校验在运行时由平台执行,Agent 逻辑无法绕过。

Human-in-the-Loop

删除记录、发送组织外消息、触发支付、做基础设施变更——这些都需要人工确认再执行。把审批门做成系统中命名的显式对象,容易添加、不会被意外绕过。每次触发、批准、拒绝和决策耗时都要记录。

测试和评估管道

没有评估直接上线,跟不做测试就部署一样不靠谱。Agent 的失败模式往往是隐形的:看起来合理的错误答案,或者本应成功却被拒绝的任务。

五级评估层级

评估类型 测什么 何时跑 是否阻断部署
Unit 单次 prompt 或工具调用返回预期输出 每次提交 硬失败时阻断
Integration 工具链和交接端到端正常 每次 PR 有回归就阻断
End to End 完整任务在类生产输入上完成 每次发布 低于阈值阻断
Regression 关键指标 vs 上次发布基线 每次发布 超定义差值阻断
Human Spot 人工抽检真实输出质量 每周 不阻断,但指导改进

使用 数据集 评估系统质量

评估系统的质量只取决于它的数据集。用简单规整的示例构建的数据集,在真正糟糕的构建上也会全绿通过。

数据集应来自三个真实来源:首次 staging 运行的输入、团队遇到的边界案例、Agent 应该拒绝而非尝试的场景。数据集和 Agent 代码一起做版本管理。每次生产事故后,在修代码之前先把出问题的 case 加入数据集。

CI/CD Eval Gates

评估连接到部署流程后,就从定期的质量检查变成了每次构建的自动发布标准。在非生产阶段就集成 eval gates,不要只在最终部署前才跑。

首次发布前设好阈值:任务成功率 80% 以上、安全拒绝率不超过可完成任务数的 3%、p95 延迟在 SLA 以内。上线后根据实际数据调整。

打包规范

Agent 和普通服务一样遵循容器规则,外加一项:模型版本放在配置里,这样无需改代码就能回滚。需要固定的内容:

  • 基础镜像:Dockerfile 中用精确 tag(如 python:3.11.9-slim
  • 运行时版本: .tool-versions 或 Dockerfile 中的 ARG
  • 依赖:带哈希值的 requirements.txtpackage-lock.json
  • 模型名称:配置文件或环境变量,绝不能出现在源码里
  • 系统 prompt:带版本管理变更历史的 prompt 注册表

超过一秒的 Agent 任务应该异步执行。API 接受请求后立即返回,任务队列持有作业直到工作进程取走,客户端通过轮询或 webhook 获取结果。

监控、成本和反馈闭环

上线不是终点。模型更新后 Agent 开始给错误答案,但它不会抛异常,标准基础设施监控抓不到它。

七个监控信号

  • Traces(追踪) :每个步骤、工具调用、模型调用和决策点的完整序列(工具示例:LangSmith、Arize Phoenix、Weave)
  • Token 用量 :每次运行、每个用户、每个模型版本的输入/输出 tokens(工具示例:Provider dashboards、custom span attributes)
  • 工具调用 :哪些工具被调用、传了什么参数、每次耗时(工具示例:Custom spans inside your task runner)
  • 延迟 :p50/p95/p99 的完整运行和单步延迟(工具示例:Prometheus、Datadog、Grafana)
  • 错误率 :工具失败、模型超时、审批门触发、解析错误(工具示例:Alerting platform + custom counters)
  • 输出质量 :通过定时任务对实时输出的随机样本跑评估(工具示例:DeepEval、Ragas、LangSmith eval runs)
  • 成本 :每次运行、每个用户、每种 Agent 类型、每个模型版本的费用消耗(工具示例:Provider billing API + custom resource tagging)

成本护栏

Token 成本不是线性的。检索步骤返回更长文档会让每次运行的输入 tokens 翻倍。推理循环多一步就会给所有用户的每次请求增加 token 消耗。按 Agent 类型和租户设置预算告警。突然的成本飙升几乎总指向一个具体、可修复的问题。

信号 通常意味着什么 先查哪里
单次成本翻倍 检索返回更长文档,或循环多了一步 按步骤看 token 用量分解
拒绝率高于基线 Prompt 变更、模型更新、输入分布偏移 对比 prompt 版本变化
p95 延迟升 50% 工具调用变慢,或供应商负载高 看工具耗时 span,再看供应商状态页
评估分数下降 5%+ 模型漂移、数据漂移、prompt 回归 跑完整 eval 套件对比上个基线

事件响应三问

Agent 事故需要不同的初始响应。模型输出的不确定性往往让你无法复现事件,事件波及范围也很难评估——因为你不知道 Agent 碰过哪些外部系统。

开始调查时先问三个问题:(1) 根据输入和它生成的计划,Agent 想做什么?(2) 根据追踪记录,它实际做了什么?(3) 根据审计日志,它改变了哪些外部状态?审计日志不是可选项。它让你能在出错的运行之后做撤销或补偿,也是回答第三个问题的唯一可靠手段。

反馈闭环

每次出了生产事故,修代码之前先把出问题的例子加入评估数据集。这样一来,以后再有类似的问题,回归测试那一关就会拦住它,不会悄无声息地又上线了。团队还应该按周检查评估分数的变化趋势、成本有没有异常、以及审批门触发了多少次。

收尾

生产就绪的 Agent,本质上是一个围绕"什么东西会坏"刻意构建的系统:能安全跨环境流动的配置、崩溃后还能恢复的状态、不会被滥用的工具、能在用户发现问题之前就拦住质量退步的自动化评估体系、以及每次运行后能告诉你发生了什么的可观测性。

原文的建议是从密钥管理和评估数据集开始,给你风险最高的工具加一个人工审批门,为第一次部署配上监控。每次发布之后就是下一轮评估周期的起点,构建周期结束了,评估周期才开始。

AI : Agent : 生产部署 : 架构 : 安全 : 监控