面向模型的回忆能力:让模型读取某个会话在压缩之前的自身历史,服务于 DeepSeek Harness。
30.7/100
综合分
1
GitHub 星标
—
npm 周下载
—/5
用户评分
数据截至 2026/10/8 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。
该插件未发布到 npm,按作者文档从 GitHub 源安装即可(静态检查只覆盖 npm 路径,不代表插件不可用)。
安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add windwhiterain/dsh-history-access该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)
状态速览
判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态信任档位:已验证
是什么
dsh 原生插件 · chat
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
活跃:最近一次提交在 24 天前
档位由哪些信号合成
本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。
社区实装还没有人打卡 · 装过的第一个就是你
安装兼容性检查需源码安装仓库 package.json 标记 private,未发布到 npm,需从源码安装
展开查看检查明细 ↓
以下结论由程序自动检查 npm 包、engines 声明与入口文件得出,未做人工实机验证——能装不等于用着没问题。
✗npm 包dsh-history-access(未发布到 npm,仅可源码安装)
✓Node 引擎未声明 engines.node
✓dsh CLI 依赖未声明 dsh 版本约束
✓入口文件main/exports/bin 已声明
源码安装时若 pnpm 拦截 prepare 脚本,按其提示在 pnpm-workspace.yaml 的 allowBuilds 中放行后重跑。
验证方式:npm registry 存在性 + package.json 静态校验 · 最后检查 2026/10/15 09:45:36
安全扫描自动 · 静态分析源码v2.7.0🟢 扫描:未发现敏感能力尚无人工评估展开查看扫描说明与证据 ↓
安全扫描自动 · 静态分析源码
v2.7.0静态扫描未发现敏感能力:最多只发网络请求、读取自身元数据或只读文件,未发现执行命令、文件写入或敏感信息读取。
扫描于 2026/11/1(0 天前) · 范围 入口闭包 + 发布文件清单 · 来源 GitHub 仓库
静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。
给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个
功能亮点
- 召回压缩前会话历史
- 大纲与分页读取记录
- 持久日志字面搜索
面向智能体的会话压缩前历史召回,用于 DeepSeek Harness:大纲、分页读取记录,以及对持久日志的字面搜索。
README
由 DeepSeek 最新模型翻译生成dsh-history-access
面向模型的回忆能力:让模型读取某个会话在压缩之前的自身历史,服务于 DeepSeek Harness。
压缩会把较早的对话替换成摘要。原始内容仍留在会话的追加式日志里,但没人告诉模型这些内容还能拿到,所以想找回被压缩掉的细节,只能靠记忆,或者手动 shell 出去读一个 session.vN.jsonl.zstd 文件再解压。这个插件在持久日志之上注册了三个工具——一份大纲、一次分页的对话记录读取、一次字面搜索——并在压缩过程结束后注入一条简短指引,让模型知道哪些内容被压缩了、怎么把它们取回来。
这三个工具是懒注册的:如果一个会话什么都没压缩过,就永远看不到它们,所以在没有东西可回忆之前,回忆能力不消耗任何 schema token。注册发生在需要出现的那一刻,落在调用方智能体自己的作用域里——要么是压缩过程完成时,要么是会话本身已带检查点、智能体创建时(即恢复会话)。在会话中途注册是一等公民级别的 harness 操作:循环会为新工具集记录一条 request/header,再加一条 developer/message,其中携带 tool-addition 块,于是模型会被告知这些工具出现了,并从下一步开始看到它们的 schema。
一切都通过 ctx.sessionQuery 从日志读取。
展开完整文档(README 剩余 1 节)
dsh-history-access
面向模型的回忆能力:让模型读取某个会话在压缩之前的自身历史,服务于 DeepSeek Harness。
压缩会把较早的对话替换成摘要。原始内容仍留在会话的追加式日志里,但没人告诉模型这些内容还能拿到,所以想找回被压缩掉的细节,只能靠记忆,或者手动 shell 出去读一个 session.vN.jsonl.zstd 文件再解压。这个插件在持久日志之上注册了三个工具——一份大纲、一次分页的对话记录读取、一次字面搜索——并在压缩过程结束后注入一条简短指引,让模型知道哪些内容被压缩了、怎么把它们取回来。
这三个工具是懒注册的:如果一个会话什么都没压缩过,就永远看不到它们,所以在没有东西可回忆之前,回忆能力不消耗任何 schema token。注册发生在需要出现的那一刻,落在调用方智能体自己的作用域里——要么是压缩过程完成时,要么是会话本身已带检查点、智能体创建时(即恢复会话)。在会话中途注册是一等公民级别的 harness 操作:循环会为新工具集记录一条 request/header,再加一条 developer/message,其中携带 tool-addition 块,于是模型会被告知这些工具出现了,并从下一步开始看到它们的 schema。
一切都通过 ctx.sessionQuery 从日志读取。没有索引,没有 embedding,没有 sidecar 文件,没有磁盘读取,也没有第二次模型调用,所以回忆结果完全由会话记录的内容决定。这个插件不声明任何依赖,也不导入任何 harness 包:它只和注入的 ctx 服务打交道。
三个工具
| 工具 | 参数 | 返回 |
| history_outline | 无 | 会话的事件总数、每一个压缩检查点(id 为 c<summarySeq>、摘要 seq、被遮蔽的事件数、被遮蔽的 seq 范围、被遮蔽的 token 数、时间、是否被后续检查点取代,以及一行摘要预览),还有轮次列表(索引、seq 范围、事件数、可见还是被遮蔽,以及该轮的第一条用户消息)。受 outlineMaxChars 限制;检查点列表保持完整,轮次细节被省略,并留下明确的标记。 |
| history_read | checkpoint(可选)、seq(可选)、cursor(可选) | 一页带角色标注的对话记录(User:、Assistant:、Tool result:,每条都带自己的事件 seq)。checkpoint 读取该检查点替换掉的那段确切范围,包括已被取代的检查点;seq 从该位置向后读取;cursor 读取上一次结果的下一页。受 readMaxChars 和 readMaxEvents 限制;被截断的事件或页面会明确标记。 |
| history_search | query(必填)、checkpoint(可选)、limit(可选) | 在当前会话的消息文本里做编号匹配——既覆盖每一段被遮蔽的内容,也覆盖当前可见的历史,或者只匹配某个检查点的范围——每条结果都带 seq、surface、所属检查点 id(或 (visible))、时间,以及匹配位置附近的片段,最后跟上 scanned、matched 和 truncated。 |
history_read 和 history_search 都在各自的描述里写明:它们是恢复被压缩历史的受支持方式,会话文件不得读取或解压。插件不附带任何系统提示词段落,所以这些描述就是模型能拿到的唯一常驻提示——而在延迟注册之后,harness 会自己宣告这些工具,每个工具一个 tool-addition 块,于是模型就知道它们存在,插件一个字都不用花。
返回文本示例:
history_read checkpoint c245 — shadowed seqs 41-188, 96 events, ~18422 tokens
User (seq 41): Fix the failing retry tests.
Assistant (seq 42): I will inspect the retry helper first.
[tool call] read {"path":"src/retry.ts"}
Tool result (seq 44): export const RETRY_BUDGET_ATTEMPTS = 3
… [page cut; more events follow — call history_read again with this cursor]
cursor: c245@45
history_search "retry budget" — 412 events scanned, 2 matched, showing 2
1. seq 44 | shadowed | c245 | 2026-07-06 12:03Z
…export const RETRY_BUDGET_ATTEMPTS = 3…
2. seq 401 | visible | (visible) | 2026-07-06 12:41Z
…the retry budget is 3 attempts, then it gives up…
scanned 412, matched 2, truncated false
配置
每个字段都是可选的;未知字段、非整数、非正值,或超出范围的取值,都会在加载时失败,并给出可操作的提示信息。
| 字段 | 类型 | 默认值 | 范围 | 含义 |
| readMaxChars | integer | 8000 | 400–1000000 | 单页 history_read 的字符预算。同一预算在命中上限之后,也限制单页 history_search。 |
| readMaxEvents | integer | 80 | 1–1000 | 单页 history_read 渲染的最大事件数。 |
| searchMaxHits | integer | 20 | 1–200 | 单次 history_search 调用报告的最大匹配数,也是其 limit 参数可请求的上限。 |
| outlineMaxChars | integer | 4000 | 200–1000000 | history_outline 的字符预算。即使检查点列表本身就超出预算,也保持完整。 |
| pointer | 'inject' \| 'off' | 'inject' | — | 一次完成的压缩过程是否注入下面描述的指针。 |
压缩后的指针
对仍持有活跃智能体的会话,在一次完成的压缩过程(compaction/end 且无 error)中,插件先把它的三个工具注册进该智能体的作用域,然后用 Agent.inject 暂存一条短消息:
Context was condensed into checkpoint c245: 96 earlier events (~18422 tokens) were replaced by its summary.
原始内容仍记录在本会话中——调用 history_read(检查点 c245)或 history_search 即可取回;不要读取或解压会话文件。
投递按 compactionId 去重,所以一次完成的 pass 只产生一个指针,即使事件流重复也一样;失败的 pass(compaction/end 带 error)不产生指针;没有活跃智能体的会话直接跳过。监听器绝不向宿主抛异常:已销毁智能体的拒绝会被记录并丢弃。消息携带 source: { kind: 'history-access' },像其他注入的上下文一样出现在会话日志里。
投递会延后一个微任务,晚于发布那次 append。session/event 监听器在 Session.append() 内部运行,此时 append 锁仍被持有,所以同步拼接 inbox 会被拒绝,报 session append cannot reenter while another append is being published;只有拼接成功,这次 pass 才记为已投递,因此投递失败会由同一 pass 的下一个 compaction/end 重试。
每完成一次 pass,指针大约消耗 40 个 token 的上下文,而这是本插件唯一提供的上下文。
工具懒注册
apply() 不注册任何工具。需要召回能力的智能体各自在自己的作用域里拿到工具(agent.ctx.tools.register),时机有两种:
| 时机 | 触发条件 | 覆盖场景 |
| 一次完成的压缩 pass | 会话有活跃智能体时,compaction/end 不带 error | 常规情况:本会话刚刚压缩过内容。 |
| 智能体创建 | agent/created,且会话自己的日志里已含 compaction/summary | 恢复会话,其早先的压缩发生在本插件加载之前。检查只需遍历恢复时已加载的日志,不调用服务。 |
有三点后果值得明确说明:
- 触发压缩的那一步仍按旧 schema 运行。 自动压缩在 agent/pre-step 瀑布(上下文压力)或 agent/request-error(溢出恢复)中运行,两者都在该步的组装已经取走之后。工具会出现在下一步的请求里,tool-addition 开发者消息会在同一时间宣布这一点。
- 注册是幂等的,且按会话隔离。 第二次检查点、重复的 agent/created、热重载,都不能与作用域里已存在的名字冲突,所以作用域已能解析的名字会被跳过。
- 无需清理。 注册归智能体自己的 fiber 所有,智能体销毁时随之展开。由于作用域自己的层不受 tools.restrict() 约束,屏蔽全局工具的预设无法从它的智能体身上剥掉召回能力。
热重载会在新的 fiber 上再次运行 apply(),订阅自己的监听器;重载之前创建的智能体已经持有自己的注册,会被那条幂等检查跳过。
安装与接线
分三步:把包安装进配置档,把行加进配置档的实时补丁层,开发插件时再把源文件加进 hmr.root。
1. 安装为 link: 依赖
在包含本仓库检出副本的目录下执行:
dsh plugin --profile web add ./dsh-history-access
link: 依赖会解析到真实目录,所以宿主运行的就是那棵目录树里的文件。请安装稳定的检出副本,不要用开发用的工作树。新依赖通常在启动时读取,所以安装后要重启宿主。
本包没有声明 dsh.bundle 清单,因此 dsh plugin add 会把它当作普通依赖安装,不会激活它自己的任何层。第 2 步负责接上这一行。
2. 接上这一行
~/.dsh/profiles/web/cordis.patch.yml 会被监听并实时重载。裸的顶层行会被当成按 id 定位的覆盖并给出警告,所以这一行必须放进 insert 列表:
- insert:
- id: history-access
name: 'dsh-history-access'
config:
readMaxChars: 8000
readMaxEvents: 80
searchMaxHits: 20
outlineMaxChars: 4000
pointer: inject
config 就是整个配置对象——后续的覆盖会替换它,而不是合并进去。
这一行注册的是插件,不是工具:在某个智能体自己的会话压缩出内容之前,任何智能体都看不到东西。由于注册落在智能体自己的作用域里,即使某个预设的 tool-restrict 行屏蔽了全局工具,也藏不住它旗下智能体的 recall——作用域自己的层不受限制。把同一行挂进预设里同样可行,而且无论哪种方式,插件的两个监听器都订阅在全局,所以按预设挂的行依然服务该预设拥有的每个会话。
3. 把源文件加进 hmr.root
要在宿主运行时编辑插件,就把文件(不是目录)列进 hmr 行的配置里。覆盖会替换整个 config,所以要重述每一个键:
- id: hmr
name: '@deepseek-ai/dsh-hmr'
config:
The directory that contains your dsh-history-access checkout.
base: '/path/to/parent'
root:
- '/path/to/parent/dsh-history-access/index.js'
- '/path/to/parent/dsh-history-access/lib/config.js'
- '/path/to/parent/dsh-history-access/lib/render.js'
- '/path/to/parent/dsh-history-access/lib/query.js'
- '/path/to/parent/dsh-history-access/lib/pointer.js'
base 接受相对路径或 file:// URL(绝对盘符路径会被解析成 URL scheme,导致激活失败),而且它必须是每个 root 的祖先目录。重载会销毁插件再重新导入,所以 apply() 会重新运行;监听器挂在 fiber 上,因此不会重复,已经武装好的智能体也保留它自己拥有的注册。
验证
node probe/probe.mjs
探针不需要宿主,也不需要依赖。它把 apply() 驱动到一个内存里的假 ctx,再用一个假 sessionQuery 提供合成日志:日志里有四个回合、一条带工具调用的助手消息、与之匹配的工具结果、两个压缩检查点(第二个取代第一个),以及替换用的 user/message 事件,事件里带 surfaceOp: { op: 'replace', … }。42 个探针全部通过,覆盖了懒注册(apply() 时什么都不做,在完成一轮后和 agent/created 时武装,跨轮幂等,按智能体归属,失败的一轮和无智能体的一轮都不武装)、大纲、transcript 分页(游标可用,事件不重复也不跳过)、显式截断和每一页的字符预算、能指出所属检查点的字面搜索、执行中步骤的排除、每一条拒绝路径、配置校验、服务失败转译、精确取消,以及指针的文本、去重、延迟和失败隔离。
第二个探针是只读的,报告真实会话日志能证明什么,用于对活宿主做验收运行:
node probe/session-inspect.mjs <session-log|sessions-root> [limit]
它解码 zstd 分帧的日志,并按会话打印:第一个提供历史工具的请求头(武装时刻)和最新请求头的工具数量、每一次压缩过程及其遮蔽的区间、本插件注入的每一个指针,以及工具收到的每一次调用及其结果大小。
已知限制
- 召回是一种习得行为。 未经训练的模型会少用任何新工具,而本插件不附带系统提示词段落,所以工具描述就是全部教学面。出现漏用是模型的选择,不是读取失败。懒注册还多一层麻烦:模型在工具出现的那个步骤之前从没见过这些工具,所以 tool-addition 公告就是全部介绍。
- 触发压缩的那个步骤上,真正能干活的工具还没到。 模型在回合中途耗尽上下文时,无法在同一个步骤里调用 history_read,因为该步骤的请求在压缩之前就已组装完成;工具要到下一个步骤才到。插件做什么都改变不了这一点——正在运行的请求,其 schema 已经冻结。
- 插件热加载时已经在跑的会话,会一直不武装,直到它再次压缩。 agent/created 引导覆盖的是插件加载期间创建或恢复的会话,但活着的会话不会再触发该事件,所以重新加载前就已带检查点的会话,要等下一次完成一轮——或者等一次恢复。
- 只做字面搜索。 history_search 是不区分大小写的字面短语匹配(词可以跨空白匹配)。不支持正则,不支持模糊匹配,也不做语义搜索。它还继承了 harness 的文本提取规则:推理块和 system/developer 消息不贡献可搜索文本,所以只出现在那里的短语搜不到——改用 history_read 读那段区间。
- 只限单个会话。 只有调用方智能体自己的会话可以访问。父会话、子会话、兄弟会话都不在范围内,也不支持跨会话搜索。
- 指针在下一步到达,而不是在携带摘要的那次请求里。 指针在 compaction/end 处用 Agent.inject 暂存,注入的上下文在下一个步骤边界被认领。因此,在一轮结束时运行的一趟,会把指针投递到下一轮的第一个请求;而 inject 永远不会唤醒空闲的智能体,所以一直空闲的会话只有在别的东西把它唤醒时才会看到指针。这一点在一次一次性宿主运行中观察到了:每一趟完成的运行都把指针投递到下一步,模型随后用 history_read 读取压缩后的区间。
- 注入的归属信息会被格式读取器接受,并且已在真实日志中观察到。 V4 的准入规则(packages/session/session-format-v3-to-v4/src/message-sources.ts)要求 source.kind 非空,且不能是已废弃的 'plugin'——树外插件用不了这个值;'history-access' 满足要求。对一个携带 20 个已投递指针的会话执行 --session-id 恢复,在驱动其任务之前通过了查询服务的重放校验。
- 被取代的检查点,其自身节点渲染在自己的日志位置上。 转录事件按原始 seq 排序。当一次压缩替换掉更早检查点的替换节点时,那个节点的文本(更早的摘要)出现在它 seq 所在的位置,而不是在恢复区间的开头。文本是完整的;只是顺序与模型最初看到的不同。
- outlineMaxChars 可能被检查点列表超出。 这个列表有意保持完整——模型看不到的检查点就是它读不到的检查点——所以只有轮次详情会被省略。
- 每次读取都经过 ctx.sessionQuery。 没有挂载这个服务,三个工具都会以模型安全的报错信息失败。插件本身不做任何 I/O;服务可能会为不在线的会话加载持久化日志,而对预期的调用方(它自己的在线会话)来说不会出现这种情况。
- readMaxEvents 统计的是渲染出的事件,不是读取的事件。 一页可能会继续读取更多原始事件,以凑够足够多可渲染的事件,所以原始读取数量不受该字段限制;字符预算仍然约束返回的这一页。
- 插件不做工作区授权。 它只读取调用方自己的会话,所以没有第二个会话需要授权,也没有 cwd 检查。
- 细节如果没有任何摘要、也没有任何字面短语指向它,就永远取不到。 Recall 把「即使怀疑也取不到」变成「一怀疑就能取到」;但模型如果压根没理由去找某个事实,Recall 也翻不出来。
许可证
MIT预览分享卡片长什么样 ↓
分享 · DeepSeek Harness Hub
windwhiterain/dsh-history-access
面向模型的回忆能力:让模型读取某个会话在压缩之前的自身历史,服务于 DeepSeek Harness。
相关插件 · 对话 / 记忆
上下文中枢oceanbase/powercontext
上下文跟着工作走 —— 跨会话、跨智能体、跨人。
★ 1,462已汉化DSH
73
智能体记忆库plastic-labs/honcho
Honcho 是记忆基础设施,用来构建有状态的智能体。这些智能体能理解不断变化的人、智能体、群组、项目和想法。
★ 7,848已汉化DSH
71.7
长程智能体控制面loopx-project/loopx
给 Agent 一个目标,让工作持续向前。
★ 6,358已汉化DSH
71.3
智能体上下文数据库volcengine/OpenViking
给 AI 智能体用的上下文数据库
★ 41,246已汉化DSH
71.3
长效机器人团队Fei2411/DS-Bot
DS Bot 是一个基于 DeepSeek Harness简称 dsh的 bot 插件,插件将 dsh 改造为 bot…
★ 4,717已汉化DSH
71.1
可携带记忆层EverMind-AI/EverOS
为什么选择 EverOS
★ 13,711已汉化DSH
71.1