
字节笔记本
2026年10月6日 · 约 4 分钟读完
DeepSeek Harness 怎么给会话数 Token
跑过 agent 的人都清楚,上下文窗口就是预算,token 就是现金:请求发出去之前只能估一个数,响应回来才拿到官方账单。DeepSeek Harness 是 DeepSeek 开源的智能体框架,走"一切皆插件"的路线,底座是 Cordis 插件框架,目前仍处于开发者预览阶段。这个项目把"估算 token"做成一个独立子系统,对应 npm 包 @deepseek-ai/dsh-token-meter。本文基于它的官方文档,拆解这份设计的几个关键约定。
一份脱离的不可变快照
token-meter 对外暴露的核心类型叫 TokenMeasurement,文档对它的定位是:在某个已消费日志修订号上,对请求压力与表层定价的一份"脱离的"不可变快照。
"脱离"是理解它的钥匙。会话在推进,持久事件日志在增长,但拿到的快照不会跟着变,它钉死在 logRevision 上。这个字段记录生成该计量时消费了多少条持久事件,数值上等于下一条未读事件的 seq。换句话说,每个测量结果都自带"我基于哪个版本的数据"的凭证,调用方拿到的是稳定值,不存在读到一半底层翻页的问题。文档还明确:快照不可变,不会随底层回放折叠的推进而增长。

快照里三个数字最容易混淆。totalTokens 是当前请求加响应的压力,恒为非负;surfaceTokens 是仅针对表层的启发式总量,等于所有节点价格之和;surfaceDeltaTokens 是有符号的重定价,表示当前表层内容相对基线锚点的增减。三者各管一段,互不重复计费。
双锚点:usage 优先,启发式兜底
baseline 字段说明这次计量站在哪个地基上,只有两种取值。
第一种是 usage,即复用提供方账单,但前提很苛刻:存在最近一次成功的提供方调用,其规范化请求信封与本次请求一致,且该调用的总量不低于它自己的完整启发式锚点。这几道检查全部通过,那次成功调用的 usage 才配当锚点。
第二种是 estimated。不存在可复用的保守 usage 锚点时,服务退回固定启发式,对完整信封和表层全量计价。
设计取向很明确:宁可给保守的估计值,也不复用一份可能失真的旧账单。信封不一致说明请求结构变了,旧 usage 对不上新请求;总量低于启发式锚点说明账单可能不完整。两种情况都直接放弃复用。另外,后续成功的请求会替换早先的锚点;而有了有符号的 surfaceDeltaTokens,表层的增长与缩减都能相对匹配锚点表达出来,删内容会看到负数,这是纯累计计数器做不到的。

表层节点:顺序即权威
快照的 nodes 数组按头到尾的位置顺序排列表层节点,每个 TokenSurfaceNode 只有两个字段:表层事件的持久 seq,以及该节点投影的那条消息的启发式 token 数。
文档特别强调:表层顺序具有权威性,替换节点的持久 seq 可能大于位置上排在其后的节点。也就是说不能拿 seq 当排序键,位置顺序才是准绳。这与事件溯源系统的常见直觉相反,却是编辑重写场景的必然:旧消息被替换后产生更大的 seq,但它在对话中的位置不变。
测量的成本账
计量服务以 Cordis 服务的形式挂在 ctx 上。入口是 ctx.tokenMeter.measure(session, requestHeader?),沿会话的持久尾部回放得到快照。可选参数 requestHeader 只影响请求压力一侧,表层字段始终描述当前会话表层。每次调用都会克隆位置节点,所以测量成本是 O(surface),与表层大小成正比。配套的 estimateMessage(message) 对单条模型可见消息计价,覆盖内容与角色框架两部分,纯函数,不修改消息。
小结
把约定收拢一下:计量结果是一份绑定日志修订号的不可变快照;锚点只有 usage 与启发式两档,复用账单要过信封一致、总量不低的检查;三个 token 数字分工明确,有符号差值让增减可见;节点顺序看位置不看 seq;测量成本随表层线性增长。对任何需要自己做上下文预算管理的团队,这套"锚点加启发式"的账本设计都值得参考。



