Files
deepseek-harness/docs/subsystems/telemetry.zh.md
Tianyi Cui 061100f6f2 docs: fix four factual errors found by Codex review round 1
- plan.md/.zh.md (+ plan-mode module JSDoc and README pair): the sole
  flush point is the prepended agent/step listener; prompt admission is
  pre-turn and never flushes — the pages had it backwards.
- workspace.md/.zh.md: pending-mutation recovery deletes the marked
  table row — completing an interrupted delete but rolling back an
  interrupted create; 'completes exactly the marked mutation' oversold.
- telemetry.md/.zh.md: delivery is best-effort with possible loss AND
  duplication, not at-most-once; TelemetryRecord.attributes JSDoc (source
  + both fences) now lists session.seed_length, which the coordinator
  emits for forked sessions.
- Agent Note consequence bullet: nine pages cover ten services (storage
  owns two keys); client-modules.zh.md wire-single-source phrasing.

Pairs re-recorded; plan-mode and telemetry suites green.
2026-08-09 01:27:20 +08:00

6.8 KiB
Raw Blame History

遥测telemetry

English | 中文

对外的会话上报,拆分为一项能力 seamseam 一侧(dsh-session-telemetryctx.telemetry)拥有捕获点、固定分片投影、telemetry/record 脱敏 waterfall瀑布式事件、handoff 游标与最小后端契约;部署方加载的后端(dsh-session-telemetry-otel)则是原样配置的 OpenTelemetry JS SDK 日志流水线。它是一项可选能力,不属于 agent loop智能体循环主干这里也没有任何内容会进入模型请求。边界公理harness 的职责止于 emit();批处理、重试、排队与丢失策略都属于上报 SDK连同被否决的替代方案均已在复活 Agent Noteagent 决策记录)中定案;捕获点、游标与投影的契约见 seam README

源码:packages/telemetry/session-telemetry/src/index.ts

逻辑记录

/**
 * Severity of a telemetry record, pre-mapped at capture so a receiver can
 * alert with zero configuration: `error` for events whose own outcome flag
 * says so (`tool/result.isError`, `turn/end` error reasons) and for
 * `agent-error` operational records. Captured events otherwise default to
 * `info`; `warn` remains available to `telemetry/record` policies and
 * backends.
 */
type TelemetrySeverity = 'info' | 'warn' | 'error'
/**
 * One logical record handed to a backend — the seam's whole outbound
 * vocabulary. Ledger records mirror session-log events one-to-one;
 * operational records (`channel: 'ops'`) carry the two signals with no log
 * home (`agent-error`, `shutdown`) and deliberately omit `event.seq`-style
 * identity so they can never be mistaken for ledger rows.
 */
interface TelemetryRecord {
  /** Ledger (session-log mirror) or ops (operational signal) channel; backends keep the two under separate instrumentation scopes. */
  channel: 'ledger' | 'ops'
  /** Unix epoch milliseconds — the source event's append time for ledger records, the emission time for ops records. */
  time: number
  /** Pre-mapped alerting severity; see {@link TelemetrySeverity}. */
  severity: TelemetrySeverity
  /**
   * Identity attributes, deliberately minimal: ledger records carry
   * `session.id`, `event.type`, `event.seq`, plus `session.cwd` /
   * `session.parent_id` / `session.seed_length` when the header has them;
   * ops records carry `telemetry.op`, `session.id`, and (for `agent-error`)
   * `agent.id`, `turn`, `step`, `error.name`. Anything recoverable from the
   * body is intentionally NOT duplicated here.
   */
  attributes: Record<string, string | number>
  /**
   * The complete payload: a deep copy of the session event's `data` for
   * ledger records (JSON-serializable by `Session.append`'s own
   * validation), or the op payload for ops records. Never mutated after
   * handoff.
   */
  body: unknown
}

每个 (turn, step) 只发出第一条 assistant/chunk,即「流已开始」的信号;其余分片在捕获时丢弃,因此导出流中的 seq 缺口是常态,绝不是丢失信号。其他所有会话事件类型都会完整透传,包括该 seam 从未听说过、由插件合并进来的事件类型。投递是尽力而为的游标标记的是「已交接」而非「已送达」记录可能丢失崩溃、重载窗口也可能重复无游标的重新接管、SDK 重试),因此接收端基于 (session.id, event.seq) 去重。

后端契约

/**
 * The backend contract the coordinator hands records to — the minimum any
 * reporting SDK satisfies with zero bending. {@link Telemetry} is its
 * service-registered form; tests compose the coordinator with a bare
 * implementation of this interface.
 */
interface TelemetryBackend {
  /**
   * Hand one record to the backend's pipeline. MUST be a non-blocking
   * enqueue — the coordinator calls this synchronously from the
   * `session/event` hot path, so anything slower than a queue push would tax
   * the agent loop. Errors thrown here are contained by the coordinator and
   * logged; they never reach the loop.
   * @param record - the logical record to report; owned by the backend after the call.
   */
  emit(record: TelemetryRecord): void
  /**
   * Optional hint that a natural boundary (turn end) passed — a backend may
   * forward it to its SDK's flush so records land at turn boundaries. Called
   * fire-and-forget; implementations must not block and must not throw
   * meaningfully (the coordinator contains exceptions). Most backends should
   * leave this unimplemented and let their SDK's own batching cadence govern
   * export timing: a backend that does implement it owns the interaction
   * between its concurrent flushes and {@link shutdown}'s drain (the OTel
   * backend removed its implementation for exactly that hazard — see the
   * revival Agent Note).
   */
  flush?(): void
  /**
   * Forward the fiber's disposal to the SDK: flush whatever is queued and
   * reach quiescence, per the SDK's own shutdown contract. Everything
   * emitted before this call must still be delivered — including records
   * enqueued while a {@link flush} hint is in flight, so a backend whose SDK
   * guards against concurrent flushes orders behind the outstanding one (the
   * coordinator emits its dispose-time `shutdown` markers immediately before
   * calling this). Awaited by the coordinator's dispose; a rejection is
   * logged as a warning and never fails application teardown.
   * @returns resolves when the backend's pipeline has quiesced.
   */
  shutdown(): Promise<void>
}

Telemetryctx.telemetry签名)是该契约的可加载形态:每个上下文只允许一个实现,重复加载会抛出异常;后端在其构造函数中组合 seam 的 TelemetryCoordinator,以此装配捕获侧。

脱敏 waterfalltelemetry/record

每条记录在投影与 emit() 之间都要经过 telemetry/record waterfall事件条目。seam 自身不带任何规则:未挂载监听器时,记录以捕获时的原样到达后端;导出数据能干净到什么程度,恰恰取决于部署方挂载了什么规则。监听器通过变换 next() 的返回值来堆叠;不调用 next() 就返回,即替换其下方的全部逻辑;抛出异常的监听器会在协调器的隔离范围内以 fail-closed 方式扣下这一条记录。脱敏只作用于导出副本;权威会话日志永不改写。