发布日期:2026-09-02 | 话题标签:DeepSeek Harness、DSH、模型配置、自定义提供方、OpenAI 兼容网关、llm-pi-ai

DeepSeek Harness(DSH)是 DeepSeek AI 于 2026 年 8 月开源的 Agent Harness,模型在它的"一切皆插件"架构里只是一种可替换能力,由两个官方 LLM 适配器插件提供:dsh-llm-deepseek 直连 DeepSeek 官方 API,dsh-llm-pi-ai 基于 Pi 项目的 pi-ai 库承载其他所有提供方。接入非 DeepSeek 模型有三种方式,从易到难依次是:在 Web UI 的"设置 → 模型"里添加目录提供方(Anthropic、OpenAI 等,填 API Key 即可);添加自定义提供方,填写 Provider ID、基础 URL、协议和模型列表,把任意 OpenAI 兼容网关、国内多模型平台或本地 vLLM/Ollama 服务接进来;直接编辑 $DSH_HOME/settings.yamlllm-pi-ai 分节,解锁表单没有的字段,例如视觉模型的 input: [text, image]、修复网关拒绝请求的 compat 开关、推理等级重命名。自定义路由目前支持三种协议:openai-completionsopenai-responsesanthropic-messages。所有配置在下一次请求生效,不需要重启服务。本文基于 DSH 官方文档《配置模型》、两个适配器包的 README 和自动生成的配置目录,逐条给出可直接复制的 YAML 和排错对照表。


DSH 的模型层是怎么组织的

DeepSeek Harness 把模型接入拆成两个独立插件,一个只管 DeepSeek,一个管其他所有提供方,两者可以同时挂载。

插件

路由名

负责什么

默认模型

@deepseek-ai/dsh-llm-deepseek

deepseek-official

DeepSeek chat-completions 协议直连,支持 thinking 强度、图片 Files API

deepseek-v4-flashdeepseek-v4-prodeepseek-v4-flash-vision-exp,均 1M 上下文

@deepseek-ai/dsh-llm-pi-ai

由你命名

通过 pi-ai 库承载目录提供方和手工声明的网关路由

取决于目录或你的声明

dsh-llm-pi-ai 的 README 把它的定位说得很清楚:"OpenAI 兼容网关或自托管服务器只是配置,而非代码变更。"整个配置面就是一个 providers 字典,每个键是一条路由,请求时用 provider 字段选择。

三个前置概念:

  • 目录提供方:pi-ai 已内置端点、协议和模型列表的提供方(Anthropic、OpenAI、Google、Azure、Bedrock、Mistral、Groq、xAI、OpenRouter、Ollama 等,pi-ai 官网称"15+ 供应商")。接入只需凭据。

  • 自定义提供方:目录里没有的地址,必须自己写 apibaseURL 和非空 models 列表。

  • 凭据引用:配置文件里永远不放明文密钥,apiKeyEnv 写的是环境变量名或凭据存储的引用;Web UI 保存的密钥落在 $DSH_HOME/.credentials.yaml


方式一:Web UI 添加目录提供方

对 Anthropic、OpenAI 这类目录内提供方,在"设置 → 模型"点击"添加提供方",选中后填 API Key 保存即可,端点、协议和模型列表由目录提供。

