我在 DeepSeek Harness 本地 Web UI 跑了五個真的會用到的工作:能完成,但不是每件事都快
-
這篇測的是 DeepSeek Harness 裝好之後出現的本地 Web UI,不是 headless CLI,也不是把模型排行榜上的 tok/s 拿來當成自己的成績。
我真正想知道的是:把一個有明確需求的小型工作交給它,它能不能自己讀檔、寫檔、執行命令、看測試結果、發現問題,再把結果交付出來?如果只問一句「請介紹 MCP」,得到的答案再漂亮,也不能回答這個問題。
所以這次我在 Windows 的 DeepSeek Harness Web UI 裡,讓它連續完成五種不同的工作。五項都在掄槌者工作區內另外建立的隔離資料夾進行,沒有碰原本的 danial 專案,也沒有把測試檔案放進既有專案。每一項都有不同的目標和產物,不是同一個 prompt 換五種說法。
這次五項工作的總結果先放在前面:
工作 Web UI 實際耗時 Agent steps 工具呼叫 交付結果 把既有 Python 工具接成 MCP Server 492.53 秒 25 28 12/12 測試通過 自己建立輸入規模與錯誤恢復 benchmark 249.87 秒 7 8 20/20 正確 對成果做獨立程式碼審查與邊界探針 445.44 秒 13 15 找到 8 個 Low/Info 問題 整理成可以交給別人使用的文件 200.58 秒 9 12 README 完成並核對 複製到乾淨副本重新執行 99.26 秒 7 8 測試、demo、benchmark 全通過 五項主要工作合計約 24 分 48 秒、61 個 Agent steps、71 次工具呼叫。下面不是只列結果,而是把每項到底交代了什麼、實際留下什麼,以及數字代表什麼寫清楚。
測試環境和限制
- DeepSeek Harness 本地 Web UI,網址是 127.0.0.1:3080。
- Web UI session 實際使用模型:DeepSeek V4 Pro。
- reasoning effort:Max。
- Windows 10,Python 3.14.3,PowerShell。
- 工作資料夾只使用 Python 標準函式庫,不安裝額外套件、不連網。
- 原始 input_tool.py 只讀取,不允許修改。
原本的工具很小:input_tool.py 接受 Markdown 文字,回傳第一個標題、標題數、字元數和非空行數。這個大小剛好能讓我把注意力放在 Harness 的工作流程,而不是把外部框架、套件安裝和大型專案本身混進來。
我記錄的不是只有最後一句回答。每項都記錄 Web UI 顯示的耗時、Agent steps、工具呼叫、實際建立或修改的檔案、命令退出碼,以及能不能在本地重新核對。費用則根據 session 遙測估算,因為我沒有拿到帳戶實際帳單。
第一項:把既有 Python 工具接成真的 MCP Server
第一項是主要工程任務,也是最接近日常使用 Agent 的一項。
我給它的要求不是「幫我寫一個 MCP 範例」,而是把目前已經存在的 input_tool.py 包成可以用 stdio 溝通的 MCP Server。Server 要處理 initialize、notifications/initialized、tools/list 和 tools/call;分析邏輯必須直接呼叫原本的 input_tool,不可以複製一份同樣的 Markdown 計算邏輯。
除此之外,它還要自己完成兩個能被真正執行的交付物:
- 用 subprocess 啟動 Server 的測試,而不是只在同一個 Python process 裡呼叫函式。
- 一個獨立的 MCP client,實際送出 JSON-RPC,讀取 Server 回應,最後留下結果報告。
這項任務的驗收條件也包含錯誤路徑。我要求它測短文、中文和 Emoji、多層標題、空字串、同一個 Server 連續呼叫、未知工具、無效 JSON、缺少 method、未知 method 和缺少 arguments。換句話說,不能只讓一條正常輸入跑通就算完成。
實際交付
它最後留下:
- mcp_server.py:stdlib MCP stdio JSON-RPC Server。
- test_mcp_server.py:12 個 subprocess 測試情境。
- demo_mcp_client.py:獨立 client,包含正常、錯誤和錯誤後恢復的呼叫。
- RESULTS.md:驗收結果、遙測和費用估算。
這一輪不是一次成功。它在執行過程中遇到兩個實際問題:一個 Unicode 測試的斷言和工具真正回傳的內容不一致,另一個是 demo client 讀錯誤回應時的讀取順序不對。它重新讀取結果、修改測試和 client,再跑一次。
另外,獨立 review 發現 demo client 遇到 stdout timeout 或 Server 提前關閉時,原本可能只回傳 None,主程式卻仍以退出碼 0 結束。這會把失敗誤報成成功。修正成直接拋出 RuntimeError 後,再重新跑 unittest 和 demo,結果仍然通過。
最後的實際結果是:
- unittest:12/12 通過,退出碼 0。
- 最新獨立重跑:12 tests in 0.583 秒。
- demo client:client exit 0,server exit 0。
- PowerShell 原始 stdin 管線:9 行 JSON-RPC,Server exit 0。
- initialized 通知沒有多送回應,錯誤後仍能再做正常呼叫。
12 個測試的實際情境如下:
類型 驗證內容 握手 initialize 回傳 protocolVersion、capabilities、serverInfo 通知 notifications/initialized 不回應 工具發現 tools/list 暴露 analyze_markdown 及 input schema 正常資料 短文、Unicode、多層標題、空字串 連續性 同一個 Server 連續兩次呼叫 錯誤輸入 未知工具、無效 JSON、格式錯誤、未知 method、缺少 arguments 這項實測可以證明的是:在需求有限、驗收條件清楚的小型工程任務裡,DeepSeek Harness 能走完讀檔、實作、執行、看錯誤、修正、重跑和交付。它不能證明大型專案一定成功,但至少不是只產生一段看起來像程式的文字。
第二項:讓它自己建立輸入規模和錯誤恢復 benchmark
第二項不再叫它繼續加功能,而是要求它把剛完成的 Server 當成待測對象,自己建立一個可以重複執行的 benchmark。
這個任務有三個硬條件:
- 不修改 mcp_server.py 和既有測試。
- 不能只量一次,要有四種輸入大小、每種五次重複。
- 每次不只記時間,也要把回應和 input_tool 的參考值逐欄核對。
四種輸入是 20 bytes、1 KB、100 KB 和 1 MB;每種各呼叫五次,而且是在同一個 Server process 裡完成,不是每次都重啟。量測的 roundtrip 是從建立請求到解析完成回應的總時間,包含 JSON encode、pipe 寫入、Server 處理、pipe 讀取和 decode。它不是模型生成速度,也不是顯卡 decode 速度。
原始結果
輸入大小 呼叫次數 最小 roundtrip 中位數 最大 roundtrip 正確率 20 B 5 0.053 ms 0.078 ms 0.114 ms 5/5 1 KB 5 0.060 ms 0.087 ms 0.177 ms 5/5 100 KB 5 1.498 ms 1.752 ms 2.077 ms 5/5 1 MB 5 18.747 ms 20.196 ms 24.671 ms 5/5 20 次正常呼叫全部正確。1 MB 輸入的標題原樣保留,字元數沒有截斷,也沒有出現亂碼。以 20 B 的中位數作基準,1 KB 約 1.1 倍、100 KB 約 22.5 倍、1 MB 約 258.9 倍。
這個結果有一個很實際的解讀:對這個只做文字分析的 stdio Server,小檔案延遲幾乎可以忽略,但資料放大後 roundtrip 會明顯上升。1 MB 的 pipe 寫入中位數約 1.094 ms,整體 roundtrip 中位數是 20.196 ms,表示主要時間不只是把資料寫進 pipe。
接著我讓它送出未知工具 benchmark_no_such_tool。Server 回傳 -32602,錯誤 roundtrip 是 0.544 ms;下一個正常的 20 bytes 呼叫在 0.108 ms 完成,Server 仍存活,最後正常關閉的 exit code 是 0。
這是五項裡面最像「硬數據」的一項,但仍然要把範圍說清楚:這些數字只代表本機 Windows、Python 3.14.3、這個 stdio Server 和這個輸入工具。它不能拿來和論壇文章裡的 GPU tok/s 比較,也不能推論 DeepSeek V4 Pro 本身每秒能生成多少 token。
第三項:對剛完成的成果做獨立程式碼審查
第三項我把角色換掉,不讓它繼續扮演原作者,而是要求它像另一位 reviewer 一樣,只讀取 mcp_server.py、input_tool.py、test_mcp_server.py 和 demo_mcp_client.py,重新執行測試,再用額外的 stdin 探針攻擊協定邊界。
這一項的限制是「只讀」。不可以為了讓報告看起來乾淨而順手修改程式。審查前後要比對 sha256 和 mtime,證明被審查的檔案沒有被動過。
它執行了:
- unittest 和 demo client。
- 18 組唯讀 protocol edge probes。
- 無效 JSON、缺 method、缺 params、params 非物件、text 非字串、id=null、batch、CRLF、空行、非法 UTF-8 和 client 提前關閉 stdout 等情境。
- 前後 sha256 和 mtime 比對。
審查結論沒有 High 或 Medium 級問題,列出 8 個 Low/Info 問題。其中幾個比較有代表性:
發現 實際行為 影響 F1 缺少 method 的畸形通知仍回 -32600 和嚴格 JSON-RPC 通知規則不完全一致 F2 字串內非法 UTF-8 以 U+FFFD 靜默替換 client 送出的內容可能和 Server 分析內容不同 F3 client 提前關閉 stdout 時,_send 可能拋 OSError Server 出現 traceback,探針 exit 120 T1 測試 helper 使用裸 assert python -O 時 envelope 檢查會被移除 T2 Server stderr 導向 DEVNULL Server 崩潰時看不到 traceback D1 demo timeout 後 kill 沒有立即 wait 錯誤路徑的子程序回收不完整 這裡有一點我覺得比「找到幾個問題」更重要:它沒有把所有問題都誇大成嚴重漏洞。報告把 F1、F2、F3、T1、T2、D1 定為 Low,把寬鬆接受 initialize 前呼叫、空白行和 batch 陣列等行為列為 Info,也明確寫出沒有 High/Medium。
審查還列出 17 個 unittest 沒有覆蓋、但探針可以觀察到的情境。例如 initialize 版本協商、params 完全缺失、重複 request id、id=null、batch、lone surrogate 和 1 MB 大輸入。這讓報告不只是「程式碼看起來沒問題」,而是把已測、未測和已知偏差分開。
這項任務的實際價值在於,它測到 Harness 能不能停下來檢查自己的產物。很多 Agent 會把第一輪產出的程式直接宣布完成;這次至少能在第二個角色裡找到測試工具本身的弱點,也能指出 Server 的規範邊界。
第四項:把程式和數據整理成真的能用的文件
第四項看起來不像 benchmark,但很接近日常工程工作。讓模型寫一份 README 很容易,難的是 README 裡的檔名、命令、輸出和限制不能靠想像。
我要求它只讀取已經存在的程式和兩份實測報告,建立 README_MCP.md。文件必須說明:
- Server 支援哪些 method。
- Python 版本和安裝前提。
- 如何啟動 Server。
- initialize、tools/list、tools/call 的實際例子。
- 正常回應、錯誤回應和錯誤後恢復。
- unittest、demo 和 benchmark 的命令。
- 20 B 到 1 MB 的實測結果。
- 已知限制和沒有測到的整合情境。
它完成後,又逐一檢查 README 提到的檔案和命令是否真的存在,沒有把不存在的 requirements.txt 或第三方套件寫進去。最後的 README 也保留了這個專案最重要的限制:沒有使用 Claude Desktop、Cursor 或其他 MCP client,只有 stdlib client 和 PowerShell 管線。
這一輪花了 200.58 秒、9 個 Agent steps、12 次工具呼叫。時間不算短,因為它要讀程式、讀結果、組織文件,再核對命令。可是這一項不能用「字寫得順不順」判斷,真正的驗收是別人拿到 README 後能不能照著跑。
我把這項列為獨立任務,是因為實際使用 Agent 時,程式完成不是終點。沒有命令、輸出範例、限制和重現方式,下一個人還是得重新猜一次。這也是 Harness 評測裡容易被忽略、但很能看出交付品質的一段。
第五項:複製到乾淨副本,看看是不是只在原資料夾能跑
第五項是重現性測試。我要求它建立新的 repro_check 資料夾,只複製必要檔案,不能依賴原本目錄裡的暫存檔、設定檔、套件或某個剛好存在的狀態。
乾淨副本只放五個檔案:
- mcp_server.py
- input_tool.py
- test_mcp_server.py
- demo_mcp_client.py
- benchmark_mcp.py
它在副本裡重新跑三條命令:
- python -X utf8 -m unittest -v:12/12,0.886 秒,exit 0。
- python -X utf8 demo_mcp_client.py:client 0,server 0。
- python benchmark_mcp.py:20/20 正確,未知工具後恢復,server exit 0。
副本內的 benchmark 數字和原始目錄不同:20 B 中位數 0.078 ms、1 KB 0.132 ms、100 KB 1.606 ms、1 MB 16.697 ms。這不是矛盾,因為是不同次執行;真正要看的不是把兩次毫秒數硬湊成排名,而是正確率、錯誤後恢復和退出碼是否一致。
它也比對了原始檔案的 sha256。mcp_server.py、input_tool.py、test_mcp_server.py、demo_mcp_client.py 和根目錄 PERFORMANCE.md 前後一致,沒有被乾淨副本測試改掉。副本不需要 pip install、不需要 requirements、不需要網路;執行後新增的只有 pycache 和副本內由 benchmark 產生的 PERFORMANCE.md。
這項只花了 99.26 秒,是五項裡最快的一項,因為大部分實作都已經存在。但它回答了一個很實際的問題:前面那些「12/12」和「20/20」是不是只在原本那個工作目錄裡成立?這次答案是,至少在這個乾淨副本條件下,主要流程可以重現。
五項任務的費用
以下不是帳單截圖,而是 DSH session 遙測加上 DeepSeek 官方 V4 Pro 價格的估算。inputTokens 依 adapter 定義拆成 cache miss input;cacheReadTokens 是 cache hit;outputTokens 用於輸出計價;reasoningTokens 另外記錄,但不再重複加進 output,避免把同一段 token 算兩次。
官方價格頁:DeepSeek API Pricing
任務 inputTokens cacheReadTokens outputTokens reasoningTokens 費用估算 MCP Server 工程化 18,404 876,544 37,696 21,288 US$0.04398 輸入規模 benchmark 4,246 762,624 16,917 10,605 US$0.01933 程式碼審查 15,098 1,779,328 27,880 17,833 US$0.03727 文件生成 13,940 1,540,992 13,749 8,085 US$0.02361 乾淨副本重現 2,442 1,295,104 6,143 2,517 US$0.01110 五項合計 54,130 6,254,480 102,385 60,328 US$0.13529 計算使用的單價是 cache miss input 每百萬 token US$0.435、cache hit input 每百萬 token US$0.003625、output 每百萬 token US$0.87。五項任務的實際帳單沒有取得,因此 US$0.13529 只能寫成估算,不可以寫成信用卡真的被扣了這個數字。
另外還有一個後來停止的核對 session,估算約 US$0.05441。它沒有列進上面的五項,因為那一輪沒有形成完整交付結果;如果把它也算入整個 Web UI session,總估算約 US$0.18971。這兩個數字我分開列,避免把未完成工作混成成功測試的成本。
這五項實測真正測到什麼
把所有結果放在一起,我的判斷是:
第一,DeepSeek Harness 在本地 Web UI 裡確實能做多步驟工作。第一項不是只寫檔案,它要把程式接起來、執行 subprocess、看失敗、修正,再重新驗收;最後有可以直接執行的 Server、測試和 client。
第二,它可以使用工具完成相對完整的驗收閉環。第二項留下了每筆呼叫的原始數據,第三項留下了只讀 review 和邊界探針,第五項再把流程搬到乾淨副本。這幾項都不是模型自己說「完成」,而是有退出碼、hash、測試結果或逐筆數字可以核對。
第三,它的速度不能只看最後產物。最小的 20 B benchmark 本身只花不到 0.2 ms,但讓 Harness 建立 benchmark、讀結果和寫報告,整輪花了 249.87 秒。程式碼審查沒有修改程式,仍然花了 445.44 秒。對使用者來說,真正的等待時間是 Agent 的規劃和工具迴圈,不是 Server 本身的毫秒級處理時間。
第四,費用主要跟 Agent 讀了多少上下文、產生多少 output 有關,不是跟本地 Server 的 roundtrip 毫秒數直接相關。第二項的本地程式執行很快,但 DSH session 仍估算 US$0.01933;第一項因為需要多次讀檔、改檔和驗證,估算到 US$0.04398。
第五,它仍然需要人定義驗收條件。這次能得到 12/12、20/20、hash 一致和 exit 0,是因為我在任務開始前把這些條件寫清楚。如果只叫它「做一個完整 MCP」,最後很可能只得到一個看似完整、但不知道怎麼驗證的資料夾。