deepseek-harness
deepseek-ai
DeepSeek Harness: Everything is a Plugin.
PROJECT TOPICS
INSTALL REFERENCE
dsh plugin --profile web add github:ltxlong/dsh-session-kit
该命令指向仓库当前默认分支;尚无绑定当前 commit 的完整验证结果。
PROJECT README
English | 中文
dsh-session-kit 是一个 DeepSeek Harness 插件,用于增强会话页的日常管理能力。它不修改 DSH 核心源码,而是通过官方扩展点为会话增加管理菜单、归档会话管理、任务管理与任务档案、运行时全局提示、运行时上下文压缩配置、轮次级删除/重新生成、本地记忆管理与召回,以及左右侧话题快捷导航。
dsh plugin --profile web add dsh-session-kit
dsh plugin --profile web add github:ltxlong/dsh-session-kit
如果更新了dsh版本0.1.5导致出现会话加载失败报错,比如:历史加载失败 @deepseek-ai/dsh-session-format-v0-to-v1 refuses this format v0 Session, 解决方法是:“会话管理”->“修复会话”-> 点击“修复”按钮即可修复当前会话
插件会在会话页头部增加 会话管理 按钮,菜单包含:
任务管理用于记录任务从识别到完成的全过程,包括子任务、工具操作、文件观察、踩坑和涉及会话。数据与记忆共用同一个本地 SQLite 文件(默认 <profile>/.dsh-session-kit/memory.sqlite,随记忆存储目录设置一同变更)。
任务状态与回收站生命周期是两个维度。任务状态共有 5 种:
| 状态 | 含义 |
|---|---|
not_started |
未开始 |
active |
进行中 |
paused |
已暂停 |
completed |
已完成 |
abandoned |
已放弃 |
回收站不是一种任务状态,而由 deleted_at 标记。回收站任务不会计入“全部”页签的列表、统计圆环或自动提示。
todo/write、tool/call、tool/result、turn/end 和文件观察事件。todo/write 会自动创建任务,并根据会话工作目录记录项目名。completed;paused 和 abandoned 等人工状态不会被自动覆盖。每轮开始前,插件最多为当前会话提示两个已经参与过的 active 任务。自动提示只包含任务名、项目、进度和已知踩坑等摘要,不会自动把完整任务档案塞入上下文。
当模型判断当前需求确实属于某个任务时,可以调用 task_inject;用户也可以在任务管理卡片上点击“注入当前会话”。完整档案会以插件来源的用户消息加入当前会话,并建立该任务与会话的关联。重复注入会重新建立当前任务归属,后续事件会同步到最近注入的任务。
普通删除会把任务移入回收站,而不是立即抹除任务档案。子任务、操作记录和踩坑仍会保留:
active 的任务时会变为 paused,避免恢复后自动继续;其他状态保持不变;会话管理 → 全局提示 会打开“全局提示词设置”弹窗:
ctx.systemPrompt.section() 把提示词注册到运行时系统提示词组装中;system-prompt 配置;归档弹窗用于管理已经归档、也就是从侧边栏隐藏的会话:
删除会话时,Windows/macOS 会尽量移动到系统回收站/废纸篓;没有系统回收站集成的平台会直接删除会话目录。正在运行的归档会话不会被删除。
插件会在已完成的顶层助手轮次旁,以及部分失败轮次尾部增加操作:
安全策略:
dsh-turns-del / tombstone。sessions.flush()。每个会话页右侧会显示类似 chat.deepseek.com 的 话题 导航:
侧边栏 记忆 按钮打开“记忆管理”弹窗。记忆数据全部存储在本地 SQLite 库(WAL 模式),不依赖任何外部服务;核心逻辑位于 lib/memory.js。默认位置为 <profile>/.dsh-session-kit/memory.sqlite,可在设置页切换为任意绝对路径的自定义目录(写入存储域配置,切换后需重启生效)。
default 项目(不可改名/删除);每个项目可配置自动启用的会话 ID 列表。active 参与召回 / inactive 仅存档);正文归一化后计算 SHA-256 作为唯一键,天然防止重复写入;pinned 标记表示固定召回。customTag 权重的来源。位置/对象 推导出的记忆间关联(倒排键表加速查找),供 memory_relate 查询。记忆有三条独立入口,最终写入持久库或进入内存中的临时记忆池:
1. 工具写入(Agent 调用) — LLM 通过 memory_add / memory_update 工具写入:
{accepted: true},实际写库在后台任务队列中 FIFO 执行——工具结果先送达模型,写库失败不会打断对话流,只记录警告与活动日志(可在记忆管理弹窗日志页查看);default;update 改写既有记忆(自动留存修订)、skip 判定语义等价不新增、add 走新增;裁决失败或无候选时回落到新增,并把「未生效」的原因写入活动日志,便于事后排查为何这次新增没做去重;2. UI 手动写入 — 记忆管理弹窗内的创建、编辑、删除、跨项目移动同步执行并记录活动日志;“临时记忆 → 存储”转正操作会把临时条目写入持久库并移出临时池。
3. 蒸馏写入(自动) — 每轮对话正常结束(turn/end 且原因为 completed)且自动蒸馏开启时触发,按会话串行排队执行:
{"位置":\[…],"对象":\[…],"内容":"…","踩坑":"…","tags":\[…]};也接受 paths / symbols / content / pitfall / tags 英文 key。标签按两段式生成(先 1~2 个描述性标签,再映射到稳定标签),程序只做清洗与分档,不覆盖模型结果;active 状态创建;与持久库或临时池内容重复的自动合并(临时池内同文条目改为刷新时间与来源轮次,不新增);召回挂载在每轮请求前(agent/pre-step),以本轮用户输入为查询自动执行,总预算 30s。默认最多 20 条;也可以选择“临时记忆不参与召回”(最多 15 条)或自定义 8-20 条。自定义时段1为 3-5 条、段2为 0-5 条、段3为 0-5 条,段4动态等于总数减去前3段且至少 3 条;当总数不超过15条时段2强制为0,当总数不超过10条时段3强制为0;四段配额之和等于最多召回数量。
预处理
候选收集
四段式选拔
候选按标签划分为底色池(含任一第一档稳定标签:用户偏好、用户画像、项目画像、项目架构、项目约束、模块路径)与普通池,然后四段各自竞争选拔:
| 段 | 席位 | 成员 | 排序与准入门槛 |
|---|---|---|---|
| 段1 底色 | 默认 5;自定义 3~5 | 底色池 | RRF 排序(词法 + 向量 + 标签三路);准入沿用「相关性三选一」,名额不足按标签优先级补足。只施加向量守门,不施加 BM25 门槛——段1 是身份保底通道,成员多为与查询无关的身份记忆,BM25 天然偏低,加词法门槛会把身份保底误杀 |
| 段2 临时 | 默认 5;排除临时为 0;自定义 0~5 | 临时记忆池 | 保留 v9 加法矩阵(BM25 + 自定义标签 + 画像标签)。临时记忆不落库、无向量、标签恒为预设标签,三路中只剩词法一路,RRF 会退化为词法排序、与原矩阵等价,故不纳入 |
| 段3 混合 | 默认 5;自定义 0~5 | 底色剩余 + 普通池 | RRF 排序;准入门槛 = BM25 ≥ 6 且 余弦 ≥ 0.30(两道都需通过) |
| 段4 兜底 | 动态计算,至少 3 | 普通池剩余永久记忆 | RRF 排序;准入门槛同段3;候选不足时自然吸收前三段缺口 |
段3/段4 的两道准入门槛(v10 新增,此前这两段只做池内竞争、无任何门槛,导致弱匹配候选照样占席位):
bm25Weight ≥ 6(0~8 刻度上的「强匹配」线)。只作用于确有 FTS 信息的行,无 FTS 命中的行交由向量守门判定;≥ 0.30。候选必须同时通过两道门槛才允许占用段3/段4 席位;RRF(Reciprocal Rank Fusion)把三路名单按名次融合,只吃名次、不吃分数,因此不需要在不同量纲之间手工配权:
k = 10:RRF 按 1/(k + 名次) 累加各路名次分,因此 k 只调节「名次优势的强度」(k 越小、头部名次越占优;k 越大、名次差异越被压平),不改变任何一路内部的排序;各段用到的分量含义:
段2 是不可见上下文补偿通道:本会话近期轮次的蒸馏产物因尚未出窗而不入选(避免与对话历史重复),只有跨会话临时记忆、以及本会话中已被上下文压缩吞掉的轮次产出的临时记忆才准入——后者以最后一条压缩事件的序号为边界判定。打包阶段在字符预算内放不下的条目跳过继续(保序),超长记忆截断并标注。
固定召回
每条永久记忆都有“固定注入”开关,打开后,只要该记忆所属项目被会话启用,则保证该记忆能够被固定召回。固定记忆本身也是普通记忆:它照常参与四段竞争、不额外挤占席位,只在四段筛选之后补入那些未命中任何取数通道的固定记忆。代价是最终注入总量可能超过召回条数设置(该上限约束的是四段筛选规模,不是最终条数)。固定记忆排在最前,便于模型优先读到。
注入格式
命中结果组装为一条插件来源的用户消息,插在本轮用户消息之前:编号列表(目录/标签/更新日期 + 正文),头部声明“与用户最新消息冲突时以用户消息为准”,固定召回条目额外带【固定召回】标记。注入同时把命中快照(与正文 1:1)随会话事件持久化,供每轮消息旁的记忆面板跨重启回看。
每条结构化记忆的 内容/content 字段注入限制 500 字符;位置、对象、踩坑和未知字段完整保留。超限时截断 content 并追加「该记忆已截断 · id: … · 调用 memory_read 工具可查看全文」提示。
除自动召回外,还可以在记忆管理弹窗里手动把某条记忆注入当前会话(走独立的 source 类型,不参与召回与剔除流程),用于临时把某条记忆摆到模型眼前。
已注入上下文的记忆不会永久占位。每轮正常召回后执行 top-k 语义的 diff 剔除:
插件为 Agent 注册 7 个记忆工具:
| 工具 | 用途 | 要点 |
|---|---|---|
memory_add |
新增长期记忆 | 后台写入;写入前做冲突裁决与哈希查重;仅在用户明确要求记住或信息明显需要长期保留时使用 |
memory_update |
更新正文/标签/状态/项目 | 后台写入;可调整固定召回标记,改写正文自动留存修订 |
memory_stop |
停用记忆 | 状态改为 inactive,不参与召回但保留在库 |
memory_read |
阅读记忆 | 读取一条记忆的全文 |
memory_search |
主动检索记忆库 | 支持从查询解析时间表达(今天/昨天/前天/最近 N 天/本周/上周/本月/上月/具体日期),可按项目/标签/状态过滤,默认 10 条上限 50;结果按关系边聚成同源簇渲染 |
memory_relate |
查询记忆间的结构关联 | 从一条记忆出发,沿共享的文件路径/符号找到相关记忆(默认 1 跳、最多 2 跳),入参给 memoryId 或 query 二选一;与 memory_search 互补——search 按内容词面匹配,relate 按共享文件或符号精确匹配 |
conversation_search |
跨会话搜索历史对话 | 扫描内存会话与持久化会话日志,按行词法打分;默认排除子代理会话 |
同一轮内相同参数的 memory_search / conversation_search 重复调用会被直接拦截,并提示模型使用上一次结果。
memory_relate 明确降级提示稍后重试。共享标签的边默认关闭(标签边数量远超结构边,会淹没后者),可在设置中开启。lib/index.js:Host 路由、全局提示运行时注册、归档/会话操作、轮次删除与重新生成逻辑。lib/client.js:Web UI Slot、全局提示弹窗、其他弹窗、话题导航、轮次操作、样式与 locale 字典。lib/memory.js:本地记忆库(SQLite)、jieba/二元组分词召回、蒸馏与后台索引重建逻辑。lib/task.js:任务档案采集、状态同步、任务工具、自动提示、注入、提取与回收站路由。cordis.patch.yml:插件 bundle 插入 patch。README.md / README.en.md:中文与英文说明文档。systemPrompt.section() 注册,压缩阈值配置也不写入官方或用户 Agent preset 文件,卸载/关闭插件后 DSH 会回到原本的系统提示词与压缩配置。<profile>/.dsh-session-kit/memory.sqlite,可在设置页改为自定义目录);删除项目或记忆不可恢复(改写正文会留存修订,删除记忆不会),卸载插件不会自动删除记忆库文件。CLASSIFICATION EVIDENCE
系统优先读取 GitHub Topics,再与站内分类词典和词根规则比对。当前命中: 无有效分类标签。