# DSH 接本地 AI：工具能用之後，瓶頸才開始浮現

作者：Ian
發布：2026-10-13
更新：2026-10-13
實作紀錄期間：2026-10-11 至 2026-10-12
正式網址：https://ianinfra.com/knowledge/dsh-local-ai-bottlenecks/

模型能在本機回答問題之後，下一步是讓它做事：讀檔、建立資料、修改文件，再用程式檢查結果。我選擇接進既有的 **DSH（DeepSeek Harness）**，讓它管理工具與對話迴圈。

這輪確實完成了基本檔案任務，也遇到一個很有代表性的落差：一次診斷加日誌整理，完整流程花了 **23 分鐘**；但其中一段可解析快照裡，40 次工具執行合計只有 **27.808 秒**。工具本身的執行速度，解釋不了大部分等待。

本文記錄我與 AI 工具協作核對的歷史結果。第一篇的硬體受控基準、這篇的 agent 流程耗時，以及介面顯示的 tok/s，各有不同量測範圍。

## 實作接線：DSH 管工具，Strata 做本地推論

| 層級 | 本次角色 |
| --- | --- |
| DSH | 維護 session、提供工具、執行工具呼叫、把結果送回下一輪 |
| Provider | strata-local，使用 openai-completions 路徑 |
| API | Strata 的本機 OpenAI 相容端點，base path 為 /v1 |
| 模型 ID | qwen3.8-flash-next-iq3_s |
| 模型設定 | 非思考模式，131,072-token 窗口 |
| 已見實際工作 | read、write、edit、pwsh 等工具事件 |

一次任務的路徑是：使用者提出工作 → DSH 組合提示與工具資訊 → 本地模型提出工具呼叫 → DSH 執行 → 結果回到上下文 → 模型決定下一步或回答。

這個區分很重要。Strata 直接聊天的 MCP 檢查當時仍是 **servers=[]、tools=0**；DSH 可以提供工具，不代表 Strata 自己的聊天介面已裝好 MCP。也不能因為模型在本機，就宣稱整條知識庫檢索流程都離線：檢索階段仍可能依賴雲端。

## 第一個瓶頸：一個任務會反覆支付模型等待成本

第一輪同時做工具診斷與日誌整理。完整 23 分鐘來自我的使用回報與更正；可解析的匯出檔只涵蓋其中一段，約 **12 分 48 秒**。以下數字僅屬於這份快照。

| 快照中的量測 | 結果 |
| --- | --- |
| 39 步開始到首個已記錄串流事件，合計 | 250.949 秒 |
| 首個串流事件到各步 assistant/message，合計 | 488.972 秒 |
| 40 次有配對結果的工具執行，合計 | 27.808 秒 |
| 第二輪工具呼叫 | 41 次，7 種工具 |
| 整個匯出檔，含前一輪 | 233 行，43 筆 tool/call、42 筆 tool/result |

前兩段合計約 739.921 秒，約佔這段快照時間的 **96%**。這裡是模型回應階段，包含處理、等待與串流，不能全算成 GPU 推論；也不能把比例外推成完整 23 分鐘的精確分布。

第二輪 41 次呼叫的組成如下。它與整個匯出檔的 43 次不是同一範圍。

| 工具 | 次數 |
| --- | --- |
| pwsh | 33 |
| write | 2 |
| read | 2 |
| edit | 1 |
| glob | 1 |
| load_workspace_dependencies | 1 |
| todo_write | 1 |

中間還遇到解壓格式不支援、安裝路徑錯誤、暫存寫入遭拒與腳本未簽署。檔案存在與雜湊核對約在本輪第 **4 分 11 秒**完成，解壓日誌直到約第 **9 分 3 秒**才成功。這些繞路會觸發更多模型輪次，所以「請模型自己分析日誌」也會改變原本要量的工作量。

## 第二個瓶頸：工具回傳越多，下一輪越重

