DeepSeek 開源的 Super-agent 原型:源碼級拆解
定位聲明:本文分析對象是研究原型(research code),不是可上線產品。官方自述「Research prototype for reference only, not an official DeepSeek product」(README.md:3)。
2026-10-31,DeepSeek Harness(DSH)團隊配合《Super-agent 設計探索》長文(原文)放出倉庫 dsh-superagent-prototype:MIT 授權、TypeScript、全倉僅一個提交(6337fc8,建立 09:32 UTC、最後推送同日 12:05 UTC),首日 1,515 stars、113 forks。配套文章講理念,這個倉庫講落地——文章裡部分設計明確標注「未在此原型實作」(README.md:5),哪些真的寫成了代碼,只有讀源碼才知道。以下是逐檔讀完後的工程結論。
一、為什麼值得看:不是 demo,是可運行的插件
多數「配套開源」是截取文章一節做的玩具。這個倉庫不同:它是打包成 DSH bundle 的插件,宿主按 cordis.patch.yml 把三個插件——主插件、github-watch、feishu-watch——插入 DSH profile(package.json:30);並導出 github-watch 與 feishu-watch 兩個 Source 插件入口(package.json:17-18)。入口走 Cordis 插件協議(Cordis 是 DSH 的 everything-is-a-plugin 基座,cordiverse/cordis):src/index.ts:5-7 聲明插件名與 inject 陣列,共 11 項宿主服務注入;"private": true(package.json:6)說明它無意做獨立 npm 產品,就是給 DSH 宿主用的。
它有完整的領域模型、事務化狀態機、持久化、測試與管理面板。文章裡的 Router/Worker、事件驅動、Inline/Spill,哪些落了地、哪些只是設想,代碼裡都對得出答案。
二、它解決什麼問題:單倉主動式編碼代理
官方定位一句話:「a proactive coding agent for one GitHub repository」(README.md:7)。流程是:監聽 GitHub(可選飛書)→ 經 Policy 閘門與模型評估,把獲授權請求變成 Ticket → 每張 Ticket 在獨立 DSH Session 與工作目錄中執行 → 回到原對話交付(例如 PR)→ Web 面板顯示哪裡需要人。
痛點是真實的:編碼代理已能獨立完成單任務,瓶頸轉移到人的注意力——誰盯 issue、評論、CI 紅燈,誰把任務搬進代理。這個原型把「監聽—評估—執行—回覆」閉環化,人只在兩個時刻出現:授權與驗收。設計哲學寫在 docs/000-philosophy.md:「Take as little human attention as possible, and give as much value as possible.」代碼確實服務這句話:主 Session 被設計成「不等待」,一切到來皆為消息,guard 正則攔截 sleep、拒絕超過 30 秒的阻塞調用(src/app/sessions.ts:64-66、70-82)。
三、架構拆解:寄生在 DSH 上的三插件組合
先說清它不是獨立框架。運行時直接依賴只有兩個:proper-lockfile 4.1.2 與 zod 4.4.3,另有 23 個 @deepseek-ai/* peer 依賴,並鎖定宿主 dsh ^0.2.1-alpha.2(package.json:53-56)。分層是全倉最乾淨的部分:src/core/(16 檔)是純領域模型,Engine 是 Trigger/Thread/Decision/Ticket/Assignment 的唯一寫入者,全部方法同步、每命令一事務(src/core/engine.ts:47),零 I/O、不 import core 以外的東西;src/app/(44 檔)是組合根與膠水;src/sources/(18 檔)是 Source 抽象與 GitHub、飛書兩個實作;src/client/(26 檔)是注入 DSH sidebar 的 React 面板。核心還給每類調用者暴露角色視圖:engine.ts:261-269 用五個 EngineFor* Pick 型把接口裁到「你只需要看的部分」。
角色約束寫在 bundle 補丁裡:worker preset 是 DSH standard 的裁剪版,worker 工具白名單 21 項(src/app/sessions.ts:60-62);router preset 反向收緊——tool-fs 配 write: false, edit: false 唯讀、禁子代理(cordis.patch.yml:125),理由很直接:評估者一動手寫碼,路由就成了執行。通訊也收口:回覆統一 100 詞硬上限、purpose 由工具強制(prompts/replies.md),prompts/ 全部「每行一句」由 promptFile 拼裝(docs/004-prompts.md),且每次保存成不可變版本,Session 綁定當前 revision(src/app/sessions.ts:148-157)——提示詞是可審計的配置,不是散落的字符串。
(圖 1 建議 designer 重繪為正式架構圖:三插件 → Engine → Executor → Worker → Outbox 回源,旁註 11 項注入。)
四、代碼亮點:狀態、隔離、節拍
狀態存儲與原子落盤。 全部狀態進單一 SQLite(<stateDir>/orchestrator.sqlite,9 張表:trigger/disposition/trigger_thread/thread/ticket/decision/effect/outbox/kv,docs/007-architecture.md「Persistence」段)。啟動時 Runtime 先用 proper-lockfile 鎖住 stateDir 再開庫(src/app/runtime.ts:59),杜絕雙進程同寫。副作用全部走持久 effect 隊列:事務內 enqueue、commit 之後才執行(src/app/effects.ts:46),六種 kind(assessment/launch/delivery/relay/notice/reply)帶指數退避——「做了」與「發出去了」被拆成兩個可恢復階段,這是 agent 系統最常被忽略的一課。schema 帶 11 次數據遷移,拒絕更舊版本(src/app/migration.ts)。
任務隔離。 每張 Ticket 生成一個 worker-<ticketId> Session 與獨立 worktree 目錄(src/executor/dsh.ts:24);併發由 WorkerSlots 按 executor.maxWorkers 封頂,人類 follow-up 可多佔一槽且優先於新任務(src/executor/dsh.ts:171);worker 的背景 shell 任務在 turn 結束後可續跑,上限 30 分鐘(src/executor/dsh.ts:37),超時 kill 並在下一 turn 告知。
節拍與面板。 後端每 2 秒一個 pass,推進到期 effect 與定時評估(src/app/passes.ts:28);GitHub 輪詢默認 60 秒、可調 60–3600 秒(src/sources/github.ts 的 pollSeconds schema)。面板是 26 個檔案的 React 應用,雙語(locale/zh.json 與 en.json),每頁都有對應測試(tests/panel-*.spec.tsx,共 10 個檔案)。
上下文注入:文章的 Inline/Spill 落地成「內聯卡+讀指針」。 assignment 內聯上限 1,500 字符、trigger 上限 600(src/executor/dsh.ts:113 的 ASSIGNMENT_CHARS = 1500, TRIGGER_CHARS = 600),超限截斷並附總長與 trigger/<id> 這類資源指針,按需再讀(docs/007-architecture.md:594)。文章中更激進的分層記憶 spill 並未實現——全倉 grep「spill」零命中,這是「文章 vs 代碼」差距的典型樣本。
(圖 2 建議 designer 繪為事件流泳道圖。)
五、工程完成度:以原型標準相當高
9 篇自洽編號文檔、59 個測試檔案(含 vitest 配置)與 6 個 fixtures、雙語面板、SQLite 遷移。最值得注意是三個「元測試」:tests/docs.spec.ts 強制文檔交叉引用只指向更早文檔且全部可解析;tests/class-docs.spec.ts 要求 src 內每個 class 都有 JSDoc;tests/model-surface.spec.ts 盯住模型可讀表面(工具/提示詞/技能)不漂移且在尺寸預算內。把「文檔與代碼同步」變成機械閘門,這一手值得所有團隊抄。
不成熟面同樣要列清楚:全倉僅 1 個提交、無 CHANGELOG、無 release;沒有 CI(倉內不存在 .github/,檢查靠手動 pnpm check);數據無清理機制——docs/007-architecture.md:484 明言 trigger、disposition、decision 等記錄「grow without bound」;文檔末尾還掛著兩個開放問題(Trigger 字段可信度、部署隔離)。
六、和誰比:三種物種,別硬比
(圖 3 建議 designer 繪為三欄對照卡。)
Dify 長在平台側,賣的是應用分發;LangGraph 這類編排框架賣的是流程表達能力。本原型是第三種物種:範圍刻意收窄到一個 GitHub 倉庫(Source 配置 hard-code 單一 owner/name,src/sources/github.ts),換來領域模型可以做深——Mandate 授權、訂閱扇出、事務化審計。拿它跟 Dify 比生態、跟編排框架比通用性,都不對題;它回答的問題是「一個倉庫的日常雜務,能不能少佔人的注意力」。
七、值得借鑒五點,不宜照搬三點
借鑒(按優先級):
- observe 灰度:主動候選先「只記錄會做什麼」不執行(docs/002 的 admission 表;prompts/admission.md「observe mode records the judgement only」),人審一段時間再切 auto。放開任何代理自主性之前都該有這一檔。
- 內聯卡+讀指針:所有跨會話輸入統一「≤N 字內聯+資源指針按需讀」(src/executor/dsh.ts:113),杜絕整檔貼進上下文。
- Mandate:授權記錄「憑什麼」:accept 必須附 intent_evidence 原文引證(prompts/admission.md);policy 變更時通知在跑的 ticket 而不是殺掉它(src/policy.ts:167 與 engine.policyChanged)。
- 持久 effect 隊列:對外動作一律入隊、合併、退避、每 kind 一個健康項(src/app/effects.ts:46)。
- 元測試護城河:文檔同步、JSDoc 覆蓋、模型表面無漂移全部機械化(tests/docs.spec.ts、class-docs.spec.ts、model-surface.spec.ts)。
不照搬:
- DSH alpha 生態綁定:23 個 peer 鎖 alpha 版,src/index.ts:17 的 TODO 就是為宿主行為打的兼容墊片——離開該生態,這套代碼基本歸零。
- 單進程 SQLite+數據無限增長:directory lock 加單一寫入者的假設只適合單機單倉(docs/007-architecture.md:484)。
- 「工具裁剪」當安全邊界:worker 權限是 danger-full-access(src/app/sessions.ts:152),隔離靠 21 項 WORK_TOOLS 白名單與 guard(src/app/sessions.ts:60-62),不是沙箱。移植其任務模型必須自帶沙箱層。
八、怎麼試:前置、風險、觀察點
前置條件(SETUP.md「Probe」段):Node.js 22.19+ 或 24+、pnpm、git 2.32+、tmux、Python 3.8+、GitHub CLI 2.48+、engines 區間內的 DSH(package.json:53-56)、模型 provider,以及一個專用 GitHub agent 賬號——SETUP.md 明言「never the operator's own」,代理寫下的一切都署這個名。服務由 250 行 Python 腳本管理(scripts/dsh-superagent),面板端口 3082,狀態目錄 ~/.dsh/state/superagent。依賴可得性已核實:@deepseek-ai/dsh-agent 在 npm 公開渠道含 0.2.1-alpha.2。
風險提示:alpha 依賴、官方自認 research code、無 CI、數據只增不清;飛書 Source 默認關閉(cordis.patch.yml:10-11),開箱只有 GitHub。觀察重點:先開 observe 模式跑一段時間,看 admission 決策日誌的誤報率,再考慮 auto;同時盯 worker 併發上限與 effect 隊列健康項。
九、結語:原型與產品的距離
距離不在功能面——從觸發到回覆的生命週期已經閉環——而在生態與治理:宿主還在 alpha、無 CI、無版本化發布、數據治理未做、兩個開放問題未決。它的真正價值是提供了「單倉主動式代理」的一份完整參考實現:五部件事務核、訂閱扇出、持久 effect 隊列、元測試閘門,這些都可以脫離 DSH 被重新實現。對工程師,讀它比裝它划算;等它的宿主生態長大,再考慮跑它。