兰 亭 墨 苑
期货 · 量化 · AI · 终身学习
首页
归档
编辑文章
标题 *
URL 别名 *
内容 *
(支持 Markdown 格式)
# ds2api 实现原理解析:让 DeepSeek 网页学会说 OpenAI 普通话 要一句话说清 `ds2api` 是干什么的,其实很简单: **它是一个“万能翻译官”,让只会刷网页的 DeepSeek,学会了说 OpenAI、Claude、Gemini 三家的普通话。** 你手里各种 AI 软件,比如 Cherry Studio、NextChat、各种编程助手、Agent 框架,它们只认 OpenAI 那套接口。但 DeepSeek 最强、最便宜、更新最快的模型,偏偏藏在 `chat.deepseek.com` 这个网页后面。你不能直接插上去用。 `ds2api` 就在中间开了家“翻译餐厅”:前面迎接所有客人,后厨只跟 DeepSeek 网页打交道。 ## 1. 它解决了一个很现实的别扭事 想象一下,你有个特别聪明的朋友,什么都会,但他有个怪癖:只愿意在微信里用语音跟你聊天,不接电话,不回邮件。 而你公司所有的办公系统,都只会发邮件。你想让他帮你干活,怎么办?你只能雇一个人,专门坐在中间:把邮件念成大白话发微信给他,再把他的微信语音整理成正式邮件发回公司。 `ds2api` 就是这个中间人。 DeepSeek 官方 API 和网页版,其实是两套东西。网页版往往模型更新、能力更全,还有思考过程、联网搜索。但它没有给开发者用的标准插口。而全世界的 AI 工具,默认插口都是 OpenAI 定的:`POST /v1/chat/completions` 发过去,SSE 一行行流回来。 `ds2api` 把这两头接起来了。你在代码里写 `model: gpt-4o`、`model: claude-sonnet`,它都笑着收下,转头翻译成 deepseek-v4-flash / pro,然后去网页端帮你问完,再包装成你想要的样子还给你。 这就是为什么它 `config/models.go` 里有一张巨大的“别名表”:`gpt-5` 对应 flash,`o1`、`gpt-5-pro` 对应 pro,`gemini-pro-vision` 对应 vision。就像万能充电头,不管你拿的是美标、欧标插头,到它这儿都能插上。 ## 2. 整家店的结构:前厅、翻译官、后厨 你可以把 `ds2api` 想象成一家餐厅。 **前厅是 `internal/server/router.go`。** 基于 Go 的 chi 路由。迎宾员站在门口,不管你是 OpenAI 的客人、Claude 的客人还是 Gemini 的客人,都领进来。还顺手管 CORS 跨域、RequestID、日志、panic 恢复。健康检查 `/healthz` 就像门口挂的“正常营业”牌子。 **翻译官是 `internal/promptcompat`,全店灵魂。** 所有点菜单到了这里,都被压成一张后厨能看懂的小纸条。 **后厨是 `internal/deepseek/client`。** 真正去跟 DeepSeek 网页后厨打交道的地方:登录、占个桌子(建会话)、买门票(过 PoW 验证)、下单(发 completion)、端菜(收 SSE)。 **装盘工是 `internal/format` + `internal/assistantturn`。** 后厨端出来是一大盆乱炖,装盘工负责分成:这是思考过程,这是正文,这是工具调用,这是引用链接,再按你点的菜系摆盘。 这家店有个铁规矩:**翻译官只做一次,所有菜系共享。** 不允许 OpenAI 后厨和 Claude 后厨各炒一锅。先归一,再渲染。这保证了不管你从哪个门进来,吃到的味道是一致的。 ## 3. 门口保安:两种客人两种进法 `internal/auth/request.go` 就像小区保安,认两种人。 第一种,**自带钥匙的散客:直通模式。** 你请求头里带的 Bearer Token 本来就是 DeepSeek 的 token,保安直接放你过去,不占小区资源。适合你自己有号,只想借个翻译。 第二种,**拿会员卡的住户:托管模式。** 你带的 Token 是 `ds2api` 自己发的 API Key。保安就会去后面的“司机池”给你叫个司机,帮你全程代驾。你甚至可以用 `X-Ds2-Target-Account` 指定司机。用完司机要归还。 个人玩家和工作室多账号玩法,一套代码全兼容。 ## 4. 司机池:滴滴代驾那套玩法 `internal/account` 就是一个滴滴调度中心。 它手里攥着几十个 DeepSeek 账号。每个账号默认最多同时接 2 单,全局还有总并发上限。新请求来了,就从队列里轮着派单,有 token 的优先派。 `Acquire` 是叫车,`Release` 是结单,`waiters` 是排队的人。如果司机全忙,就让客人在门口排队等,而不是直接赶走。 更狠的是 `SwitchAccount`:如果这个司机开到一半被交警拦了(上游 429 限流、token 失效),调度中心立刻给你换个司机,重下一单。对用户来说只是慢了一点,完全无感。 ## 5. 口音伪装:TLS 指纹,学得像 Safari DeepSeek 会看你“长得像不像自己人”。浏览器和 Go 程序发 HTTPS 请求时,握手阶段的“口音”是不一样的,叫 TLS 指纹。你用 Go 原生一开口,人家一听机器人,直接拦掉。 `internal/deepseek/transport` 干的就是“学口音”。它用 `utls` 库硬是把握手伪装成 Safari,还强制只说 `http/1.1`,禁用 HTTP/2。因为真正的 DeepSeek 客户端就是这个腔调。 这就像去批发市场拿货,你必须穿得像本地餐馆老板,说本地话,老板才给你批发价。 ## 6. 买门票:PoW,那道变态数学题 DeepSeek 为了防机器人,下单前还要你做数学题,叫 PoW,`pow/` 目录就是解题的。 你先去问要啥题,对方给你 `challenge` 哈希、`salt`、`difficulty`(约 14 万)、过期时间。你要在 0 到 14 万之间一个个试,找到 `hash(salt_expire_ + 数字) == challenge` 的幸运数字。 更变态的是哈希是魔改版 `DeepSeekHashV1`:Keccak 大转盘本来转 24 轮,它偏偏跳过第 0 轮,只转 1~23 轮。拿现成库算永远对不上。 所以作者用纯 Go 手搓了 Keccak,还做了优化:公共前缀提前揉进状态,循环内零分配,几十毫秒出答案。然后把答案 `base64(json)` 塞进 `x-ds-pow-response` 头,这才算买到门票。 ## 7. 把西餐菜单翻译成大白话:PromptCompat OpenAI 的请求是结构化的乐高:system、user、assistant、tool 分得清清楚楚。DeepSeek 网页版只认一根面条:`prompt: string` 大文本框。 `promptcompat` 就是把乐高压成面条还不丢味道的大厨:先归一成 `StandardRequest`,再把工具说明书贴进 system,把聊天记录熬成一锅粥,太长就拆成附件 `ref_file_ids`,最后看模型名定思考和搜索开关。 ## 8. 听懂碎碎念:SSE 电报碎片 DeepSeek 回来的不是完整句子,而是一堆电报碎片。`internal/sse` 就是电报员:按路径分拣思考与正文,扔掉 `token_usage` 等噪音,看到 `</think>` 强行切换,还要收集搜索引用、处理风控截断。`internal/stream/engine.go` 则是传送带,带心跳和超时,保证长思考也不断线。 ## 9. 脑内小剧场 vs 嘴上说的话:AssistantTurn `internal/assistantturn/turn.go` 像心理医生:`RawThinking` 是脑内小剧场,`RawText` 是嘴上说的话。还要查工具调用、用 tiktoken 本地估算 token 用量、判定空输出原因(限流 429 / 风控 400 / 不可用 503),直接驱动重试策略。 ## 10. 假装会用工具:最像魔术的一招 网页本身不会调函数,只能演。翻译官把调用格式写进 prompt,模型配合输出 XML,`internal/toolcall` 在后台盯着,一看到就拉上幕布不让用户看到,转头用 OpenAI 格式喊工具登场。还能容错修 JSON、流式防泄漏,Go 和 Node 各养了一个场务保证一致。 ## 11. 回译三国语言 + 售后重做 `internal/format` 按客人国籍上菜:OpenAI、Claude、Gemini 各摆各的盘,但后厨同一锅。`internal/completionruntime` 是大堂经理:空输出就重做,429 就换厨师(切账号),流式断了就续上,保证成功率莫名其妙地高。 ## 12. 前台大屏与摆摊车 `admin` + `webui/`(React)是酒店前台大屏:账号管理、测活、热更新、排队查看、抓包回放。支持 Docker、Zeabur、Vercel 部署,`api/chat-stream.js` 给无服务器环境留了 Node 小桥。 ## 结语:桥很精致,但河是别人的 `ds2api` 是在别人家河上造的桥:这头是全世界统一的标准,那头是随时会变的私协议。它靠伪装混进去,靠解题买门票,靠 prompt 骗模型,靠拼图还原思考,靠账号池保 SLA。厉害,也脆弱——上游一改就得连夜修。所以仓库里存了大量真实抓包和法医级 SSE 报告。 如果你只是想用,记住三件事:配好账号池,选对模型别名,开好重试。剩下的,交给这位翻译官吧。 > 项目地址:git@github.com:yuanguangshan/ds2api.git(fork 自 CJackHwang/ds2api)
配图 (可多选)
选择新图片文件或拖拽到此处
标签
更新文章
删除文章