步骤:

  1. 启动 DSH(npx @deepseek-ai/dsh web,默认 http://127.0.0.1:3080),打开 设置 → 模型

  2. 点击 添加提供方,从列表选择目标提供方

  3. 填入 API Key,保存。密钥是只写的,页面之后只显示脱敏描述符

  4. 回到会话页,模型选择器里会出现该提供方的模型,选中即成为新会话默认值

两个例外要注意:

  • 原生认证的提供方不能只填 Key。官方文档明确:Bedrock、Vertex、Azure 和 Codex 分别需要 AWS 凭据与区域、ADC 项目、api-version 和 OAuth。只填 API 密钥字段无法完成配置。

  • Codex 走登录流程dsh-llm-pi-ai 支持通过 harness 授权流程做 OAuth 登录,凭据存在凭据存储的 llm-pi-ai/<provider id> 记录里,会自动刷新;退出登录即删除记录。


方式二:Web UI 添加自定义提供方

公司网关、国内多模型平台、自建 vLLM 或 Ollama,都走"添加自定义提供方",需要填五项:Provider ID、基础 URL、API 协议、凭据、至少一个模型。

字段

填什么

注意

Provider ID

小写连字符标识,如 my-gateway

永久不可改,会话记录、模型默认值、凭据引用都绑定它。要改名只能新建再删旧

显示名称

选择器里的标签

可随时改

基础 URL

网关地址,如 https://gateway.example/v1

可随时改

API 协议

openai-completions / openai-responses / anthropic-messages 三选一

源码 provider.ts 的协议表只有这三种,每条路由只能一种协议

凭据

API Key

存入凭据存储

模型

至少一个模型 ID

可点 获取可用模型 让 DSH 调 GET /models 自动拉取

"获取可用模型"只对自定义路由发网络请求,目录提供方直接读本地目录。拉取返回 401 说明 Key 有问题;网关没有 /models 端点就手动输入模型 ID。

保存后同样在下一次请求生效。表单没有的字段(图片模态、兼容开关、推理等级)要走方式三。


方式三:直接写 settings.yaml

$DSH_HOME/settings.yaml 里的 llm-pi-ai 分节是配置的完整真源,Web UI 只是它的子集。一条自定义路由的完整写法如下:

llm-pi-ai:
  providers:
    my-gateway:
      displayName: My Gateway
      apiKeyEnv: GATEWAY_API_KEY
      api: openai-completions
      baseURL: https://gateway.example/v1
      defaultContextWindow: 262144
      defaultMaxTokens: 32768
      compat:
        supportsDeveloperRole: false
        maxTokensField: max_tokens
      models:
        - id: chat-model
          name: Chat Model
          contextWindow: 131072
        - id: vision-model
          input: [text, image]
        - id: reasoner
          compat:
            thinkingFormat: deepseek
          reasoningEfforts:
            off:
            low: low
            high: high

字段含义(来自 dsh-llm-pi-ai README 和配置目录):

字段

默认值

含义

apiKeyEnv

按请求解析的凭据引用;省略则交给 pi-ai 的环境发现

api

目录协议

协议格式,目录外路由必填

baseURL

目录端点

路由上所有模型共用

models

已安装目录

整体替换路由的模型目录

modelOverrides

只改目录里的个别模型,其余不动;不能与 models 并存

compat

目录检测

请求形状兼容开关

defaultContextWindow

262,144

未声明容量的模型回退值

defaultMaxTokens

32,768

未声明输出上限的模型回退值

defaultInput

[text]

未声明模态的模型回退值

headers

附加请求头

retryPolicy

normal,5 次

重试策略

国内多模型平台的接法是同一套配置。以七牛云 Token Plan 为例,它兼容 OpenAI 与 Anthropic 两种接口格式,把 baseURL 换成其接口地址、apiopenai-completionsanthropic-messagesmodels 填平台上的模型 ID 即可,一个 Key 覆盖多款主流大模型。具体地址和模型 ID 以平台调用文档为准。

改完不用重启。README 写明 profile "每次操作重新读取",用户层的 llm-pi-ai: 分节与组合层按提供方合并,"全部在下一个请求生效、无需重启"。写错的分节会在写入处被拒绝并保留上一个有效值。


网关拒绝请求怎么办:compat 开关

Key 和 URL 都对、网关却拒绝每一个请求,几乎都是请求形状问题。pi-ai 按 URL 猜协议细节,认不出的地址一律按 OpenAI 本身处理,而多数兼容网关至少会拒绝 OpenAI 接受的某一样东西。

官方文档指出两个最常见的元凶,先加这两行:

      compat:
        supportsDeveloperRole: false   # 推理模型的系统提示不再用 developer 角色
        maxTokensField: max_tokens     # 输出上限字段从 max_completion_tokens 改回 max_tokens

openai-completions 协议下常用的开关:

开关

作用

典型场景

supportsDeveloperRole

系统提示是否可用 developer 角色

大多数国产网关设 false

maxTokensField

输出上限字段名

只认 max_tokens 的服务端

supportsReasoningEffort

是否接受 reasoning_effort

不支持该参数的网关设 false

thinkingFormat

推理参数的传输格式

DeepSeek 风格设 deepseek;vLLM 用 chat-template 系列

chatTemplateKwargs

chat_template_kwargs 发送的参数

只在 chat-template 类 thinkingFormat 下生效

supportsThinkingTokenBudget

是否接受 thinking_token_budget

vLLM 推理预算

supportsUsageInStreaming

是否接受 stream_options.include_usage

流式不返回用量的服务端

supportsFinishReason

流里是否有 finish_reason

false 让 pi-ai 自行推断

requiresToolResultName

工具结果是否必须带 name

部分网关校验严格

requiresThinkingAsText

思考块是否必须以 <thinking> 文本传输

不支持原生推理块的服务端

cacheControlFormat

提示缓存标记格式

有缓存但格式不同的网关

anthropic-messages 协议另有 supportsTemperaturesupportsCacheControlOnToolsforceAdaptiveThinkingallowEmptySignaturesupportsStrictTools 等;三种 Responses 协议共享 supportsDeveloperRolesupportsStrictModesupportsLongCacheRetention

三条硬规则:

  1. 开关归属协议。在 openai-completions 上合法的开关放到 anthropic-messages 路由会被拒绝,报错会列出该协议可用的开关。

  2. 写了就要给值supportsDeveloperRole: 冒号后留空会被拒绝,因为空值会抹掉目录已知信息。

  3. 路由级是默认,模型级逐字段胜出。只有一个模型有问题,就在它自己的 compat 下改,不必重写整条路由。


接入视觉模型:input 与 defaultInput

手工录入的模型默认按纯文本处理,附图会在发送前被拒绝,因为 DSH 无法询问端点接受什么模态。要用视觉模型必须显式声明。

单个模型加一行:

      models:
        - id: vision-preview
          input: [text, image]

路由上所有手工模型都支持图片,在路由上设一次回退:

    vision-gateway:
      defaultInput: [text, image]

三个规则:

  • input 只作用于那个模型;defaultInput 是回退值不是覆盖值,绝不会去掉目录模型本来有的图片能力

  • 目录提供方没有 models 列表可填,要收窄某个目录模型的模态用 modelOverrides,以模型 ID 为键

  • 这是"断言"不是"检查":声明了端点其实不支持的图片能力,请求会被提供方拒绝。此时要从授予它图片能力的那个列表里移除 image开新会话,因为附加的图片留在会话日志里,同一请求会不断重复失败

dsh-llm-deepseek 路由是纯文本的,无法通过配置改成视觉;DeepSeek 自家的视觉模型通过该适配器的 Files API 路径处理图片。


接入本地模型:Ollama 与 vLLM

本地服务走自定义提供方,协议选 openai-completions,两个坑是无密钥和推理格式。

无密钥服务需要占位凭据。README 的已知限制写明:pi-ai 的 OpenAI 兼容实现"仍要求 API 密钥或 Authorization 标头,因此无密钥本地服务器需要由 apiKeyEnv 引用或 headers 中的 Authorization 条目提供的占位凭据"。

    local-vllm:
      apiKeyEnv: LOCAL_PLACEHOLDER_KEY    # 环境变量里随便设一个非空值
      api: openai-completions
      baseURL: http://127.0.0.1:8000/v1
      defaultContextWindow: 32768
      compat:
        supportsDeveloperRole: false
        maxTokensField: max_tokens
        supportsThinkingTokenBudget: true
      models:
        - id: <本地模型名>
          reasoningEfforts: false        # 非推理模型显式关掉

要点:

  • defaultContextWindow 默认 262,144,本地小模型务必改小,否则上下文管理会按错误容量工作

  • reasoningEfforts: false 声明非推理模型;推理模型则按网关词汇写 reasoningEfforts,每个键是等级、值是过线拼写,max: ultra 这种重命名是允许的

  • Ollama 在 pi-ai 目录内,可直接作为目录提供方添加;vLLM 等自建服务按上面手工声明


目录模型微调:models 替换 vs modelOverrides

想修正目录里某个模型的容量、模态或推理能力,不要用 models 列表,用 modelOverrides

写法

效果

适用

models: [...]

整体替换路由目录,未列出的模型消失;每个条目从同 ID 目录模型继承未设字段

想把路由收窄到两三个模型,或加目录里还没有的新模型

modelOverrides: {id: {...}}

只改点名的模型,其余原样服务

"修正一个,保留其余三十七个"

    anthropic:
      apiKeyEnv: ANTHROPIC_API_KEY
      modelOverrides:
        <模型ID>:
          contextWindow: 200000
          input: [text]

modelOverrides 有三种情况会被直接拒绝而不是静默跳过:与 models 并存、写在手工声明的路由上、点名目录里没有的模型。文档的理由是"静默不变的模型会成为别人日后寻找的拼写错误"。


排错对照表

DSH 的模型层错误带稳定错误码,对照即可定位。

现象 / 错误码

原因

处理

MISSING_CREDENTIAL

apiKeyEnv 引用解析为空

在模型页存密钥,或设置对应环境变量

INVALID_CREDENTIAL

凭据无法使用

报错会点名路由与引用,更换密钥

UNKNOWN_MODEL

请求的模型未配置

选已配置模型,或把它加进自定义路由的 models

获取可用模型返回 401

Key 错

检查密钥;无 /models 端点则手动填模型

Key 和 URL 都对但全部拒绝

请求形状与 OpenAI 不同

先加 supportsDeveloperRole: falsemaxTokensField: max_tokens

只有推理模型失败

系统提示以 developer 角色发出被拒

supportsDeveloperRole: false

compat 开关被拒绝

冒号后没写值,或开关不属于该协议

给值或删键;按报错列出的可用开关改

图片发送前被拒

模型未声明图片模态

input: [text, image]

提供方拒绝带图请求

声明了端点不支持的图片能力

移除 image 并开新会话

UNSTORABLE_PROVIDER_ID

路由键不是小写连字符标识,无法登录

改用 apiKeyEnv

DUPLICATE_ADAPTER

两个适配器注册了同名路由

改路由名;deepseek-official 只属于 dsh-llm-deepseek

QUOTA / RATE_LIMIT

配额耗尽 / 暂时限流

前者换 Key 或充值,后者等待重试

模型选择器显示"选择模型"且无法输入

默认值指向已删除的提供方

重新选一个模型


常见问题

Q:可以同时用 DeepSeek 官方和其他提供方吗? 可以。dsh-llm-deepseekdsh-llm-pi-ai 路由名不冲突,官方文档明确"两个适配器可以同时挂载"。会话级别按模型选择器切换即可,已发送过请求的会话保留自己日志里记录的模型。

Q:一条路由能混用 OpenAI 和 Anthropic 两种协议的模型吗? 不能。README 已知限制写明"每条路由一种协议格式",变通办法是把同一提供方拆成两个路由键,各选一种 api

Q:改了 settings.yaml 要重启 DSH 吗? 不用。配置按操作重新读取,下一个请求生效。但 DSH Desktop 用户注意:插件的增删需要重启 Desktop,模型配置不需要。

Q:DSH 支持哪些协议的自定义网关? 源码协议表只有三种:openai-completionsopenai-responsesanthropic-messages。Bedrock、Vertex、Azure、Codex 只能通过目录提供方走各自原生认证,不能用自定义路由的 api 显式指向。

Q:模型目录会自动刷新吗? 不会。README 写明"目录就是 settings.yaml 的内容",没有机制向提供方查询它新增了什么模型。新模型要手动加进 models 列表,或在 Web UI 重新点"获取可用模型"后保存。


总结

DeepSeek Harness 接入其他模型的核心是 dsh-llm-pi-ai 插件的 providers 字典:目录内提供方填 Key 就通,目录外网关写 apibaseURLmodels 三项就通,剩下的问题基本落在 compat 开关和 input 模态声明上。Web UI 覆盖前两步,settings.yaml 覆盖全部,且改完即生效。国内多模型平台、本地 vLLM 与海外提供方走的是同一套配置,差别只在协议选择和兼容开关。

据 DSH 官方《配置模型》文档,pi-ai"对于它无法识别的地址,会当作 OpenAI 本身来对待",这是绝大多数网关接入失败的根源;dsh-llm-pi-ai README 则强调配置目录"派生自源码,因此不会落后于适配器实际接受的内容"。本文基于 2026 年 9 月 2 日 DeepSeek Harness 仓库(dsh-v0.1.2-alpha.4)的官方文档,项目处于开发者预览阶段并明确"未来将出现破坏兼容性的变更",字段名以配置目录最新版为准。


参考资料