一次目錄列舉回了 **49,931 字元**。緊接著一輪記錄 inputTokens=**14,767**，首個串流事件前等待 **47.705 秒**。

這是一個具體的上下文膨脹觀察，尚不是控制其他變因後的因果實驗。但它已足以提示下一輪測試：工具結果應只保留完成任務需要的路徑、欄位與錯誤片段，再比較提示長度與完整耗時。

當工具迴圈持續累加，速度不只取決於生成每個 token 多快。每次重新送出的工具描述、歷史對話、目錄輸出與錯誤訊息，都可能增加 prefill 或後續決策成本。

同一快照另有 inputTokens=**28,112**、outputTokens=**6,243**、cacheReadTokens=**1,148,409**。這些是逐步累計欄位，不能把 114 萬 cache tokens 說成單次塞進超過百萬 tokens 的上下文。

## 第三個瓶頸：快取有效，要看請求長什麼樣子

硬體測試中，一次 **22,664-token** 請求花 **34 秒**讀提示、**19 秒**生成 524 tokens，prefill 約佔兩段時間的 **64%**。這能解釋為什麼只盯 decode tok/s，常常錯過主要等待。

我也測了 Strata 的 message-boundary cache。情境刻意固定長歷史，只替換最後一則短訊息：

| 配置 | 冷輪 | 後續輪次 |
| --- | --- | --- |
| 基準 | 14,162 read，約 33.5 秒 | 0 reused＋14,162 read，仍約 33.5 秒 |
| 開關開啟 | 14,162 read，約 34.0 秒 | 14,146 reused＋16 read，約 0.4 秒 |

**約 84 倍**是這個特定重用段落的時間比，不是 DSH 整體加速。第一次測試的前綴只有 **7,551 tokens**，未達當時文件的 **8,192** 門檻，因此沒有觸發；修正測試設計後才得到上表。文件的另兩項條件是尾端不超過 **1,024 tokens**，以及固定前綴逐字相同。

我的實際 DSH 聊天是累加歷史，當時觀察第一句約 30 秒、第二句明顯變快，符合既有 prompt cache 可重用的形狀；沒有證據顯示再開 message-boundary 開關能帶來額外收益。知識庫則每題送全新單輪請求，不符合這次固定長歷史的測試情境，因此最後沒有採用。

「功能有加速效果」與「這個應用能取得該效果」需要兩次驗證。原始效能筆記曾把 SELECT／生成／REVIEW 當成三次本地模型呼叫，後來查碼修正為檢索流程階段；公開結論採用修正後的資料流。

