跳转至

追踪 Schema 与事件目录

这一页要解决一个很实际的问题:怎样把关于可观测性的高层讨论,落到可以真正导出、检查并复用于评测流程的事件结构上。

它同时连接本书的两部分:

以及可运行的参考包:

为什么需要显式的追踪 Schema

如果团队没有显式的追踪 Schema,通常会落入两种情况之一:

  • 事件虽然存在,但只是一些临时拼出来的 JSON;
  • 事件对调试有帮助,但很难用于分级、审计或事故复盘。

所以最好把下面三层明确分开:

  • 追踪信封
  • 事件目录
  • 载荷契约
  • 验证器契约身份
  • 验证器证据链接

哪怕运行时还很小,也值得这样做。

最小追踪信封

agent_runtime_ref 目前使用的是一个有意保持精简的信封:

{
  "event_type": "run_start",
  "trace_id": "trace-demo-001",
  "payload": {
    "agent_id": "support-triage-ref",
    "tenant_id": "tenant-acme",
    "principal_id": "user-42",
    "session_id": "session-demo-001",
    "user_input": "Please create a ticket for this onboarding issue."
  }
}

最小可用字段集是:

  • event_type
  • trace_id
  • payload

到了生产环境,通常还应该再补上:

  • session_id
  • agent_id
  • tenant_id
  • principal_id
  • event_ts
  • span_id
  • parent_span_id

在参考运行时里,其中一些字段暂时放在 payload 里,这样结构更小,也更方便阅读。同时,序列化后的事件现在会带上 schema_versionredacted_fields,导出路径也支持按字段做脱敏。Event loader 会显式校验这个 shape:Telemetry path must be a string or path-like objectTelemetry event line is not valid JSON: {line_number}Telemetry event must be a mappingTelemetry event is missing required field: {required_field}Telemetry event field must be a string: {field}Telemetry event field must not be empty: {field}Telemetry schema version is not supported: {schema_version}Telemetry event payload must be a mappingTelemetry event payload key must be a stringTelemetry event payload key must not be emptyTelemetry event payload keys must be uniqueTelemetry event payload value must be a string: {payload_key}Telemetry event redacted_fields must be a tupleTelemetry event redacted_fields must be a listTelemetry event redacted_fields entries must be stringsTelemetry redact field must not be emptyTelemetry redact field is not present in events: {missing}

追踪和会话的关系

对于智能体系统来说,一条追踪往往不够。你几乎总是还需要更长的上下文:

  • 一个 trace_id 描述一次运行;
  • 一个 session_id 把多次运行串起来;
  • 会话级摘要已经可以支持评测、发布审查和复盘。

这也是为什么包里已经有:

  • inspect-trace
  • inspect-session
  • session-eval-summary
  • export-session
  • export-eval-dataset

dump-eventsexport-eventsinspect-trace 也会让命令响应本身可用于 triage,而不只是 raw JSONL dump:它们会在操作者手动扫描每个 approval_requestedtool_execution payload 之前,直接暴露 session_idtenant_idprincipal_idagent_idauthorization_modedelegated_principal_iddelegated_scopestatusresultoutput_previewfailure_reasonapproval_idsapproval_capability_namespending_approval_idspending_approval_capability_namesapproval_status_counts 和非空 idempotency_keysreplay-run 随后会分别返回 source_idempotency_keysreplay_idempotency_keys,明确说明 replay 是带有自身重复写入 key 的新 run,而不是静默复用原始写入。

Trace replay 会先校验这些 evidence,然后才允许它们作为新 run 的 seed:Trace ID request must be a stringTrace ID not found in event file: {requested_trace_id}Trace file does not contain any trace IDsTrace file contains multiple trace IDs; pass --trace-id explicitlyTrace file does not contain a run_start eventTrace file contains multiple run_start eventsTrace run_start event is missing replay fields: {missing_keys}Trace run_start event has redacted replay fields: {redacted_keys}Trace run_start replay field must be a string: {field}Trace run_start replay field must not be empty: {field}

参考运行时的事件目录

下面是当前最小事件目录。

事件类型 何时出现 为什么重要
run_start 运行开始时 记录输入与行动者身份
policy_precheck 运行准入后立刻出现 记录 policy precheck 的 action、reason 和 policy ID
retrieval 获取 memory context 时 记录 source 与 retrieved records 数量
context_layers_built 上下文组装完成后 说明哪些上下文层真正进入了这次运行;internally RunContext 会在处理 tool_request 前保留 retrieved_contextretrieved_records
tool_policy_decision 工具执行前 记录策略门禁以及允许、拒绝或需要审批的原因
tool_execution capability call 或 approval handoff 后 记录 capability status 与 tool-principal context
approval_requested 高风险写入路径上 表示执行已经进入人工评审队列
sandbox_profile_reviewed 由 sandbox 支撑的路径被评审时 记录 workspace、permissions 与 snapshot/resume evidence review
memory_write_decision 后台写入记忆前 记录 candidate memory write 被允许还是拒绝
memory_persisted 后台写入后 记录记忆记录的来源和修订
background_compaction background memory maintenance 后 记录 tenant-level compaction results
background_update_scheduled background work 排队或完成后 记录该运行的 background update status
run_failed 工具失败成为运行结果时 保留明确的 failed-run traceability
run_complete 运行结束时 闭合运行级结果
span 单个调用周围 提供基础延迟与状态遥测

这不是所谓“完美通用目录”。它只是一个紧凑但已经有实际价值的运行词汇表,足以支持:

