ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

逐行读懂deepclaude model-proxy源码:如何拦截并归一化Claude API的SSE流

逐行读懂deepclaude model-proxy源码:如何拦截并归一化Claude API的SSE流 逐行读懂deepclaude model-proxy源码如何拦截并归一化Claude API的SSE流【免费下载链接】deepclaudeUse Claude Codes autonomous agent loop with DeepSeek V4 Pro, OpenRouter, or any Anthropic-compatible backend. Same UX, 17x cheaper.项目地址: https://gitcode.com/gh_mirrors/deepc/deepclaude本文带你逐行读懂deepclaude 的 model-proxy 源码这个本地模型代理如何拦截 Claude Code 发出的所有模型 API 请求并把 DeepSeek 返回的SSE 流归一化成 Claude Code 能安全消费的标准格式。deepclaude 让你继续用 Claude Code 的自主智能体循环只需把大脑换成 DeepSeek V4 Pro、OpenRouter 或任意 Anthropic 兼容后端——同样的体验成本最多便宜 17 倍。 deepclaude 是什么保留 Claude Code 的身体只换大脑Claude Code 是目前最强的自主编码智能体之一但 Max 订阅每月 $200 且有用量上限。deepclaude 的思路非常简单不改 CLI 本身只把 API 调用的目的地换掉——文件读写、bash 执行、git 操作、子代理全部照常工作唯一的区别是负责思考的模型变成了 DeepSeek V4 Pro输出价低至 $0.87/M tokens而 Anthropic 是 $15/M。用deepclaude --remote启动后你可以在浏览器甚至手机上打开一个 Claude Code 会话deepclaude 会自动在本地拉起代理模型调用被路由到 DeepSeek而桥接认证仍走 Anthropic。️ 整体架构所有请求先过 localhost:3200整个方案的枢纽是一个跑在127.0.0.1:3200的轻量 HTTP 代理入口见 proxy/start-proxy.js核心实现在 proxy/model-proxy.jsClaude Code └── 所有模型请求 → http://localhost:3200model-proxy ├── /v1/messages → DeepSeek / OpenRouter / Fireworks便宜大脑 ├── /_proxy/mode → 会话中途热切换后端 ├── /_proxy/status、/_proxy/cost → 状态与成本统计 └── 其他一切 → api.anthropic.com透明透传之所以必须用代理而不是直接改环境变量是因为 Claude Code 的远程控制有两条独立通道桥接 WebSocket硬编码指向 Anthropic必须用官方 OAuth和模型 HTTP 调用可配置。把 API Key 直接换成 DeepSeek 会弄坏桥接而代理可以劈开这两股流量——详细说明见 proxy/README.md。源码结构一张表模块位置职责MODEL_REMAPproxy/model-proxy.jsClaude 模型名 → 各后端模型名映射PRICING_PER_Mproxy/model-proxy.js各后端每百万 token 单价表UsageNormalizerproxy/model-proxy.js⭐ SSE 流归一化核心类normalizeJsonBodyproxy/model-proxy.js非流式 JSON 响应补齐 usagestripAllThinkingBlocksproxy/model-proxy.js剥离 thinking 内容块startModelProxyproxy/model-proxy.js入口HTTP 服务 路由 成本统计 拦截层请求路由与身份替换代理服务创建后proxy/model-proxy.js每个进来的请求先做路径判断控制端点/_proxy/*走本地处理逻辑下一节讲绝不转发。模型调用只有路径精确匹配MODEL_PATHS里的/v1/messagesproxy/model-proxy.js且当前不在 anthropic 模式时才转发到便宜后端。其余流量透明透传回 AnthropicClaude Code 完全无感。转发前代理对请求做了三处手术换身份proxy/model-proxy.js删掉客户端自带的authorization/x-api-key头再按后端口味注入新密钥——OpenRouter、Fireworks 用Bearer令牌DeepSeek 兼容端点用x-api-key。换模型名proxy/model-proxy.js请求体里的claude-opus-4-6会被MODEL_REMAP映射成deepseek-v4-proOpus 级任务落到 Pro 模型Sonnet/Haiku 级任务落到轻量的deepseek-v4-flash。清理 thinking 块proxy/model-proxy.jsClaude Code 会在多轮对话中回传上一轮的思考块但第三方后端会拒绝生成它的思考块直接全部剥掉切回 Anthropic 后若会话里混过其他后端也要剥掉否则触发 400 错误。还有一个容易忽略的细节路径前缀去重proxy/model-proxy.js。OpenRouter 的基址是/api/v1拼上客户端的/v1/messages会变成/api/v1/v1/messages代理会计算两段路径的重叠前缀再拼接避免这类拼接事故。 SSE 流归一化全文最关键的一段这是本项目的灵魂问题DeepSeek/OpenRouter 的兼容端点有时会在message_start或message_delta事件里省略usage字段而 Claude Code 直接按$.input_tokens取值——字段不存在就崩溃。解决方案是一个继承自 Node.jsTransform的流UsageNormalizerproxy/model-proxy.js。第一步按 SSE 事件切块_transformSSE 协议用空行\n\n分隔事件但 TCP 分块chunk边界是任意的——一个事件可能被拦腰截断。所以它先做缓冲proxy/model-proxy.js_transform(chunk, _enc, cb) { this._buf chunk.toString(); const parts this._buf.split(\n\n); this._buf parts.pop(); // 最后一段可能不完整留到下一轮 for (const part of parts) { this.push(this._fix(part) \n\n); } cb(); }完整的事件修好后立即push给下游边收边发不缓存整个响应——对长对话的流式输出至关重要。第二步补齐缺失字段_fix对每个完整事件proxy/model-proxy.js先用正则/^data: (.)$/m取出数据行并解析 JSON然后做两处填空message_start事件缺message.usage→ 注入{ input_tokens: 0, output_tokens: 0 }message_delta事件缺usage→ 注入{ output_tokens: 0 }。只有真的改过才重新序列化否则原样放行——零开销透传。同时它顺手记录inputTokens/outputTokens为成本统计提供数据。第三步收尾回调_flush流结束时proxy/model-proxy.js处理缓冲区里最后一个不完整事件并触发onUsage回调把本轮 token 数交给recordUsage记账。流式与非流式两条路径代理根据上游响应的content-type分流proxy/model-proxy.jstext/event-stream→ 管道接上UsageNormalizer再交给客户端application/json非流式→ 整体缓冲后用normalizeJsonBody补齐usage字段再一次性返回proxy/model-proxy.js其他情况 → 原样透传。 控制端点/_proxy/mode 实现会话中途热切换代理还内置了三个控制端点proxy/model-proxy.js前缀/_proxy/保证永远不会和模型路径/v1/*冲突GET /_proxy/status当前模式、运行时长、请求数GET /_proxy/costtoken 用量与省钱金额下一节POST /_proxy/mode热切换后端无需重启。/_proxy/mode做了三重防护校验Origin只允许本机来源防跨站请求篡改、请求体限 1KB超尺寸直接销毁连接、非 POST 一律 405。切换动作由switchModeproxy/model-proxy.js完成——只需更新内存里的target/apiKey/useBearer三个状态字段下一条请求就立刻走新后端。在 Claude Code 里添加自定义斜杠命令后输入/deepseek就能完成切换命令本质是一条curl调用该端点Claude Code 终端中 /deepseek 命令调用 model-proxy 的 /_proxy/mode 端点切换后端同样在 VS Code 扩展里/openrouter与/deepseek可以来回切状态栏的模型名实时变化VS Code 扩展中 model-proxy 从 OpenRouter 热切换到 DeepSeek 后端 成本追踪内置的省钱计算器每一次归一化流都会留下 token 记账proxy/model-proxy.jsgetCostSummaryproxy/model-proxy.js再按PRICING_PER_M单价表算出实际花费、等价的 Anthropic 花费、以及差值savings。curl -s http://127.0.0.1:3200/_proxy/cost # → { total_cost: 0.0941, anthropic_equivalent: 1.05, savings: 0.9559, ... }配合 DeepSeek 的自动上下文缓存重复轮次命中缓存后输入价降至 $0.004/M长会话的 agent 循环成本几乎可以忽略——这是17x cheaper的直接来源。️ 健壮性细节端口自增、超时与降级最后几个小而实用的设计proxy/model-proxy.js端口自增3200 被占用时自动尝试 3201~3220避免和已有服务打架5 分钟请求超时agent 任务可能思考很久超时给足超时或上游报错时返回结构化的 502而不是让客户端干等全程可观测每个请求打印序号、目标主机、TTFB首字节时间、耗时和 token 数排查问题一目了然最小依赖整个代理只用 Node.js 内置的http/https/stream模块零 npm 依赖。✅ 总结deepclaude 的 model-proxy 用约 450 行零依赖的 JavaScript完成了四件事按路径拦截模型请求、替换身份与模型名转发给便宜后端、用UsageNormalizer流式归一化 SSE 事件防崩溃、并提供热切换与成本统计端点。理解它的实现也顺带掌握了为不兼容的 API 写一层归一化代理这一通用技巧缓冲切块 → 逐事件修正 → 边收边发 → 记账回调。想动手改造时建议从 proxy/model-proxy.js 的UsageNormalizer类读起再对照 README.md 中的后端配置说明和 deepclaude.sh / deepclaude.ps1 启动脚本即可在自己的后端上复刻这套架构。【免费下载链接】deepclaudeUse Claude Codes autonomous agent loop with DeepSeek V4 Pro, OpenRouter, or any Anthropic-compatible backend. Same UX, 17x cheaper.项目地址: https://gitcode.com/gh_mirrors/deepc/deepclaude创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表