Skip to content

06. 评测、可观测性与安全

版本:v1.2

最后更新:2026-07-09

1. 为什么很多 Agent 项目最后卡在这里

不少 Agent Demo 能跑起来,但一进真实环境就会暴露三个根问题:

  • 你不知道系统到底有没有持续变好
  • 出错以后你不知道具体错在第几步
  • 一接真实工具和真实数据,风险立刻升级

这三个问题分别对应:

  • 评测
  • 可观测性
  • 安全

它们不是三个并列附属模块,而是 Agent 从 Demo 走向生产的必要闭环。没有这三层,系统即使短期看起来能跑,也很难稳定迭代。

2. Agent 的评测,到底在评什么

Agent 评测不能只看“最终答案像不像对”。因为 Agent 的真实复杂度往往发生在中间步骤:

  • 是否选对了工具
  • 是否在正确时机调用工具
  • 参数是否填对
  • 检索是否拿到有效证据
  • 是否错误进入循环
  • 是否触发了不该触发的高风险动作

根据 OpenAI Evaluate agent workflowsIntegrations and observabilityTrace gradingAgents SDK 官方资料在 2026-07-08 可访问的说明,当前更推荐把 Agent 评测理解为一套围绕 tracesdatasetsgradersevaluation runs 的体系,而不是只盯最终文本结果。

更实用的评测层次通常至少包括:

2.1 结果层

  • 任务是否完成
  • 输出是否符合格式
  • 用户问题是否真正被解决

2.2 过程层

  • 工具选择是否正确
  • 工具参数是否正确
  • handoff 是否发生在合理时机
  • 中间状态是否保持一致

2.3 运行层

  • token 成本是否可控
  • 总时延是否可接受
  • 重试次数是否异常
  • fallback 是否频繁触发

2.4 风险层

  • 是否出现越权调用
  • 是否漏掉审批
  • 是否被注入带偏
  • 是否输出不合规建议

3. 一个最小可行的 Agent 评测闭环

如果团队还在早期,不需要一开始就上很重的平台,先把闭环跑通更重要。

一个最小闭环通常可以是:

  1. 收集 20-50 条真实任务或真实失败样例。
  2. 为每条任务写“成功定义”。
  3. 固定版本跑一轮。
  4. 记录 traces、输出、成本、时延和失败原因。
  5. 按失败类型分桶。
  6. 修改 prompt、工具边界、工作流或 guardrails。
  7. 再跑一轮对比前后差异。

这个方法的价值,不在于样本数很大,而在于你从“凭感觉改 Agent”转向“带证据改 Agent”。

3.1 更像生产系统的评测,通常会拆成离线、在线和发布前三层

很多团队一提 eval,就只想到:

  • 跑一套离线样本

这远远不够。

更像真实系统的做法通常会把评测拆成三层:

层级主要回答什么问题典型资产
离线评测这版改动在已知样本上是否更好datasets、graders、trace eval runs
在线观测真实流量里是否出现新退化traces、metrics、投诉样例、人工接管率
发布前门禁这版是否具备放量资格must-pass cases、risk gates、release checklist

这三层不能互相替代:

  • 离线评测不能保证真实流量无新问题
  • 在线观测不能替代发布前的硬门禁
  • 发布门禁也不能替代持续样例积累

一个更稳的循环通常是:

  1. 线上发现失败样例
  2. 进入离线 eval 集
  3. 修复后重跑离线评测
  4. 满足门禁再灰度上线
  5. 灰度 traces 再回流下一轮

4. 失败样例不分桶,评测价值会大打折扣

很多团队说自己“做了评测”,实际上只是保存了一堆失败记录,却没法支持下一步优化。

更实用的分桶方式通常是:

  • 任务理解错误
  • Router 路由错误
  • Planner 拆解错误
  • 检索结果不相关
  • 工具选择错误
  • 工具参数错误
  • 状态管理错误
  • 输出结构错误
  • guardrails 误拦或漏拦
  • 审批策略缺失

