前言¶
在 DSH(DeepSeek Harness)裏用同一個工作區開多個會話時,上下文默認是斷的:新會話不知道上一手做到哪、卡在哪、下一步該接什麼。常見做法是手動複製粘貼一段說明,或靠記憶補全,既費事又容易漏關鍵信息。dsh-handoff 是社區維護的 DSH 插件,按工作區目錄維護一份交接文檔,會話結束自動壓成簡短摘要,同目錄開新會話時在運行時上下文裏讀回最近幾條。實現爲純插件、零第三方依賴、零外部程序,版本 0.1.0,MIT 許可證。
這是什麼¶
插件倉庫:wonderandyou/dsh-handoff,維護者 wonderandyou,在 SkillHub 插件目錄 分類爲「記憶」。一句話定位:每個工作區一份交接文檔,會話結束自動寫簡短摘要,同一工作區開新會話自動讀回。
核心行爲¶
下面按觸發時機說明插件在做什麼。
| 時機 | 做什麼 |
|---|---|
一輪結束(turn/end) |
等防抖窗口(默認 15 秒),把這一段會話壓成一條「標題 / 做了什麼 / 結果 / 下次接手」寫進該工作區的文檔 |
會話銷燬(agent/disposed) |
不等防抖,立刻把沒落盤的內容寫掉 |
| 新會話開頭 | 掛一段注入:讀該工作區最近 N 條交接塞進運行時上下文,默認只注入一次 |
工具 handoff |
支持 list / read / append / clear / status / flush |
| 設置頁「交接」 | 列出所有工作區(無記錄標「暫無記錄」)、切換查看條目、清空 |
同一工作區、同一會話只佔一條記錄:會話變長是更新該條,不是追加,避免長會話把文檔刷滿。
注入只在會話開頭來一次¶
默認 injectOnce: true:交接文本只在該會話的第一次模型請求裏出現,之後每步返回空。原因是 systemPrompt.context 每步都會重新組裝;若每步都塞長文本,多步對話會重複佔用上下文,而歷史消息裏已保留首次注入內容。
默認 injectChars: 10000(約 3100 token)、injectEntries: 20。裝不下時會截斷並提示還有幾條未列出。若需要每步都注入,可設 injectOnce: false,並把 injectChars 調到約 1200。
工作區如何識別¶
按順序嘗試,前一條不行才走下一條:
- DSH 工作區賬本
~/.dsh/storages/workspace.json中sessionIds命中(只讀,不改寫) - 會話
cwd與工作區path相同 - 用
cwd本身作爲工作區(未登記目錄也可用)
數據存放位置¶
默認目錄爲 ~/.dsh/handoff(可通過配置 dir 修改):
~/.dsh/handoff/
├── index.json 工作區索引(面板用)
├── stats.json 當日總結次數(預算用)
└── workspaces/
├── 插件-3f2a91cd.json 條目數組(真相源)
└── 插件-3f2a91cd.md 渲染版,便於人工閱讀
文件名形如 <目錄名>-<路徑哈希 8 位>,按規範路徑識別;工作區刪了再加回,或未登記,交接文件仍可保留。
配置¶
全部在 cordis.patch.yml 中設置,省略項用默認值:
| 鍵 | 默認 | 說明 |
|---|---|---|
enabled |
true |
總開關 |
dir |
"" |
數據目錄;空則 ~/.dsh/handoff |
workspaceFile |
"" |
工作區賬本路徑;空則 ~/.dsh/storages/workspace.json |
injectOrder |
320 |
交接段在運行時上下文中的排序 |
injectOnce |
true |
每會話只注入一次 |
injectEntries |
20 |
新會話最多讀回條數 |
injectChars |
10000 |
讀回字符預算 |
maxEntries |
40 |
每工作區最多保留條數 |
autoWrite |
true |
會話結束是否自動寫 |
minGapMs |
90000 |
兩次總結最小間隔 |
debounceMs |
15000 |
一輪結束後等待再總結 |
maxPerDay |
120 |
每天最多總結次數,0 爲不限 |
summarizeModel |
"" |
指定模型;空則自動選較便宜的 flash / mini / lite |
summarizeProvider |
"" |
指定 provider;空則優先官方通道 |
總結失敗時(模型不可用、返回非 JSON、拿不到 llm 服務)會回退爲「最初需求 + 最後進展」的規則摘要,不會留空條。注入組裝失敗則返回空,避免拖垮整次模型請求。
安裝與啓用¶
官方 README 未給出 dsh plugin add 一類命令,安裝方式是寫入 profile 並鏈接本地包,改完後重啓 DSH。
- 在
~/.dsh/profiles/desktop/package.json的dependencies增加:
"dsh-handoff": "link:<你的路徑>/dsh-handoff"
-
同文件
dsh.profile.bundles增加"dsh-handoff"。 -
在
node_modules/dsh-handoff建立 junction 指向插件目錄(Windows 示例:New-Item -ItemType Junction)。
DSH 生態是「一切皆插件」;SkillHub 等爲社區目錄站點,與 DeepSeek / 幻方無官方從屬關係。安裝前建議閱讀倉庫源碼與 MIT 許可證:插件以當前 DSH 進程權限讀寫 ~/.dsh/handoff 與會話相關數據。
典型用法¶
工具 handoff¶
在會話中通過 DSH 暴露的 handoff 工具手動 list、read、append、clear、status、flush,與自動寫入互補。
把歷史會話補進交接¶
插件從安裝時刻起才自動記錄。可用本機回填腳本(只讀會話緩存,不聯網):
node _backfill.mjs --dry # 預覽將寫入內容
node _backfill.mjs # 每工作區補最近 4 個會話
node _backfill.mjs --per=8 # 每工作區多補幾條
node _backfill.mjs --all # 含未登記在工作區列表的目錄
歷史條目只能還原標題和開場需求,結果標爲「未判斷」。
預覽新會話會看到什麼¶
不啓動 DSH、不改文檔,用真實交接數據打印注入文本與長度:
node _preview_inject.mjs # 當前目錄
node _preview_inject.mjs D:\軟件 # 指定工作區路徑
輸出包含注入長度、估算 token、條數列表,以及第二次取文本應爲 0 字符(驗證只注入一次)。
自測¶
倉庫內可在無 DSH 進程下跑斷言(假 ctx、假 llm、假賬本):
node _selftest.mjs # host 側,71 項斷言
node _selftest_client.mjs # 設置頁側,23 項斷言
適用場景與注意¶
適合在同一項目目錄下頻繁開新會話、需要延續「做到哪 / 下次接哪」的開發者。自動總結會調用 LLM,受 minGapMs、maxPerDay、debounceMs 等限制,避免連續對話反覆總結。
插件紀律(README 原文要點):只讀會話事件,不向會話日誌 append;同一會話讀回時會排除剛寫入的那條,避免循環注入。
結尾¶
dsh-handoff 把交接綁在工作區目錄上,用結束時的摘要和新會話開頭的一次性注入,減輕換會話時的上下文斷裂。目錄頁:https://www.skillhub.cn/plugins/wonderandyou/dsh-handoff;源碼與完整說明:https://github.com/wonderandyou/dsh-handoff。