作者注:拆解 DeepSeek Harness《超級 Agent 設計》中的全雙工、記憶、憑據三個設計問題,說明哪些做法現在就能借鑑、哪些仍是“開放問題”,並給出接口契約與落地清單。
一個長時間運行的 Agent 往往會同時卡在三件事上。跑測試的 6 分鐘裏,用戶的新問題只能排隊;昨天的上下文被今天的事件擠出窗口;調試時它順手打開了 .env,密鑰就進了對話記錄。2026-11-01,DeepSeek Harness 團隊發佈設計長文 “Exploring Super-agent Design”,把這三個問題分別概括爲 全雙工(full-duplex)、記憶(Chain of Recall)和“使用憑據但看不到憑據”。
這不是一篇產品發佈解讀。原文描述的是一套架構,不是可以直接打開的開關:全雙工已在 DeepSeek Harness 中實現但默認關閉,部分內容放在原型插件 dsh-superagent-prototype 裏,作者明確說明它“不是 DeepSeek 官方產品”。長期記憶和憑據問題,原文也列在開放問題裏。
核心價值:讀完本文,你會知道這三個設計問題裏哪些可以照搬,每一項背後的 API 需要滿足哪些契約,以及在自己的 Agent 項目裏先做哪一步。

DeepSeek Harness 超級 Agent 設計核心要點
先用一張表看清三個問題在原文裏的定位,以及哪些現在就能借鑑。
| 設計問題 | 原文的核心思路 | 原文狀態 | 可直接借鑑的部分 |
|---|---|---|---|
| 全雙工 | 把阻塞的 run() 拆成 start() 和 stop(),Agent 在工作期間仍能接收指令 |
已實現但默認關閉 | 異步工具契約、事件回注、批處理 |
| 記憶 | 上下文只放穩定 ID、短摘要和鄰近消息,其餘內容溢出並留指針,靠 ID 鏈接多跳召回 | 長期記憶列爲開放問題 | 穩定 ID、inline/spill、按 ID 精確取回 |
| 憑據 | Agent 應該能使用憑據,但憑據不進入它的上下文 | 列爲開放問題 | 名字進上下文、值留在外部的一組工程模式 |
DeepSeek Harness 超級 Agent 的整體架構
原文裏的超級 Agent 由 Router 和 Worker 組成。Router 是常駐的調度入口,同時監聽聊天、GitHub、CI 等來源的事件;Worker 是隔離的 Agent 會話,一個 Worker 只處理一個任務。每條進入系統的事件叫 Trigger,同一個 PR、同一個 IM 話題或同一封郵件鏈上的一串相關事件歸爲一個 Thread。
這套架構還有一個部署上的特點:Agent 循環跑在雲端,用戶自己的執行環境留在本機,由一個小型守護進程負責對接,憑據也跟着環境留在本地。三個設計問題都建立在這個前提上。理解了 Router、Worker、Trigger、Thread 這四個概念,後面的全雙工和記憶設計就比較好讀了。