一旦失败分类做对了,优化方向会立刻清晰很多。否则你只能不断“再调一版 prompt 试试看”。

5. traces 是 Agent 评测的原始证据

根据 OpenAI Integrations and observability 官方文档在 2026-07-08 的说明,Agents SDK 默认就能记录结构化 tracing,覆盖:

  • model calls
  • tool calls
  • handoffs
  • guardrails
  • custom spans

这意味着 Agent 评测的证据不该只来自最终对话结果,还应来自运行轨迹本身。真正有用的问题往往是:

  • 为什么选择了这个工具
  • 为什么在这里发生 handoff
  • 为什么这一步耗时暴涨
  • 为什么 guardrail 触发后流程还继续了

没有 trace,这些问题几乎只能靠猜。

5.1 Trace grading 适合解决“到底坏在第几步”

OpenAI 当前 Trace grading 文档把一个很关键的思路讲得很清楚:

  • 不是只给 final output 打分
  • 而是给整条 trace 的关键行为打结构化标签

这件事非常适合回答下面这些问题:

  • 这次是不是选错工具了
  • handoff 是不是发生得太早或太晚
  • guardrail 有没有漏拦
  • reroute / fallback 是不是比之前更频繁

相比只看最终答案,trace grading 的优势在于:

  • 能按步骤定位退化点
  • 更容易把问题归到 routing / tool use / guardrail / state
  • 更适合比较“同样答对,但过程是否更稳”

如果团队已经开始做 Agents SDK tracing,这通常是从“能看到 trace”走向“能系统评估 trace”的第一步。

6. 可观测性不是“多打一层日志”

可观测性的目标不是让系统“记录更多东西”,而是让团队在出问题时不用临时加日志也能定位。

OpenTelemetry 的概念里,完整观测通常由三类信号协同:

  • traces:看单次请求走了哪些步骤
  • metrics:看整体趋势是不是在变差
  • logs:看具体事件与异常细节

在 Agent 系统里,这三者可以简单理解成:

  • trace 负责还原一次任务经历了什么
  • metric 负责发现某一类请求整体在退化
  • log 负责保留规则命中、异常分支、审批动作等离散事件

6.1 可观测性还要回答“谁能看什么、保留多久”

很多团队把 observability 只当成技术平台问题,但对 Agent 来说,它同时也是数据治理问题。

至少建议提前定义三件事:

  1. 哪些字段可以进入公共 trace 面板
  2. 哪些字段只能进入受控日志或审计系统
  3. 哪些字段需要定期过期、脱敏或只保留引用 ID

更稳的做法通常是:

  • 低敏摘要进 trace
  • 原始高敏内容只保留在受控存储
  • artifact_idapproval_idtrace_id 做跨系统关联

这样既能保留可诊断性,也不会为了排障把敏感内容打得到处都是。

7. Agent 系统至少要观测哪些维度

7.1 请求级

  • 用户目标
  • 输入摘要
  • 最终输出
  • 总 token
  • 总时延
  • 终态成功/失败

7.2 工作流级

  • 经过了哪些节点
  • 每步耗时
  • 每步模型
  • 每步工具
  • 每步重试情况
  • 是否走了 fallback

7.3 质量级

  • 任务完成率
  • 用户纠正率
  • 人工接管率
  • 安全拦截率
  • 结构化输出失败率

7.4 风险级

  • 高风险工具调用次数
  • 高风险动作审批触发率
  • 漏审批率
  • 越权调用拦截率
  • 注入攻击命中率

7.5 版本与发布级

  • 当前模型版本
  • prompt / tool schema 版本
  • workflow / graph 版本
  • guardrail policy 版本
  • eval bundle 版本
  • 当前灰度批次或 release ring

如果这些版本字段没打进观测体系,后面最常见的问题就是:

  • 指标变差了
  • 但没人说得清到底是模型变了、提示词变了、工具变了,还是审批策略变了

如果这些维度看不到,Agent 一旦进入真实流量,团队就很难区分问题到底来自:

  • 模型
  • prompt
  • 检索
  • 工具
  • 编排
  • 审批
  • 安全策略

