生命不息,折腾不止。dsh 自己就是 DeepSeek 的模型,但它偏偏设计成「谁都能接」——这集把自定义 Provider 讲透,一个框架通吃所有 OpenAI 兼容的大模型。

前两集咱们把 Harness 装起来了、也写了第一个插件让 Agent 会调工具。但这套框架真正香的地方,在于它默认就是个「多模型挂载台」:DeepSeek 自己的模型只是其中一个插件,Claude、GPT、Gemini、本地 Ollama,只要走的是 OpenAI 兼容接口,都能塞进来,而且不换工具、不重装、只换一个 key 的事。今天就把「自定义 Provider」这条进阶路线一次说清。

一、先分清:目录供应商 vs 自定义 Provider

打开 Settings → Models,点「添加供应商(Add provider)」时,你会看到两条路:

  • 目录供应商(catalog provider):Anthropic、OpenAI、Google 这类官方渠道,dsh 已经把 SDK 和字段模板给你备好了(默认安装里甚至把 @anthropic-ai/sdk、@google/genai 这些依赖都拉进来了)。选它,填 key 就行,不用写 base URL。
  • 自定义 Provider(Add a custom provider):面向「公司网关、中转站、本地模型、自建端点」这类不是官方目录里的入口。需要你自己填 Provider ID、Base URL、协议和模型 ID。

今天的主角是后者。原因很现实:目录供应商填的是官方的 base URL 和官方 key,而大多数人真正用的是中转站 / 网关——一个 OpenAI 兼容入口,背后聚合了好几家模型,一个 key 通吃。这正是「自定义 Provider」的用武之地。

二、添加自定义 Provider:五个字段填对就通

点「Add a custom provider」后,表单里这几个字段是核心,我按「必须填对」的优先级排一遍:

字段 怎么填 说明
Provider ID 小写字母,如 my-gateway 一经保存永久生效,因为会话、默认配置、凭据引用全都指向它。想改名等于「新建一个再删掉旧的」
Base URL 网关地址,如 https://ai.aklibk.com/v1 通常带 /v1 后缀,具体看你中转站文档
协议(API) openai-completions 必须选网关实际用的那种,绝大多数中转站是 OpenAI Chat Completions 协议
API Key 你的网关密钥 见下一节,建议别写死在这里
模型 ID 至少一个,如 deepseek-v4-flash、claude-sonnet-4-5 至少要填一个模型,否则路由是空的

填完保存,模型路由立即生效,不用重启服务。这时候新建一个会话,模型选择器里就能看到你刚加的模型了。

一个容易踩的坑:Protocol 别选错。官方讨论区里有人接「只支持 system role 的 OpenAI 兼容端点」时因为协议对不上,system prompt 被当成 developer role 发出去直接报错。所以填之前先确认你的网关到底走的是 openai-completions 还是别的协议,拿不准就查网关文档。

三、密钥别写死:用 apiKeyEnv 指向环境变量

表单里直接贴 key 有个隐患:key 一旦存进去就再也取不出来(页面只会回显一个打码的描述符,密钥实际落在 $DSH_HOME/.credentials.yaml 里,且是只写不读)。这在多台机器、或者想把配置提交到 git 时很麻烦。

更稳的做法是不存密钥,只存引用。dsh 支持用环境变量托管密钥,配置里写变量名而不是密钥本身:

1
2
llm-deepseek:
apiKeyEnv: MY_DEEPSEEK_KEY

这个 apiKeyEnv 是每次请求时实时解析的——启动时变量不存在也不会崩,只有真的发起请求、变量又没设时,才会报 MISSING_CREDENTIAL。所以你的启动方式变成:

1
2
export MY_DEEPSEEK_KEY="sk-你的密钥"
npx @deepseek-ai/dsh web

好处很直接:密钥不进配置文件、不进 git、换机器换 key 只改环境变量。凭据的解析顺序是固定的——先继承环境变量,再读 $DSH_HOME/.credentials.yaml,然后才是调用目录和 $DSH_HOME 下的 .env——记住这个顺序,排查「明明设了 key 却报 MISSING_CREDENTIAL」时很有用。

四、接多模态:给模型开「看图」权限

自定义 Provider 表单里填进去的模型,dsh 默认按纯文本处理——表单上根本没有让你勾「支持图片」的地方。想让 Agent 看图(比如丢给它一张截图让它改 UI),得手动改 ~/.dsh/settings.yaml:

1
2
3
4
5
6
7
8
9
10
llm-pi-ai:
providers:
my-gateway:
apiKeyEnv: GATEWAY_API_KEY
api: openai-completions
baseURL: https://ai.aklibk.com/v1
models:
- id: legacy-chat
- id: vision-preview
input: [text, image]

注意这里的细节:

  • input: [text, image] 是逐个模型声明的。上例里 legacy-chat 只能收文本,vision-preview 额外能收图片。
  • 如果你这个网关下所有模型都支持图片,可以偷懒设一个兜底字段 defaultInput: [text, image],就不用每个模型写一遍了。
  • 目录供应商(catalog)没有 models 列表,想单独给某个模型收窄能力,用 modelOverrides 按 id 覆盖。
  • DeepSeek 自家的 chat-completions 路由是纯文本的,改不了,别指望它看图。

这一段 YAML 属于「配置文件手改」,不同版本字段名可能有微调,具体以官方文档为准;但 input: [text, image] 这条思路是当前版本通用写法。

五、实战:一个框架,接中转站 + 接本地模型

把上面串起来,给你两条最常见的落地路线:

路线 A:接中转站用 Claude / GPT

国产框架 dsh 最大的卖点是多模型对接 + 价格便宜——框架是免费的,模型成本另算。想用 Claude 或 GPT,直接走中转站(比如 ai.aklibk.com),国内直连、免绑卡、人民币按量付费,比直接刷外币卡省心也省钱。配置就两步:

  1. Settings → Models → Add a custom provider,填 Provider ID、Base URL = https://ai.aklibk.com/v1、协议 openai-completions、贴中转站 key;
  2. 模型 ID 填中转站支持的模型名(如 claude-sonnet-4-5、gpt-5),保存即用。

路线 B:接本地 Ollama 白嫖

本地跑模型零成本,dsh 也能接。先起 Ollama,再走同一套「自定义 Provider」流程,Base URL 填 http://localhost:11434/v1,协议 openai-completions,模型 ID 填你 ollama list 里的名字。适合拿小模型做试验、不想花一分钱调 API 的场景。

两条路线共用同一个框架,这正是 Harness「一切皆插件」的爽点:模型只是挂在上下文里的一个插件,换哪个都不动你的工具、文件、会话。

六、小结

回顾这集的关键点:

  1. 目录供应商填 key 就够,自定义 Provider 才是接网关/中转站/本地模型的正确姿势;
  2. 五个字段里 Provider ID 永久、协议必须选对,这两条最容易翻车;
  3. 密钥用 apiKeyEnv 托管环境变量,别写死在配置里;
  4. 想看图,手动改 settings.yaml 给模型加 input: [text, image]。

自定义 Provider 只是「多模型对接」的一半。下一半更有意思:dsh 有个 Creator(创造)模式,能让 Agent 在运行时自己写插件、给自己挂新工具——等于让 AI 改造自己的「能力面板」。这就是下集要拆的东西。

生命不息,折腾不止。下一集《DeepSeek Harness Creator 模式:让 Agent 自己写插件改造自己》——七行代码看懂「动态挂载工具」是怎么一回事,顺带把运行时审批和沙箱安全一起讲清楚。