
字节笔记本
2026年10月6日 · 约 8 分钟读完
DeepSeek Harness 会话引用子系统解析
DeepSeek Harness(命令行工具名为 dsh)是 DeepSeek AI 开源的 agent harness,采用一切皆插件的架构,底层由 Cordis 框架驱动,目前处于 developer preview 阶段,通过 npx @deepseek-ai/dsh web 就能把 Web UI 跑起来。实际使用中有一个很自然的诉求:开新会话时,把之前某个会话的上下文带过来,免去从头交代背景。为此,这个项目设计了会话引用(session reference)子系统,把跨会话引用做成一条结构化的请求与准备管线,类型定义集中在 packages/context/session-reference 包里,覆盖规范 URI、当前表层投影、标签安全的 JSON 与字节保留、稳定错误和不可信的模型提示词。

接缝设计:宿主语法不进核心
各家宿主都有自己习惯的「提及」写法,比如在输入框里引用某个历史会话。DeepSeek Harness 划了一条清晰的界线:宿主适配器使用统一的类型,而不把各自 UI 的提及语法传进 agent 核心。核心只消费结构化数据,宿主想怎么表达都行,进核心之前先翻译好。这层接缝让核心保持稳定,宿主的交互改动不至于波及 agent 本体。
输入与候选
SessionReferenceInput 是与宿主无关的选择:
/** One source session selected by a host. */
interface SessionReferenceInput {
/** Opaque source session identity. */
sessionId: SessionId
/** Optional user-facing mention label. */
label?: string
}id 具有权威性,label 是随快照携带的显示元数据。发现环节的输出则是 SessionReferenceCandidate:
/** One host-facing candidate from exact session metadata. */
interface SessionReferenceCandidate {
/** Opaque source session identity. */
sessionId: SessionId
/** Latest log-backed title, falling back to the opaque session id. */
label: string
/** Source session working directory, when recorded. */
cwd?: string
/** Source session creation time in Unix epoch milliseconds. */
createdAt: number
}候选的 label 优先取该会话最新的日志标题,取不到就回退为不透明的 session id,另外带源会话的工作目录与创建时间。这里有一条值得注意的检索边界:筛选只搜索 session id 和 cwd,绝不搜索 transcript(文本记录)。引用是「点名到会话」,不是全文检索;只有真正准备上下文时,正文才会以快照形式进入。
准备后的消息
准备过程保留可读的当前消息内容,并最多返回一个聚合上下文:
/** Direct message content and optional referenced-session context. */
interface PreparedReferencedMessage {
/** Readable message content after host mention tokens are removed. */
content: ContentBlock[]
/** Aggregated untrusted snapshot, absent when the message has no references. */
additionalContext?: UserMessage
}两个字段把「用户说了什么」和「引用带来了什么」分开:content 是移除宿主提及标记后仍然可读的消息内容;additionalContext 是聚合后的引用上下文,类型上明确标注为不可信快照,消息没有引用时这个字段直接缺省。多个引用也只合并成一份上下文,不会往消息里塞进好几段来路不明的文本,上下文边界因此可控。
七个稳定错误码
错误处理同样在边界定型。SessionReferenceError.code 区分七种情况:
- SESSION_REFERENCE_INVALID_CONFIG:无效配置或输入
- SESSION_REFERENCE_INVALID_REFERENCE:引用无效
- SESSION_REFERENCE_SELF_REFERENCE:会话引用了自己
- SESSION_REFERENCE_TOO_MANY:超出数量限制
- SESSION_REFERENCE_READ_FAILED:源会话读取失败
- SESSION_REFERENCE_BUDGET_EXCEEDED:预算超限
- SESSION_REFERENCE_CANCELLED:已取消

宿主协议把这些 code 映射到各自的错误封装,不需要检查提示词字节。也就是说,不管宿主怎么包装错误,语义都由这组稳定码定义,核心与宿主不必共享同一种错误格式。
解析器 API
上述能力通过 Cordis 上下文暴露为 ctx.sessionReferenceResolver,类型为 SessionReferenceResolver,文档对它的定位是 exact-read consumer,负责准备不可变的跨会话消息上下文。两个方法:
- listCandidates(agent, query?, limit?, signal?):列出引用候选,按工作目录亲和度排序;目标 agent 自身被排除,其 cwd 驱动排序;query 是大小写不敏感的 session id、cwd、标题子串;limit 限制结果数量;signal 是取消边界,宿主自动补全关闭时可以即时停下。
- prepare(agent, content, references, signal?):在消息入队前对全部引用做快照,返回分离后的内容与可选的聚合持久上下文;references 按提及顺序传入,指向 agent 自身的引用会被拒绝。
三点可以借鉴
一是结构化接缝,UI 语法止步于宿主适配器,核心只认类型;二是最小搜索面,候选检索只查 id 与目录,不碰会话正文,既省开销也避免意外的内容外泄;三是稳定错误码,用枚举值完成协议映射,而不是让宿主去解析提示词字节。项目以 MIT 协议开源,仓库中的 packages/context/session-reference 是这套设计的完整实现,感兴趣可以对照源码细读。