8. span 设计比“有没有 trace”更关键

很多系统声称接了 tracing,但 trace 里只有一个总请求和一个总响应,几乎没有诊断价值。

更推荐为这些关键步骤单独打 span:

  • retrieval
  • ranking / reranking
  • planner
  • tool execution
  • handoff
  • output validation
  • guardrail check
  • approval wait

这样才能回答下面这些真实问题:

  • 慢到底慢在检索还是模型推理
  • 是工具调用失败,还是工具成功但结果被误用
  • 是 guardrail 拦住了任务,还是根本没拦住该拦的东西

8.1 span 属性不要只图“多”,还要控制可读性和基数

很多团队一开始接 trace,会恨不得把所有字段都塞进 span attributes。

但更稳的设计通常会区分三类字段:

  • 低基数、适合聚合:tool_name、route_name、risk_level、approval_required
  • 中基数、适合定位:request_id、tenant_id、workflow_version
  • 高敏感或高基数:原始用户文本、完整参数、长文证据、PII

最后一类通常不该直接进公共指标面,而应:

  • 做脱敏
  • 单独进受控日志
  • 或只保留引用 ID

否则会直接带来两个问题:

  • 可观测平台本身被高基数字段拖垮
  • 为了排查问题把敏感数据打得到处都是

9. Agent 安全为什么不是“最后加个审核接口”

一旦 Agent 能调用工具,风险模型就从“错误回答”升级成“错误行动”。

根据 OpenAI Safety in building agentsGuardrails and human review 官方文档,安全控制不应只发生在输出末端,而要覆盖输入、上下文、工具、输出和执行决策。

风险最常见的放大路径包括:

  • 用户输入带偏模型
  • 外部文档或网页通过间接注入污染上下文
  • 模型选择了本不该用的工具
  • 工具参数不安全
  • 高风险动作没有经过审批
  • 日志里留不下足够审计证据

10. 安全控制应当嵌进工作流,而不是悬在旁边

OpenAI 官方将 guardrails 描述为对输入、输出或工具行为的自动校验,而 human review 负责对敏感动作做审批判断。

从工程角度看,更稳的多层控制通常像这样:

text
Input checks
 -> Context checks
 -> Tool checks
 -> Output checks
 -> Human approval for risky actions
 -> Execution

这里最关键的认知是:

  • guardrails 决定流程能否继续
  • approvals 决定高风险动作能否执行

如果把“模型建议”和“系统执行”混为一体,Agent 风险会迅速失控。

11. 评测、可观测性、安全三者怎么形成闭环

它们之间不是三条独立流水线,而是一个持续改进环:

text
Observe traces
 -> Find bad cases
 -> Add them to eval sets
 -> Improve prompts/tools/guardrails
 -> Re-run evals
 -> Re-observe production behavior

OpenAI 的官方 cookbook 也在强调用 traces、evals 和改进循环去推进 Agent 迭代,而不是依赖单点手工调优。

如果没有这个闭环,团队常见的状态会是:

  • 线上出问题
  • 人工看几条日志猜原因
  • 改一版 prompt
  • 再上线碰运气

12. 高风险动作默认应该怎么处理

更稳妥的默认策略通常是:

  • 生成建议可以自动
  • 不可逆执行必须谨慎
  • 涉及真实业务写操作应有审批
  • 高权限工具必须最小化暴露

常见需要默认进入审批或人工复核的动作包括:

  • 发邮件或发消息
  • 写数据库
  • 建工单、关工单
  • 修改生产配置
  • 访问敏感客户数据
  • 调用外部付费或交易接口

这不是因为系统“太弱”,而是因为你已经在认真对待真实副作用。

12.1 高风险动作最好显式建一张 risk matrix

很多团队对“高风险”只停留在口头共识,真正上线时还是靠临场判断。

更像生产系统的做法通常会显式列一张矩阵:

