我做了个 MCP server,让 DeepSeek 在 Claude Code 里跑完整 agent loop
刚被 awesome-mcp-servers 收录(PR #6190),借这个机会写一下 deepseek-as-subagent 解决了什么问题、和现有 deepseek-mcp 的本质差异。
TL;DR
- 现有 deepseek-mcp 服务把 DeepSeek 当成"一次 LLM 调用",Claude 还是要自己读文件、写文件、跑命令 —— 省的只是"思考"成本,没省"读写"成本。
- 本项目让 DeepSeek 拥有完整的 agent loop:Read / Write / Edit / Bash / Glob / Grep / NotebookEdit 七个沙箱工具,DeepSeek 在工作区里自己跑,Claude 只交付任务和接收摘要。
- 因此节省是端到端的:DeepSeek API 比 Claude 便宜约 50 倍,对批量改文件、扫日志、写脚本、补测试这类机械活,一次任务能省下绝大部分成本。
问题:现有 deepseek-mcp 只省了"思考",没省"读写"
去 awesome-mcp-servers 里翻一圈 DeepSeek 相关的 MCP server,基本都是同一种模式:
# 伪代码,但精神基本是这样的
def create_chat_completion(messages):
return deepseek_api.chat(messages)
或者像 Composio 那种把 DeepSeek 包成 create_anthropic_message 让 Claude 当工具调用。本质都是一次性 LLM 调用 —— 你给一段 prompt、它返回一段文本。
问题来了:Claude Code 跑任务的真实成本结构是什么?
- 读源代码(每个文件几 KB 到几十 KB)→ 进 context
- 写代码(编辑或新建)→ 进 context
- 跑命令、看输出 → 进 context
- 真正的"思考"只是 model 在这堆 context 上做 inference
LLM 计费按 token 算,绝大部分 token 都花在读和写上,不是花在思考上。
所以"把 DeepSeek 当成一次 chat completion"的方案,结构上是这样:
用户 → Claude(读 10 个文件 → 几万 token)→ 把这堆文件塞进 prompt
→ 调 DeepSeek 一次 → DeepSeek 返回结果 → Claude 再写文件
Claude 已经付了"读 10 个文件"的钱,DeepSeek 还要再读一遍同样的内容(因为它通过 prompt 才看到这些)。两份 token 钱,省下来的只是一次 Claude 推理。
方案:把 DeepSeek 做成真正的 sub-agent
正确的结构应该是这样:
用户 → Claude(决定派工)→ delegate_to_deepseek(task, context)
→ DeepSeek 自己 Read / Glob / Edit / Bash
→ 完成后返回总结 → Claude 抽样验证
Claude 完全不读这些文件。读写都由 DeepSeek 在自己的 agent loop 里完成。这才是端到端的节省。
要做到这点,DeepSeek 这边必须拥有跟 Claude 同款的工具集,而且要在沙箱里跑。所以我实现了:
delegate_to_deepseek(task, context)—— 唯一对 Claude 暴露的 MCP 工具- 内部 agent loop(
agent_loop.py),使用 OpenAI 兼容的 function calling - 7 个沙箱工具:Read / Write / Edit / Bash / Glob / Grep / NotebookEdit
- 路径沙箱 + 命令黑名单(DeepSeek 跳不出 workspace,也跑不了
rm -rf /)
架构
┌───────────────────────────────────────────────────────────────┐
│ Claude Code (CLI / VSCode 插件,你的 Max OAuth) │
│ ↓ stdio (MCP 协议,无网络) │
│ deepseek-as-subagent (本项目,Python 子进程) │
│ ↓ HTTPS │
│ api.deepseek.com (你的 API key) │
└───────────────────────────────────────────────────────────────┘
除了真正的 DeepSeek API 调用本身需要走 HTTPS,其它一切都在你本机。没有第三方代理,没有云端转发,代码不离开笔记本。
三个不显然但关键的设计点
1. 派工决策必须发生在 Claude 读源代码之前
这是整个项目最反直觉、也最容易被新用户违反的规则。skill 文件里直接编码了这条:
调用
mcp__deepseek__delegate_to_deepseek工具前,只能用Glob/LS/ 只读Bash看范围,不能Read文件内容。
原因:一旦 Claude 自己已经 Read 了源代码,那些内容已经进了 Claude 的 context(你已经付过钱)。这时候再派给 DeepSeek,DeepSeek 还要重新读一遍。双倍消耗,比不派工还贵。
如果你判断不读源码就没法决定要不要派工,那这个任务本身就不该派 —— 它太需要细节判断了。
2. 派工粒度必须粗 —— 一次派"完整逻辑单元",不要拆"步骤"
刚开始我也犯过这个错:把任务拆成 5 个小步骤分 5 次派给 DeepSeek。结果反而比不派还贵。
原因是每次派工都要付 5 个税:
- 拆任务税 —— Claude 做规划的 token
- 上下文重读税 —— DeepSeek 每次任务启动都要重新理解项目结构
- 验证税 —— Claude 抽样核实结果
- 起步费 —— 每次 LLM 调用都有 system prompt overhead
- 返工税 —— 一个步骤错了,后面的可能要返工
正确的派工粒度:让 DeepSeek 内部跑 10-30 turns 一次到位。例:
- ❌ "你帮我列出 i18n key" → "你帮我提取 zh 文案" → "你帮我转 JSON" → "你帮我替换源码"(4 次派工)
- ✅ "扫描 src/ 提取所有硬编码中文,按文件分组生成 i18n JSON,并把源码里替换成 i18next 调用,输出迁移报告"(1 次派工)
3. DeepSeek 不能联网 —— Claude 替它查
DeepSeek 的 agent loop 故意不给 WebSearch / WebFetch 工具。原因有两个:
- 安全:DeepSeek 在沙箱里跑,给它联网能力就破坏了沙箱边界
- 成本:Anthropic Max OAuth 包了 WebSearch / WebFetch 的费用,让 Claude 查是免费的,让 DeepSeek 查要走外部 API
所以遇到 DeepSeek 需要外部文档 / 新 API spec / 错误码时,Claude 必须先用自己的 WebSearch / WebFetch 查好,把摘要塞进任务 context 一起派出去。
什么时候用 / 什么时候别用
派工甜区:
- ✅ 10–50 文件、机械模式(i18n 提取、批量 refactor、ETL)
- ✅ 大数据 + 简单处理(日志扫描、文件转换、CRUD 增删)
- ✅ 写脚本、补测试、写文档
派工反甜区:
- ❌ 单文件 < 500 行的微调(DeepSeek reasoning overhead 不划算)
- ❌ 跨文件架构设计 / 选型决策
- ❌ 强依赖项目 CLAUDE.md / 内部约定文档的任务(DeepSeek 拿不到)
- ❌ Bug 根因分析(推理密集,Claude 更强)
一行安装
curl -sSL https://raw.githubusercontent.com/PsChina/deepseek-as-subagent/main/curl-install.sh | bash
装完编辑 ~/.deepseek-mcp/config.json 把 DeepSeek API key 填进去(去 platform.deepseek.com 拿,¥20 能用很久),然后 claude 启动,试一句:
/ds write a python hello world to /tmp/hi.py
Claude 会调 delegate_to_deepseek,DeepSeek 自己跑完返回结果。
Codex CLI / Cursor / Cline / Claude Desktop 等其它 MCP 客户端也支持,README 里有适配说明。
项目地址
如果觉得有用欢迎 star / issue / PR。被 awesome-mcp-servers 收录后这两天会陆续完善:
- 录一个 30 秒的 demo GIF(直观看到"任务派出去 → DeepSeek 自己跑 → 返回结果")
- 加更多 adapter(目前 Claude Code / Codex 一档,欢迎贡献其它客户端的 onboarding)
- 完善 skill 的边界 case(特别是"判断派工与否"的启发式)
欢迎拍砖。