DCP 统计语义(M7.0 冻结)
August 28, 2026 · View on GitHub
原则
- 原始 session 日志是唯一真相;统计永远是从日志可重算的缓存。
- 所有 token 数字都是 heuristic estimate(默认四字符/token;生产路径传入
ctx.tokenMeter.estimateMessage)。 - 持久化只保存 per-session snapshot(
eventCount边界下的冷重算结果), domain 聚合 = 各 session 最新 record 的逐字段求和,不做全局+=。
SessionStats(signed ledger)
| 字段 | 语义 |
|---|---|
blockCount | 历史 DCP summary + expansion 事务数 |
activeBlockCount | 当前 surface 上的 active DCP block 数(gauge) |
pruneReplacements | DCP 去重/错误单元清理的替换数 |
shadowedTokens | DCP summary 遮蔽的 heuristic token 总量 |
checkpointTokens | DCP checkpoint 与 prune 替换文本的 estimate |
pruneTokens | 被清理原始工具结果的 estimate |
expansionTokens | semantic expansion 的有符号 delta(通常为负) |
markerTokens | boundary marker 的 estimate(单独列出) |
historyReduction | shadowed + prune - checkpoint + expansion - marker(有符号;负值显示为 overhead) |
不再使用 clamp 后的 netSavedTokens;负数如实呈现为 history overhead。
token 口径区分
compaction/summary.shadowedTokenCount是被压缩区间的 heuristic token 总量,对应shadowedTokens(区间压缩)。compaction/prune.shadowedTokenCount是 inline cleanup 所替换的单条 作者 assistant 消息 estimate,对应pruneTokens/checkpointTokens中的 prune 部分(去重/错误清理)。- 两者口径不同,不要直接比较:前者是整段被遮蔽历史区间,后者只是同一步
清理占位时被替换的模型消息。统计聚合时分别进入
shadowedTokens与pruneTokens,不会混入同一个字段。
Domain record v1
{ v: 1, eventCount: number, ledger: SessionStats, updatedAt: string }
eventCount = events.length(当前实现的日志长度语义);不同时保存可推导的lastEventSeq,避免 off-by-one。- 只前向追平:
eventCount倒退时拒绝覆盖(防旧异步快照覆盖新快照)。 - 单进程口径:JSON backend 无跨进程写锁,domain 不描述跨进程一致。
/dcp stats 输出
- 始终先显示 session 部分;domain 部分只在可用时出现。
- 状态:
current(已追平)/stale(同步失败)/unavailable(未接线)。 - storage 任何失败只降低 persistent stats 可见性,不影响 compress/control/ marker/request invariant。