mcpField
D
deepseek-harness

deepseek-harness

github.com/henryz838978开发4752 次安装7 周前更新
代码仓库

关于 deepseek-harness

deepseek-harness 是通过 OpenAI 兼容 API 调用 DeepSeek V4-Pro 和 V4-Flash 的技能及即用实现指南,列出十项请求与流式处理规则,并提供 Python、命令行、MCP 服务及轻依赖方案。

主要功能

  1. 01十项 API 契约规则
  2. 02Python 库和命令行方案
  3. 03即用型安全初始化脚本
  4. 04流式响应与工具调用处理
  5. 05用于复现问题的探测脚本

适用场景

  1. 01配置 DeepSeek V4 API 请求
  2. 02在多轮调用中保留推理数据
  3. 03处理并行工具调用的流式响应
  4. 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-harnessfrom deepseek_harness import DeepSeekHarness
Python CLIpip install deepseek-harness-clidsh 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。

评论

支持 Markdown