Files
workspace/dsh-thinking-effort-fix.md
T
2026-10-16 17:30:17 +08:00

97 lines
5.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# dsh 思考强度报错解决方案(11128 请求被拦截 / developer role 400)
> 适用症状:dsh(DeepSeek Harness)在 `settings.yaml` 给模型声明 `reasoningEfforts` 后(注意:**声明即触发,与选了哪个档位无关,含 off**),请求第三方/私有 OpenAI 兼容网关时失败:
>
> - 网关带内容审计时:`本轮运行失败 {"error":{"code":"11128","message":"请求被拦截,请重新发送","type":"invalid_request_error"}}`
> - 网关严格校验 role 时:`400 ... messages[0].role: unknown variant 'developer', expected one of 'system', 'user', 'assistant', 'tool', ...`
>
> 已于 2026-10-16 在 Windows + dsh 0.1.1-rc.2 上验证解决(示例 provider:coderelay,本地网关 `http://127.0.0.1:11435/v1`,上游带内容审计)。
## 根因(代码级因果链)
1. `settings.yaml` 给模型声明 `reasoningEfforts`(字典)后,dsh-llm-pi-ai 的 `resolveModelReasoning` 把该模型标记为 `reasoning: true` 并生成 `thinkingLevelMap`。
2. pi-ai 构造请求时据此决定系统提示词是否改用 `developer` role:
`openai-completions.js:787` — `useDeveloperRole = model.reasoning && compat.supportsDeveloperRole`
3. `supportsDeveloperRole` 的默认值按 provider 名 / baseURL 识别:只有非标准名单(nvidia / cerebras / xai / together / deepseek.com / zai / moonshot / opencode 等)默认 false;**私有网关不在名单里,默认 true**(`openai-completions.js:1148`)。
4. 于是系统提示词以 `developer` role 发出。上游网关不认识(或审计层直接拦截)时:严格校验的报 400 反序列化错误;带内容审计的直接拦截报 11128「请求被拦截」。
上游参考:deepseek-ai/deepseek-harness **Discussion #636**(第三方模型设置思考强度报错),评论区有腾讯系网关 content-audit 拒绝 developer role 的实测结论。
## 解决方案:加一行 compat
在 `~/.dsh/settings.yaml`(Windows:`C:\Users\<用户名>\.dsh\settings.yaml`)对应 provider 下加:
```yaml
llm-pi-ai:
providers:
<provider 名>:
displayName: ...
apiKeyEnv: ...
api: openai-completions
baseURL: ...
compat:
supportsDeveloperRole: false # ← 新增:系统提示词改回 system role 发送
models:
- id: ...
reasoningEfforts:
...
```
- 配在 provider(路由)级即对该 provider 下所有模型生效;也可配在单个 model 级。逐字段优先级:**模型 → 路由 → 内置 catalog → pi-ai 自动检测**。
- 思考强度功能保留,`reasoning_effort` 照常传递,只是 role 从 `developer` 改回 `system`。
- 改完重启 dsh 生效。多个 provider 都报同样错时每个都加。
本机实例(coderelay):
```yaml
coderelay:
displayName: coderelay
apiKeyEnv: CODERELAY_API_KEY
api: openai-completions
baseURL: http://127.0.0.1:11435/v1
compat:
supportsDeveloperRole: false
models:
- id: deepseek-v4-pro
...
- id: deepseek-v4.1-flash
...
reasoningEfforts:
# ③ 逐模型声明可选档位
off: # 提供"关闭"档,发送时省略参数
low: low
medium: medium
high: high
max: max
```
## 新机器上先检查版本
`compat.supportsDeveloperRole` 需要 dsh-llm-pi-ai **0.1.1-rc.2 及以上**(更早版本 compat schema 没有这个开关,配置会被拒绝)。验证:
```bash
grep -c "supportsDeveloperRole" "$(npm root -g)/@deepseek-ai/dsh/node_modules/@deepseek-ai/dsh-llm-pi-ai/lib/index.js"
```
返回 >0 即支持本方案;否则先把 dsh 升级到 0.1.1-rc.2(本机版本)再改配置。
## 改了还没好时的备用手段
按网关实际报错继续补 compat(同在 provider 的 compat 下):
- 输出上限字段被拒:`maxTokensField: max_tokens`(未识别网关默认发 `max_completion_tokens`)
- 思考参数传输格式不对:`thinkingFormat: deepseek` 等
- 替代路线:
1. 本地起一个几十行的 Node 转发器:把请求体里 `messages[].role === "developer"` 改写为 `"system"` 后原样透传(含 reasoning_effort),settings.yaml 的 `baseURL` 指向转发器。
2. `dsh plugin --profile web add pi2dsh` + 对应网关的 Pi provider 包(Discussion #636 评论里的通用插件方案,较重)。
3. 保底:删掉模型的 `reasoningEfforts` 声明,并把 `agent-default-model.reasoningEffort` 一起去掉;代价是思考强度功能不可用。
## 相关路径速查
| 内容 | 路径 |
| --- | --- |
| 配置 | `~/.dsh/settings.yaml` |
| pi-ai developer role 判定 | `<dsh 安装目录>/node_modules/@deepseek-ai/dsh/node_modules/@earendil-works/pi-ai/dist/api/openai-completions.js`(787、1148 行) |
| 插件 compat schema | `<dsh 安装目录>/node_modules/@deepseek-ai/dsh/node_modules/@deepseek-ai/dsh-llm-pi-ai/lib/index.js`(compatProfile,884 行起) |
| 插件中文文档 | 同目录 `README.zh.md`(含 `supportsDeveloperRole: false` 的官方私有网关示例) |