工具调用观测与审计
核对日期:2026-05-09。
1. 定义与边界
工具调用观测与审计是指记录、查询、回放和分析一次 Agent 任务中的模型调用、工具选择、参数、审批、执行结果、错误和最终输出。
观测用于工程调试和质量改进;审计用于安全、合规和责任追踪。两者数据结构可以复用,但保留周期、访问权限和脱敏规则不同。
2. 为什么重要
没有工具调用观测,生产问题很难定位:
- 用户说“Agent 改错了配置”,但无法知道模型传了什么参数。
- 工具返回错误,模型却输出成功,无法定位是哪一层丢失状态。
- 提示注入诱导工具调用,事后没有证据链。
- 评测只看最终答案,无法发现工具选择退化。
3. 核心机制
3.1 Trace / Span 模型
3.2 事件结构
{
"trace_id": "tr_123",
"span_id": "sp_tool_1",
"parent_span_id": "sp_model_1",
"type": "tool_call",
"timestamp": "2026-05-09T11:00:00+08:00",
"user_id": "u_123",
"tool": "crm.update_customer_status",
"arguments_redacted": {
"customer_id": "cus_9",
"status": "suspended"
},
"policy_decision": "require_approval",
"approval_id": "ap_456",
"status": "success",
"latency_ms": 842,
"result_summary": "customer status updated",
"risk_level": "L3"
}
4. 架构模式
4.1 Runtime 内置 Trace
适合早期系统,所有事件写入应用数据库。实现快,但查询、采样和保留策略容易受限。
4.2 OpenTelemetry 风格 Span
适合已有可观测平台的团队。把模型调用、工具执行、外部 API 调用都表示为 span,并通过 trace_id 串联。
4.3 审计 Ledger
对高风险工具,除了普通日志,还应写入不可随意修改的审计存储:
- 写操作。
- 审批结果。
- 权限拒绝。
- 访问敏感数据。
- 连接第三方 MCP Server。
5. 工程实现
5.1 必须记录的字段
| 字段 | 用途 |
|---|---|
| trace_id / run_id | 串联一次任务 |
| tool_call_id | 关联模型输出和工具结果 |
| user / tenant / environment | 权限和责任归属 |
| tool name / version | 定位 schema 版本 |
| arguments hash + redacted args | 审计和隐私平衡 |
| policy decision | 证明系统执行了策略 |
| approval record | 证明人类确认 |
| result status / error code | 失败分析 |
| latency / retry count | 性能和稳定性 |
| model id / prompt version | 回归定位 |
5.2 敏感数据处理
const auditArgs = redact(call.arguments, {
mask: ["email", "phone", "access_token"],
hash: ["customer_id", "account_id"],
drop: ["password", "secret"]
});
6. 生产实践
- 所有工具调用都记录 trace,抽样只用于详细 payload,不用于事件存在性。
- 高风险工具参数保存 hash,敏感字段保存脱敏摘要。
- schema 版本、模型版本、prompt 版本必须入 trace。
- 审批事件与工具执行事件绑定同一参数 hash,防止审批后参数被替换。
- 支持按用户、工具、风险等级、错误码、时间范围查询。
- 定期从真实 trace 抽样生成评测集。
7. 常见反模式
| 反模式 | 后果 |
|---|---|
| 只记录最终答案 | 无法定位工具层问题 |
| 日志保存完整敏感数据 | 合规和泄露风险 |
| 不记录被拒绝的调用 | 看不到攻击和策略效果 |
| trace 无 schema 版本 | 无法复现旧问题 |
| 审批和执行分离 | 不能证明执行的是被批准动作 |
8. 评测方法
观测数据本身也要验收:
- trace 完整率:每个 tool result 是否能找到 tool call。
- 审批绑定率:高风险写操作是否都有 approval_id。
- 脱敏正确率:日志中是否出现敏感字段明文。
- 回放成功率:能否用 trace 复现模型输入、工具输出和最终答案。
- 告警有效率:异常工具调用是否触发告警。
9. 安全与治理
- 审计日志访问权限应高于普通应用日志。
- 日志保留周期按数据等级配置。
- 审计导出要脱敏,并记录导出人和用途。
- 对异常模式建立告警:短时间大量工具调用、权限拒绝激增、第三方 MCP Server 连接异常。
- 不把完整系统提示和密钥写入可被普通开发者查看的 trace。
10. 审计日志 Schema
{
"event_type": "tool_execution",
"trace_id": "tr_123",
"tool_call_id": "call_456",
"timestamp": "2026-05-09T11:15:00+08:00",
"actor": {
"user_id": "u_123",
"tenant_id": "t_01",
"agent_id": "agent_support"
},
"model": {
"provider": "openai",
"model": "configured-model-id",
"prompt_version": "support-v8"
},
"tool": {
"name": "crm.update_customer_status",
"schema_version": "2.1.0",
"risk_level": "L3"
},
"policy": {
"decision": "require_approval",
"policy_version": "tool-policy-2026-05-09"
},
"approval": {
"approval_id": "ap_789",
"arguments_hash": "sha256:...",
"approved_by": "u_manager"
},
"execution": {
"status": "success",
"latency_ms": 842,
"idempotency_key": "run_123:call_456"
}
}
11. 告警规则
| 告警 | 触发条件 | 处理 |
|---|---|---|
| 工具调用激增 | 单用户/租户短时间调用量异常 | 限流并审计 |
| 权限拒绝激增 | deny rate 突然升高 | 检查攻击或策略变更 |
| 高风险无审批 | L3/L4 执行缺 approval_id | 立即熔断工具 |
| 参数 hash 不一致 | 审批 hash 与执行 hash 不同 | 拒绝执行并告警 |
| 第三方 MCP 变更 | tools/list 出现新增写工具 | 暂停并重新审核 |
| 敏感日志泄露 | 日志扫描发现 token/secret | 轮换密钥并清理日志 |
12. 评测与回放流程
回放必须能恢复:
- 当时可用工具列表和 schema 版本。
- 当时模型、提示词、路由和策略版本。
- 工具 observation 的脱敏内容。
- 审批状态和参数 hash。
- 最终输出和用户可见错误。
13. 权威资料
- OpenAI Agents SDK tracing docs: https://openai.github.io/openai-agents-python/tracing/
- OpenAI Function Calling guide: https://platform.openai.com/docs/guides/function-calling
- MCP Logging utility specification 2025-11-25: https://modelcontextprotocol.io/specification/2025-11-25/server/utilities/logging
- NIST AI Risk Management Framework: https://www.nist.gov/itl/ai-risk-management-framework
- OWASP Top 10 for LLM Applications 2025: https://owasp.org/www-project-top-10-for-large-language-model-applications/