给 Agent 工具日志做脱敏时,我会先把原始参数和观测事件分开
最近给一个内部 Agent 工具台补排障面板时,我遇到一个很现实的问题:工具调用失败后,研发希望看到参数和返回值,安全同学希望日志里不要出现邮箱、客户编号、文件路径、临时 token 和内部文档标题。第一版把 tool args、tool result 和模型中间消息都塞进 trace,定位快了,但日志平台也成了新的敏感信息聚集点。

原创示意图:把 UI 事件、Agent runner、工具网关、脱敏策略、trace 存储和证据复核拆成可追踪链路。 来源:Codex image generation
问题背景
OpenAI Agents SDK 的 tracing 文档说明,内置追踪会记录 agent run 里的 LLM generation、tool call、handoff、guardrail 和 custom event。OpenTelemetry 的敏感数据文档提醒,遥测系统无法自动判断业务上下文里哪些内容敏感,保护责任在实现方。OWASP LLM02 也把个人身份信息、财务信息、商业机密、凭证和法律文档列入敏感信息范围。
放到 Agent 工具台里,这意味着可观测性不能只追求完整。工具参数常常来自用户输入、RAG 文档片段、桌面端文件路径和第三方 API 返回,如果原样进入日志,权限、留存、导出和搜索都会变成风险点。
踩坑和关键难点
第一个坑是把执行 payload 和调试 payload 混在一起。工具需要的参数很细,排障面板常常只需要字段名、长度、hash、状态和错误分类。第二个坑是导出后再脱敏,数据已经离开应用进程,窗口太晚。第三个坑是只靠正则,邮箱和 token 容易识别,客户代号、合同标题、知识库文件名更依赖 schema。第四个坑是回放需求,排障要知道步骤和结果,但未必需要原始值。
解决思路
我把链路拆成四层。raw execution 只在内存和短生命周期任务上下文里保存原始参数。redaction policy 按字段路径声明 allow、hash、mask、drop 和 vault。safe telemetry 只写入脱敏后的 span、log 和 UI 事件。evidence vault 只在高权限复核场景保存加密证据包,并带上到期时间和访问记录。
这样拆完后,traceId 和 runId 仍能串起一次工具调用,日志里只留下可排障的摘要。文件路径保留 basename hash 和扩展名,用户文本保留字符数与语言,API 返回保留 status、duration、errorCode 和 resultShape。需要复核原文时,必须走 evidence vault 的单独授权。
关键步骤
第一步,在工具 schema 旁边补 sensitivity map。每个入参和关键返回字段都要有默认策略,缺省字段按 drop 处理。第二步,工具执行前生成 runId、traceId 和 redactionVersion,后续事件都带这三个字段。第三步,脱敏发生在事件创建处,应用层先产出 safe event,再交给 OpenTelemetry 或日志 exporter。第四步,错误对象只保留 name、code、retryable、stage 和 messageTemplate。第五步,排障面板默认展示安全摘要,高权限复核才请求证据包。
可复用经验
Agent 工具日志治理的重点是让排障信息可用,同时减少敏感值停留。我的验收清单固定成五问:字段有没有 sensitivity map,脱敏是否早于导出,日志能否只靠摘要定位阶段,原始证据是否有权限和过期时间,redactionVersion 是否写进每条事件。五问清楚后,再接 OpenTelemetry、Agents SDK tracing 或内部日志平台,风险会小很多。
这套做法也适合 RAG 导入、Electron 本地任务、自动发布脚本和批量数据处理。只要系统会把用户输入交给工具执行,就要先区分执行所需的原始数据和排障所需的安全事件。
上线前我还会准备一组小回归样例:邮箱、订单号、文件路径、长文本、失败堆栈和第三方 API 错误各放一份。每次调整工具 schema 或脱敏规则后,重新跑这些样例,检查安全事件里是否只剩摘要,证据包是否按时过期,排障面板是否还能定位失败阶段。这个检查不复杂,却能防止新工具绕过默认策略。我也会把样例放进 CI,避免只在上线前人工检查,并留下证据。
主要来源
OpenAI Agents SDK Running agents