动作类型默认策略是否审批是否可自动重试是否需审计留档
只读检索自动选做
外发消息建议自动、执行谨慎
写数据库默认谨慎视幂等性而定
改生产配置默认阻断或强审批
访问敏感数据最小暴露常常需要

这张表的价值不是形式化,而是让:

  • 产品
  • 安全
  • 平台
  • 业务 owner

在上线前就先把默认边界对齐。

12.2 审批不是“一个按钮”,而是一次显式中断

OpenAI 当前 Guardrails and human review 文档里,一个非常值得借鉴的点是:

  • 高风险工具调用不是继续执行
  • 而是先进入 interruption

这背后的工程意义非常重要:

  • 审批不是日志事件
  • 审批是运行时状态转移

一个更像生产系统的审批对象通常至少要包含:

  • approval_id
  • trace_id
  • run_id
  • tool_call_id
  • requested_action
  • risk_level
  • reviewer
  • decision
  • decision_reason
  • resume_state_ref

如果没有这层对象,后面最容易乱的就是:

  • 审批通过后从哪一步继续
  • 驳回后是改计划、终止还是转人工
  • 到底是哪位 reviewer 为这次动作负责

13. 最容易被忽视的几个反模式

13.1 只评最终答案,不评过程

这会让团队永远分不清是检索错、工具错还是状态机错。

13.2 trace 只保留成功案例

真正最值得留的通常是失败样例、高成本样例、高延迟样例和人工投诉样例。

13.3 只接入安全检测,不接审批

检测到风险不代表系统就一定能正确阻断高风险动作。

13.4 为了调试把敏感数据全打进日志

可观测性不能以泄露数据为代价,日志与 trace 也要脱敏和分级。

13.5 把所有问题都归结到模型

很多线上问题根本不在模型本身,而在工具契约、状态传递、fallback 逻辑或审批边界。

14. 一个实用的落地顺序

如果你准备把 Agent 系统做稳,比较建议按这个顺序推进:

  1. 先定义任务成功标准。
  2. 接入基础 trace。
  3. 为关键步骤打 span。
  4. 沉淀一批失败样例与 eval 集。
  5. 在高风险动作前加 guardrails 和审批。
  6. 把线上 traces 反哺到下一轮评测。

做到这一步后,系统才真正具备“可持续优化”的基础。

15. 这一章最值得掌握的六个问题

每做一个 Agent,都应该反复问自己:

  1. 我如何证明这次改动真的让系统变好了?
  2. 出错时我能不能定位到具体哪一步?
  3. 关键步骤有没有留下足够 trace 证据?
  4. 哪些动作必须走审批,而不是自动执行?
  5. 哪类失败正在系统性增加?
  6. 如果遭遇恶意输入,最坏会发生什么?

这六个问题答得越清楚,系统离生产级就越近。

16. 发布门禁最好提前定义,而不是上线前临时拍脑袋

很多团队做评测,真正卡住的不是“会不会跑 eval”,而是:

  • 到底什么情况能上线
  • 什么情况必须拦截

如果这条门禁不提前定义,评测报告再多,最后也很容易变成:

  • 分数看起来还行
  • 但没人敢真的做发布决定

更实用的门禁通常至少分三层:

层级常见判断
必过门禁结构化输出、审批约束、高风险样本不得退化
软门禁成本、时延、人工接管率不应明显恶化
观察门禁某些长尾问题允许带观察上线,但必须持续监控

根据 OpenAI Evaluate agent workflowsGuardrails and human review 的思路放到工程里,一个稳妥的发布门禁,不只是比较总分,而是明确:

  1. 哪些样本一旦退化就不能上线。
  2. 哪些风险动作永远不能绕过审批。
  3. 哪些异常可以灰度观察,哪些异常必须立即阻断。

17. trace 不是只给调试看的,还要服务审计与事故复盘

很多人一提 trace,第一反应都是:

  • 方便排查 bug

这当然没错,但在 Agent 系统里,trace 还承担了更重的角色:

  • 审批证据
  • 事故复盘材料
  • 安全审计对象
  • 评测样本来源

