前言¶
DeepSeek Harness(dsh)的核心理念是「一切皆插件」:模型、工具、會話、沙箱和界面都可以換。官方倉庫是 deepseek-ai/deepseek-harness。日常驅動它的,往往是 DeepSeek、稠密 Qwen、Llama、Mistral 這類純文本模型。
把截圖貼進對話時,會撞上兩堵牆。第一堵在發送前:dsh 按路由聲明的模態檢查附件,文本模型會被直接拒絕,並點出模型名。第二堵更麻煩:如果在文本路由上硬寫 input: [text, image],附件能發出去,但上游會在回合中途返回 400 "not a multimodal model"——此時用戶消息已經落盤,會話會反覆重試一個永遠成功不了的請求。
只加一個「看圖工具」也解不開第一扇門:模型要先看見圖片,纔會決定去調工具,而那正是 dsh 拒絕的請求。社區維護者 tonyd2wild 因此做了 DeepSeek-Harness-Vision-Tools:文本模型繼續當大腦,視覺模型只負責看,圖片字節不到大腦上下文裏。本文按插件目錄頁、GitHub README、examples/dsh.md 和倉庫源碼覈對後整理。
這是什麼¶
DeepSeek-Harness-Vision-Tools 是一款會話與消息類社區插件,由 tonyd2wild 維護,許可證 MIT。目錄頁與 GitHub 均標註 10 stars;目錄收錄日期爲 2026-08-10,倉庫最近推送時間爲 2026-08-13。插件包名是 dsh-plugin-vision,package.json 中的版本爲 0.1.0。
README 開頭寫明:這是非官方社區項目,與 DeepSeek AI 無隸屬、無背書、非其維護。問題請開到本倉庫,不要報到 DeepSeek。社區插件目錄 deepseek-harness-plugin.com 是獨立站點,也不是 DeepSeek / 幻方的官方應用商店。
它解決的問題可以縮成一句:任意文本模型搭配任意視覺模型,給 dsh 兩條進圖通道。
| 入口 | 機制 | 誰觸發 |
|---|---|---|
| 聊天裏附上的圖片 | 視覺代理 shim/vision_shim.py |
自動攔截,模型到達前改寫 |
| 磁盤上的圖片文件 | analyze_image 工具 plugin/vision/ |
智能體按需調用 |
兩條通道互補,不是主備關係。工具接不住聊天附件:附件必須先到模型,模型纔會去調工具。代理也撿不起智能體還沒放進消息的磁盤文件。圖片只發給視覺模型;大腦看到的是 [Image: ...] 這類文字。
核心功能¶
大腦和眼睛分開,兩端都由你選¶
倉庫刻意不寫死模型。維護者自己的 DeepSeek 構建和硬件組合別人很難複用,所以配方只留兩個槽位:
| 槽位 | 放什麼 | 建議 |
|---|---|---|
| 大腦(文本) | dsh 已經在跑的任意 OpenAI 兼容文本模型 |
沿用現有模型 |
| 眼睛(視覺) | 代理和/或工具去調的本地 VLM | 按 fast / detailed 分檔 |
同一套眼睛可以服務兩扇門。工具按調用選擇後端;代理通過 --vision-model 指定一個:
| 角色 | 適用 | 倉庫舉例 |
|---|---|---|
fast(默認) |
顏色、版面、粗內容 | 約 0.8B 的小 VLM,如 Qwen3.5-0.8B |
detailed |
小字、細部、偏 OCR 的工作 | 更大的 VLM,如約 27B 的 Qwen2.5-VL / Qwen3-VL |
MODELS.md 給出的 fast 默認是 Qwen3.5-0.8B:Apple Silicon 走 MLX(mlx-community/Qwen3.5-0.8B-MLX-8bit),Windows / Linux / NVIDIA 走 llama.cpp(GGUF + mmproj)。活體佔用大約 Mac 統一內存 2–3 GB,或 PC 約 2 GB 顯存。不一定兩檔都開,先跑 fast 即可。
Ollama 目前還不能加載 Qwen3.5 的獨立 mmproj,默認 fast 模型不能走 Ollama。若堅持用 Ollama 一行命令,倉庫建議改 Moondream 或 Qwen2.5-VL,再把後端指到 http://127.0.0.1:11434/v1/chat/completions。
視覺代理:聊天附件在到達大腦前變成文字¶
代理是一個只依賴 Python 標準庫的本地 HTTP 服務,對外說 OpenAI API,夾在 dsh 和文本上游之間:
POST /v1/chat/completions:把每條消息裏的image_url塊換成{"type":"text","text":"[Image: ...]"};若整條消息都變成文本,再收成普通字符串(有的服務器對 block 數組更挑剔)。GET /v1/models以及其他 GET 原樣轉發,方便dsh做模型發現。- 流式響應按字節轉發。
dsh每個回合都在流式輸出,緩衝會卡住界面。 - 視覺失敗時降級,不拋死:塊變成
[Image: (image could not be analyzed: ...)],回合仍能結束。 - 請求體上限 64 MB,因爲圖片是 base64 內聯的。
dsh 的模型路由要指向代理,並聲明 input: [text, image]。這句話對代理爲真,對文本大腦爲假。路由描述的是它正在對話的對象。
analyze_image:磁盤文件由智能體決定何時看¶
plugin/vision/index.js 用 @deepseek-ai/dsh-tools 的 defineTool() 註冊模型可見工具。參數來自源碼:
| 參數 | 是否必填 | 含義 |
|---|---|---|
path |
是 | 要分析的圖片路徑 |
backend |
否 | fast 或 detailed(以掛載時實際配置爲準) |
prompt |
否 | 問視覺模型的問題,默認 "Describe this image in detail." |
工具把文件讀成 base64,POST 到對應後端的 /v1/chat/completions,把返回的純文本寫進工具結果。未知後端會拋錯並列出合法名稱,沒有靜默回退,避免把 detailed 打成 fast 卻看不出來。
讀文件優先走 ctx.fs(遵守工作區邊界和審批策略)。若退化到 readFileSync,會繞過沙箱,模型理論上能通過這個工具讀盤上任意文件。倉庫要求:只在受信任、有人值守的機器上依賴這條回退,無人值守前先把門閂上。
安裝與啓用¶
插件目錄頁給出的安裝命令如下,在 DeepSeek Harness 終端執行:
dsh plugin add github:tonyd2wild/DeepSeek-Harness-Vision-Tools
目錄頁同時寫了可復現寫法:把 commit 哈希接到倉庫名後面。
dsh plugin add github:tonyd2wild/DeepSeek-Harness-Vision-Tools#commit
插件以當前 dsh 進程的權限運行,安裝時可能執行代碼。安裝前應檢查源代碼倉庫和許可證。
這個倉庫不是「只丟一個 JS 插件」那麼簡單:代理是獨立 Python 進程,工具在 plugin/vision/。要兩扇門都工作,需要按 README 把眼睛服務、代理和工具分別拉起來。前置條件(README「What you need」):
- 已有
dsh在跑的文本模型(任意 OpenAI 兼容端點) - 一臺本地 VLM;最小的
fast檔大約還要 2–3 GB 餘量 - Python 3.8+(代理只用標準庫,零第三方依賴)
pnpm(dsh plugin會調它;只裝工具時需要)- 視覺運行時:Mac 用 MLX(
mlx-vlm),Windows / PC 用 llama.cpp(或 Ollama 跑回退模型)
快速起步:
git clone https://github.com/tonyd2wild/DeepSeek-Harness-Vision-Tools
cd DeepSeek-Harness-Vision-Tools
cp .env.example .env # 把端點改成你自己的主機
./setup.sh # 拉起本地視覺服務(RUN_PROXY=1 時連代理一起起)
門 1,代理(聊天附件):
python3 shim/vision_shim.py --port 8900 \
--upstream http://127.0.0.1:8000 \
--vision-url http://YOUR_FAST_VISION_HOST:8081/v1/chat/completions \
--vision-model your-fast-vlm
環境變量與 CLI 一一對應,CLI 優先:SHIM_PORT / --port,VISION_TARGET / --upstream,EYES_URL / --vision-url,EYES_MODEL / --vision-model。健康檢查:
curl http://127.0.0.1:8900/health
門 2,工具(磁盤文件)。先把插件拷到穩定路徑,並按倉庫「陷阱 2」改 package.json 裏 @deepseek-ai/dsh-tools 的 link:,指向當前 Harness 自帶的那一份,不要裝 npm 上的舊包(文檔寫的是 npm 上的 0.0.1-rc.1 比 Harness 自帶的 0.1.0-rc.6 更老,而且會去引一個從未發佈的包):
cp -r plugin/vision ~/.dsh/plugins/vision
dsh plugin --profile <p> add link:~/.dsh/plugins/vision
<p> 換成實際 profile,例如 web 或 headless。插件從 profile 目錄解析,不要丟進安裝目錄的 node_modules,否則所有 profile 啓動都會 ERR_MODULE_NOT_FOUND。每個要用的 profile 都要加一次。
典型用法¶
把一條 dsh 路由指到代理¶
模型路由寫在 $DSH_HOME/settings.yaml 的 pi-ai 提供方塊裏。baseURL 指向代理,並聲明圖文輸入。下面是 examples/dsh.md 的佔位配置,主機和模型 id 換成你的:
llm-pi-ai:
providers:
vision-proxy:
displayName: Your Text Model (via vision proxy)
apiKeyEnv: YOUR_PLACEHOLDER_KEY_ENV
api: openai-completions
baseURL: http://127.0.0.1:8900/v1
models:
- id: your-text-model-id
contextWindow: 262144
maxTokens: 32768
input: [text, image]
無密鑰的上游也要填 apiKeyEnv,指向任意非空環境變量。省略的話 pi-ai 會去做環境發現,找不到就報 PI_AI_ERROR: No API key。
再留一條直連上游、不聲明 input 的後備路由,代理掛了還能繼續幹活:
text-only-direct:
displayName: Your Text Model (direct, no vision)
apiKeyEnv: YOUR_PLACEHOLDER_KEY_ENV
api: openai-completions
baseURL: http://127.0.0.1:8000/v1
models:
- id: your-text-model-id
contextWindow: 262144
maxTokens: 32768
模型路由熱加載,不用重啓。保存後在模型選擇器裏選代理那條,附上一張圖即可。
給 analyze_image 配兩個後端¶
在插件配置塊或環境變量裏寫:
export VISION_FAST_URL=http://YOUR_FAST_VISION_HOST:8081/v1/chat/completions
export VISION_FAST_MODEL=your-fast-vlm
export VISION_DETAILED_URL=http://YOUR_DETAILED_VISION_HOST:8010/v1/chat/completions
export VISION_DETAILED_MODEL=your-detailed-vlm
智能體調用形態是 analyze_image(path, backend, prompt)。例如對截圖或票據覆蓋提示詞:prompt: "List every object and any visible text."。
Web 表面上,面向模型的工具行在宿主層是關掉的,要靠 agent preset 才能看見。不要去改隨安裝分發的 standard preset,升級會被覆蓋。建一個新 id 的用戶 preset(例如 standard-vision),組合 web 和 analyze_image。用戶 preset 不能複用已分發的 id,否則會被靜默遮住。然後在 settings.yaml 裏設默認(熱加載):
agent-presets:
default: standard-vision
Preset 第一次開會話才掛載。看乾淨啓動日誌不能證明工具在;要開一場真實會話。
告訴智能體:它並沒有變成多模態模型¶
dsh 會把 $DSH_HOME/AGENTS.md 讀進每場會話。代理生效後,模型常會推斷自己被切到了視覺路由。倉庫提供了一段可粘貼說明,核心是:你仍是原來的文本模型;圖已經被代理或工具寫成了 [Image: ...];請說「描述表明……」,不要說「我能看見……」。
倉庫給出的端到端覈對方法¶
文本模型拿到圖片塊時,會編一段看起來合理的描述,讀起來像成功。倉庫用模型猜不到的純色圖做過觀察:
- 非流式:純綠 → “The image is a solid, bright green.”
- 流式:純藍 → “a solid, uniform field of deep, saturated blue”(5 個 chunk,乾淨的
[DONE]) - 同一套文本模型,直接塞圖片會返回
400 "is not a multimodal model",用來證明字來自代理的視覺腿,不是大腦
復現方式:生成幾張純色 PNG,聊天裏附一張問顏色(代理路徑),或讓 analyze_image 指向文件(工具路徑),覈對描述是否對得上。
適用場景與注意事項¶
適合:希望保住現在這顆文本大腦,又要讓 dsh 對截圖、照片、攝像頭幀有情境感知的人。倉庫原話是:它附加能力,不接管部署;代理是獨立進程,隨時可殺;工具只是多一個智能體可以調用的能力。
不適合當成原生多模態。倉庫「Honest limits」寫得很直:
- 描述是有損的。細部、精確空間關係和小物體可能丟。版面推理請換更大的
detailed模型。 - 小 VLM 讀圖中文字弱。
fast用體積換精度。OCR 重的工作把代理或工具指到更大的 VLM,並接受額外內存和延遲。 - 大腦推理的是字,不是像素。多數智能體工作(屏幕上有什麼、照片裏是什麼、讀一條報錯)夠用;關鍵 OCR 或細粒度視覺推理不夠。
input: [text, image]是聲明,不是檢查。只對真正收圖的端點聲明:代理,或真正的 VLM。寫在純文本模型上,會在消息落盤後中途 400。
另外幾條來自 examples/dsh.md 的坑:
- llama.cpp 路徑必須帶
--mmproj(視覺投影器)。backends/pc_llamacpp.sh會自動傳。漏了的話 llama.cpp 會靜默按純文本跑,描述全是空話。這是最常見的「進程在跑但看不見」。 - Windows 絕對路徑在 preset 裏可用,在 profile patch 裏會把
C:當成 URL scheme,報ERR_UNSUPPORTED_ESM_URL_SCHEME。兩邊都用裸包名更穩。 - 改
settings.yaml(模型路由、默認 preset)不用重啓;改 preset 的agent.cordis.yml也不用,下場會話按文件時間戳換代;改插件index.js要重啓(ESM 按進程緩存);代理本身只重啓代理進程,dsh不受影響。
若文本大腦跑在 DGX Spark 上,倉庫認爲 fast 視覺模型大約 2–3 GB,通常可以和大腦放在同一臺機器,把 --vision-url 指到 127.0.0.1。Spark 上報的「空閒」內存會高估 CUDA 實際可用量(GPU 與 CPU 共用一塊池);小 fast 多半放得下,大 detailed VLM 未必。先確認服務起來再依賴。
持久化方面:代理可用 autostart/ 裏的 Windows 登錄腳本(.vbs)或 Linux systemd user unit;工具靠上面的用戶 preset。兩者獨立。
小結¶
DeepSeek-Harness-Vision-Tools 做的不是把 dsh 換成多模態模型,而是在聊天附件和磁盤文件兩條入口上,把「看」交給本地視覺模型,把「想」留給原來的文本模型。目錄頁安裝命令是 dsh plugin add github:tonyd2wild/DeepSeek-Harness-Vision-Tools;真要兩扇門都通,還要按 README 起視覺服務、代理,並按 profile 用 link: 掛上 plugin/vision。
安裝前請閱讀源碼和 MIT 許可證。插件以當前 dsh 進程權限運行。問題請開到本倉庫,不要報到 DeepSeek。
- 插件目錄:https://deepseek-harness-plugin.com/zh-CN/plugins/deepseek-harness-vision-tools/
- GitHub:https://github.com/tonyd2wild/DeepSeek-Harness-Vision-Tools
- 集成說明:倉庫內
examples/dsh.md - DeepSeek Harness 官方倉庫:https://github.com/deepseek-ai/deepseek-harness