ByteNoteByteNote
DeepSeek Harness 怎么给会话数 Token
字

字节笔记本

2026年10月6日 · 约 4 分钟读完

DeepSeek Harness 怎么给会话数 Token

API中转
¥120

跑过 agent 的人都清楚,上下文窗口就是预算,token 就是现金:请求发出去之前只能估一个数,响应回来才拿到官方账单。DeepSeek Harness 是 DeepSeek 开源的智能体框架,走"一切皆插件"的路线,底座是 Cordis 插件框架,目前仍处于开发者预览阶段。这个项目把"估算 token"做成一个独立子系统,对应 npm 包 @deepseek-ai/dsh-token-meter。本文基于它的官方文档,拆解这份设计的几个关键约定。

一份脱离的不可变快照

token-meter 对外暴露的核心类型叫 TokenMeasurement,文档对它的定位是:在某个已消费日志修订号上,对请求压力与表层定价的一份"脱离的"不可变快照。

"脱离"是理解它的钥匙。会话在推进,持久事件日志在增长,但拿到的快照不会跟着变,它钉死在 logRevision 上。这个字段记录生成该计量时消费了多少条持久事件,数值上等于下一条未读事件的 seq。换句话说,每个测量结果都自带"我基于哪个版本的数据"的凭证,调用方拿到的是稳定值,不存在读到一半底层翻页的问题。文档还明确:快照不可变,不会随底层回放折叠的推进而增长。

token-meter 架构:从持久事件日志到计量快照

快照里三个数字最容易混淆。totalTokens 是当前请求加响应的压力,恒为非负;surfaceTokens 是仅针对表层的启发式总量,等于所有节点价格之和;surfaceDeltaTokens 是有符号的重定价,表示当前表层内容相对基线锚点的增减。三者各管一段,互不重复计费。

双锚点:usage 优先,启发式兜底

baseline 字段说明这次计量站在哪个地基上,只有两种取值。

第一种是 usage,即复用提供方账单,但前提很苛刻:存在最近一次成功的提供方调用,其规范化请求信封与本次请求一致,且该调用的总量不低于它自己的完整启发式锚点。这几道检查全部通过,那次成功调用的 usage 才配当锚点。

第二种是 estimated。不存在可复用的保守 usage 锚点时,服务退回固定启发式,对完整信封和表层全量计价。

设计取向很明确:宁可给保守的估计值,也不复用一份可能失真的旧账单。信封不一致说明请求结构变了,旧 usage 对不上新请求;总量低于启发式锚点说明账单可能不完整。两种情况都直接放弃复用。另外,后续成功的请求会替换早先的锚点;而有了有符号的 surfaceDeltaTokens,表层的增长与缩减都能相对匹配锚点表达出来,删内容会看到负数,这是纯累计计数器做不到的。

锚点决策:usage 三道检查,否则启发式全量计价

表层节点:顺序即权威

快照的 nodes 数组按头到尾的位置顺序排列表层节点,每个 TokenSurfaceNode 只有两个字段:表层事件的持久 seq,以及该节点投影的那条消息的启发式 token 数。

文档特别强调:表层顺序具有权威性,替换节点的持久 seq 可能大于位置上排在其后的节点。也就是说不能拿 seq 当排序键,位置顺序才是准绳。这与事件溯源系统的常见直觉相反,却是编辑重写场景的必然:旧消息被替换后产生更大的 seq,但它在对话中的位置不变。

测量的成本账

计量服务以 Cordis 服务的形式挂在 ctx 上。入口是 ctx.tokenMeter.measure(session, requestHeader?),沿会话的持久尾部回放得到快照。可选参数 requestHeader 只影响请求压力一侧,表层字段始终描述当前会话表层。每次调用都会克隆位置节点,所以测量成本是 O(surface),与表层大小成正比。配套的 estimateMessage(message) 对单条模型可见消息计价,覆盖内容与角色框架两部分,纯函数,不修改消息。

小结

把约定收拢一下:计量结果是一份绑定日志修订号的不可变快照;锚点只有 usage 与启发式两档,复用账单要过信封一致、总量不低的检查;三个 token 数字分工明确,有符号差值让增减可见;节点顺序看位置不看 seq;测量成本随表层线性增长。对任何需要自己做上下文预算管理的团队,这套"锚点加启发式"的账本设计都值得参考。

相关文章

分享: