前言¶
在 DeepSeek Harness(DSH)裏,若啓用了 @deepseek-ai/dsh-fs-observation-policy,文件版本只來自受 instrumentation 的讀寫操作(會發出 fs/observed)。dsh-tool-bash、dsh-shell、dsh-subprocess-local 等工具不會上報這類事件;DSH 文檔也寫明:只有受 instrumentation 的文件系統操作會在這裏報告,操作系統層面不會被監視。
因此,智能體用 bash 或 shell 改動了它之前「觀測過」的文件後,內存裏的觀測版本會滯後;緊接着再用 DSH 自帶的 edit 改同一文件,常會收到 FS_STALE_VERSION——錯誤來自本會話自己的 shell 寫入,而不是外部進程。關掉觀測策略可以消除這類報錯,但第三方改寫文件時也會失去保護,最壞情況是靜默數據丟失。
下面介紹社區插件 dsh-fs-reobserve(維護者 lucagiftzek,npm 包 @lucagiftzek/dsh-fs-reobserve,當前版本 1.0.0,MIT 許可證)。它在「嚴格策略」與「完全關閉」之間補一層:僅在本會話自己的 bash/shell 調用結束後,重新 stat 本會話曾觀測過的路徑並再次發出 fs/observed;他人或外部進程造成的變更仍保持舊觀測,下一筆 edit 仍會正確觸發 FS_STALE_VERSION。
這是什麼¶
dsh-fs-reobserve 是 DSH 工作流類插件,定位爲 @deepseek-ai/dsh-fs-observation-policy 的補充中間方案:消除「自傷式」陳舊文件錯誤,同時保留對第三方寫入的 stale 檢測,並繼續強制執行「先 read 再 edit」相關的 FS_NOT_OBSERVED 約束。
背景:三種取捨¶
README 用表格對比三種模式,核心差異如下。
| 行爲 | 嚴格策略 | dsh-fs-reobserve | 關閉策略 |
|---|---|---|---|
| 本會話 bash 寫入導致的 stale | 會報錯 | 不再誤報 | 不報錯 |
| 第三方寫入導致的 stale | 會報錯(正確) | 會報錯(正確) | 被壓制(不安全) |
FS_NOT_OBSERVED |
強制 | 強制 | 不強制 |
| 最壞失敗 | 浪費一次調用 | 浪費一次調用 | 靜默數據丟失 |
插件不會爲未發生的變更重新觀測:cron、其他智能體或桌面編輯器改寫的文件仍保留舊觀測,智能體仍需 re-read,這是刻意保留的保護。
核心功能¶
在本會話的一次 bash 或 shell(可配置)調用 settle 之後,插件對該會話曾觀測過的目標重新 stat,並通過 ctx.fs.stat 作爲唯一合法來源再次發出 fs/observed,覆蓋三種狀態遷移:
- 存在 → 存在(新版本):命令重寫了文件。
- 存在 → 不存在:命令刪除了文件。
- 不存在 → 存在:命令創建了此前 read 已確認不存在的文件。
版本號不會被憑空製造。默認監聽的工具爲 bash 與 shell;可選在工具結果上附加說明(notify),便於智能體知道發生了 re-observe。
安裝與啓用¶
需要 Node 22.5 及以上,以及自帶 @deepseek-ai/dsh-fs-observation-policy 的 DSH 構建(README 寫明在 DSH 0.1.5 與 0.2.1 上使用)。包聲明瞭 dsh.bundle,dsh plugin add 會寫入 dsh.profile.bundles 並由插件自帶的 patch 插入 fs-reobserve 條目,不要再手工添加重複的 insert 行。
官方安裝方式:
dsh plugin --profile web add @lucagiftzek/dsh-fs-reobserve
# or from GitHub: dsh plugin --profile web add github:lucagiftzek/dsh-fs-reobserve
# then restart `dsh web`; the log shows "fs-reobserve: armed ..." once
本地 checkout 也可用 link 方式安裝:
dsh plugin --profile web add link:/absolute/path/to/dsh-fs-reobserve
安裝後重啓 dsh web;日誌中出現一次 fs-reobserve: armed ... 表示已就緒。
配置¶
選項從插件 loader 條目讀取(profile 的 cordis.patch.yml 裏 fs-reobserve 那一行),不會讀取 settings.yaml 段。示例見倉庫 docs/TROUBLESHOOTING.md。
| 鍵 | 默認值 | 含義 |
|---|---|---|
tools |
[bash, shell] |
需要在其結束後觸發 re-observe 的工具 |
notify |
true |
是否在工具結果上附加說明 |
maxNotifyPaths |
4 |
說明中列出的路徑數量上限,超出則省略 |
臨時關閉而不卸載:在 ~/.dsh/profiles/web/cordis.patch.yml 增加:
- id: fs-reobserve
disabled: true
典型用法與排錯¶
日常用法即:在 web profile 安裝插件並重啓 DSH web,繼續讓智能體用 bash/shell 改文件後再用 instrumentation 的 edit;自傷式 FS_STALE_VERSION 應消失,外部改寫仍應觸發 stale。
出問題時:
- 可將倉庫中的
skills/fs-reobserve-doctor複製到~/.dsh/skills/(該版本不會自動註冊該 skill),再讓智能體加載fs-reobserve-doctorskill。 - 按症狀查閱 docs/TROUBLESHOOTING.md。
- 錯誤碼與日誌行見 docs/ERRORS.md。
包內測試:npm test(node --test test/*.test.mjs)。
適用場景與注意¶
適合在 web profile 下長期啓用文件觀測策略、且智能體頻繁通過 shell 改工作區文件的開發流程。不適合期望「關閉所有 stale 檢測」或「對外部改寫也自動刷新觀測」的場景——後者與安全模型相悖。
插件與 DSH 進程同權限運行;安裝前請自行查看 GitHub 倉庫 源碼與 MIT 許可證。DSH 生態強調「一切皆插件」;社區目錄 skillhub.cn 爲獨立站點,與 DeepSeek / 幻方無官方從屬關係。
結尾¶
dsh-fs-reobserve 把「本會話 shell 寫入」與「他人改寫」區分開:前者在命令結束後自動刷新觀測,後者仍迫使 re-read。需要安裝命令、配置與排錯細節時,可看目錄頁 skillhub.cn/plugins/lucagiftzek/dsh-fs-reobserve 與 GitHub github.com/lucagiftzek/dsh-fs-reobserve。