我把 DeepSeek Harness 源码跑了一遍,终于看懂了它的“一切皆插件”
ææ DeepSeek Harness æºç è·äºä¸éï¼ç»äºçæäºå®çâä¸åçæä»¶â
çº¯ç±æé¨äºº 2026-08-14 0 é 读6åéDeepSeek Harness å½åä»å¤äº Developer Previewï¼æ¬æåºäº
0.1.0-rc.5ã
æè¿ DeepSeek 弿ºäºä¸ä¸ªå« DeepSeek Harness ç Agent æ¡æ¶ã
çå° Harness è¿ä¸ªè¯ï¼å¾å¤äººç第ä¸ååºå¯è½æ¯ï¼åä¸ä¸ªå°è£ 大模åãæ³¨åå 个 Toolãåå¥ä¸ªè天页é¢çæ¡æ¶ã
æä¸å¼å§ä¹æ¯è¿ä¹æ³çã
使æºç æä¸æ¥ãè·å®æå»ºï¼å顺ç packages/coreãpackages/bundle å apps/cli çäºä¸éä¹åï¼æåç°å®çæ£æ³è§£å³ç䏿¯âæä¹è°ç¨æ¨¡åâï¼èæ¯å¦ä¸ä¸ªæ´éº»ç¦çé®é¢ï¼
å½ Agent å¼å§æ¥ææä»¶ç³»ç»ãShellãæéãä¼è¯ãå Agent ååå°ä»»å¡ä¹åï¼æä¹é¿å æ´ä¸ªç³»ç»åæä¸å¢æ æ³æ¿æ¢çè¶æ°´ä»£ç ï¼
DeepSeek Harness ç»åºççæ¡æ¯ï¼ææ´ä¸ª Agent äº§åæææä»¶ã
䏿¯âæ¯ææä»¶âï¼èæ¯âä¸åçæä»¶âã
Agent Loop ä¹ä¸æ¯å æ ¸
ä¼ ç» Agent æ¡æ¶é叏齿䏿®µå°ä½ç¹æ®ç主循ç¯ï¼
æ¥æ¶æ¶æ¯
â è°ç¨æ¨¡å
â è§£æ Tool Call
â æ§è¡å·¥å
·
â æç»æäº¤è¿æ¨¡å
â ç»§ç»ä¸ä¸è½®
模åãå·¥å ·ãåå²è®°å½åæéé»è¾ä¼éæ¸å è¿è¿æ®µå¾ªç¯ãåå¼å§å¾å¥½çè§£ï¼å颿¯å¢å ä¸ç§è½åï¼é½è¦å¨ä¸»æµç¨éå æ°çæ¡ä»¶åæ¯ã
DeepSeek Harness æ²¡ææ Agent Loop æ¾å¨ä¸å¯æ¿æ¢çä½ç½®ã
模åéé
å¨ãå·¥å
·æ³¨å表ãä¼è¯æ¥å¿ãæéçç¥ãæä»¶ç³»ç»ï¼çè³ Agent Loop æ¬èº«ï¼é½æ¯æè½½å¨ Cordis ä¸çæä»¶ãå®ä»¬éè¿å
±äº«ä¸ä¸æ ctx åä½ï¼è䏿¯äºç¸å¼ç¨å
·ä½å®ç°ã
Cordis Context
âââ ctx.sessions
âââ ctx.tools
âââ ctx.llm
âââ ctx.agents
âââ ctx.agentLoop
âââ ctx.fs
âââ ctx.subprocess
âââ ctx.sandbox
âââ ctx.jobs
è¿å¸¦æ¥ä¸ä¸ªå¾ç´æ¥çç»æï¼æ°å¢è½åæ¶ï¼é»è®¤å¨ä½ä¸åæ¯ä¿®æ¹ Agent Loopï¼èæ¯æ¾å°å¯¹åºæ©å±ç¹ï¼æè½½ä¸ä¸ªæ°æä»¶ã
ä¾å¦ï¼
- æ°æ¨¡å注åå°
ctx.llm - æ°å·¥å
·æ³¨åå°
ctx.tools - Shell æ¢ææ¬å°ææ²ç®± Provider
- è¯·æ±æ¦æªä½¿ç¨
agent/*äºä»¶ - å·¥å
·å®¡æ¹ä½¿ç¨
tools/*äºä»¶ - åå°ä»»å¡æ³¨åå°
ctx.jobs
åªæç°ææ©å±ç¹ççæ æ³è¡¨è¾¾éæ±æ¶ï¼æéè¦ç¢° Agent Loopã
Cordis 管çä¸åªæ¯ä¾èµæ³¨å ¥
Cordis æ¯ Harness çåºå±æä»¶æ¡æ¶ã
ä¸ä¸ªæå°æä»¶åªæå è¡ï¼
import type { Context } from '@deepseek-ai/cordis'
export const name = 'hello-plugin'
export function apply(ctx: Context) {
console.log('plugin loaded')
}
妿æä»¶ä¾èµå·¥å ·æ³¨å表ï¼éè¦æ¾å¼å£°æï¼
export const inject = ['tools']
export function apply(ctx: Context) {
ctx.tools.register(/* ... */)
}
Cordis ä¼çå° tools æå¡å¯ç¨ååå è½½æä»¶ãè¿ä¸åªæ¯æ¹ä¾¿è·åä¾èµï¼å®åæ¶è§£å³äºå¯å¨é¡ºåºåçå½å¨æé®é¢ã
æ´å ³é®çæ¯å¯ä½ç¨å¯éã
export function apply(ctx: Context) {
ctx.effect(() => {
const timer = setInterval(() => {
console.log('heartbeat')
}, 5000)
return () => clearInterval(timer)
})
}
æä»¶å¸è½½æ¶ï¼Cordis 伿§è¡æ¸ ç彿°ãäºä»¶çå¬ãå·¥å ·æ³¨ååéè¿ä¸ä¸æå建çè½åä¹ä¼éæä»¶ä¸èµ·æ¤éã
è¿æ£æ¯ Harness è½æ¯æçæ´æ°åé ç½®éç»çåºç¡ãå¦åæ¯æ¬¡ä¿®æ¹é ç½®é½éæ°å è½½æä»¶ï¼æ§å®æ¶å¨ãäºä»¶çå¬å¨åå·¥å ·æ³¨åä¼ä¸ææ®çã
Profile 䏿¯é ç½®æä»¶ï¼èæ¯ä¸å¥ Agent 产å
Harness å¯å¨ç䏿¯æä¸ªåºå®åºç¨ï¼èæ¯ä¸ä¸ª Profileã
ä¸ä¸ªè¿è¡ä¸ç Profileï¼æ¬è´¨ä¸æ¯ä¸æ£µç±å¤å±é ç½®ç»ååºæ¥çæä»¶æ ï¼
Bundle å表
â Profile èªå·±ç cordis.patch.yml
â $DSH_HOME/cordis.patch.yml
â å½ä»¤è¡ä¼ å
¥ç --patch
å
ç½®ç dsh-base æä¾æ¨¡åãå·¥å
·ãæä¹
åãæ²ç®±ã审æ¹ååæ®çåºç¡è½åã
dsh-web-app å¨å®ä¸é¢å¢å Web æå¡åå端çé¢ï¼dsh-headless åå¢å 䏿¬¡æ§ä»»å¡æ§è¡å¨ï¼ä¸å¯å¨ Web æå¡ã
æä»¥ Web å Headless 并䏿¯ä¸¤å¥ç¬ç«å®ç°ï¼èæ¯ä¸¤ç§æä»¶ç»åã
æ¥çå½åæºå¨æç»è¿è¡äºä»ä¹ï¼ä¸éè¦çï¼
dsh --profile web --dump-config
è¿æ¡å½ä»¤ä¼æå°ç»ååçé ç½®æ ã
éè¦æ³¨æçæ¯ï¼Patch æ¿æ¢çæ¯ç®æ è¡çæ´ä¸ª configï¼ä¸æ¯æ·±åº¦åå¹¶ãè¦çå·²ææä»¶é
ç½®æ¶ï¼å¿
é¡»æéè¦ä¿ççåæ®µä¸èµ·å忥ã
çæ£å¼å¾ç ç©¶çæ¯ Capability Seam
Harness çå å¾å¤ï¼ä½å®å¹¶ä¸æ¯å纯æå¤§æ¨¡åææå°å ã
ä¸é¡¹éè¦æ¿æ¢å®ç°çè½åï¼é常ä¼è¢«ææä¸ç§è§è²ï¼
Service Definition
â
Service Provider
â
Consumer
以 Shell 为ä¾ï¼
- Definition å®ä¹æ§è¡è¯·æ±åç»æ
- Provider å³å®å¨æ¬æºãè¿ç«¯è¿æ¯æ²ç®±éæ§è¡
- Consumer æå®å è£ æ BashãPowerShell æç»ç«¯ Tool
Tool ä¸åºè¯¥ç¥éè¿ç¨å°åºå¨åªéè¿è¡ã
è¿ä½¿å¾æä»¶ç³»ç»ä¸è¿ç¨ Provider 忢å°è¿ç¨æ²ç®±åï¼BashãPTY å LSP å¯ä»¥æ´ä½è¿ç§»ï¼ä¸éè¦ä¸ºæ¯ä¸ª Tool åç¬ç»´æ¤è¿ç¨çæ¬ã
å½ç¶ï¼è¿ç§è®¾è®¡ä¸æ¯å è´¹çã
å®ä¼å¸¦æ¥æ´å¤å ãæ´é¿çä¾èµå¾ï¼ä»¥åæ´é«ççè§£ææ¬ã妿æé¡¹è½ååªæä¸ä¸ªå®ç°ï¼ä¹ä¸ä¼è¢«å¤ç¨ï¼æ´ä¸éè¦é离ï¼é£ä¹ç¡¬æ DefinitionãProvider å Consumer åªæ¯å¨å¶é å½¢å¼ä¸»ä¹ã
Harness çåæ³æ´éåé£äºçæ£éè¦æ¿æ¢è¿è¡ç¯å¢çè½åã
ä¼è¯æ¥å¿ææ¯ç³»ç»çäºå®æº
æè®¤ä¸º Harness æéè¦ç约æä¸æ¯æä»¶ï¼èæ¯è¿å¥è¯ï¼
模åå¯è§ï¼å³å·²è®°å½ã
Harness 䏿ä¸ä¸ªå¯åç messages[] 彿ä¼è¯æ¬èº«ï¼èæ¯ç»´æ¤ä»
追å ç SessionEvent æ¥å¿ã
SessionEvent Log
âââ æå½±ææ¨¡ååå²
âââ æ¸²æå° Web UI
âââ æä¹
åå° JSONL æ SQLite
âââ æ¯ææ¢å¤ä¸ Fork
âââ çæ Transcript å饿µ
è¿è§£å³äº Agent ç³»ç»ä¸ä¸ä¸ªå¾å¸¸è§çé®é¢ï¼è¿è¡æ¶ç»æ¨¡åå·å·å¡äºä¸ä¸æï¼ä½æ¢å¤ä¼è¯æ¶æ æ³éå»ºï¼æè 页颿¾ç¤ºäºæä¸ªç¶æï¼æ¨¡åå´ä¸ç¥éå®åå¨ã
å¨ Harness éï¼å¦ææ°å
容ä¼è¿å
¥æ¨¡å请æ±ï¼å°±ä¸è½åªå¨ agent/request ä¸ä¸´æ¶æ¼æ¥ãå®å¿
é¡»æä¸ºä¼è¯äºä»¶ï¼å¹¶æ¯æä»æ¥å¿éæ°æå½±ã
代价æ¯å¼åæ´ä¸¥æ ¼ï¼ä½æ¢æ¥çæ¯å¯æ¢å¤ãå¯åæ¾åå¯å®¡è®¡ã
䏿¬¡ Turn å°åºåçäºä»ä¹
Harness æä¸æ¬¡æ¨¡å请æ±å å·¥å ·æ§è¡ç§°ä¸º Stepï¼ä¸æ¬¡ Turn å¯ä»¥å å«å¤ä¸ª Stepã
ç®ååçæµç¨å¦ä¸ï¼
turn/start
â é¢åè¾å
¥
â agent/pre-step
â ç»è£
æç¤ºè¯ä¸ Tool Schema
â step/start
â 仿¥å¿æ´¾ç模ååå²
â agent/request
â llm/stream
â assistant/message
â tool/call
â tools/pre-execute
â tools/execute
â tools/post-execute
â tool/result
â step/end
â turn/end
å
¶ä¸ agent/requestãllm/stream å tools/* çé¨åäºä»¶éç¨ Waterfall æºå¶ã
çå¬å¨å¿
é¡»è°ç¨ next()ï¼
ctx.on('tools/pre-execute', async (request, next) => {
validateRequest(request)
return next()
})
æ¼æ next() 䏿¯ä»ä¹é½æ²¡åï¼èæ¯ç´æ¥æªæåç»å¤çé¾ãå¼åçç¥æä»¶æ¶ï¼è¿ä¸ç¹å¾å®¹æè¸©åã
å®éåä»ä¹é¡¹ç®
å¦æåªæ¯åä¸ä¸ªè°ç¨æ¨¡åãæ§è¡å 个åºå®å½æ°çå°åºç¨ï¼DeepSeek Harness å¯è½å¤ªéã
宿´éåä¸é¢è¿äºåºæ¯ï¼
- åä¸å¥ Agent éè¦ WebãHeadlessãACP çå¤ç§å ¥å£
- æä»¶ç³»ç»åè¿ç¨éè¦å¨æ¬å°ãæ²ç®±ãè¿ç«¯ä¹é´åæ¢
- éè¦æä¹ ä¼è¯ãæ¢å¤ãFork å审计
- Tool æ§è¡éè¦æéã审æ¹åçç¥æ¦æª
- ä¸å Agent éè¦ä¸åè½åéå
- å¸æç¬¬ä¸æ¹æ©å±è½åï¼ä½ä¸æ³ Fork 主ä»åº
DeepSeek Harness æå¼å¾åé´çå°æ¹ï¼å¹¶ä¸æ¯âç¨äºæä»¶æ¶æâã
èæ¯å®æ Agent çè¿è¡ç¶æãè½åè¾¹çåå¯ä½ç¨çå½å¨æé½åæäºå¯ä»¥ç»åãæ¿æ¢åéªè¯ç对象ã
è¿æ¯åå°è£ ä¸å±æ¨¡å API é¾å¾å¤ï¼ä¹æ´æ¥è¿çæ£ç Agent å·¥ç¨ã
Aitishiku.com