在更成熟的生产词汇表里,也应该预留验证器感知证据的位置,让追踪不只解释运行时做了什么,还能解释验证器依据什么来判断过程质量、结果质量或失败归因。

  • 追踪检查;
  • 回归种子数据;
  • 会话摘要;
  • 事故复盘。

为什么载荷契约很重要

问题不在于事件太朴素,而在于没有契约的载荷很快就会变成垃圾。

对每一种事件类型,最好提前想清楚:

  • 哪些字段是必需的;
  • 哪些字段是稳定的;
  • 哪些字段可以新增而不破坏下游工具;
  • 哪些字段对分级重要;
  • 哪些字段对审计重要。

例如,tool_policy_decision 至少通常应该包含:

  • capability_name
  • decision
  • reason
  • risk_tier
  • tool_principal

重复工单线索的 trace

在 support-triage 案例里,tool_policy_decisionapproval_requestedtool_execution 和最终 outcome 应该由同一个 trace_idsession_idapproval_idtool_principalidempotency_key 连接起来。如果 create_ticket 超时且副作用状态未知,trace 应显示 side_effect_unknown,而不是把运行伪装成成功,或在没有 reconciliation 的情况下重复写入。

对于由 sandbox 支撑的运行,也应该预留把追踪和执行边界关联起来的字段:

  • sandbox_session_id
  • sandbox_manifest_version
  • sandbox_permissions_profile
  • snapshot_id
  • workspace_manifest_ref

如果 rollout 或 eval 要求 sandbox_profile_review,追踪还应该能指向 review evidence,而不只是 state fields:

  • sandbox_profile_contract
  • workspace_entries_reviewed
  • permissions_profile
  • network_secrets_posture
  • snapshot_policy
  • reviewed_by
  • review_evidence_refs

如果系统依赖验证器感知评测,也很适合单独定义一个事件或关联载荷契约来承载验证器证据,例如:

  • verifier_id
  • verifier_contract_version
  • process_score
  • outcome_score
  • failure_attribution
  • evidence_refs

memory_persisted 通常应该包含:

  • memory_class
  • kind
  • provenance
  • revision

当前 reference payloads 也使用这些 operational metadata fields:runtime_principal, authorization_mode, delegated_principal_id, delegated_scope, policy_id, static_items, session_items, retrieved_items, tool_items, approval_id, reviewer, capability_session_id, capability_session_status, tool_status, output_preview, memory_id, revision_mode, compacted_records, persisted_records, tool_results, span_name, and duration_ms。Tool request/result model validation 也属于同一条 trace boundary:malformed tool calls 会以 Tool request capability name must be a stringTool request capability name must not be emptyTool request arguments must be a mappingTool request argument key must be a stringTool request argument key must not be emptyTool request argument keys must be uniqueTool request argument value must be a string: {argument_key} 失败;malformed tool results 会以 Tool result status must be a stringTool result status must not be emptyTool result payload must be a mappingTool result payload key must be a stringTool result payload key must not be emptyTool result payload keys must be uniqueTool result payload value must be a string: {payload_key} 失败。

参考包现在已经支持什么

你可以直接这样查看:

.venv/bin/python -m agent_runtime_ref dump-events
.venv/bin/python -m agent_runtime_ref export-events --output artifacts/trace-demo.jsonl
.venv/bin/python -m agent_runtime_ref export-events --output artifacts/trace-demo.jsonl --redact-field user_input
.venv/bin/python -m agent_runtime_ref inspect-trace --input artifacts/trace-demo.jsonl
.venv/bin/python -m agent_runtime_ref export-session --output artifacts/session-demo-001.json
.venv/bin/python -m agent_runtime_ref export-eval-dataset --output artifacts/eval-dataset.json

这很重要,因为同一套追踪词汇已经同时活在三个地方:

  • 运行时里;
  • 书里;
  • 评测工件里。

生产级 Schema 还应该补什么

参考运行时有意保持精简,所以更成熟的系统应该很快补上:

  • 每个事件的时间戳;
  • 明确的 span_idparent_span_id
  • 独立且稳定的 run_id
  • Schema 版本字段;
  • 展示载荷与机器载荷的分离;
  • 敏感字段的脱敏规则;
  • 把追踪与验证器证据、截图或打分工件显式关联起来的方式;
  • 稳定记录是哪个验证器契约版本产出该打分输出的方式;
  • sandbox state fields,用于那些会物化 workspace、使用 shell/filesystem capabilities,或从 snapshot 继续的 runs;
  • 用于 sandbox_profile_reviewed 的 event 或 linked payload,确保 workspace、permissions 与 snapshot/resume policy 的 rollout/eval evidence 可以被追踪。

只有这样,事件流才会从调试输出变成真正的平台工件。

现在就该做什么

先过一遍这份短清单,把所有回答为“否”的地方单独记下来:

  • 有没有稳定的事件目录?
  • 是否清楚区分了 trace_idsession_id
  • 每种事件类型的必需字段是否明确?
  • 能不能从追踪里还原出策略决策和工具路径?
  • 能不能从会话导出结果构建评测数据集?
  • 能不能把追踪关联到用于打分或发布评审的验证器证据?
  • 如果 rollout 要求 sandbox_profile_review,是否有关于 workspace entries、permissions 与 snapshot/resume policy 的 trace evidence?
  • 能不能看出是哪一个验证器契约版本产出了这份打分输出?
  • 有没有脱敏与 Schema 版本化的计划?

如果连续几个答案都是“没有”,那你现在更像是拥有日志,而不是拥有真正的追踪 Schema。

下一步做什么