如何借鑑 DeepSeek Harness 全雙工設計
全雙工要解決的是“一個慢工具凍結整個 Agent”。傳統做法是調用工具後同步等待,一次 200 ms 的查詢無所謂,一次 6 分鐘的測試運行就會帶來三個問題:後續請求的延遲層層疊加;用戶中途說“跳過 e2e 測試”時 Agent 聽不到;網關會斷開長時間掛起的連接,工作明明成功了,調用卻報超時。
原文把理想狀態稱爲“productive”,也就是上一條指令還沒完成,Agent 已經能接下一條。實現方式是把一個阻塞的 run() 拆成一組小契約:start() 立刻返回任務句柄,status() 彙報進度,stop() 發起取消,結果在之後以事件形式回到對話中。區別在於由誰等待:用 run() 時是模型在等,用 start() 時是運行時在等。
DeepSeek Harness 全雙工的異步工具契約
落到工具定義上,每個長耗時能力對外提供三個工具,而不是一個。以測試爲例,start_test_run 只返回 job_id 和 queued 狀態,不返回任何業務數據;get_job_status 返回 queued、running、done、failed 之一和一句進度說明;stop_job 發起取消,並返回實際到達的狀態。
有兩條規則能避免模型行爲跑偏。第一,工具描述裏要寫明“不要等待結果”,否則模型會頻繁輪詢 get_job_status。第二,start 永遠不返回數據,否則模型需要猜這次拿到的是哪種結構。工具背後的任務 API 可以參考下表設計,RFC 9110 對 202 Accepted 的定義正好是“請求已接受處理,但處理尚未完成”。
| 調用 | 響應 | 對應的工具 |
|---|---|---|
POST /jobs(帶 Idempotency-Key 請求頭) |
202,返回 job_id 和 queued 狀態,Location 指向 /jobs/{id} |
start |
GET /jobs/{id} |
200,返回 queued / running / done / failed | status、任務監聽器 |
GET /jobs/{id}/result |
完成時 200 返回結果,未完成時 409 | 結果獲取工具 |
DELETE /jobs/{id} |
202 表示取消請求已受理,之後再調用返回 404 或 409 | stop |
| 可選回調 URL | 任務完成時向調用方 POST | 任務監聽器 |
DeepSeek Harness 全雙工的結果回注與批處理
輪詢只是兜底方案。更好的設計是由運行時監聽任務,完成後往對話裏推一條簡短的完成事件,內容包括 job_id、狀態和一行摘要,例如“412 通過,3 失敗”。完整日誌放在結果獲取工具後面,這樣四萬行的日誌不會直接進入上下文。
原文還描述了 Router 的批處理:一輪生成期間到達的 Trigger 先排隊,合併進下一次模型調用。這類調用輸入長、輸出短,大部分開銷落在 prefill 階段。原文實驗中,Trigger 頻率從每分鐘 1 個提高到 40 個時,平均批大小從 1.0 升到 2.8,單次決策耗時從 6.4 s 降到 1.6 s。這是原文自己的測試數據,不是通用基準,但思路可以直接用:模型生成期間,事件和用戶消息先排隊,本輪結束後按到達順序一起送入。
排序、取消與冪等的工程細節
這幾處細節在原型階段最容易被忽略,上線後又最容易出事故:
- 排序:任務完成順序不固定。B 依賴 A 時要顯式表達依賴關係,要麼等 A 的完成事件到達後再啓動 B,要麼讓 API 支持
depends_on。 - 取消:
stop只是請求,不能保證一定生效。要返回真實的結束狀態,如果任務在取消前已經完成,應如實返回done,讓模型照實轉告用戶。 - 冪等鍵:模型會重試,響應丟失可能觸發第二次
start。每次start都要求帶idempotency_key,重複的鍵返回已存在的任務,否則一句“執行遷移”可能被執行兩次。 - 部分結果與超時:通過帶遊標的結果接口提供早期輸出;每個任務都設截止時間,超時後發出
job_timed_out事件。
如果你的工具走 MCP,可以關注 MCP 規範 2026-07-28 版本中的可選擴展 Tasks。服務端可以用帶 taskId 的結果響應工具調用,客戶端通過 tasks/get 輪詢,或者監聽 notifications/tasks,用 tasks/cancel 發起取消。這個擴展需要客戶端和服務端都主動啓用,各宿主的支持程度也不一樣,使用前要先確認。
什麼時候不必用異步:調用一兩秒內就能返回、下一步必須拿到結果才能開始、或者背後沒有真正的任務 API。如果工具內部其實是阻塞的,對外包裝成異步只會增加複雜度。比較實用的劃分是:讀操作保持阻塞,耗時較長的寫操作和計算改成異步。
如何借鑑 DeepSeek Harness 記憶設計:Chain of Recall
長時間運行的 Agent 遲早會撞上上下文上限,因爲新的工作一直在進來。常見的三種應對各有代價:全部保留,窗口會滿,成本隨輪次上漲;滾動摘要,會丟掉之後需要的具體報錯或 PR 編號;按相似度檢索,一旦需要的事實和查詢語句字面上不像,就找不到。
原文的思路是把上下文當作緩存,只做兩種操作。Inline 放 Agent 眼下最可能用到的內容,包括 ID、短摘要和鄰近消息。Spill 處理其餘內容,截斷後留一個指針,之後需要時按指針取回。被溢出的內容並沒有刪除,只是在 prompt 裏只剩指針。比如一條 CI 失敗事件,上下文裏只留“PR #412 的 CI 失敗,payments 目錄下 118 個測試中 3 個變紅”這樣一行摘要,41 KB 的完整日誌只保留取回路徑。如果摘要夠用,Agent 就不用爲這 41 KB 付費。
DeepSeek Harness 記憶設計中的穩定 ID 與引用圖
Chain of Recall 成立的前提是 ID 永遠不變。原文中有三類對象帶 ID:
| 對象 | 含義 | 示例 ID | 鏈接關係 |
|---|---|---|---|
| Trigger | 一條進入系統的事件:聊天消息、Webhook、CI 回調 | trg_8f21 |
屬於某個 Thread |
| Thread | 同一 PR、IM 話題或郵件鏈上的一串相關事件 | thr_pr_412 |
由一個或多個 Worker 持有 |
| Worker | 一個處理單一任務的隔離 Agent 會話 | wkr_77a0 |
報告中引用它處理過的 Trigger |
這些鏈接組成一張引用圖,這張圖就是 Agent 的記憶。召回時沿鏈接一跳一跳地走,不加載全部歷史,也不做相似文本搜索。舉個例子:週五有人問 Router“爲什麼給支付客戶端加了重試”,而相關討論發生在週二,早已溢出。第一跳,Router 用上下文裏仍保留的一行索引取回 thr_pr_412;第二跳,從 Thread 記錄裏讀到持有它的 Worker,取回該 Worker 的最終報告;第三跳,報告裏引用了 CI 失敗的 Trigger,取回其日誌,看到超時報錯。三次精確的小查詢,答案沒有任何猜測成分。

