很多团队以为有 trace、有日志,就已经能审计 AI agent 了。实际做过事故复盘、费用核对或权限追责后会发现,这还不够。日志擅长记录过程事件,trace 擅长串起调用链,但真正用于“对账”和“追责”的,通常需要一套更稳定的事实账本。
Run Ledger 的意义,不是把所有细节都重复记一遍,而是沉淀那些必须可验证、可引用、可对账的事实。
建议先配合 AI Agent 可观测性设计、AI agent 产品成功指标、AI agent Policy Engine 规则分层 和 AI Agent 成本控制与预算治理 一起看。
先给结论:Ledger 记录事实,不记录猜测
| 记录类型 | 应不应该进 ledger |
|---|---|
| 谁发起了任务 | 应该 |
| 哪个版本的 prompt / model / tool 被使用 | 应该 |
| 哪个步骤真的产生了外部副作用 | 应该 |
| 模型当时“可能在想什么” | 不应该 |
| 某个建议看起来是否合理 | 不应该 |
Ledger 的价值在于可核对。不能核对的东西,更适合进日志或 artifact。
一、一次 Run 至少要记 5 组事实
| 事实组 | 记录什么 |
|---|---|
| 发起事实 | user、tenant、taskType、runId |
| 配置事实 | promptVersion、modelRoute、toolSetVersion |
| 执行事实 | 状态迁移、工具调用、policy decision |
| 副作用事实 | 写入、外发、扣费、审批结果 |
| 结算事实 | token、工具费用、重试成本、最终结果 |
如果缺任意一组,后面就会在“这次到底发生了什么”上扯不清。
如果系统已经有 artifact、policy engine、checkpoint 和 billing 服务,这 5 组事实最好都能落到统一的 run identity 之下,而不是分散在各个子系统各自命名的 id 里。否则跨系统对账时,第一步就会卡在“这些记录到底是不是同一次 Run”。
二、Ledger 记录的是业务主事实,不是所有 debug 细节
一个好用的 ledger 应该很稳定。不要把临时 debug 字段全部灌进去,否则:
- 结构会频繁变动
- 报表和审计会越来越脆
- 历史 run 的兼容成本会变高
更合适的做法是:
- debug 细节放 trace/logs
- 可追责事实放 ledger
一个实用判断是:这条记录未来是否可能被财务、风控、客服、审计、平台工程同时引用?如果会,它更像 ledger;如果只在排查某次故障时短期有用,它更像 trace。
三、Ledger 里的字段要能支持计费和审计双用途
例如:
{
"runId": "run_123",
"tenantId": "team_001",
"taskType": "content_review",
"promptVersion": "review-agent-v5",
"model": "gpt-x-large",
"toolCalls": 4,
"tokenInput": 5200,
"tokenOutput": 1300,
"sideEffects": [
{
"type": "status_update",
"targetId": "doc_789",
"result": "success"
}
],
"billing": {
"modelCost": 0.18,
"toolCost": 0.03,
"retryCost": 0.01
},
"finalOutcome": "completed"
}
这样的结构既能做费用归集,也能解释“为什么这个 run 计费更多”。
再进一步,ledger 里的关键事实最好带上引用关系,例如:
traceId:对接可观测链路artifactIds:对接证据和草稿policyDecisionIds:对接规则决策checkpointIds:对接恢复节点
这样 ledger 不会变成一套孤立账本,而是整个运行系统的“可核对索引”。
四、Policy 和审批结果也值得进 Ledger
一旦任务涉及高风险动作,仅记录最终外发或写入是不够的。还要记录:
- 哪条 policy 触发了拦截或放行
- 是否有人工审批
- 审批结论是什么
- 是否用了 exception / 豁免规则
否则出现争议时,系统只能证明“事情发生了”,却不能证明“为什么允许发生”。
对高风险动作来说,建议把“谁批准了、批准时看到什么、批准后放行了什么”分成独立事实写入 ledger,而不是只写一个 approved=true。审批一旦成为责任节点,细节就必须可核对。
五、Ledger 最适合 append-only,而不是频繁覆盖更新
审计账本最怕被反复重写。一个更稳的思路是 append-only 事件:
RUN_CREATED
POLICY_EVALUATED
TOOL_EXECUTED
SIDE_EFFECT_RECORDED
BILLING_FINALIZED
RUN_CLOSED
最终报表可以从这些事实归并出来,但原始事实不要轻易覆盖。否则你会失去“当时系统到底记录了什么”的证据链。
很多团队还会再补一层 correction event,而不是直接改旧记录。例如:
BILLING_FINALIZED
BILLING_CORRECTED
SIDE_EFFECT_RECONCILED
这样历史事实仍然保留,只是后续通过更正事件来修正口径。对账系统通常更喜欢这种做法,因为它更容易还原时间线。
六、Ledger 最好支持分阶段对账,而不是等月底一次算总账
如果 run ledger 只在 Run 完成后一次性汇总,任何中途失败、补执行、人工接管都很容易被漏算。更稳的方式是分阶段对账:
| 阶段 | 对账内容 |
|---|---|
| 运行中 | token、工具调用、checkpoint 次数 |
| 副作用发生后 | 外发、写入、审批结果 |
| Run 关闭后 | 总成本、最终结果、异常更正 |
分阶段对账的价值是:问题会更早暴露,而不是月底才发现总账不对。
七、上线后要看 ledger 完整性指标
建议持续观察:
| 指标 | 用途 |
|---|---|
| trace 与 ledger 关联完整率 | 判断索引链路是否完整 |
| side effect 无 ledger 记录数 | 判断关键事实是否漏记 |
| billing correction 占比 | 判断计费初始记录是否稳定 |
| 审批事实缺失率 | 判断高风险动作是否留痕充分 |
| append-only 更正比例 | 判断账本是否被过度修补 |
如果 side effect 已发生,但 ledger 没记到,这不是报表问题,而是审计断链问题。
八、失败案例:日志能看过程,但月底账单对不上 Run
一个团队的 agent 日志非常详细,trace 也完整,但月底做费用分析时,无法把账单和具体 run 对上。原因是:
- token 使用量分散在日志里
- 工具调用费用没有汇总
- 重试导致的额外成本没有单独计入
- 某些人工审批后的补执行也没和原 run 关联
修复后,他们增加了 run ledger,把 billing、policy、side effects 和 final outcome 统一写入 append-only 账本。之后费用复盘终于能落到具体任务,而不只是看平台总账单。
九、Run Ledger Checklist
- 是否区分发起、配置、执行、副作用、结算五组事实
- ledger 是否只记录可核对事实
- 全系统是否围绕统一 run identity 对账
- token、工具费、重试费是否能落到 run 级别
- policy 与审批结果是否可追溯
- ledger 记录是否能关联 traceId、artifactIds、checkpointIds
- 是否采用 append-only 事实记录
- 是否通过 correction event 而不是直接改旧事实
- 是否能把 ledger 与 trace / artifact 关联起来
- 是否支持运行中、完成后两阶段以上对账
- 历史 ledger schema 是否有兼容策略
结语
AI agent 的 Run Ledger,不是为了多做一套日志,而是为了让“发生了什么、为什么这么发生、花了多少钱、谁批准了它”都能在事后被核对。系统一旦进入真实业务,这套账本就会变得比你想的更重要。
延伸阅读:


