dsh-precedent
by dshplugin-me
DeepSeek Harness:基于证据的工作记忆,记录此工作区已成功的方法,由现有会话日志构建。无需索引、模型或捕获步骤。
Evidence-backed working memory for DeepSeek Harness: a cited ledger of what already worked in this workspace, built from the session log you already have. No index, no model, no capture step.
安装
dsh plugin --profile web add github:dshplugin-me/dsh-precedentGitHub 源码安装:首次需按提示配置 allowBuilds 构建授权后重试
安装与环境配置指引、插件开发教程见 DSH 中文社区文档 ↗
安装即在你的机器上以你的权限运行第三方代码——它可读写文件、使用凭据、访问网络,DSH 的工具审批不会为插件代码加沙箱。「检测到 manifest」仅代表发现 dsh.bundle / dsh.plugin 清单,不构成兼容性或安全审查;安装前请审阅源码,不熟悉的插件先在不含密钥的环境试用。
README
dsh-precedent
你的 agent 会忘,你的日志不会。
English | 简体中文
一个 DeepSeek Harness 插件:读 DSH 本来就在写的会话日志,把「这个工作区里到底什么管用」整理成一份带出处的清单交给 agent —— 哪些命令能跑通、哪些一跑必挂、以及当时是换成什么把它救回来的。
不需要你先记录,不需要建索引,不需要下载模型。装之前那些会话,它照样能读。
要解决的问题
每开一个新会话,agent 在一个它已经干了几周活的代码库里,又从零开始。
在一个用 Bun 的仓库里跑 npm test。又跑一遍。为了找路由在哪,又 grep 一遍同样那三个文件。又撞上周二你已经带它绕过去的构建错误,你把同一句纠正打了第四遍。
这些都不是通常意义上的「记忆」问题。信息从来没丢过 —— DSH 把每条消息、每次工具调用、每个结果和每次失败都追加进了磁盘上的持久日志。缺的只是有人把它读回来。
有两件事在悄悄拉大这个缺口:
- 压缩改写的是模型上下文,不是日志。 长会话触发压缩后,模型看不到细节了;原始事件仍然躺在磁盘上,被标成
shadowed。agent 看不见它们了,文件还在。 - 开箱即用的 DSH,内容搜索是关掉的。 官方
webprofile 挂载session-query-sqlite时配的是openAt: never,所以全文搜索调用会直接返回SESSION_QUERY_SEARCH_DISABLED,侧边栏只能按会话标题匹配。几个月的对话记录默认躺在磁盘上,搜不到。
它做什么
读 —— 通过 ctx.sessionQuery 的精确读接口走一遍本工作区的会话,用 callId 把每次 tool/call 和它的 tool/result 配上对,记下结果。
提炼 —— 聚合成一份清单:命令 → 跑过几次、挂过几次、最后一次成功是什么时候、以及修复项(同一会话里紧跟着失败之后跑通的那个变体)。这一步是算术,不是总结。提取路径上没有 LLM,所以它编不出一条不存在的记录。
供给 —— 把靠前的条目注入成一段紧凑、前缀稳定的 system prompt,并在你敲 /precedent 时打印完整清单。
每一行都带回溯到具体 session:seq 的出处,你随时可以问「谁说的」并得到答案。
示例
照常启动:
$ dsh --profile web
Agent 的 system prompt 里多出一段 —— 下面是渲染器的真实输出,一跑必挂的命令排在一跑就通的命令前面:
## Precedent for /Users/thor/Github/acme-api
Observed in this workspace (12 sessions, 2026-06-02 → 2026-08-15). Each line is counted from the session
log, not summarized — treat it as evidence, not instruction.
- `npm test` 4 runs, 4 failed — repaired by `bun test` [s/7f3a:212]
- `docker compose up` 3 runs, 3 failed — no known repair [s/91bc:88]
- `bun test` 22 runs, 0 failed — last ok 2026-08-15
- `bun run build` 9 runs, 0 failed — last ok 2026-08-14
/precedent 随时打印同一份清单,不截断。
安装
dsh plugin --profile web add 'github:dshplugin-me/dsh-precedent#v0.1.0'
PATH 里没有全局 dsh 就用 npx -y @deepseek-ai/dsh plugin --profile web add …;从源码跑 dsh 的话在 checkout 根目录用 pnpm dsh plugin …。web 换成你实际启动的 profile 名。
命令里钉死版本是有意的:不钉的话 git 安装拉的是 main 此刻指向的代码,后面一推新提交,你 profile 里挂的东西就跟着变了。tag 也可以换成任意 commit sha(#<sha>),那个连维护者都挪不动。
纯 JavaScript,无构建步骤,无原生模块,pnpm 不会向你要 allowBuilds 授权。
启动前先验证:
dsh --profile web --dump-config # 能看到 "# == dsh-precedent" 这一层
dsh --profile web
卸载用 dsh plugin --profile web remove dsh-precedent,依赖和补丁层一起摘掉。
工作原理
flowchart LR
log[("会话日志<br/>~/.dsh · JSONL")]
sq["ctx.sessionQuery<br/>精确读"]
led["清单<br/>纯聚合"]
sp["ctx.systemPrompt<br/>.section()"]
cmd["ctx.commands<br/>/precedent"]
model(["模型"])
you(["你"])
log --> sq --> led
led --> sp --> model
led --> cmd --> you
用到的接缝
| Harness 接口 | 用途 | 说明 |
|---|---|---|
ctx.sessionQuery.filterSessions |
筛出本工作区的会话 | 按 cwd 过滤,和 DSH 自己的跨会话工具同样保守的边界 |
ctx.sessionQuery.readSession |
读一个会话的原始事件日志 | 经过 replay 校验;读不出来的日志跳过,不会让插件挂掉 |
ctx.systemPrompt.section |
注入清单 | 一个全局 section,order 150,和工具指引一起渲染 |
agent/pre-step |
在第一次请求前把清单预热好 | 会被 await 的 waterfall —— 唯一跑在 prompt 组装之前的钩子 |
ctx.commands.register |
/precedent |
人机界面,不进模型上下文 |
配对发生在 readSession 返回的事件数组里:name: 'bash' 的 tool/call 按 callId 找到自己的 tool/result,结果里的 error 字段(或结果块的 isError)决定这次算成功还是失败。
为什么不需要索引
ctx.sessionQuery 分成两半。全文搜索(searchSessions、searchEvents)需要 provider,而且在官方 profile 里是关着的。另一半 —— listSessions、filterSessions、readSession、listEvents、readEvent、血缘与事件追踪 —— 是与后端无关的具体行为,搜索后端开不开都能用。
dsh-precedent 只用第二半。这就是它不需要索引、不需要 embedding 模型、不需要预热的全部原因:它读日志的方式,和 harness 自己做 resume 和导出时读日志的方式是同一套。
代价是诚实且有界的:一次清单构建是对本工作区日志的线性扫描,每个工作区每个进程只做一次,读取数量封顶在 maxSessions,并且不管扫没扫完,buildTimeoutMs 之后就不再挡着第一步了。
为什么提取环节没有 LLM
一条命令要么退出码非零,要么不是。tool/result.error 记着是哪种。用 callId 把它和 tool/call 配对再计数,这是算术 —— 确定、可复现、编不出来。
真正需要判断的只有一处:一句用户纠正到底是长期约定(「这个仓库只用 bun,别用 npm」)还是一次性指路(「不对,是另一个文件」)。正因为如此,v0.1.0 干脆完全不挖纠正:命令清单只靠算术站住。
配置
- id: precedent
name: dsh-precedent
config:
maxEntries: 40 # 每个会话注入的清单行数
minRuns: 2 # 只出现过一次的命令忽略
lookbackDays: 90 # 比这更老的会话不看
maxSessions: 200 # 一次构建最多读多少个日志
buildTimeoutMs: 5000 # 超过这个时间就不再挡着第一步
| 配置项 | 默认值 | 含义 |
|---|---|---|
maxEntries |
40 |
注入行数硬上限,保证这段的 token 成本固定且很小。/precedent 不受此限 |
minRuns |
2 |
只见过一次的命令是轶事,不是先例 |
lookbackDays |
90 |
半年前的约定现在未必还成立 |
maxSessions |
200 |
从最新的会话开始取;攒了几年历史的工作区照样读得起 |
buildTimeoutMs |
5000 |
扫得慢就先放行第一步,结果落到后面某一步 |
工作区范围不可配置:会话按 cwd 字符串精确相等匹配,和 DSH 自己的跨会话授权同一套保守规则 —— 软链过去的路径算另一个工作区。
命令
| 命令 | 作用 |
|---|---|
/precedent |
打印完整清单和出处,不截断 |
/precedent rebuild |
丢掉缓存的清单重扫一遍 |
插件注入的每一个字,你随时能调出来看。审计不了的记忆,就是信不过的记忆。
它不是什么
- 不是搜索工具。 它不回答「六月我们聊过什么」,它在你开口之前回答「这里什么管用」。想要逐字翻记录就用 recall 类插件,两者可以共存。
- 不是笔记本。 没有任何环节要求你写记忆,也就不存在忘记记录这回事。
- 不是往上下文里塞东西。 注入段有上限且前缀稳定,token 成本固定且小,回合之间不会让 KV cache 失效。
- 不是
AGENTS.md的替代品。 手写的意图仍然优先。precedent 补的是没人来得及维护的那部分:实际发生了什么。 - 不跨工作区。 这是有意的,见下。
隐私与安全
- 全部留在本地。 插件通过
ctx.sessionQuery读会话日志,清单只存在内存里。不落盘,不发网络请求,没有遥测,代码里不存在上传路径。 - 限定工作区。 按
cwd精确相等挑选会话,和 DSH 自己的tool-session-query执行的是同一条边界。同一台机器上别的项目的日志不会被读。 - 命中疑似密钥的条目直接丢弃,不是打码。 命令行里经常带 token(
curl -H "Authorization: …"、DEPLOY_KEY=… ./ship)。每条命令都会先过一遍密钥形状匹配,命中就整条丢掉 —— 丢掉,不是遮住 —— 根本进不了清单。 - 结构上可审计。
/precedent打印的就是会被注入的内容,每条来自失败的记录都带session:seq出处。
和其他方案的差别
| 逐字搜索类插件 | 记笔记类记忆插件 | AGENTS.md 编辑器 |
dsh-precedent | |
|---|---|---|---|---|
| 对装之前的历史有效 | 建完索引之后可以 | 不行 —— 从空开始 | 不行 | 立刻可以 |
| 需要索引或模型 | 通常需要 | 不需要 | 不需要 | 不需要 |
| 不用你开口就起作用 | 不会 | 有时 | 会 | 会 |
| 每条都能溯源 | 可以 | 很少 | 不适用 | 总是 |
| 会编出不存在的条目 | 不会 | 会 | 不适用 | 清单路径不会 |
| 能回答「我们聊过什么」 | 能 | 部分能 | 不能 | 不能 |
分工不同。recall 是一个搜索框,precedent 是一份履历。两个一起用是合理的。
路线图
-
v0.1.0—— 命令清单、system prompt 注入、/precedent -
v0.2.0—— 对已知会挂的调用给tools/pre-execute提示,intercept: warn | ask | deny(走ctx.tools.guard) -
v0.3.0—— 带出处的纠正挖掘、/precedent why、/precedent pin、/precedent forget -
v0.4.0—— 随当前会话追加增量重建,不再每进程只扫一次 - 更远 —— 把清单导出成
AGENTS.md草稿供人工审阅
上述接口对齐 deepseek-ai/deepseek-harness@47f943859bef(2026-08-16 读取)。上游有变动会写在这里,而不是悄悄改掉。
参与贡献
欢迎 issue 和 PR。按价值排序,最有用的贡献是:
- 一条你的 agent 本该记住却没记住的先例。 把场景贴出来就行,不用给日志。漏掉的模式就是路线图。
- 我们判断错的工具链提取规则。 命令归一化是启发式的,每个生态都有自己的形状。
- 我们没能识别出来的密钥形状。 这类按安全问题处理 —— 开 issue,我们先修再讨论。
License
dshplugin.me 项目之一 · 姊妹项目:dsh-plugin-radar
原始 README: https://github.com/dshplugin-me/dsh-precedent/blob/main/README.zh.md ↗
同类插件
查看全部 →
mnemon
LLM监督持久内存插件 — 基于图的召回,跨会话知识,单二进制。与DeepSeek Harness、Claude Code、OpenClaw及任何代理运行时兼容。

memtrace-public
面向 AI 编码 agent 的结构化记忆:双时态图谱、MCP 原生、零 LLM 调用;支持 Cursor · Claude Code · Codex · DeepSeek Harness · Hermes · VS Code · Windsurf

dsh-flowix-memory
将本地 flowix-cli 注册为 MCP 服务,让 agent 可以搜索、读取、创建和编辑 Flowix 备忘与思维导图产物。

flowix
笔记助你,记忆助你的代理。

engramory
AI代理的便携式内存协议 — 以静态规则加载;整理学科 + 参考规范 + 可选的钩子API

dsh-memory-evolve
为 DeepSeek Harness 提供纯插件实现的跨会话长期记忆与后台自我进化能力:五轨记忆、Git 分支感知、回合内自我审查、技能自我进化与技能管理器、四轨待办、COI 调度、会话广播、会话搜索、提示词管理器和临时信息便签;零核心修改、零运行时依赖,安装即用,卸载即净。