DeepSeek Harness 記憶 API 必須滿足的四條契約
召回鏈裏的每一跳都是一次 API 調用,任何一次返回了不同的記錄或者沒有返回,鏈條就會斷,Agent 要麼卡住,要麼靠猜來回答。所以底層 API 必須滿足四條契約:
- ID 永不變化:今天返回的 ID 下個月必須解析到同一個對象,刪除後不復用,遷移後不重新編號。
- 按 ID 取回要便宜且精確:
GET /threads/{id}只返回這一條記錄,不做搜索,也不返回“最接近的匹配”。 - 未知 ID 要明確失敗:返回 404 和清晰的錯誤體。如果返回 200 加空對象,Agent 會以爲這段記憶存在。
- 遊標分頁無缺口:長 Thread 按順序分頁,每個事件只出現一次,有新事件寫入時遊標依然有效。
這些契約在重構時很容易被悄悄破壞,應該寫成自動化測試,在每次合併時運行。
要客觀看待兩點限制。第一,Chain of Recall 不能替代向量檢索:向量檢索回答“什麼和這個相似”,Chain of Recall 回答“什麼和這個有鏈接”,實際項目中常見的組合是先用向量索引找到起始 Thread ID,再沿鏈接走到精確事實。第二,原文中“37%”這個數字說的是 Thread 透傳:去掉透傳後,每次運行的緩存讀取 token 從 23.2M 漲到 31.8M。這是缺少某個功能的代價,不是 Chain of Recall 本身帶來的節省,引用時不要混淆。
如何借鑑 DeepSeek Harness 憑據設計:用憑據但看不到憑據
原文把這個問題列爲開放問題:憑據進入 Agent 上下文就可能泄露,所以 Agent 應該能使用憑據,卻看不到憑據。常見的泄露路徑有四種:爲了排查故障讀取 .env;在調試命令裏寫出明文請求頭,或者執行 echo 來“確認變量已設置”;把真實值寫進 PR 描述、Issue 評論或測試夾具;被網頁或接口響應裏的提示注入誘導,打印出環境變量。OWASP 把提示注入列爲 LLM 應用的首要風險,並把憑據暴露歸在敏感信息泄露一類。
所有防護手段都遵循同一條規則:上下文裏只放名字,值留在模型外部。上下文可以出現變量名 STRIPE_KEY、密鑰管理器引用、{{token}} 這類佔位符,或者打了掩碼的值;不能出現真實密鑰、解析後的值和未脫敏的日誌行。一旦真實值出現在對話裏,當天就要輪換這個密鑰,因爲對話記錄會被記錄、緩存和導出,發出去的 token 沒法撤回。

