关于 deepseek-harness
deepseek-harness 是通过 OpenAI 兼容 API 调用 DeepSeek V4-Pro 和 V4-Flash 的技能及即用实现指南,列出十项请求与流式处理规则,并提供 Python、命令行、MCP 服务及轻依赖方案。
主要功能
- 01十项 API 契约规则
- 02Python 库和命令行方案
- 03即用型安全初始化脚本
- 04流式响应与工具调用处理
- 05用于复现问题的探测脚本
适用场景
- 01配置 DeepSeek V4 API 请求
- 02在多轮调用中保留推理数据
- 03处理并行工具调用的流式响应
- 04复现文档记录的 API 行为
MCP 相关
该技能介绍了可通过 `npx -y @deepseek-harness/mcp` 安装的 MCP 服务,用于接入 MCP 配置。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ henryz838978/ deepseek-harness --skill deepseek-harness安装后在 Claude Code 中输入/deepseek-harness确认已加载。
附带文件reference/findings.mdscripts/safe_init.py
详细介绍
DeepSeek V4 Harness
通过 OpenAI 兼容 API 调用 DeepSeek V4-Pro 或 V4-Flash 时,MUST 遵守以下 10 条约定规则。违反其中任意一条都会导致已有记录的生产环境 Bug(每条规则均附有上游问题和我们的复现探测)。
10 条约定规则(按影响范围排序)
C1 · 除非任务确实需要大量推理,否则禁用思考
deepseek-v4-pro 默认设置为 thinking=enabled。因此,即使是简单的提示词,每次调用也会消耗 30-300 个 reasoning_tokens。
client.chat.completions.create(
model="deepseek-v4-pro",
messages=messages,
extra_body={"thinking": {"type": "disabled"}}, # ← saves money on every non-reasoning call
)
对于 TypeScript / openai-node,请将 thinking 放在请求的顶层,而不是 extra_body 中(JS SDK 会透传未知的顶层键):
await openai.chat.completions.create({
model: "deepseek-v4-pro",
messages,
thinking: { type: "disabled" },
} as any);
C2 · 在多轮循环中,保留助手消息中的 reasoning_content
如果启用了思考,且你重新发送一条带有 tool_calls 的先前助手消息,就必须包含原始的 reasoning_content 字段。否则,下一个请求会返回:
HTTP 400: The reasoning_content in the thinking mode must be passed back to the API.
(已在 V4-Pro 和 V4-Flash 上通过 reports/probes/probe_2_reasoning_lifecycle.py 复现,2026-05-09,3/3 次试验。)
msg = response.choices[0].message
history.append({
"role": "assistant",
"content": msg.content,
"tool_calls": _serialize_tool_calls(msg.tool_calls),
"reasoning_content": getattr(msg, "reasoning_content", None), # ← REQUIRED
})
当收到新一轮用户消息时,你可以移除先前助手消息中的 reasoning_content——DeepSeek 不要求在用户轮次边界之间保留它,而且保留它会使前缀缓存键变大。
C3 · 始终设置 max_tokens(默认值为 4096)
如果不限制输出,reasoning_content 可能会流式输出 8000+ 个分块(probes/probe_9_reasoning_runaway.py 测得,在一个自我怀疑提示词上产生了 26 KB / 84 s),导致下游 Electron 客户端(ChatWise、Cherry Studio)在字符串缓冲区达到 V8 的 512 MB 上限时因 RangeError: Invalid string length 崩溃。
C4 · 流式处理:按 tc.index 聚合并行 tool_calls,而不是按列表顺序
DeepSeek 会交错输出并行工具调用的分块(probe_7 在 V4-Pro 和 V4-Flash 的 3/3 次试验中均观察到 100% 交错)。使用 dict[int, slot]:
tool_call_acc: dict[int, dict] = {}
for chunk in stream:
for tc in (chunk.choices[0].delta.tool_calls or []):
slot = tool_call_acc.setdefault(tc.index, {"id": None, "name": None, "arguments": ""})
if tc.id: slot["id"] = tc.id
if tc.function and tc.function.name: slot["name"] = tc.function.name
if tc.function and tc.function.arguments: slot["arguments"] += tc.function.arguments
C5 · 流式处理:使用列表缓冲区 + "".join,不要使用 state += chunk
DeepSeek 每个推理分块会流式输出 1-3 个字符。state.text += chunk 会导致 O(n²) 字符串分配:
buf = []
for chunk in stream:
if c := (chunk.choices[0].delta.content or ""):
buf.append(c)
final = "".join(buf)
C6 · 兼容空的流式分块
DeepSeek 每个响应会输出约 3 个 choices == [] 的分块。索引前先检查真值:
for chunk in stream:
choices = chunk.choices or []
if not choices:
if chunk.usage is not None: usage = chunk.usage
continue
...
C7 · 将上下文长度限制在 1,048,576 个 token 以内
V4-Pro / V4-Flash 的硬上限恰好为 2^20 = 1,048,576 个 token(已由 probe_6b 验证)。服务端会强制检查 len(messages_tokens) + max_tokens <= 1,048,576,超出时返回 400。
C8 · 注意缓存——不要在系统提示词中注入易变内容
DeepSeek 的前缀缓存按 256 个 token 分块,命中时可享受 50× 折扣。要最大限度提高缓存效果:
- 不要激进地裁剪或总结历史记录(每次裁剪都会导致缓存未命中)
- 不要在缓存前缀中注入“current date: 2026-05-09”等类似内容
- 请同时读取
prompt_cache_hit_tokens(DeepSeek 原生字段)和prompt_tokens_details.cached_tokens(OpenAI 格式字段)——两者都会返回
C9 · 使用工具调用 V4 时避免使用 /beta 端点
/beta 会静默地将 deepseek-v4-pro 重新映射为旧版 deepseek-reasoner,而后者会拒绝特定格式的 tool_choice={"type":"function","function":{"name":"..."}}。工具调用流程请使用 https://api.deepseek.com。
C10 · 在 V4 上使用 strict: true 经实测可行(尽管 #1069 仍未解决)
你可以在 V4-Pro / V4-Flash 上启用 function.strict=true 和 additionalProperties=false——历史上的 JSON 损坏 Bug(deepseek-ai/DeepSeek-V3#1069)在 2026-05-09 的 32 次试验中未能复现。仍应使用 jsonschema 在事后验证 JSON。
即插即用的实现
如果用户的环境允许安装第三方库,可使用以下任一方式:
| 形式 | 安装 | 命令 |
|---|---|---|
| Python 库 | pip install deepseek-harness | from deepseek_harness import DeepSeekHarness |
| Python CLI | pip install deepseek-harness-cli | dsh chat、dsh doctor、dsh validate |
| MCP 服务 | npx -y @deepseek-harness/mcp | 接入 Claude/Cursor/Cline/ChatWise 的 MCP 配置 |
如果他们希望除 openai 外零依赖,可将 scripts/safe_init.py(位于此技能文件夹中)复制到其项目中。它用 200 行代码实现了全部 10 条规则。
复现命令
此技能中的每项声明都有 reports/probes/ 中可运行的探测脚本作为依据:
# Reproduce the reasoning_content 400:
python reports/probes/probe_2_reasoning_lifecycle.py --n 3
# Expected: 3/3 phase-B BadRequestError with the verbatim error message above.
# Confirm tool-call leakage rate at 0% on official endpoint:
python reports/probes/probe_3_tool_call_leakage.py --n 30
# Map cache prefix sensitivity:
python reports/probes/probe_5_cache_prefix_sensitivity.py --n 8
完整的 16 项发现报告请参阅 reports/REPORT_2026-05-09.md。