一个 dsh 插件:把「工作 topic 记忆」维护成 OKF 标准Open Knowledge Format…
34.1/100
综合分
6
GitHub 星标
523
npm 周下载
—/5
用户评分
数据截至 2026/10/21 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。
安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add @aiwayds/dsh-topics-memorynpm 源 · @aiwayds/dsh-topics-memory 的发布者账号已校验与本仓库一致
状态速览
判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态信任档位:已验证
是什么
dsh 原生插件 · chat
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
活跃:最近一次提交在 15 天前
档位由哪些信号合成
本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。
社区实装还没有人打卡 · 装过的第一个就是你
安装兼容性检查✓ 自动检查通过展开查看检查明细 ↓
以下结论由程序自动检查 npm 包、engines 声明与入口文件得出,未做人工实机验证——能装不等于用着没问题。
✓npm 包@aiwayds/dsh-topics-memory @ 0.25.1
✓Node 引擎要求 >=22.19.0 · 基线 Node 22.19 满足
✓dsh CLI 依赖未声明 dsh 版本约束
✓入口文件main/exports/bin 已声明
验证方式:npm registry 存在性 + package.json 静态校验 · 最后检查 2026/10/28 08:37:51
安全扫描自动 · 静态分析源码v2.7.0🔵 扫描:含敏感能力尚无人工评估展开查看扫描说明与证据 ↓
安全扫描自动 · 静态分析源码
v2.7.0静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。
可执行外部命令读写/删除本地文件读取剪贴板或密钥环境变量发起外部网络请求
查看扫描证据(共 182 处,展示前 110 条)
- 读取本地文件lib/index.js:230
content: stripFrontmatter(await readFile(bodyUrl, 'utf8')), - 发起网络请求lib/index.js:580
const run = distiller.request(sessionId, reason); - 发起网络请求lib/index.js:793
const run = distiller.request(sessionId, 'boot-replay'); - 发起网络请求lib/index.js:954
const run = distiller.request(sessionId, 'manual'); - 读取本地文件lib/store.js:24
return access(path, FsConstants.F_OK).then(() => true, () => false); - 写入本地文件lib/store.js:27
await mkdir(dirname(file), { recursive: true }); - 写入本地文件lib/store.js:29
await writeFile(tmp, content, 'utf8'); - 写入本地文件lib/store.js:30
await rename(tmp, file); - 读取本地文件lib/store.js:98
const lines = (await readFile(file, 'utf8')).trimEnd().split('\n'); - 写入本地文件lib/store.js:119
await mkdir(this.metaDir(), { recursive: true }); - 读取本地文件lib/store.js:124
return JSON.parse(await readFile(this.distillStatePath(), 'utf8')); - 写入本地文件lib/store.js:135
await mkdir(this.metaDir(), { recursive: true }); - 读取本地文件lib/store.js:140
return JSON.parse(await readFile(this.consolidateStatePath(), 'utf8')); - 写入本地文件lib/store.js:149
await mkdir(this.topicsDir(), { recursive: true }); - 读取本地文件lib/store.js:173
files = await readdir(this.topicsDir()); - 读取本地文件lib/store.js:183
const raw = await readFile(join(this.topicsDir(), f), 'utf8'); - 删除本地文件lib/store.js:350
await rm(file); - 删除本地文件lib/store.js:374
await rm(file); - 读取本地文件lib/service.js:25
return readFileSync(file, 'utf8').split('\n'); - 读取本地文件lib/service.js:90
st = await stat(path); - 读取本地文件lib/service.js:99
const doc = okf.parseTopicDoc(await readFile(path, 'utf8')); - 读取本地文件lib/service.js:157
st = statSync(file); - 读取本地文件lib/service.js:166
const lines = readFileSync(file, 'utf8').split('\n'); - 读取本地文件lib/service.js:233
const st = statSync(file); - 写入本地文件lib/service.js:317
writeFileSync(file, lines.join('\n') + '\n'); - 读取密钥环境变量lib/sync.js:167
const env = process.env.GITHUB_TOKEN?.trim(); - 执行外部命令固定命令lib/sync.js:175
const child = spawn('gh', ['auth', 'token'], { stdio: ['ignore', 'pipe', 'ignore'], env: process.env }); - 写入本地文件lib/commands.js:472
await writeFile(file, html, 'utf8'); - 执行外部命令来自配置/变量lib/commands.js:484
const child = spawn(cmd, args, { detached: true, stdio: 'ignore' }); - 读取本地文件lib/legacy-import.js:158
if (existsSync(markerPath)) - 读取本地文件lib/legacy-import.js:171
const source = legacySettingsCandidates(input.home).find((p) => existsSync(p)); - 读取本地文件lib/legacy-import.js:176
const section = parseFlatSection(readFileSync(source, 'utf8'), LEGACY_SECTION); - 写入本地文件lib/legacy-import.js:237
mkdirSync(join(path, '..'), { recursive: true }); - 写入本地文件lib/legacy-import.js:238
writeFileSync(path, `${JSON.stringify(marker, null, 2)}\n`); - 执行外部命令固定命令lib/git.js:29
const child = spawn('git', [...extra, ...args], { - 读取本地文件lib/retrieval.js:404
raw = readFileSync(embeddingIndexPath(bundleDir), 'utf8'); - 写入本地文件lib/retrieval.js:432
mkdirSync(join(bundleDir, 'meta'), { recursive: true }); - 写入本地文件lib/retrieval.js:433
writeFileSync(embeddingIndexPath(bundleDir), JSON.stringify(index)); - 发起网络请求lib/embedding.js:79
res = await fetch(`${host}/api/embed`, { - 执行外部命令固定命令lib/embedding.js:178
raw = execFileSync('curl', [ - 写入本地文件lib/pipeline-events.js:53
await mkdir(dirname(file), { recursive: true }); - 写入本地文件lib/pipeline-events.js:54
await appendFile(file, lines.map((l) => `${l}\n`).join(''), 'utf8'); - 读取本地文件lib/pipeline-events.js:67
raw = await readFile(file, 'utf8'); - 写入本地文件lib/pipeline-events.js:78
await writeFile(tmp, keep.map((l) => `${l}\n`).join(''), 'utf8'); - 写入本地文件lib/pipeline-events.js:79
await rename(tmp, file); - 读取本地文件lib/jev/gate.js:52
raw = readFileSync(file, 'utf8'); - 执行外部命令固定命令lib/onboard.js:196
const child = spawn('gh', ['api', 'user', '--jq', '.login'], { stdio: ['ignore', 'pipe', 'ignore'] }); - 读取密钥环境变量lib/jev/client.js:56
const explicit = process.env.JEV_KEYCHAIN?.trim() ?? ''; - 发起网络请求lib/jev/client.js:186
res = await fetch(backend.endpoint, { - 写入本地文件lib/jev/log.js:52
await mkdir(dirname(file), { recursive: true }); - 写入本地文件lib/jev/log.js:53
await appendFile(file, lines.map((l) => `${l}\n`).join(''), 'utf8'); - 读取本地文件lib/jev/log.js:66
raw = await readFile(file, 'utf8'); - 写入本地文件lib/jev/log.js:77
await writeFile(tmp, keep.map((l) => `${l}\n`).join(''), 'utf8'); - 写入本地文件lib/jev/log.js:78
await rename(tmp, file); - 写入本地文件src/commands.ts:515
await writeFile(file, html, 'utf8') - 执行外部命令来自配置/变量src/commands.ts:527
const child = spawn(cmd, args, { detached: true, stdio: 'ignore' }) - 发起网络请求src/embedding.ts:147
res = await fetch(`${host}/api/embed`, { - 执行外部命令固定命令src/embedding.ts:262
raw = execFileSync( - 执行外部命令固定命令src/git.ts:48
const child = spawn('git', [...extra, ...args], { - 读取本地文件src/index.ts:358
content: stripFrontmatter(await readFile(bodyUrl, 'utf8')), - 发起网络请求src/index.ts:718
const run = distiller.request(sessionId, reason) - 发起网络请求src/index.ts:931
const run = distiller.request(sessionId, 'boot-replay') - 发起网络请求src/index.ts:1090
const run = distiller.request(sessionId, 'manual') - 读取密钥环境变量src/jev/client.ts:136
const explicit = process.env.JEV_KEYCHAIN?.trim() ?? '' - 发起网络请求src/jev/client.ts:294
res = await fetch(backend.endpoint, { - 读取本地文件src/jev/gate.ts:67
raw = readFileSync(file, 'utf8') - 写入本地文件src/jev/log.ts:122
await mkdir(dirname(file), { recursive: true }) - 写入本地文件src/jev/log.ts:123
await appendFile(file, lines.map((l) => `${l}\n`).join(''), 'utf8') - 读取本地文件src/jev/log.ts:136
raw = await readFile(file, 'utf8') - 写入本地文件src/jev/log.ts:145
await writeFile(tmp, keep.map((l) => `${l}\n`).join(''), 'utf8') - 写入本地文件src/jev/log.ts:146
await rename(tmp, file) - 读取本地文件src/legacy-import.ts:210
if (existsSync(markerPath)) return { outcome: 'marker-exists', imported, skipped } - 读取本地文件src/legacy-import.ts:224
const source = legacySettingsCandidates(input.home).find((p) => existsSync(p)) - 读取本地文件src/legacy-import.ts:230
const section = parseFlatSection(readFileSync(source, 'utf8'), LEGACY_SECTION) - 写入本地文件src/legacy-import.ts:292
mkdirSync(join(path, '..'), { recursive: true }) - 写入本地文件src/legacy-import.ts:293
writeFileSync(path, `${JSON.stringify(marker, null, 2)}\n`) - 执行外部命令固定命令src/onboard.ts:209
const child = spawn('gh', ['api', 'user', '--jq', '.login'], { stdio: ['ignore', 'pipe', 'ignore'] }) - 读取本地文件src/paths.ts:41
existsSync(path: string): boolean - 写入本地文件src/paths.ts:42
renameSync(from: string, to: string): void - 写入本地文件src/pipeline-events.ts:78
await mkdir(dirname(file), { recursive: true }) - 写入本地文件src/pipeline-events.ts:79
await appendFile(file, lines.map((l) => `${l}\n`).join(''), 'utf8') - 读取本地文件src/pipeline-events.ts:92
raw = await readFile(file, 'utf8') - 写入本地文件src/pipeline-events.ts:101
await writeFile(tmp, keep.map((l) => `${l}\n`).join(''), 'utf8') - 写入本地文件src/pipeline-events.ts:102
await rename(tmp, file) - 读取本地文件src/retrieval.ts:503
raw = readFileSync(embeddingIndexPath(bundleDir), 'utf8') - 写入本地文件src/retrieval.ts:526
if (mkdir) mkdirSync(join(bundleDir, 'meta'), { recursive: true }) - 写入本地文件src/retrieval.ts:527
writeFileSync(embeddingIndexPath(bundleDir), JSON.stringify(index)) - 读取本地文件src/service.ts:37
return readFileSync(file, 'utf8').split('\n') - 读取本地文件src/service.ts:179
st = await stat(path) - 读取本地文件src/service.ts:187
const doc = okf.parseTopicDoc(await readFile(path, 'utf8')) - 读取本地文件src/service.ts:243
st = statSync(file) - 读取本地文件src/service.ts:251
const lines = readFileSync(file, 'utf8').split('\n') - 读取本地文件src/service.ts:316
const st = statSync(file) - 写入本地文件src/service.ts:402
writeFileSync(file, lines.join('\n') + '\n') - 读取本地文件src/store.ts:84
return access(path, FsConstants.F_OK).then( - 写入本地文件src/store.ts:91
await mkdir(dirname(file), { recursive: true }) - 写入本地文件src/store.ts:93
await writeFile(tmp, content, 'utf8') - 写入本地文件src/store.ts:94
await rename(tmp, file) - 读取本地文件src/store.ts:180
const lines = (await readFile(file, 'utf8')).trimEnd().split('\n') - 写入本地文件src/store.ts:203
await mkdir(this.metaDir(), { recursive: true }) - 读取本地文件src/store.ts:209
return JSON.parse(await readFile(this.distillStatePath(), 'utf8')) as Record<string, unknown> - 写入本地文件src/store.ts:221
await mkdir(this.metaDir(), { recursive: true }) - 读取本地文件src/store.ts:227
return JSON.parse(await readFile(this.consolidateStatePath(), 'utf8')) as Record<string, unknown> - 写入本地文件src/store.ts:236
await mkdir(this.topicsDir(), { recursive: true }) - 读取本地文件src/store.ts:261
files = await readdir(this.topicsDir()) - 读取本地文件src/store.ts:269
const raw = await readFile(join(this.topicsDir(), f), 'utf8') - 删除本地文件src/store.ts:430
await rm(file) - 删除本地文件src/store.ts:454
await rm(file) - 读取密钥环境变量src/sync.ts:181
const env = process.env.GITHUB_TOKEN?.trim() - 执行外部命令固定命令src/sync.ts:189
const child = spawn('gh', ['auth', 'token'], { stdio: ['ignore', 'pipe', 'ignore'], env: process.env })
扫描于 2026/11/3(0 天前) · 范围 入口闭包 + 全包扫描 · 来源 npm 发布包
静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。
依赖的 DSH / Cordis 模块
@deepseek-ai/cordis@deepseek-ai/dsh-agent@deepseek-ai/dsh-attachment@deepseek-ai/dsh-brand@deepseek-ai/dsh-commands@deepseek-ai/dsh-invariants@deepseek-ai/dsh-llm@deepseek-ai/dsh-scope@deepseek-ai/dsh-sandbox@deepseek-ai/dsh-session@deepseek-ai/dsh-settings@deepseek-ai/dsh-skill给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个
功能亮点
- 维护主题记忆
- 按OKF标准组织
- 本地优先可追溯
面向 LLM 智能体的主题记忆——靠编辑而非堆积:主题只保留起始问题、结论、影响和依赖,过程不算记忆。dsh 的 OKF 包,本地优先、可 git 追溯、按预算注入且不调用 LLM。
最近更新
在 GitHub 查看全部 →v0.25.12026-10-19
修复(boot):智能体创建后 1.5 秒再跑启动链,避开首帧窗口
v0.24.12026-10-11
fix(service):影子账本追加时覆盖了 512KB 上限以下的已有记录
之前只在压缩分支里重新读取已有行,所以向小于 512KB 的账本追加时,整个文件会被重写成只剩新条目(dsh-self-improve N1 波次的账本交叉校验发现)。现在每次追加都会带上已有行;超过上限时压缩仍会裁到最新的 3/4。同时保护 package-shadow 和 lesson-shadow 两类账本(共用辅助函数)。回归测试锁定两条记录都能存活。
v0.22.02026-10-09
Merge feat/open-rate-metrics: injection-vs-open metrics and zero-open decay
原文(未汉化)
数据来自仓库的 GitHub Release,可能与插件实际版本不一致。
README
由 DeepSeek 最新模型翻译生成dsh-topics-memory
一个 dsh 插件:把「工作 topic 记忆」维护成 OKF 标准(Open Knowledge Format v0.2)的知识 bundle,持久化在本地 git 仓库(可选同步到 GitHub 私有仓库),利用 git 历史提供结论可追溯性,自动观察会话沉淀知识,并在每轮对话前向模型注入相关 Topic。
要求 dsh >= 0.2.0-rc.2 — 本插件只跟随 dsh RC/stable 线(CI 与发版在运行时解析 latest/next 中更新的 dist-tag)。不再支持 alpha 线。
演示
约 4 分钟的完整流程:topic 沉淀、蒸馏、注入在真实会话里跑起来。
https://github.com/user-attachments/assets/6e9b346d-2ec9-4148-ae62-7087797d3188
它解决什么问题
长会话会失忆,跨会话更会。本插件维护一份结构化的 topic 记忆:每个 Topic 记录一件事的名字、依赖、未决问题、目前结论、影响、建议。结论变了就改文件、打 commit——git log 直接回答「这个结论什么时候、被谁、为什么改的」。
初衷:记忆是编辑出来的,不是攒出来的
先说结论:记忆不是越多越好。
展开完整文档(README 剩余 1 节)
dsh-topics-memory 一个 dsh 插件:把「工作 topic 记忆」维护成 OKF 标准(Open Knowledge Format v0.2)的知识 bundle,持久化在本地 git 仓库(可选同步到 GitHub 私有仓库),利用 git 历史提供结论可追溯性,自动观察会话沉淀知识,并在每轮对话前向模型注入相关 Topic。 要求 dsh >= 0.2.0-rc.2 — 本插件只跟随 dsh RC/stable 线(CI 与发版在运行时解析 latest/next 中更新的 dist-tag)。不再支持 alpha 线。 演示 约 4 分钟的完整流程:topic 沉淀、蒸馏、注入在真实会话里跑起来。 https://github.com/user-attachments/assets/6e9b346d-2ec9-4148-ae62-7087797d3188 它解决什么问题 长会话会失忆,跨会话更会。本插件维护一份结构化的 topic 记忆:每个 Topic 记录一件事的名字、依赖、未决问题、目前结论、影响、建议。结论变了就改文件、打 commit——git log 直接回答「这个结论什么时候、被谁、为什么改的」。 初衷:记忆是编辑出来的,不是攒出来的 先说结论:记忆不是越多越好。 「记忆」类产品的常见思路是多多益善——能记的都记,用时全量检索。这对人也许成立,对 LLM 恰恰相反,而且反在两处:模型的注意力是有限资源,巨型记忆库意味着每一轮对话都在噪音里翻找信号;更危险的是,过程记忆里囤着大量「当时正确、事后失效」的中间判断,它们会理直气壮地把模型引向错误的决定。 所以本插件对「记什么」做了一次苛刻的取舍:一个 topic 只记四件事——它从什么问题开始、得出了什么结论、影响什么、依赖什么。至于得出结论的过程:讨论、试错、绕过的弯路,一概不记。过程属于 session,session 结束就该随它去;能留下的,只有经得起蒸馏的结论。 短时记忆交给 session,对话上下文本就是它,不需要插件再回喂一遍;长时记忆交给 topics——小、结构化、git 可追溯,注入按预算切片、零命中零注入,每轮给模型的都是最小的高价值上下文,而不是越大越好的仓库。 所以这个插件想做的不是模型的记事本,而是模型的编辑:替它决定什么值得记住,以及——更要紧的——什么应该被忘掉。 核心特性 - OKF v0.2 严格合规:每个 Topic 是 markdown + YAML frontmatter 的 concept 文档(type: Topic),可被 Obsidian、OKF 校验器等整个生态直接消费;自带 provenance(sources)、trust(generated/verified)、lifecycle(status/stale_after)三族字段。 - git 可追溯:一次结论变更 = 一个 commit(写穿);topic_history 工具和 /topics history 把变更史工具化。 - local-first:默认 local-only 模式(~/.dsh/topics/),零配置零凭据;配置 repo 后启用 GitHub 同步(单库单 Bundle 单 main,写穿 + 去抖推送,rebase 冲突标记降权等人解,不做自动智能合并)。 - 免 LLM 热路径注入:每轮输入做词法匹配(CJK bigram + 词 + tag 加权 + depends 图游走),毫秒级;无命中零注入;per-topic 摘要 ≤300 token、top-K ≤4、总预算 ≤1.5k token,全部可配。 - 注入可观测可调参:每轮落 Injection Log(命中、得分、near-miss、预算占用),/topics stats 给出 hit rate、top-N、near-miss 分布和阈值调参建议——调参看证据,不拍脑袋。 - 知识连接成图:depends(机器可读的有向依赖边)+ 正文 [[wikilink]] 与 markdown 链接(人写边)共同构成图;检索命中后沿图双向游走(每层衰减一半、深度可配),一次命中带入一个知识子图;每次写入自动重建 meta/backlinks.json 反向引用索引,/topics show 直接列出「谁引用了我、怎么引用的」——改一条结论前先看牵连面。 - 两段式观察(M2):主模型用 topic_observe 随手记原子观察,后台蒸馏 lane(session end + 每 N 轮,模型可配)把观察批量蒸馏成正式 Topic;主模型认为值得记时直接 topic_save。 Jev 决策层(System One,实验,default off) 架在异步 lane 上的可选决策层,由 System One typed-decision 模型(jev)驱动:慢车道 rerank 候选改批量 noul 打分(替换 LLM rerank)、整理 lane 的 merge 候选对在 LLM 园丁接手前先做前置过滤、快道词法门由 turn-end lane 做影子对账。每个判定都过概率门控,任何失败——超时、网络错、坏答案——一律回退到今天的纯本地行为(fail-open 硬编码,无开关键)。注入热路径永不发起远程调用(ADR 0016–0019;设计文档:docs/design/2026-09-25-system-one-integration.md)。默认关闭:jevEnabled: false 即零行为变化。 键 | 键 | 默认 | 说明 | | jevEnabled | false | 总开关(灰度:default off → shadow → opt-in per profile → 默认开观察);false 连统计一起停 | | jevBackend | zen | zen(免费)/ native / openrouter | | jevModel | 空串哨兵 | 调用时按 backend 解析:jev-1.13-free(zen)/ jev-1.13.0(native)/ typesafe/jev-1.13(openrouter)——钉版本号,永不指向别名 | | jevTimeoutMs | 3000 | 单请求超时;单发 AbortSignal.timeout 不重试(lane 的下一节拍自然重试) | | jevSecretFile | 无 | 外部 secret 清单路径;启动加载一次,热更换路径即重读 | key 配置 | Backend | key 来源 | | zen(默认,免费) | JEV_ZEN_API_KEY env,或 macOS 钥匙串服务 opencode-zen-inference(默认回退——零配置) | | native | TYPESAFE_API_KEY | | openrouter | OPENROUTER_API_KEY;钥匙串服务 openrouter-inference 需显式 JEV_KEYCHAIN | dsh 会清洗插件环境里匹配 KEY|PASSWORD|SECRET|TOKEN 的 ambient 变量,shell 里 export 的 key 到不了插件——请走 profile patch 的 env: 块显式透传,或用钥匙串(JEV_KEYCHAIN / zen 默认服务;都不匹配清洗规则)完全避开文件落 key: ~/.dsh/cordis.patch.yml — 并入你的 profile patch。!!js 表达式让 key 不落文件(与 dsh-jev-mcp 同款约定)。 - insert: - id: dsh-topics-memory name: '@aiwayds/dsh-topics-memory' env: JEV_ZEN_API_KEY: !!js process.env.JEV_ZEN_API_KEY ?? '' native: TYPESAFE_API_KEY: !!js process.env.TYPESAFE_API_KEY ?? '' openrouter: OPENROUTER_API_KEY: !!js process.env.OPENROUTER_API_KEY ?? '' 另加 JEV_KEYCHAIN: 'openrouter-inference' (zen 无需 JEV_KEYCHAIN——无 env key 时自动读默认钥匙串服务) 阈值(rerank / merge pair) | 档 | rerank(慢车道) | merge pair(整理前置) | 动作 | | 采纳 | noul ≥ 0.60 | ≥ 0.50 | 进 picks / 送 LLM 生成 | | 记录带 | 0.10 – 0.60 | 0.15 – 0.50 | 只落 decisions.jsonl,不影响行为 | | 回退 | < 0.10 | < 0.15 | 强否决,回退词法/现状行为 | 绝对线绑定批量协议(换协议必须重扫)。三缝失败回退行为见 ADR 0018。判定与调用明细落 meta/decisions.jsonl(本地 only,脱敏——绝不存 state 原文)。 延迟基准(2026-09-26 实测,Apple M5,typesafe native 后端,jev-1.13.0) 真实负载基准 + 沙箱实跑——用来选 jevTimeoutMs。各 source 形状与负载不同,除注明外均为同一 8 候选 shadow 批量: | 来源 | 形状 | p50 | p90 | max | n | | 空载基准(顺序发) | 8 问批量 | 742 ms | 1290 ms | 1461 ms | 10 | | 空载基准(顺序发) | 单问 | 367 ms | — | 925 ms | 5 | | 阈值扫描(09-25) | 20 问批量 | 均值 1760 ms | — | 8470 ms | 16 | | 真机 headless 轮 | 8 问批量,与主模型流式并发 | 327–5698 ms | — | 10619 ms | 3 | 关键读数:空载路径远低于 3000 ms 默认线(p90 约 2× 余量);但真机轮的 shadow 调用与主模型的流式响应共享网络——上表 10.6 s 离群值正是在这个位置观测到的。超时即 fail-open:该批数据丢弃(慢车道回退旧 LLM rerank),紧超时损失的是 shadow 数据,不是正确性。默认 3000 保持不变;除非 decisions.jsonl 显示 timeout 占比持续 >5%(/topics status 的 30 天摘要会露出),弱网用户可自行上调 jevTimeoutMs。zen 与 openrouter 本次未实测——开启后你自己 decisions.jsonl 的 latency 列就是你网络的真值。 工具与命令 | 模型工具 | 用途 | | topic_save | 沉淀/修订一个 Topic(名字/依赖/未决问题/结论/影响/建议) | | topic_observe | 随手记一条原子观察(decision/finding/constraint/question),等蒸馏 | | topic_search | 免 LLM 关键词检索记忆 | | topic_history | 某 Topic 的结论变更史(git log 工具化) | | 命令 | 用途 | | /topics onboard | 交互式配置向导:唤起 dsh 原生 ask-user 面板逐项问答(模式 / 仓库 / 蒸馏 / 注入档位 / 自动观察),末步确认才写入;无 ask-user UI 的环境自动退化为逐条输入 | | /topics status | bundle 健康:topic 数、观察积压、冲突、最近蒸馏结果、同步状态 | | /topics distill | 手动触发一次蒸馏 run(复用现有 lane 与 in-flight 守卫;输出摘要与 distill-state 字段一一对应) | | /topics consolidate | 手动触发一次整理 run:LLM 园丁合并重复/晋升 stable/废弃过时/刷新元数据,逐条 git commit 可回滚 | | /topics stats | 注入统计:hit rate、top-N、near-miss 分布与调参建议 | | /topics list / show / history | 浏览 Topic、反向引用与变更史 | | /topics graph | 生成关系图网页(力导向、可拖拽缩放、悬停看结论)并自动在浏览器打开 | | /topics sync [pull\|push] | GitHub 模式手动同步 | | /topics config / set <key> <value> | 查看与修改配置(阈值、预算、蒸馏模型等) | 安装 dsh plugin --profile <你的profile> add @aiwayds/dsh-topics-memory Bundle 默认在 ~/.dsh/topics/($DSH_TOPICS_HOME 可覆盖)。装好后的第一件事:跑 /topics onboard——直接弹出 dsh 原生 ask-user 交互面板逐项问答(TUI 面板 / 浏览器会话 / 飞书卡自动适配,feishu 侧装了 dsh-ask-router 还能双端竞答)。GitHub 同步:/topics set repo <owner/name>(建议仓库名 dsh-topics-data,与插件源码仓区分开),凭据走 $GITHUB_TOKEN 或已登录的 gh CLI(登录不是本插件职责)。 从 0.5.x 升级(更名) 0.6.0 起插件更名:@aiwayds/dsh-llmwiki-memory → @aiwayds/dsh-topics-memory,命令族 /wiki → /topics,settings namespace llmwiki → topics。安装新包(并把旧包从 profile 移除)即可——首次启动时插件自动完成迁移:数据目录 ~/.dsh/llmwiki 改名为 ~/.dsh/topics,旧 llmwiki namespace 里用户调过的配置值一次性拷入 topics。无需手动操作;迁移某步失败时插件回落旧路径继续工作。 快速上手 1. 安装(上方命令),重启 dsh; 2. 跑 /topics onboard,在 ask-user 面板里走完 模式 / 仓库 / 蒸馏模型 / 注入档位 / 自动观察 五个决定——末步确认才写入; 3. 正常干活:相关结论每轮自动注入;说「记住…」让模型 topic_save;/topics status 看健康,/topics stats 看注入命中。 卸载 从 profile 移除插件: dsh plugin --profile <name> remove @aiwayds/dsh-topics-memory 宿主会自动收敛:dsh.profile.bundles 条目被移除,patch 层随包消失。 以下内容有意保留在磁盘上(这是你的记忆本体): - ~/.dsh/topics/ —— 整个话题包:话题 markdown、meta/、以及内嵌的 .git 仓库(完整历史;可能带有 origin 远端 —— GitHub 同步随插件停止)。要异地归档就原样拷贝/克隆这个目录。 - 设置页 dsh-topics-memory 条目(profile patch)—— 用户覆盖项。注意:重装会静默恢复同步(包括已配置的 repo);想干净重来就先清空该条目。 - 0.5.x → 0.6.x 迁移留下的 llmwiki: 旧设置段不会被自动删除;确认无用后手动移除。 彻底清除:先备份 ~/.dsh/topics,再 rm -rf ~/.dsh/topics。 配置 首次配置交给 /topics onboard;日常微调用 /topics set <key> <value>——0.1.7+ 宿主上写设置页 dsh-topics-memory 条目(profile patch),全部键 volatile 免重启即时生效。从 0.1.7 之前升级:旧 settings.yaml 里的 topics: 段会在下次插件 boot 时一次性自动迁入新条目(审计档在 ~/.dsh/storages/dsh-topics-memory/legacy-import.json)。全部键与默认值: | 键 | 默认 | 说明 | | repo | 空(local-only) | GitHub 同步仓 owner/name;建议 dsh-topics-data;置空回 local-only | | autoInject | true | 每轮注入总开关 | | injectDedup | true | 会话级注入去重:本会话已实际注入过的 Topic 不重注(会话结束清空注册表;被预算丢弃的仍可注入;被去重占用的 topK 名额不回填)——见 ADR 0012 | | suppressEcho | true | 蒸馏回声抑制:本会话蒸馏出的 Topic 不回注同会话(provenance 记入 observations 日志的 sessionId → distilledInto) | | topK | 4 | 每轮最多注入的 Topic 数 | | perTopicBudget | 300 | 单 Topic 摘要 token 预算 | | totalBudget | 1500 | 每轮注入总预算 | | matchThreshold | 0.3 | 命中阈值;按 /topics stats 的 near-miss 证据调 | | tagBoost | 0.15 | tag 命中加成(多次命中的总上限也为此值) | | injectMode | pointer | 注入形态:pointer(轻指针,单条 ≤80 tok,topic_open 拉全文;总预算上界锁 600)/digest(完整摘要渲染,per-topic 300 / 总 1500) | | qualityLane | sampled | 慢道质量 lane:off/sampled(1/3 轮触发)/always;turn/end 产出、下一轮注入消费(消费即清),子代理会话写死不跑 | | graphDepth | 2 | depends 图双向游走深度(0 关闭) | | recencyWindowDays | 7 | 近因加分窗口(+0.2) | | autoObserve | true | 每轮自动抓原子观察 | | includeSubagents | false | 注入与观察是否作用于子代理会话(ADR 0011;0.7.0 起默认 off);off = 子代理整体跳过 | | observationMaxChars | 2000 | 每侧每轮观察截断长度 | | distillProvider / distillModel | 空(蒸馏关闭) | 蒸馏 lane 模型路由,两者都设置才启用。有 UI 时 /topics set distill-provider / distill-model 不带值会弹选择面板(provider 列表 → 该 provider 的模型目录);带值时 distill-model 支持 provider model 或 provider/model 混写自动拆成两个键 | | distillEveryTurns | 5 | 长 session 每 N 轮触发一次蒸馏 | | distillOnSessionEnd | true | session 结束时蒸馏一次 | | distillBatchSize | 40 | 每次蒸馏模型调用携带的观察条数。遇输出上限(max-tokens)失败自动减半重试(下限 5),失败批次不再活锁积压;缩小状态跨 run 保持,直到插件重载或配置变更。注意:/topics set distillBatchSize 重设为同值不触发复位,需设为不同值或重载插件 | | distillMaxModelCalls | 8 | 单次蒸馏 run 的模型调用预算,含 ops 未回显有效 observed_ids 时的纠错重试(至多一次,预算放不下即零消费停机)。预算耗尽即停,已成功的批次照常 markDistilled(部分前进优于零前进),distill state 记 partial: … | | consolidateCadence | daily | 整理 lane 节拍:daily/3d/7d/off。会话启动时检查上次整理时间(meta/consolidate-state.json),到期即在后台自动跑 LLM 园丁(复用蒸馏模型路由):本地词面聚类只送「长得像」的候选簇,四类动作 merge/promote/deprecate/refresh,越权 op 一律丢弃;模型调用失败不推进节拍,下次启动重试 | | deprecatedTtlDays | 15 | deprecated 条目超过 N 天在会话启动时自动删除(本地规则不依赖模型,逐条 git commit 可回溯找回);0 关闭清扫 | | usageBoost | 0.15 | 使用加成(ADR 0015):近 30 天被注入命中/点开过的 Topic 检索加分(计入门槛分、帽 0.2、零词面相关不加、结构门不豁免);0 关闭 | | zeroOpenDecay | false | 零打开衰减:零打开高频 slug 的命中分在阈值裁剪前减半(见下方小节) | | pushDebounceSeconds | 45 | GitHub 模式去抖推送间隔 | | jevEnabled | false | System One 决策层总开关(实验):false = 零行为变化——见上方「Jev 决策层」一节 | | jevBackend | zen | 决策端点:zen(免费)/ native / openrouter | | jevModel | 空(按 backend:jev-1.13-free / jev-1.13.0 / typesafe/jev-1.13) | 版本钉定的决策模型;升级是显式动作 | | jevTimeoutMs | 3000 | 单次决策请求超时;单发不重试 | | jevSecretFile | 无 | 出网 secret gate 的外部清单路径;热更换路径即重读 | | jevLayaFallback | false | 本地 laya 陪跑:每次 jev 调用并发一路 laya 请求;laya 为纯遥测对照(不接管决策,真实负载排序一致率 0/14) | | jevLayaUrl | http://127.0.0.1:8000/v1/systemone | 陪跑用的 laya-serve 端点 | | jevDebug | 关 | 诊断日志开关(走宿主 logger,默认静默) | 零打开衰减(默认关) zeroOpenDecay: true 时,命中分在 matchThreshold 裁剪前乘 0.5:滚动 30 天内被真正注入 ≥5 次、且 opens.jsonl 全期 0 次打开的 slug(即 /topics stats 的「零打开高频」清单——stats 面板与打分衰减共用同一条共享规则)不再霸榜;跌破阈值的候选自然落入 nearMisses 并带 zero-open-decay 标签,注入日志可见原因。动机:24 个「注入 ≥5 次、0 打开」的高频话题长期霸榜,而 score 与打开仅弱相关(阈值 0.3 不动)。默认 false 零行为变化;injections/opens 读取失败跳过衰减(fail-open);/topics set zero-open-decay on|off 运行时切换。 laya 本地陪跑(实验,默认关) jevLayaFallback: true 且本地跑着 laya serve 时,每次 jev 调用并发一路本地 laya 请求:主路答案驱动决策,laya 答案并排落账——一组永久运行的 laya vs jev 同题对照。laya 是纯遥测(真实负载实测批内排序与主路一致率 0/14、绝对分不可用),主路失败照旧回退旧路径;laya 没起 = 毫秒级连接拒绝。 laya 安装配置:随包 skill dsh-topics-memory-laya 完整覆盖安装(venv / 国内镜像加速 / checkpoint 下载)、启动 laya-serve、配置 jevLayaFallback、用 decisions.jsonl 验证生效。对 agent 说 laya 即可触发,或直接读 skills/dsh-topics-memory-laya/SKILL.md。 Acknowledgements 本项目的形态直接受以下项目的启发与支撑: - zosmaai/pi-llm-wiki — pi 上的原生 OKF v0.2 知识库扩展,本项目的直接灵感来源。其两段式观察(便宜的原子观察 + 后台蒸馏)、缓存安全注入(易变内容不进 system prompt)、分层 vault 与 ownership 模型都被本设计吸收。 - GoogleCloudPlatform/open-knowledge-format — Open Knowledge Format (OKF) v0.2 规范,本项目 Bundle 格式严格遵循的标准。 - Karpathy 的 LLM Wiki pattern — 整个 LLM 维护个人知识库方法论 的起点。 - fan56/pi-topic-memory — 同作者的前作:pi 上的工作 topic 台账与静默注入扩展,其热路径免 LLM 匹配与注入时序经验是本项目的直接技术前身。 - chancelu/dsh-llmwiki — dsh 生态的同类先例,本项目的同轮注入 seam(agent/inbox/spliced + systemPrompt.context())沿用了它在真实 dsh 上验证过的机制。 已知边界 - 子代理默认不参与记忆,可整体打开:默认(include-subagents off,0.7.0 起)delegation depth > 0 的子代理会话被整体跳过——不注入、不观察、不触发蒸馏;/topics set include-subagents on 后注入与观察同样作用于子代理会话。topic 工具始终在全局层(子代理显式 topic_save 不受开关影响)。跨进程子代理(claude-code/codex 等 provider)本就不加载本插件。 - 退出路径本地化(0.10.0):插件 disposer 只做一步本地 git commit(meta 侧车文件:observations / injections / distill state),不再等待任何网络——没有 pull、没有 push、没有模型调用,宿主退出不再支付 git 双程与有界蒸馏等待(旧的 90s 上限移除,仅保留 10s 兜底以防病理性 git 卡死)。退出蒸馏触发改为 fire-and-forget;已有 session-end run 在跑时整体跳过(否则同一全局队头批次会被双份喂给模型)。跳过不丢活:observations 本就 write-through 落盘,推迟的 push 由下次启动的 pull 补推,被跳过的蒸馏同样由下次启动回放(boot-replay)。meta/distill-state.json 记录每次 lane 的结局,/topics status 可查。 - 观察 GC(三振删除):被模型实际评估(返回了可解析应答,无论内容有无价值)却未被任何 op 消费的观察记一次 failed attempt,连续 3 次即物理删除(用户已明确授权删除 lane 确实无法处理的原始观察)。模型从未评估过的批次永不计数:基础设施失败(网络错误、蒸馏路由未配置 → 可读 no-model 短路)与输出不可解析(invalid-output)豁免;输出上限减半重试中的批次只有到达裁决(成功 / 触底 / stalled / 明确跳过)才计一次。删除立即 commit(数据销毁 git 可追溯),纯计数沿用 flush 节奏。 - 配置读取时机:/topics set 与 profile patch 修改在下次会话启动后生效最稳(dsh 0.1.7 起 settings 文档即 profile patch;旧 settings.yaml 导入一次后改名)。 - 蒸馏选模型:/topics onboard 的蒸馏一步拆成两问(先 provider 后 model,模型列表取自该 provider 的目录),选完经 resolveModelInfo 预校验——provider 无活路由会阻断重选,模型目录校验非 NO_ADAPTER 失败(目录外,可能仍可用)则警告但放行;无 ask UI 或无可用模型路由的环境自动退回文本输入。/topics set 的选择面板走同一套校验。 设计文档 - CONTEXT.md — 领域术语表 - docs/adr/ — 0001–0019:OKF 合规、Remote 形态、同步策略、两段式 Observer、Bundle 布局、注入默认值、可观测与调参、双模式持久化、配置向导、子代理隔离、include-subagents 开关、注入去重默认开、更名与迁移、双通道注入、使用加成、决策层直连 HTTP、快道零远程红线、fail-open 硬编码、secret gate 内嵌 License MIT
预览分享卡片长什么样 ↓
分享 · DeepSeek Harness Hub
fan56/dsh-topics-memory
一个 dsh 插件:把「工作 topic 记忆」维护成 OKF 标准Open Knowledge Format…
相关插件 · 对话 / 记忆
上下文中枢oceanbase/powercontext
上下文跟着工作走 —— 跨会话、跨智能体、跨人。
★ 1,487已汉化DSH
73
智能体记忆库plastic-labs/honcho
Honcho 是记忆基础设施,用来构建有状态的智能体。这些智能体能理解不断变化的人、智能体、群组、项目和想法。
★ 7,894已汉化DSH
71.7
长程智能体控制面loopx-project/loopx
给 Agent 一个目标,让工作持续向前。
★ 6,358已汉化DSH
71.3
智能体上下文数据库volcengine/OpenViking
给 AI 智能体用的上下文数据库
★ 41,379已汉化DSH
71.3
长效机器人团队Fei2411/DS-Bot
DS Bot 是一个基于 DeepSeek Harness简称 dsh的 bot 插件,插件将 dsh 改造为 bot…
★ 5,084已汉化DSH
71.1
可携带记忆层EverMind-AI/EverOS
为什么选择 EverOS
★ 13,778已汉化DSH
71.1
这是你的仓库?认领条目