機制參考：[Strata message-boundary cache 文件](https://github.com/Niko1221/Strata/blob/main/docs/MESSAGE_BOUNDARY_CACHE.md)。本文門檻與實測以 2026-10-12 的版本紀錄為準，上游可能更新。

## 第四個瓶頸：成功旗標與工具清單都不等於驗收

這輪核對日誌時，修正了三個容易被成功報告掩蓋的問題。

| 表面訊號 | 實際能證明什麼 |
| --- | --- |
| 登錄了 29 個工具 | 只證明內部清單；第二輪實際呼叫 7 種，其他未測 |
| 42 筆結果的 message.isError 全為 false | 不能證明命令成功，內文仍出現非零 exit code 與錯誤 |
| 另一個 provider 有工具清單卻 0 次呼叫 | 只證明該 session 沒有呼叫；缺實際 HTTP request body，不能定案是 API 相容層故障 |

因此工具驗收要同時看 **exit code、stderr、回傳內容，以及實際產物**。對 provider 問題，則要在去除憑證與私人內容後，核對送到 API 的工具 schema、請求與回應；模型自述「我沒有工具」不能取代這些證據。

## 把任務縮小後，完成了什麼？

下一輪開新 session，只做一個受限檔案任務：建立 CSV，讀回資料，寫摘要，改狀態，再用 PowerShell 的 Import-Csv 獨立計算。

| 品項 | 數量 | 單價 | 小計 |
| --- | --- | --- | --- |
| A | 2 | 120 | 240 |
| B | 3 | 80 | 240 |
| C | 1 | 250 | 250 |
| 合計 | — | — | **730** |

結果回報摘要含「狀態：已驗證」，沒有「狀態：初稿」。input.csv 為 **38 bytes**，summary.md 為 **165 bytes**。這輪材料是模型完成回報與 UI 截圖，未另取得原始 JSONL；產物大小與時間都保留這個證據等級。

| 回報項目 | 數值與界線 |
| --- | --- |
| 工具內取時 | 02:49:39–02:50:17，約 **38 秒** |
| 工具呼叫 | **9 次**：pwsh×2、write×2、read×3、edit×2 |
| 重試 | **1 次** |
| UI | 1 輪 8 步、35 tok/s、71.5K tok，另顯示緩存命中 87%／7% |

38 秒從首個 pwsh 取時開始，不含使用者送出到第一個工具的等待，也不含最後回答生成。UI 的步數與工具呼叫數不同；35 tok/s 與緩存百分比的完整計算口徑未查明，不用來推導引擎速度或命中率。

這一次重試也有明確原因：測試提示要求 write 後直接 edit，卻漏了工具規則中的「編輯前先 read」。補讀後修改成功。這個額外失敗來自任務流程設計，不能直接扣成模型能力不足。

因此，**23 分鐘與 38 秒不構成加速倍數**。前者包含診斷與日誌整理，後者是受限小任務，計時邊界還不一樣。同樣地，先前 UI 的 8.4 tok/s 與後來 35 tok/s，約 4.2 倍的顯示值比，也不是受控效能進步。

## 接下來該怎麼驗，而不是繼續混在一起測

下面是尚未完成的新一輪驗收設計，不把預期結果當成成果。

1. 固定新 session、模型、非思考設定與相同資料；只允許讀寫指定測試目錄。
2. 在 edit 前明確加入 read。修正後預期八次工具呼叫、零重試，實際仍需跑過確認。
3. 不混入套件安裝、環境搜尋或日誌解壓，讓工具任務本身保持固定。
4. 從按下送出計到最後回答，另外保留每輪等待、工具執行、提示長度與輸出量。
5. 結束後由外部核對產物；不要追加「請自行分析所有日誌」而改變被量測流程。
6. 若比較不同 provider，使用相同任務與獨立新 session，每次只改一個變因，保存去識別請求與回應。

更大型的程式修改、長時間穩定性、剩餘工具、網路搜尋與整體回答品質，都不能由這個 CSV 任務代為驗收。

## 我對本地 Agent 的實作判斷

DSH 接入這份本地模型，已經讓讀寫、編輯與命令驗證成為可觀察的工作流程。下一個問題是：在真實任務裡，能否控制每輪上下文、避免無效繞路，並用產物證明完成？

這輪資料把優先順序拉得更清楚：先限制工具輸出的範圍，改善任務步驟，再量完整等待；模型的品質、硬體吞吐與 harness 行為則各自保留測試。這樣才知道下一次改善來自哪裡，也知道哪些失敗還沒解決。

## 資料來源與閱讀範圍

數據主要取自 2026-10-12 的工具診斷更正紀錄與效能驗證紀錄。第一輪有經解析的 JSONL 與產物雜湊核對；完整 23 分鐘由使用者回報；第二輪約 38 秒來自完成回報與 UI 截圖。原始 session、私人檔案與主機位置未公開。

硬體與模型的完整配置、三題品質測試及七項優化評估，見：[16GB 外接顯卡跑 125B 本地 AI](/knowledge/local-ai-egpu-128k/)。延遲量測方法見：[RAG 變快了多少？先說清楚量的是哪一段](/knowledge/rag-latency-evidence/)。