DeepSeek Harness 憑據問題的四種落地模式
| 模式 | 做法 | Agent 是否持有值 | 主要侷限 |
|---|---|---|---|
| 環境變量 + 脫敏 | 命令裏寫 $NAME,由 shell 展開;禁止讀取 .env;輸出回傳前做掩碼 |
shell 中持有 | 能防誤操作,防不住被注入後的主動打印 |
| 密鑰管理器引用 | 配置裏只放類似 op://vault/item/field 的引用,運行時由 CLI 解析進子進程 |
子進程中持有 | 侷限與環境變量相同 |
| 憑據注入代理 | Agent 不帶密鑰請求本地代理,代理加上認證頭,並按白名單轉發 | 從不持有 | 需要單獨部署和維護代理 |
| 短期、窄權限令牌 | 每個會話簽發一個幾分鐘到期、只做一件事的令牌 | 持有,但價值很低 | 只是兜底,有效期內仍可能被濫用 |
在這四種模式中,只有憑據注入代理能真正讓 Agent 不持有密鑰。代理的白名單和注入同樣重要:例如允許 GET /v1/charges,拒絕 DELETE /v1/customers。即使 Agent 被注入,它也只能執行你批准過的調用,而且沒法把密鑰帶走。代理要以獨立用戶或獨立容器運行,防止 Agent 讀到它的配置。這和原文的部署思路一致:憑據跟環境一起留在本地。
如果你的 Agent 通過 API易 調用模型,同樣的思路可以用在模型密鑰上:讓代理在轉發到 API易 時注入密鑰,Agent 一側只知道“走本地代理”。這樣即使對話記錄被導出,裏面也不會有可用的 API易 Key。具體的接入地址和認證方式請以 API易 文檔 docs.apiyi.com 爲準。
最後一層是脫敏。工具輸出、CI 日誌和保存下來的會話都要對已知前綴做掩碼,包括 sk_live_、ghp_、github_pat_、AKIA、xoxb-,以及所有 Authorization 和 X-API-Key 請求頭的值,還有本次會話中注入過的具體值。只要有一行沒脫敏,前面所有防護都白做了。
DeepSeek Harness 設計快速上手:落地清單與模型選型
三個設計問題不必一次做完。按投入產出比排序,建議的落地順序如下:
- 先做憑據衛生:禁止 Agent 讀取
.env,在CLAUDE.md或AGENTS.md中寫明“不打印任何以_KEY、_TOKEN、_SECRET結尾的變量”,給輸出加脫敏過濾。這一步半天就能完成,收益立刻可見。 - 再給慢工具改異步:先挑測試、構建、部署這類經常超過幾秒的工具,按 start / status / stop 拆分,補上冪等鍵和截止時間。
- 然後建立穩定 ID:給事件、會話線程、子任務統一分配不可變 ID,上下文中只保留 ID 加一行摘要,大段內容一律溢出並留指針。
- 最後上注入代理和短期令牌:針對第三方 API 部署代理並配置白名單,每個 Agent 會話簽發一個獨立令牌。
模型選型上,Router 的特點是輸入長、輸出短,並且要頻繁做批量決策,適合便宜、快速、緩存命中價格低的模型;Worker 負責寫代碼、做複雜推理,適合能力更強的模型。下表價格摘自 API易 價格頁 docs.apiyi.com/models,計費口徑和最新單價以頁面實時數據爲準,本文不作其他報價承諾。
| 模型(API易 模型名) | 輸入單價 | 輸出單價 | 緩存價格 | 建議角色 | 可用平臺 |
|---|---|---|---|---|---|
| deepseek-v4.1-flash | $0.3 | $1.2 | $0.006 | Router 批量決策、事件摘要 | API易 apiyi.com |
| claude-sonnet-5-5 | $2 | $10 | $0.1 | 日常編碼 Worker | API易 apiyi.com |
| kimi-k3.1-pro | $2 | $10 | $0.2 | 長上下文 Worker、文檔類任務 | API易 apiyi.com |
| claude-opus-5-5 | $4 | $20 | $0.2 | 複雜重構、關鍵決策 Worker | API易 apiyi.com |
需要說明的是,原文的批處理和 Thread 透傳實驗都強調緩存讀取 token 的規模。Router 側大部分開銷落在 prefill 和緩存讀取上,所以選型時,緩存價格往往比輸出單價更值得看。
🚀 快速開始:API易 提供上表模型的 API 調用,同時兼容 OpenAI 與 Anthropic 兩種接口格式。Router 用 OpenAI 格式接 deepseek-v4.1-flash,Worker 用 Anthropic 格式接 claude-sonnet-5-5,兩邊可以共用一個賬號統一管理。接入說明見 API易 文檔 docs.apiyi.com,價格以 docs.apiyi.com/models 爲準。
常見問題 FAQ
Q1: DeepSeek Harness《超級 Agent 設計》是什麼?
這是 DeepSeek Harness 團隊在 2026-11-01 發佈的設計長文 “Exploring Super-agent Design”,討論一個常駐、同時監聽多個事件源的超級 Agent 應該怎麼設計。它描述的是架構,不是正式發佈的功能,部分內容放在原型插件 `dsh-superagent-prototype` 中,作者說明它不是 DeepSeek 官方產品。
Q2: 全雙工和並行工具調用有什麼區別?
並行工具調用是在一輪裏同時執行多個工具,模型仍然要等它們全部返回。全雙工下的異步工具調用會立刻返回句柄,結果在之後的輪次中以事件形式到達,模型在等待期間可以繼續對話、接收新指令、啓動新任務。
Q3: Chain of Recall 可以直接開啓嗎?它能替代 RAG 嗎?
都不能。Chain of Recall 是原文中的一個設計模式,沒有開關可開,需要自己實現穩定 ID 和按 ID 取回的接口。它和 RAG 解決的問題不同:RAG 找相似內容,Chain of Recall 沿精確鏈接取回。實際項目中通常先用向量檢索找到起點,再沿 ID 鏈接走到具體事實。原文也把長期記憶列爲開放問題,沒有說 Chain of Recall 已經解決了它。
Q4: 這三個設計問題最適合哪些應用場景?
– **全雙工**:測試、構建、爬取、渲染、部署這類經常超過幾秒的任務,並且用戶會在任務運行時繼續和 Agent 對話。
– **記憶**:由離散、可鏈接事件組成的歷史,例如 PR、工單、CI 運行記錄、客服會話、發佈記錄。
– **憑據**:需要調用付費或敏感第三方 API 的編碼 Agent 和運維 Agent。
Q5: 如何快速爲 Router 和 Worker 接入不同的模型?
比較省事的做法是用一個同時兼容 OpenAI 和 Anthropic 接口格式的平臺統一接入。在 API易 apiyi.com 註冊後獲取 API Key,Router 和 Worker 分別填對應的模型名即可切換,接入地址以 API易 文檔 docs.apiyi.com 爲準。上線前建議用同一批真實事件分別測試 deepseek-v4.1-flash 和 claude-sonnet-5-5 的決策質量,再確定分工。
Q6: 原文提到的模型或價格在哪裏覈對?
本文涉及的模型價格一律以 API易 價格頁 docs.apiyi.com/models 的實時數據爲準,原文和第三方材料中的數字只作爲對照引用。如果某個模型在該價格頁查不到,就表示 API易 目前暫未上線該模型,我們會盡快上線,屆時以價格頁爲準。
Q7: 這些做法有哪些已知限制?
全雙工需要真正的任務 API 支撐,用阻塞實現包裝出來的“僞異步”只會增加複雜度。Chain of Recall 找不到沒有建立鏈接的內容,ID 契約在遷移和重構時容易被破壞。在憑據方面,環境變量和密鑰引用都防不住被注入後主動打印的情況,只有注入代理能讓 Agent 完全不持有值,短期令牌只能作爲兜底。原文自己也把記憶和憑據列爲開放問題。
DeepSeek Harness 超級 Agent 設計核心要點 Key Takeaways
- 原文定位:這是一篇架構設計文章,全雙工默認關閉,原型插件不是官方產品。
- 全雙工:用 start / status / stop 替代阻塞的 run,結果以事件形式回注,並按批次合併。
- 任務 API 契約:202 受理、冪等鍵去重、取消返回真實狀態、給每個任務設截止時間。
- 記憶設計:上下文只放穩定 ID 和短摘要,其餘溢出留指針,召回時沿 ID 鏈接多跳取回。
- 記憶 API 契約:ID 不變、精確取回、未知 ID 返回 404、遊標分頁無缺口。
- 憑據原則:名字進上下文、值留在外部,優先使用注入代理,短期令牌兜底,日誌全量脫敏。
- 模型分工:Router 選便宜且緩存價低的模型,Worker 選能力強的模型,可在 API易 用一個賬號對比測試。
總結
DeepSeek Harness《超級 Agent 設計》中可以直接借鑑的內容,比它的“原型”身份看上去要多:
- 全雙工:異步工具契約和事件回注是成熟的工程做法,背後的任務 API 可以先寫測試再接入 Agent。
- 記憶:穩定 ID 加 inline/spill,是給事件型 Agent 做精確記憶成本最低的方式,但它不能替代向量檢索。
- 憑據:“名字進上下文、值留在外部”這條規則今天就能執行,注入代理是唯一讓 Agent 完全不持有密鑰的方案。
建議從憑據衛生和慢工具異步化做起,穩定 ID 和注入代理放到第二階段。需要爲 Router 和 Worker 搭配不同模型時,可以通過 API易 apiyi.com 用兼容 OpenAI 與 Anthropic 格式的統一接口做實測,價格以 docs.apiyi.com/models 爲準。
📚 參考資料
- What Is Chain of Recall? How Stable IDs Give AI Agents Memory:Chain of Recall 記憶設計解讀
- 鏈接:
apidog.com/blog/chain-of-recall-ai-agent-memory -
說明:包含穩定 ID、inline/spill、多跳召回示例和四條 API 契約
-
Async Tool Calls for AI Agents: Why start() Beats a Blocking run():全雙工異步工具設計解讀
- 鏈接:
apidog.com/blog/async-tool-calls-ai-agents -
說明:包含 start/status/stop 契約、批處理實驗數據和 MCP Tasks 擴展說明
-
How to Let AI Agents Use API Keys Without Seeing Them:Agent 憑據安全實踐
- 鏈接:
apidog.com/blog/ai-agents-use-api-keys-without-seeing-them -
說明:包含四種憑據模式、泄露路徑和脫敏清單
-
API易 文檔與價格頁:本文涉及模型的接入說明與計費數據
- 鏈接:
docs.apiyi.com與docs.apiyi.com/models - 說明:模型名、接口格式和實時價格以此爲準
作者:APIYI 技術團隊
技術交流:Agent 架構選型和多模型接入的問題,歡迎通過 API易 apiyi.com 首頁聯繫我們,更多資料見 docs.apiyi.com 文檔中心