# DeepSeek Harness（dsh）接入 QCode

> **最后核实**：2026-11-09 · 📄 依据官方文档（DeepSeek Harness 0.2.2-rc.1，2026-11-04 在 npm 与 GitHub 发布；仓库文档于 2026-11-09 读取）

## 接入速览

| 项目 | 说明 |
|---|---|
| 它是什么 | DeepSeek Harness（`dsh`）是 DeepSeek AI 开发的开源 agent harness，用 `dsh web` 启动 Web UI |
| 可用模型 | Claude ✅（Anthropic Messages provider）· GPT ✅ · GLM / Kimi / DeepSeek / Qwen ✅（OpenAI Chat Completions provider）· Gemini ❌（QCode 暂不提供 Gemini 模型） |
| 协议与 Base URL | OpenAI Chat Completions：`https://api.qcode.cc/openai/v1` · Anthropic Messages：`https://api.qcode.cc/api` |
| 配置位置 | **Settings → Models** → **Add model provider** → **Custom model API** |
| 写入位置 | `$DSH_HOME/profiles/<profile>/cordis.patch.yml`；密钥在 `$DSH_HOME/.credentials.yaml` |
| 官方文档 | [Configure models](https://github.com/deepseek-ai/deepseek-harness/blob/master/docs/user/guide/providers.md) · [代码仓库](https://github.com/deepseek-ai/deepseek-harness) |

DeepSeek Harness 处于开发者预览阶段，官方 README 写明："THERE WILL BE COMPATIBILITY-BREAKING CHANGES."。请把你运行的版本与本页对照。

## 走哪个协议

自定义 provider 的 **API protocol** 必须与网关讲的协议一致。选择器里有三项：OpenAI Chat Completions、OpenAI Responses 和 Anthropic Messages，分别存为 `openai-completions`、`openai-responses`、`anthropic-messages`。一个 provider 只讲一种协议，所以同一个网关要讲两种协议，就要建两个 provider。

QCode 上 Claude 只走 Anthropic 协议，GPT 只走 OpenAI 协议，四个国产系列两种都行，见 [接入点与 API 格式](/docs/getting-started/endpoints-and-api-paths)。因此建两个 provider：

| Provider | API protocol | Base URL | 模型 ID（示例） |
|---|---|---|---|
| `qcode` | OpenAI Chat Completions（`openai-completions`） | `https://api.qcode.cc/openai/v1` | `gpt-6-sol`、`deepseek-v4-pro`、`glm-5.3`、`kimi-k3`、`qwen3.8-max` |
| `qcode-claude` | Anthropic Messages（`anthropic-messages`） | `https://api.qcode.cc/api` | `claude-sonnet-5`、`claude-opus-5` |

Provider ID 是你自己起的名字。模型 ID 以 [qcode.cc/models](https://qcode.cc/models) 上的为准、逐字照填，国产系列的 ID 也可查 [国产模型](/docs/usage/cn-models)。base URL 末尾不要加 `/`，也不要把 `claude-…` 填到 OpenAI 的 base URL 后面。

## 安装

DeepSeek Harness 需要 Node.js 24.9 或更高版本（npm 包声明 `node >=24.9.0`，v0.2.2-rc.1 发布说明写的是 "Raise the minimum supported Node.js version to 24.9."）。装好 Node.js 后运行：

```sh
npx @deepseek-ai/dsh web
```

命令默认在 `http://127.0.0.1:3080` 启动 Web UI，本机启动时会用默认浏览器打开；SSH 启动只打印主机 URL。加 `--no-open` 可以只启动服务、不开浏览器。

想从仓库源码运行：

```sh
git clone https://github.com/deepseek-ai/deepseek-harness.git
cd deepseek-harness
pnpm install
pnpm run build
pnpm dsh web
```

`$DSH_HOME` 是 harness 的数据根目录，默认是 `~/.dsh`，也可以用环境变量 `DSH_HOME` 指定。运行前请先看官方的 [安全说明](https://github.com/deepseek-ai/deepseek-harness/blob/master/SAFETY.md)。

## 配置

模型改动在下一次请求时生效，不需要重启服务。

Web UI 的界面语言跟随浏览器。下面的步骤按英文界面写；中文界面里对应的名称如下：

| 英文界面 | 中文界面 |
|---|---|
| Settings → Models | 设置 → 模型 |
| Add model provider · Custom model API | 添加模型提供商 · 自定义模型 API |
| Provider ID · Display name · Base URL | Provider ID · 显示名称 · API 地址 |
| API protocol · API key | API 协议 · API 密钥 |
| Models · Add model · Fetch available models | 模型目录 · 添加模型 · 获取可用模型 |
| Create provider | 创建提供商 |
| Model options · Reasoning levels · Image | 模型选项 · 推理等级 · 图片 |

1. 打开 Web UI，进入 **Settings → Models**，点 **Add model provider**。
2. 把卡片切换到 **Custom model API**。它用于中转、公司网关、自建服务，或安装目录里没有的任何 provider。
3. 填第一个 provider：
   - **Provider ID**：`qcode`（小写；创建后不可改，请想好再填）
   - **Display name**：`QCode`（可选）
   - **Base URL**：`https://api.qcode.cc/openai/v1`
   - **API protocol**：OpenAI Chat Completions
   - **API key**：你的 QCode key（`cr_` 开头）
4. 在表单的 **Models** 列表（官方说明称之为模型目录）里点 **Add model**，逐个填入模型 ID，例如 `deepseek-v4-pro` 和 `gpt-6-sol`。**Fetch available models** 会向端点询问它提供哪些模型；它只是个方便功能，官方说明在失败或列表为空时手动添加模型 ID 效果完全一样。QCode 的 OpenAI 端点列出的是 GPT 模型，国产模型的 ID 请手动添加。
5. 点 **Create provider**。然后再建第二个：Provider ID 填 `qcode-claude`，Display name 填 `QCode Claude`，Base URL 填 `https://api.qcode.cc/api`，API protocol 选 **Anthropic Messages**，key 相同，模型填 `claude-sonnet-5`，再点一次 **Create provider**。
6. 打开模型选择器选一个模型。选中模型的同时，它也会成为新会话的默认模型。

密钥只写不读：保存后页面拿到的只是脱敏描述，永远不会收到密钥原文。密钥存放在 `$DSH_HOME/.credentials.yaml`，设置里只保留它的凭据引用。

### 页面写入了什么

作为对照，同样的两个 provider 写在 `$DSH_HOME/profiles/<profile>/cordis.patch.yml` 里是下面这样。标准的 `dsh web` 启动时 `<profile>` 是 `web`，路径即 `$DSH_HOME/profiles/web/cordis.patch.yml`。这份文档由页面替你写；只有需要表单没有的设置时才手动编辑。

```yaml
- id: llm-pi-ai
  config:
    providers:
      qcode:
        displayName: QCode
        apiKeyEnv: QCODE_API_KEY
        api: openai-completions
        baseURL: https://api.qcode.cc/openai/v1
        models:
          - id: deepseek-v4-pro
          - id: gpt-6-sol
      qcode-claude:
        displayName: QCode Claude
        apiKeyEnv: QCODE_CLAUDE_API_KEY
        api: anthropic-messages
        baseURL: https://api.qcode.cc/api
        models:
          - id: claude-sonnet-5
```

`apiKeyEnv` 是凭据引用：页面按 Provider ID 推出这个名字（`qcode` → `QCODE_API_KEY`，`qcode-claude` → `QCODE_CLAUDE_API_KEY`），并把你填的密钥存在这个名字下。官方对 `MISSING_CREDENTIAL` 的排错写法是：通过 Models 页面保存 provider 密钥，或提供被引用的环境变量。Cordis 配置覆盖会替换整个条目的配置，所以编辑已有覆盖时请保留其他 provider。

## 验证

1. 在模型选择器里选一个你添加过的模型，发一条 `ping` 之类的短消息。
2. 打开 [probe.qcode.cc](https://probe.qcode.cc)，输入你的 QCode key，确认请求出现并且模型对得上。
3. 不经过 dsh，也可以直接测 key 和路径：

```bash
KEY="cr_your_key"

# OpenAI Chat Completions provider
curl -sS https://api.qcode.cc/openai/v1/chat/completions \
  -H "Authorization: Bearer $KEY" \
  -H "content-type: application/json" \
  -d '{"model":"deepseek-v4-pro","max_tokens":32,"messages":[{"role":"user","content":"ping"}]}'

# Anthropic Messages provider
curl -sS https://api.qcode.cc/api/v1/messages \
  -H "x-api-key: $KEY" \
  -H "anthropic-version: 2023-06-01" \
  -H "content-type: application/json" \
  -d '{"model":"claude-sonnet-5","max_tokens":32,"messages":[{"role":"user","content":"ping"}]}'
```

## 排错

| 现象 | 原因 | 处理 |
|---|---|---|
| `MISSING_CREDENTIAL` | 没存密钥，或引用的环境变量为空 | 在 **Settings → Models** 里保存密钥，或启动 `dsh` 前先 export `apiKeyEnv` 里写的那个变量 |
| `UNKNOWN_MODEL` | 选中的模型不在该 provider 的列表里 | 选一个已配置的模型，或把模型 ID 加到 provider 里 |
| Fetch available models 返回 401 | key 错误 | 检查 key；模型发现调用的是 OpenAI 兼容的 `GET /models` |
| Fetch 结果为空或失败 | 端点的列表格式发现功能读不了 | 手动填模型 ID |
| `model_not_available_on_endpoint` | 把 `claude-…` ID 加进了 OpenAI Chat Completions provider | Claude 的 ID 放进 Base URL 为 `https://api.qcode.cc/api` 的 Anthropic Messages provider |
| 404 | base URL 末尾带了 `/`，或路径前缀不对 | 对照 [接入点与 API 格式](/docs/getting-started/endpoints-and-api-paths) |
| key 和 URL 都对，网关却拒绝所有请求 | 它的请求形态与 OpenAI 不同 | 官方建议：先在该 route 上设 `compat.supportsDeveloperRole: false` 与 `compat.maxTokensField: max_tokens` |
| 只有推理模型失败 | pi-ai 把它们的系统提示以 `developer` 角色发送 | 设置 `compat.supportsDeveloperRole: false` |
| 手动添加的模型没有 Effort 菜单 | 该模型没有声明推理等级 | 在模型的 **Model options** 里打开 **Reasoning levels** |

## 已知限制

- 开发者预览：配置字段和行为可能在版本之间变化；本页按 0.2.2-rc.1 核对，它是 2026-11-09 npm 上标为 `latest` 的版本。
- 表单里没有 `compat` 开关，需要按官方说明在 `cordis.patch.yml` 的 route 上设置。
- 手动添加的模型在你添加之前没有推理等级，输入类型默认只有文本，需要在 **Model options** 里选 **Image**（见官方说明中图片输入与推理强度两节）。

## 相关文档

- [接入点与 API 格式](/docs/getting-started/endpoints-and-api-paths) —— 协议 × 模型族对照表
- [国产模型](/docs/usage/cn-models) —— GLM / Kimi / DeepSeek / Qwen 的 ID 与路径
- [CodeWhale（DeepSeek-TUI）](/docs/ide/deepseek-tui) —— 同样支持两种协议的终端 agent
- [工具兼容性总览](/docs/ide/tool-compatibility) —— 各工具走哪种协议
- [T3 Code](/docs/ide/t3code) —— 调度 Claude Code 与 Codex 的控制面
- [qcode.cc 上的 DeepSeek Harness 指南](https://qcode.cc/deepseek-harness-guide) —— 背景与使用场景