Appearance
06. 评测、可观测性与安全
版本:
v1.2最后更新:
2026-07-09
1. 为什么很多 Agent 项目最后卡在这里
不少 Agent Demo 能跑起来,但一进真实环境就会暴露三个根问题:
- 你不知道系统到底有没有持续变好
- 出错以后你不知道具体错在第几步
- 一接真实工具和真实数据,风险立刻升级
这三个问题分别对应:
评测可观测性安全
它们不是三个并列附属模块,而是 Agent 从 Demo 走向生产的必要闭环。没有这三层,系统即使短期看起来能跑,也很难稳定迭代。
2. Agent 的评测,到底在评什么
Agent 评测不能只看“最终答案像不像对”。因为 Agent 的真实复杂度往往发生在中间步骤:
- 是否选对了工具
- 是否在正确时机调用工具
- 参数是否填对
- 检索是否拿到有效证据
- 是否错误进入循环
- 是否触发了不该触发的高风险动作
根据 OpenAI Evaluate agent workflows、Integrations and observability、Trace grading 与 Agents SDK 官方资料在 2026-07-08 可访问的说明,当前更推荐把 Agent 评测理解为一套围绕 traces、datasets、graders、evaluation runs 的体系,而不是只盯最终文本结果。
更实用的评测层次通常至少包括:
2.1 结果层
- 任务是否完成
- 输出是否符合格式
- 用户问题是否真正被解决
2.2 过程层
- 工具选择是否正确
- 工具参数是否正确
- handoff 是否发生在合理时机
- 中间状态是否保持一致
2.3 运行层
- token 成本是否可控
- 总时延是否可接受
- 重试次数是否异常
- fallback 是否频繁触发
2.4 风险层
- 是否出现越权调用
- 是否漏掉审批
- 是否被注入带偏
- 是否输出不合规建议
3. 一个最小可行的 Agent 评测闭环
如果团队还在早期,不需要一开始就上很重的平台,先把闭环跑通更重要。
一个最小闭环通常可以是:
- 收集
20-50条真实任务或真实失败样例。 - 为每条任务写“成功定义”。
- 固定版本跑一轮。
- 记录 traces、输出、成本、时延和失败原因。
- 按失败类型分桶。
- 修改 prompt、工具边界、工作流或 guardrails。
- 再跑一轮对比前后差异。
这个方法的价值,不在于样本数很大,而在于你从“凭感觉改 Agent”转向“带证据改 Agent”。
3.1 更像生产系统的评测,通常会拆成离线、在线和发布前三层
很多团队一提 eval,就只想到:
- 跑一套离线样本
这远远不够。
更像真实系统的做法通常会把评测拆成三层:
| 层级 | 主要回答什么问题 | 典型资产 |
|---|---|---|
| 离线评测 | 这版改动在已知样本上是否更好 | datasets、graders、trace eval runs |
| 在线观测 | 真实流量里是否出现新退化 | traces、metrics、投诉样例、人工接管率 |
| 发布前门禁 | 这版是否具备放量资格 | must-pass cases、risk gates、release checklist |
这三层不能互相替代:
- 离线评测不能保证真实流量无新问题
- 在线观测不能替代发布前的硬门禁
- 发布门禁也不能替代持续样例积累
一个更稳的循环通常是:
- 线上发现失败样例
- 进入离线 eval 集
- 修复后重跑离线评测
- 满足门禁再灰度上线
- 灰度 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 来说,它同时也是数据治理问题。
至少建议提前定义三件事:
- 哪些字段可以进入公共 trace 面板
- 哪些字段只能进入受控日志或审计系统
- 哪些字段需要定期过期、脱敏或只保留引用 ID
更稳的做法通常是:
- 低敏摘要进 trace
- 原始高敏内容只保留在受控存储
- 用
artifact_id、approval_id、trace_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 agents 与 Guardrails 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 behaviorOpenAI 的官方 cookbook 也在强调用 traces、evals 和改进循环去推进 Agent 迭代,而不是依赖单点手工调优。
如果没有这个闭环,团队常见的状态会是:
- 线上出问题
- 人工看几条日志猜原因
- 改一版 prompt
- 再上线碰运气
12. 高风险动作默认应该怎么处理
更稳妥的默认策略通常是:
- 生成建议可以自动
- 不可逆执行必须谨慎
- 涉及真实业务写操作应有审批
- 高权限工具必须最小化暴露
常见需要默认进入审批或人工复核的动作包括:
- 发邮件或发消息
- 写数据库
- 建工单、关工单
- 修改生产配置
- 访问敏感客户数据
- 调用外部付费或交易接口
这不是因为系统“太弱”,而是因为你已经在认真对待真实副作用。
12.1 高风险动作最好显式建一张 risk matrix
很多团队对“高风险”只停留在口头共识,真正上线时还是靠临场判断。
更像生产系统的做法通常会显式列一张矩阵:
| 动作类型 | 默认策略 | 是否审批 | 是否可自动重试 | 是否需审计留档 |
|---|---|---|---|---|
| 只读检索 | 自动 | 否 | 可 | 选做 |
| 外发消息 | 建议自动、执行谨慎 | 是 | 否 | 是 |
| 写数据库 | 默认谨慎 | 是 | 视幂等性而定 | 是 |
| 改生产配置 | 默认阻断或强审批 | 是 | 否 | 是 |
| 访问敏感数据 | 最小暴露 | 常常需要 | 否 | 是 |
这张表的价值不是形式化,而是让:
- 产品
- 安全
- 平台
- 业务 owner
在上线前就先把默认边界对齐。
12.2 审批不是“一个按钮”,而是一次显式中断
OpenAI 当前 Guardrails and human review 文档里,一个非常值得借鉴的点是:
- 高风险工具调用不是继续执行
- 而是先进入
interruption
这背后的工程意义非常重要:
- 审批不是日志事件
- 审批是运行时状态转移
一个更像生产系统的审批对象通常至少要包含:
approval_idtrace_idrun_idtool_call_idrequested_actionrisk_levelreviewerdecisiondecision_reasonresume_state_ref
如果没有这层对象,后面最容易乱的就是:
- 审批通过后从哪一步继续
- 驳回后是改计划、终止还是转人工
- 到底是哪位 reviewer 为这次动作负责
13. 最容易被忽视的几个反模式
13.1 只评最终答案,不评过程
这会让团队永远分不清是检索错、工具错还是状态机错。
13.2 trace 只保留成功案例
真正最值得留的通常是失败样例、高成本样例、高延迟样例和人工投诉样例。
13.3 只接入安全检测,不接审批
检测到风险不代表系统就一定能正确阻断高风险动作。
13.4 为了调试把敏感数据全打进日志
可观测性不能以泄露数据为代价,日志与 trace 也要脱敏和分级。
13.5 把所有问题都归结到模型
很多线上问题根本不在模型本身,而在工具契约、状态传递、fallback 逻辑或审批边界。
14. 一个实用的落地顺序
如果你准备把 Agent 系统做稳,比较建议按这个顺序推进:
- 先定义任务成功标准。
- 接入基础 trace。
- 为关键步骤打 span。
- 沉淀一批失败样例与 eval 集。
- 在高风险动作前加 guardrails 和审批。
- 把线上 traces 反哺到下一轮评测。
做到这一步后,系统才真正具备“可持续优化”的基础。
15. 这一章最值得掌握的六个问题
每做一个 Agent,都应该反复问自己:
- 我如何证明这次改动真的让系统变好了?
- 出错时我能不能定位到具体哪一步?
- 关键步骤有没有留下足够 trace 证据?
- 哪些动作必须走审批,而不是自动执行?
- 哪类失败正在系统性增加?
- 如果遭遇恶意输入,最坏会发生什么?
这六个问题答得越清楚,系统离生产级就越近。
16. 发布门禁最好提前定义,而不是上线前临时拍脑袋
很多团队做评测,真正卡住的不是“会不会跑 eval”,而是:
- 到底什么情况能上线
- 什么情况必须拦截
如果这条门禁不提前定义,评测报告再多,最后也很容易变成:
- 分数看起来还行
- 但没人敢真的做发布决定
更实用的门禁通常至少分三层:
| 层级 | 常见判断 |
|---|---|
| 必过门禁 | 结构化输出、审批约束、高风险样本不得退化 |
| 软门禁 | 成本、时延、人工接管率不应明显恶化 |
| 观察门禁 | 某些长尾问题允许带观察上线,但必须持续监控 |
根据 OpenAI Evaluate agent workflows 与 Guardrails and human review 的思路放到工程里,一个稳妥的发布门禁,不只是比较总分,而是明确:
- 哪些样本一旦退化就不能上线。
- 哪些风险动作永远不能绕过审批。
- 哪些异常可以灰度观察,哪些异常必须立即阻断。
17. trace 不是只给调试看的,还要服务审计与事故复盘
很多人一提 trace,第一反应都是:
- 方便排查 bug
这当然没错,但在 Agent 系统里,trace 还承担了更重的角色:
- 审批证据
- 事故复盘材料
- 安全审计对象
- 评测样本来源
这意味着你不能只保留一个“最后输出”,更稳妥的做法通常是至少额外留住:
- 用户目标摘要
- 关键工具调用
- 审批请求与审批决定
- 高风险动作前的参数快照
- guardrail 命中记录
- 最终执行对象 ID
如果这些对象不在,后面就很难回答:
- 这次高风险动作为什么会被放行
- 模型建议和最终执行到底是不是同一件事
- 是策略漏拦,还是人工误批
18. 间接注入与远端内容污染,是 Agent 安全里最容易被低估的部分
很多团队会重点防用户输入里的恶意提示,却忽略另一个更真实的入口:
- 外部网页、文档、邮件、知识库片段、远端工具返回内容,也可能把模型带偏
这类问题的难点在于:
- 污染内容看起来像“正常工具结果”
- 它不是用户直接输入,但照样会进入模型上下文
所以更稳妥的控制方式一般不是只靠最终输出检测,而是把风险控制往前移:
- 对外部内容做来源标记和可信度分层。
- 对高风险工具结果做归一化和裁剪,不把整包原始内容直接喂回模型。
- 对来自网页、邮箱、第三方系统的内容单独加注入检测或策略过滤。
- 对真正会触发副作用的动作,再叠一层审批。
这也是为什么安全治理不能只盯用户消息,而要覆盖:
- 输入
- 上下文拼接
- 工具结果回流
- 最终执行
19. 推荐搭配阅读
20. 业务回放、trace 和安全样例最好沉淀成同一套资产
很多团队会把下面三类东西分开维护:
- 线上事故样例
- eval 数据集
- trace 复盘记录
结果就是:
- 事故复盘是一份文档
- 评测是一套脚本
- 线上 trace 在另一个系统里
三者很难真正形成闭环。
更稳妥的做法通常是把它们尽量绑定起来:
- 线上事故或差评请求进入失败样例池。
- 样例绑定 trace id、版本信息和风险标签。
- 能自动回放的样例进入 eval 集。
- 高风险动作与审批证据进入审计留档。
这样评测、运营和安全才不会各跑各的。
20.1 一个更像生产系统的资产对象,通常至少包含这些字段
trace_idrequest_iddataset_case_idworkflow_versionprompt_or_agent_versiontool_schema_versionrisk_bucketfailure_bucketapproval_event_idsartifact_ids
这些字段一旦对齐,很多原本割裂的动作才真正能接起来:
- 回放
- 评测
- 灰度对比
- 事故归档
- 安全审计
20.2 最好把“样例资产”和“发布资产”也绑定起来
很多团队会分别维护:
- 一个 eval 数据集
- 一份发布记录
- 一批事故单
但它们之间没有真正打通。
更稳的做法通常是把发布也当成资产对象的一部分,至少记录:
release_ringgate_resultmust_pass_case_idsregression_case_idsobserved_risk_bucketsrollback_decision
这样后面你才能回答:
- 这次为什么允许灰度
- 哪些样例当时是带观察放出去的
- 回滚到底是因为什么桶触发的
- 同类问题以后是否已被纳入硬门禁
21. 重点官方资源
以下官方资料已按 2026-07-09 复核到当前正式入口;其中部分 OpenAI 页面对脚本访问会返回 403,但浏览器入口仍可正常打开:
- OpenAI Evaluate agent workflows:https://developers.openai.com/api/docs/guides/agent-evals
- OpenAI Integrations and observability:https://developers.openai.com/api/docs/guides/agents/integrations-observability
- OpenAI Trace grading:https://developers.openai.com/api/docs/guides/trace-grading
- OpenAI Guardrails and human review:https://developers.openai.com/api/docs/guides/agents/guardrails-approvals
- OpenAI Safety in building agents:https://developers.openai.com/api/docs/guides/agent-builder-safety
- OpenAI Safety best practices:https://developers.openai.com/api/docs/guides/safety-best-practices
- OpenTelemetry Traces:https://opentelemetry.io/docs/concepts/signals/traces/
- OpenTelemetry Observability primer:https://opentelemetry.io/docs/concepts/observability-primer/
22. 这一章最值得立刻补上的实践动作
建议你至少先补这 6 件事:
- 给关键 workflow 节点补结构化 span。
- 为工具调用失败定义统一 failure buckets。
- 为高风险动作整理一张 risk matrix。
- 把审批事件和 trace 绑到同一条链路里。
- 把最近一批真实失败样例转成 eval 集。
- 为发布定义必过门禁、软门禁和观察门禁。
只要这 6 件事落下来,你的 Agent 系统就会从“能跑 Demo”明显走向“能被持续运营和审计”。