这意味着你不能只保留一个“最后输出”,更稳妥的做法通常是至少额外留住:

  • 用户目标摘要
  • 关键工具调用
  • 审批请求与审批决定
  • 高风险动作前的参数快照
  • guardrail 命中记录
  • 最终执行对象 ID

如果这些对象不在,后面就很难回答:

  • 这次高风险动作为什么会被放行
  • 模型建议和最终执行到底是不是同一件事
  • 是策略漏拦,还是人工误批

18. 间接注入与远端内容污染,是 Agent 安全里最容易被低估的部分

很多团队会重点防用户输入里的恶意提示,却忽略另一个更真实的入口:

  • 外部网页、文档、邮件、知识库片段、远端工具返回内容,也可能把模型带偏

这类问题的难点在于:

  • 污染内容看起来像“正常工具结果”
  • 它不是用户直接输入,但照样会进入模型上下文

所以更稳妥的控制方式一般不是只靠最终输出检测,而是把风险控制往前移:

  1. 对外部内容做来源标记和可信度分层。
  2. 对高风险工具结果做归一化和裁剪,不把整包原始内容直接喂回模型。
  3. 对来自网页、邮箱、第三方系统的内容单独加注入检测或策略过滤。
  4. 对真正会触发副作用的动作,再叠一层审批。

这也是为什么安全治理不能只盯用户消息,而要覆盖:

  • 输入
  • 上下文拼接
  • 工具结果回流
  • 最终执行

19. 推荐搭配阅读

20. 业务回放、trace 和安全样例最好沉淀成同一套资产

很多团队会把下面三类东西分开维护:

  • 线上事故样例
  • eval 数据集
  • trace 复盘记录

结果就是:

  • 事故复盘是一份文档
  • 评测是一套脚本
  • 线上 trace 在另一个系统里

三者很难真正形成闭环。

更稳妥的做法通常是把它们尽量绑定起来:

  1. 线上事故或差评请求进入失败样例池。
  2. 样例绑定 trace id、版本信息和风险标签。
  3. 能自动回放的样例进入 eval 集。
  4. 高风险动作与审批证据进入审计留档。

这样评测、运营和安全才不会各跑各的。

20.1 一个更像生产系统的资产对象,通常至少包含这些字段

  • trace_id
  • request_id
  • dataset_case_id
  • workflow_version
  • prompt_or_agent_version
  • tool_schema_version
  • risk_bucket
  • failure_bucket
  • approval_event_ids
  • artifact_ids

这些字段一旦对齐,很多原本割裂的动作才真正能接起来:

  • 回放
  • 评测
  • 灰度对比
  • 事故归档
  • 安全审计

20.2 最好把“样例资产”和“发布资产”也绑定起来

很多团队会分别维护:

  • 一个 eval 数据集
  • 一份发布记录
  • 一批事故单

但它们之间没有真正打通。

更稳的做法通常是把发布也当成资产对象的一部分,至少记录:

  • release_ring
  • gate_result
  • must_pass_case_ids
  • regression_case_ids
  • observed_risk_buckets
  • rollback_decision

这样后面你才能回答:

  • 这次为什么允许灰度
  • 哪些样例当时是带观察放出去的
  • 回滚到底是因为什么桶触发的
  • 同类问题以后是否已被纳入硬门禁

21. 重点官方资源

以下官方资料已按 2026-07-09 复核到当前正式入口;其中部分 OpenAI 页面对脚本访问会返回 403,但浏览器入口仍可正常打开:

22. 这一章最值得立刻补上的实践动作

建议你至少先补这 6 件事:

  1. 给关键 workflow 节点补结构化 span。
  2. 为工具调用失败定义统一 failure buckets。
  3. 为高风险动作整理一张 risk matrix。
  4. 把审批事件和 trace 绑到同一条链路里。
  5. 把最近一批真实失败样例转成 eval 集。
  6. 为发布定义必过门禁、软门禁和观察门禁。

只要这 6 件事落下来,你的 Agent 系统就会从“能跑 Demo”明显走向“能被持续运营和审计”。