[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-10302":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":10,"language":11,"languages":10,"totalLinesOfCode":10,"stars":12,"forks":13,"watchers":14,"openIssues":15,"contributorsCount":16,"subscribersCount":16,"size":16,"stars1d":17,"stars7d":18,"stars30d":19,"stars90d":16,"forks30d":16,"starsTrendScore":20,"compositeScore":21,"rankGlobal":10,"rankLanguage":10,"license":22,"archived":23,"fork":23,"defaultBranch":24,"hasWiki":23,"hasPages":23,"topics":25,"createdAt":10,"pushedAt":10,"updatedAt":40,"readmeContent":41,"aiSummary":42,"trendingCount":16,"starSnapshotCount":16,"syncStatus":43,"lastSyncTime":44,"discoverSource":45},10302,"ds2api","CJackHwang\u002Fds2api","CJackHwang","DeepSeek-Compatible Middleware Interface: A technical exploration project in Go, focusing on high-concurrency protocol adaptation. It serves as a reference implementation for converting diverse web protocols into standardized formats.","https:\u002F\u002Flinux.do\u002Fu\u002Fcjackhwang",null,"Go",4681,1519,16,26,0,5,27,521,31,31.55,"GNU Affero General Public License v3.0",false,"main",[26,27,28,29,30,31,32,33,34,35,36,37,38,39],"api","claude-api","deepseek","deepseek-api","docker","freeapi","go","openai-api","proxy","proxy-server","react","vercel","vercel-deployment","zeabur","2026-06-12 02:02:19","\u003Cp align=\"center\">\n  \u003Cimg src=\"webui\u002Fpublic\u002Fds2api-favicon.svg\" width=\"128\" height=\"128\" alt=\"DS2API icon\" \u002F>\n\u003C\u002Fp>\n\n# DS2API\n\n\u003Ca href=\"https:\u002F\u002Ftrendshift.io\u002Frepositories\u002F24508\" target=\"_blank\">\u003Cimg src=\"https:\u002F\u002Ftrendshift.io\u002Fapi\u002Fbadge\u002Frepositories\u002F24508\" alt=\"CJackHwang%2Fds2api | Trendshift\" style=\"width: 250px; height: 55px;\" width=\"250\" height=\"55\"\u002F>\u003C\u002Fa>\n\n[![License](https:\u002F\u002Fimg.shields.io\u002Fgithub\u002Flicense\u002FCJackHwang\u002Fds2api.svg)](LICENSE)\n![Stars](https:\u002F\u002Fimg.shields.io\u002Fgithub\u002Fstars\u002FCJackHwang\u002Fds2api.svg)\n![Forks](https:\u002F\u002Fimg.shields.io\u002Fgithub\u002Fforks\u002FCJackHwang\u002Fds2api.svg)\n[![Release](https:\u002F\u002Fimg.shields.io\u002Fgithub\u002Fv\u002Frelease\u002FCJackHwang\u002Fds2api?display_name=tag)](https:\u002F\u002Fgithub.com\u002FCJackHwang\u002Fds2api\u002Freleases)\n[![Docker](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002Fdocker-ready-blue.svg)](docs\u002FDEPLOY.md)\n\n[![Deploy on Zeabur](https:\u002F\u002Fzeabur.com\u002Fbutton.svg)](https:\u002F\u002Fzeabur.com\u002Ftemplates\u002FL4CFHP)\n[![Deploy with Vercel](https:\u002F\u002Fvercel.com\u002Fbutton)](https:\u002F\u002Fvercel.com\u002Fnew\u002Fclone?repository-url=https:\u002F\u002Fgithub.com\u002FCJackHwang\u002Fds2api)\n\n语言 \u002F Language: [中文](README.MD) | [English](README.en.md)\n\n将 DeepSeek Web 对话能力转换为 OpenAI、Claude 与 Gemini 兼容 API。核心后端以 **Go** 实现，Vercel 流式桥接额外使用少量 Node Runtime，前端为 React WebUI 管理台（源码在 `webui\u002F`，部署时自动构建到 `static\u002Fadmin`）。\n\n文档入口：[文档导航](docs\u002FREADME.md) \u002F [架构说明](docs\u002FARCHITECTURE.md) \u002F [接口文档](API.md)\n\n【感谢Linux.do社区及GitHub社区各位开发者对项目的支持与贡献】\n\n## Star History\n\n\u003Ca href=\"https:\u002F\u002Fwww.star-history.com\u002F?repos=cjackhwang%2Fds2api&type=date&legend=top-left\">\n \u003Cpicture>\n   \u003Csource media=\"(prefers-color-scheme: dark)\" srcset=\"https:\u002F\u002Fapi.star-history.com\u002Fchart?repos=cjackhwang\u002Fds2api&type=date&theme=dark&legend=top-left\" \u002F>\n   \u003Csource media=\"(prefers-color-scheme: light)\" srcset=\"https:\u002F\u002Fapi.star-history.com\u002Fchart?repos=cjackhwang\u002Fds2api&type=date&legend=top-left\" \u002F>\n   \u003Cimg alt=\"Star History Chart\" src=\"https:\u002F\u002Fapi.star-history.com\u002Fchart?repos=cjackhwang\u002Fds2api&type=date&legend=top-left\" \u002F>\n \u003C\u002Fpicture>\n\u003C\u002Fa>\n\n> **重要免责声明**\n>\n> 本仓库仅供学习、研究、个人实验和内部验证使用，不提供任何形式的商业授权、适用性保证或结果保证。\n>\n> 作者及仓库维护者不对因使用、修改、分发、部署或依赖本项目而产生的任何直接或间接损失、账号封禁、数据丢失、法律风险或第三方索赔负责。\n>\n> 请勿将本项目用于违反服务条款、协议、法律法规或平台规则的场景。商业使用前请自行确认 `LICENSE`、相关协议以及你是否获得了作者的书面许可。\n\n## 目录\n\n- [架构概览（摘要）](#架构概览摘要)\n- [核心能力](#核心能力)\n- [平台兼容矩阵](#平台兼容矩阵)\n- [模型支持](#模型支持)\n  - [OpenAI 接口](#openai-接口get-v1models)\n  - [Claude 接口](#claude-接口get-anthropicv1models)\n  - [Gemini 接口](#gemini-接口)\n- [快速开始](#快速开始)\n  - [方式一：下载 Release 构建包](#方式一下载-release-构建包)\n  - [方式二：Docker 运行](#方式二docker-运行)\n  - [方式三：Vercel 部署](#方式三vercel-部署)\n  - [方式四：本地源码运行](#方式四本地源码运行)\n- [配置说明](#配置说明)\n- [鉴权模式](#鉴权模式)\n- [并发模型](#并发模型)\n- [Tool Call 适配](#tool-call-适配)\n- [本地开发抓包工具](#本地开发抓包工具)\n- [文档索引](#文档索引)\n- [测试](#测试)\n- [Release 自动构建（GitHub Actions）](#release-自动构建github-actions)\n- [免责声明](#免责声明)\n\n## 架构概览（摘要）\n\n```mermaid\nflowchart LR\n    Client[\"🖥️ 客户端 \u002F SDK\\n(OpenAI \u002F Claude \u002F Gemini)\"]\n    Upstream[\"☁️ DeepSeek API\"]\n\n    subgraph DS2API[\"DS2API 4.x（模块化 HTTP surface + PromptCompat 内核）\"]\n        Router[\"chi Router + 中间件\\n(RequestID \u002F RealIP \u002F Logger \u002F Recoverer \u002F CORS)\"]\n\n        subgraph HTTP[\"HTTP API surface\"]\n            OA[\"OpenAI\\nchat \u002F responses \u002F files \u002F embeddings\"]\n            CA[\"Claude\\n\u002Fanthropic\u002F* + \u002Fv1\u002Fmessages\"]\n            GA[\"Gemini\\n\u002Fv1beta\u002Fmodels\u002F* + \u002Fv1\u002Fmodels\u002F*\"]\n            Admin[\"Admin API\\n资源子包\"]\n            WebUI[\"WebUI\\n\u002Fadmin（静态托管）\"]\n            Vercel[\"Vercel Node Stream\\n\u002Fv1\u002Fchat\u002Fcompletions\"]\n        end\n\n        subgraph Runtime[\"运行时核心能力\"]\n            Compat[\"PromptCompat\\n(API -> 网页纯文本上下文)\"]\n            Completion[\"Completion Runtime\\n(Session \u002F PoW \u002F Completion)\"]\n            Turn[\"AssistantTurn\\n(输出语义归一)\"]\n            Auth[\"Auth Resolver\\n(API key \u002F bearer \u002F x-goog-api-key)\"]\n            Pool[\"Account Pool + Queue\\n(并发槽位 + 等待队列)\"]\n            DSClient[\"DeepSeek Client\\n(Session \u002F Auth \u002F Completion \u002F Files)\"]\n            Pow[\"PoW 实现\\n(纯 Go)\"]\n            Tool[\"Tool Sieve\\n(Go\u002FNode 语义对齐)\"]\n            History[\"Current Input File\\n(DS2API_HISTORY.txt)\"]\n        end\n    end\n\n    Client --> Router\n    Router --> OA & CA & GA\n    Router --> Admin\n    Router --> WebUI\n    Router --> Vercel\n\n    OA --> Compat\n    CA & GA --> Compat\n    Compat --> Completion\n    Completion -.完整上下文.-> History\n    Completion --> Turn\n    Vercel -.Go prepare.-> Completion\n    Vercel -.Node SSE.-> Tool\n    Completion --> Auth\n    Completion -.账号轮询.-> Pool\n    Completion -.工具调用解析.-> Tool\n    Completion -.PoW 计算.-> Pow\n    Auth --> DSClient\n    DSClient --> Upstream\n    Upstream --> DSClient\n    Turn --> Client\n    Vercel --> Client\n```\n\n详细架构拆分与目录职责见 [docs\u002FARCHITECTURE.md](docs\u002FARCHITECTURE.md)。\n\n- **后端**：Go（`cmd\u002Fds2api\u002F`、`api\u002F`、`internal\u002F`），不依赖 Python 运行时\n- **前端**：React 管理台（`webui\u002F`），运行时托管静态构建产物\n- **部署**：本地运行、Docker、Vercel Serverless、Linux systemd\n\n## 核心能力\n\n| 能力 | 说明 |\n| --- | --- |\n| OpenAI 兼容 | `GET \u002Fv1\u002Fmodels`、`GET \u002Fv1\u002Fmodels\u002F{id}`、`POST \u002Fv1\u002Fchat\u002Fcompletions`、`POST \u002Fv1\u002Fresponses`、`GET \u002Fv1\u002Fresponses\u002F{response_id}`、`POST \u002Fv1\u002Fembeddings`、`POST \u002Fv1\u002Ffiles`、`GET \u002Fv1\u002Ffiles\u002F{file_id}` |\n| Claude 兼容 | `GET \u002Fanthropic\u002Fv1\u002Fmodels`、`POST \u002Fanthropic\u002Fv1\u002Fmessages`、`POST \u002Fanthropic\u002Fv1\u002Fmessages\u002Fcount_tokens`（及快捷路径 `\u002Fv1\u002Fmessages`、`\u002Fmessages`） |\n| Gemini 兼容 | `POST \u002Fv1beta\u002Fmodels\u002F{model}:generateContent`、`POST \u002Fv1beta\u002Fmodels\u002F{model}:streamGenerateContent`（及 `\u002Fv1\u002Fmodels\u002F{model}:*` 路径） |\n| 统一 CORS 兼容 | `\u002Fv1\u002F*`、`\u002Fanthropic\u002F*`、`\u002Fv1beta\u002Fmodels\u002F*`、`\u002Fadmin\u002F*` 统一走同一套 CORS 策略；Vercel 上 `\u002Fv1\u002Fchat\u002Fcompletions` 的 Node Runtime 也对齐相同放行规则，尽量减少第三方预检请求头限制 |\n| 多账号轮询 | 自动 token 刷新、邮箱\u002F手机号双登录方式 |\n| 并发队列控制 | 每账号 in-flight 上限 + 等待队列，动态计算建议并发值 |\n| DeepSeek PoW | 纯 Go 高性能实现（DeepSeekHashV1），毫秒级响应 |\n| Tool Calling | 防泄漏处理：非代码块高置信特征识别、`delta.tool_calls` 早发、结构化增量输出 |\n| Admin API | 配置管理、运行时设置热更新、代理管理、账号测试 \u002F 批量测试、会话清理、导入导出、Vercel 同步、版本检查 |\n| WebUI 管理台 | `\u002Fadmin` 单页应用（中英文双语、深色模式，支持查看服务器端对话记录） |\n| 运维探针 | `GET \u002Fhealthz`（存活）、`GET \u002Freadyz`（就绪） |\n\nOpenAI `\u002Fv1\u002F*` 仍是推荐的规范路径；同时支持 `\u002Fmodels`、`\u002Fchat\u002Fcompletions`、`\u002Fresponses`、`\u002Fembeddings`、`\u002Ffiles`、`\u002Ffiles\u002F{file_id}` 等根路径快捷路由，方便只配置 DS2API 根地址的第三方客户端。\n\n## 平台兼容矩阵\n\n| 级别 | 平台 | 当前状态 |\n| --- | --- | --- |\n| P0 | Codex CLI\u002FSDK（`wire_api=chat` \u002F `wire_api=responses`） | ✅ |\n| P0 | OpenAI SDK（JS\u002FPython，chat + responses） | ✅ |\n| P0 | Vercel AI SDK（openai-compatible） | ✅ |\n| P0 | Anthropic SDK（messages） | ✅ |\n| P0 | Google Gemini SDK（generateContent） | ✅ |\n| P1 | LangChain \u002F LlamaIndex \u002F OpenWebUI（OpenAI 兼容接入） | ✅ |\n\n## 模型支持\n\n### OpenAI 接口（`GET \u002Fv1\u002Fmodels`）\n\n| 模型类型 | 模型 ID | thinking | search |\n| --- | --- | --- | --- |\n| default | `deepseek-v4-flash` | 默认开启，可由请求参数控制 | ❌ |\n| default | `deepseek-v4-flash-nothinking` | 永久关闭，不受请求参数影响 | ❌ |\n| expert | `deepseek-v4-pro` | 默认开启，可由请求参数控制 | ❌ |\n| expert | `deepseek-v4-pro-nothinking` | 永久关闭，不受请求参数影响 | ❌ |\n| default | `deepseek-v4-flash-search` | 默认开启，可由请求参数控制 | ✅ |\n| default | `deepseek-v4-flash-search-nothinking` | 永久关闭，不受请求参数影响 | ✅ |\n| expert | `deepseek-v4-pro-search` | 默认开启，可由请求参数控制 | ✅ |\n| expert | `deepseek-v4-pro-search-nothinking` | 永久关闭，不受请求参数影响 | ✅ |\n| vision | `deepseek-v4-vision` | 默认开启，可由请求参数控制 | ❌ |\n| vision | `deepseek-v4-vision-nothinking` | 永久关闭，不受请求参数影响 | ❌ |\n\n除原生模型外，也支持常见 alias 输入（如 `gpt-4.1`、`gpt-5`、`gpt-5-codex`、`o3`、`claude-*`、`gemini-*` 等），但 `\u002Fv1\u002Fmodels` 返回的是规范化后的 DeepSeek 原生模型 ID。若 alias 名本身追加 `-nothinking` 后缀，也会映射到对应的强制关思考模型。完整 alias 行为以 [API.md](API.md#模型-alias-解析策略) 和 `config.example.json` 为准。\n当前上游视觉模型只暴露 `vision` 通道，不提供独立的联网搜索视觉变体。\n\n### Claude 接口（`GET \u002Fanthropic\u002Fv1\u002Fmodels`）\n\n| 当前常用模型 | 默认映射 |\n| --- | --- |\n| `claude-sonnet-4-6` | `deepseek-v4-flash` |\n| `claude-sonnet-4-6-nothinking` | `deepseek-v4-flash-nothinking` |\n| `claude-haiku-4-5`（兼容 `claude-3-5-haiku-latest`） | `deepseek-v4-flash` |\n| `claude-haiku-4-5-nothinking` | `deepseek-v4-flash-nothinking` |\n| `claude-opus-4-6` | `deepseek-v4-pro` |\n| `claude-opus-4-6-nothinking` | `deepseek-v4-pro-nothinking` |\n\n可通过配置中的 `model_aliases` 覆盖映射关系；若请求模型名带 `-nothinking`，会在最终映射结果上强制追加无思考语义。\n`\u002Fanthropic\u002Fv1\u002Fmodels` 除上述主别名外，还会返回 Claude 4.x snapshots、3.x 历史模型 ID 与常见 alias，便于旧客户端直接兼容。\n\n#### Claude Code 接入避坑（实测）\n\n- `ANTHROPIC_BASE_URL` 推荐直接指向 DS2API 根地址（例如 `http:\u002F\u002F127.0.0.1:5001`），Claude Code 会请求 `\u002Fv1\u002Fmessages?beta=true`。\n- `ANTHROPIC_API_KEY` 需要与 `config.json` 中 `keys` 一致；建议同时保留常规 key 与 `sk-ant-*` 形态 key，兼容不同客户端校验习惯。\n- 若系统设置了代理，建议对 DS2API 地址配置 `NO_PROXY=127.0.0.1,localhost,\u003C你的主机IP>`，避免本地回环请求被代理拦截。\n- 如遇“工具调用输出成文本、未执行”问题，请优先检查模型输出是否为推荐的 DSML 工具块：`\u003C|DSML|tool_calls>\u003C|DSML|invoke name=\"...\">\u003C|DSML|parameter name=\"...\">...`。兼容层也接受旧式 canonical XML：`\u003Ctool_calls>\u003Cinvoke name=\"...\">\u003Cparameter name=\"...\">...`；旧式 `\u003Ctools>` \u002F `\u003Ctool_call>` \u002F `\u003Ctool_name>` \u002F `\u003Cparam>`、`\u003Cfunction_call>`、`tool_use` 或纯 JSON `tool_calls` 片段不会执行。\n\n### Gemini 接口\n\nGemini 适配器将模型名通过 `model_aliases` 或内置规则映射到 DeepSeek 原生模型，支持 `generateContent` 和 `streamGenerateContent` 两种调用方式，并完整支持 Tool Calling（`functionDeclarations` → `functionCall` 输出）。若 Gemini 模型名带 `-nothinking` 后缀，例如 `gemini-2.5-pro-nothinking`，会映射到对应的强制关闭思考模型。\n\n## 快速开始\n\n### 部署方式优先级建议\n\n推荐按以下顺序选择部署方式：\n\n1. **下载 Release 构建包运行**：最省事，产物已编译完成，最适合大多数用户。\n2. **Docker \u002F GHCR 镜像部署**：适合需要容器化、编排或云环境部署。\n3. **Vercel 部署**：适合已有 Vercel 环境且接受其平台约束的场景。\n4. **本地源码运行 \u002F 自行编译**：适合开发、调试或需要自行修改代码的场景。\n\n### 通用第一步（所有部署方式）\n\n把 `config.json` 作为唯一配置源（推荐做法）：\n\n```bash\ncp config.example.json config.json\n# 编辑 config.json\n```\n\n后续部署建议：\n- 本地运行：直接读取 `config.json`\n- Docker \u002F Vercel：由 `config.json` 生成 `DS2API_CONFIG_JSON`（Base64）注入环境变量，也可以直接写原始 JSON\n\nWebUI 管理台里的“全量配置模板”也直接复用同一份 `config.example.json`，所以更新示例文件后，前端模板会自动保持一致。\n\n### 方式一：下载 Release 构建包\n\n每次发布 Release 时，GitHub Actions 会自动构建多平台二进制包：\n\n```bash\n# 下载对应平台的压缩包后\ntar -xzf ds2api_\u003Ctag>_linux_amd64.tar.gz\ncd ds2api_\u003Ctag>_linux_amd64\ncp config.example.json config.json\n# 编辑 config.json\n.\u002Fds2api\n```\n\n### 方式二：Docker 运行\n\n```bash\n# 1. 准备环境变量和配置文件\ncp .env.example .env\ncp config.example.json config.json\n\n# 2. 编辑 .env（至少设置 DS2API_ADMIN_KEY；如需修改宿主机端口，可额外设置 DS2API_HOST_PORT）\n#    DS2API_ADMIN_KEY=请替换为强密码\n\n# 3. 启动\ndocker-compose up -d\n\n# 4. 查看日志\ndocker-compose logs -f\n```\n\n默认 `docker-compose.yml` 会把宿主机 `6011` 映射到容器内的 `5001`。如果你希望直接对外暴露 `5001`，请设置 `DS2API_HOST_PORT=5001`（或者手动调整 `ports` 配置）。\n同时默认把 `.\u002Fconfig.json` 挂载到容器 `\u002Fdata\u002Fconfig.json`，并设置 `DS2API_CONFIG_PATH=\u002Fdata\u002Fconfig.json`，用于避免 `\u002Fapp` 只读导致运行时 token 持久化失败。\n镜像会预创建 `\u002Fdata` 并授权给非 root 的 `ds2api` 用户；如果使用单文件 bind mount，请确保宿主机 `config.json` 对容器用户可读写，例如 `chmod 644 config.json`。\n\n更新镜像：`docker-compose up -d --build`\n\n#### Zeabur 一键部署（Dockerfile）\n\n1. 点击上方 “Deploy on Zeabur” 按钮，一键部署。\n2. 部署完成后访问 `\u002Fadmin`，使用 Zeabur 环境变量\u002F模板指引中的 `DS2API_ADMIN_KEY` 登录。\n3. 在管理台导入\u002F编辑配置（会写入并持久化到 `\u002Fdata\u002Fconfig.json`）。\n\nZeabur 首次空卷启动时可以没有 `\u002Fdata\u002Fconfig.json`；DS2API 会先使用空的文件模式配置启动，并在管理台首次保存时创建该文件。\n\n不依赖模板手动部署时，在 Zeabur 中选择 GitHub 仓库服务，Root Directory 保持 `\u002F`，使用仓库根目录 `Dockerfile` 构建；添加持久卷 `\u002Fdata`，设置 `PORT=5001`、`DS2API_ADMIN_KEY=你的强密钥`、`DS2API_CONFIG_PATH=\u002Fdata\u002Fconfig.json`，然后暴露 HTTP 端口 `5001`。更完整步骤见 [docs\u002FDEPLOY.md](docs\u002FDEPLOY.md#不使用模板手动部署)。\n\n说明：Zeabur 使用仓库内 `Dockerfile` 直接构建时，不需要额外传入 `BUILD_VERSION`；镜像会优先读取该构建参数，未提供时自动回退到仓库根目录的 `VERSION` 文件。\n\n### 方式三：Vercel 部署\n\n1. Fork 仓库到自己的 GitHub\n2. 在 Vercel 上导入项目\n3. 配置环境变量（最少设置 `DS2API_ADMIN_KEY`；推荐同时设置 `DS2API_CONFIG_JSON`）\n4. 部署\n\n建议先在仓库目录复制模板并填写：\n\n```bash\ncp config.example.json config.json\n# 编辑 config.json\n```\n\n推荐：先本地把 `config.json` 转成 Base64，再粘贴到 `DS2API_CONFIG_JSON`，避免 JSON 格式错误：\n\n```bash\nbase64 \u003C config.json | tr -d '\\n'\n```\n\n> **流式说明**：`\u002Fv1\u002Fchat\u002Fcompletions` 在 Vercel 上默认走 `api\u002Fchat-stream.js`（Node Runtime）以保证实时 SSE。鉴权、账号选择、会话\u002FPoW 准备仍由 Go 内部 prepare 接口完成；流式响应（含 `tools`）在 Node 侧执行与 Go 对齐的输出组装与防泄漏处理。虽然这里只有 OpenAI chat 流式走 Node，但 CORS 放行策略仍与 Go 主路由保持一致，统一覆盖第三方客户端预检场景。\n\n详细部署说明请参阅 [部署指南](docs\u002FDEPLOY.md)。\n\n### 方式四：本地源码运行\n\n**前置要求**：Go 1.26+，Node.js `20.19+` 或 `22.12+`（仅在需要构建 WebUI 时）；同时确保 `npm` 可用，建议 `npm 10+`\n\n```bash\n# 1. 克隆仓库\ngit clone https:\u002F\u002Fgithub.com\u002FCJackHwang\u002Fds2api.git\ncd ds2api\n\n# 2. 配置\ncp config.example.json config.json\n# 编辑 config.json，填入你的 DeepSeek 账号信息和 API key\n\n# 3. 启动\ngo run .\u002Fcmd\u002Fds2api\n```\n\n默认本地访问地址：`http:\u002F\u002F127.0.0.1:5001`\n\n服务实际绑定：`0.0.0.0:5001`，因此同一局域网设备通常也可以通过你的内网 IP 访问。\n\n> **WebUI 自动构建**：本地首次启动时，若 `static\u002Fadmin` 不存在，会自动尝试执行 `npm ci`（仅在缺少依赖时）和 `npm run build -- --outDir static\u002Fadmin --emptyOutDir`（需要本机有 Node.js 和 npm）。你也可以手动构建：`.\u002Fscripts\u002Fbuild-webui.sh`\n\n## 配置说明\n\n`README` 只保留快速入口，完整字段请以 [config.example.json](config.example.json) 为模板，并参考 [部署指南](docs\u002FDEPLOY.md#0-前置要求) 与 [API 配置最佳实践](API.md#配置最佳实践)。\n\n常用字段：\n\n- `keys` \u002F `api_keys`：客户端访问密钥，`api_keys` 支持 `name` 与 `remark` 元信息，`keys` 继续兼容。\n- `accounts`：DeepSeek 托管账号，支持 `email` 或 `mobile` 登录，可配置代理、名称和备注。\n- `model_aliases`：OpenAI \u002F Claude \u002F Gemini 共用的模型 alias 映射。\n- `runtime`：账号并发、队列与 token 刷新策略，可通过 Admin Settings 热更新。\n- `auto_delete.mode`：请求结束后的远端会话清理策略，支持 `none` \u002F `single` \u002F `all`。\n- `current_input_file`：全局生效的上下文拆分上传策略；默认开启且阈值为 `0`，触发时将完整上下文合并上传为 `DS2API_HISTORY.txt` 上下文文件。\n- 如果关闭 `current_input_file`，请求会直接透传，不上传拆分上下文文件。\n- `thinking_injection`：默认开启；在最新 user 消息末尾追加思考增强提示词，提高高强度推理与工具调用前的思考稳定性；`prompt` 留空时使用内置默认提示词。\n\n环境变量完整列表见 [部署指南](docs\u002FDEPLOY.md)，接口鉴权规则见 [API.md](API.md#鉴权规则)。\n\n## 鉴权模式\n\n调用业务接口（`\u002Fv1\u002F*`、`\u002Fanthropic\u002F*`、Gemini 路由）时支持两种模式：\n\n| 模式 | 说明 |\n| --- | --- |\n| **托管账号模式** | `Bearer` 或 `x-api-key` 传入 `config.keys` 中的 key，由服务自动轮询选择账号 |\n| **直通 token 模式** | 传入 token 不在 `config.keys` 中时，直接作为 DeepSeek token 使用 |\n\n可选请求头 `X-Ds2-Target-Account`：指定使用某个托管账号（值为 email 或 mobile）。\n如果指定账号不存在，或者当前管理账号队列已满，请求会返回 `429`；当前 `429` 不附带 `Retry-After` 头。若账号存在但登录\u002F刷新失败，则返回对应的鉴权错误。\nGemini 路由还可以使用 `x-goog-api-key`，或在没有认证头时使用 `?key=` \u002F `?api_key=` 作为调用方凭据。\n\n## 并发模型\n\n```\n每账号可用并发 = DS2API_ACCOUNT_MAX_INFLIGHT（默认 2）\n建议并发值 = 账号数量 × 每账号并发上限\n等待队列上限 = DS2API_ACCOUNT_MAX_QUEUE（默认 = 建议并发值）\n429 阈值 = in-flight + 等待队列 ≈ 账号数量 × 4\n```\n\n- 当 in-flight 槽位满时，请求进入等待队列，**不会立即 429**\n- 超出总承载上限后才返回 `429 Too Many Requests`，当前响应不附带 `Retry-After`\n- `GET \u002Fadmin\u002Fqueue\u002Fstatus` 返回实时并发状态\n\n## Tool Call 适配\n\n当请求中带 `tools` 时，DS2API 会做防泄漏处理与结构化转译：\n\n1. 只在**非代码块上下文**启用执行型 toolcall 识别（代码块示例默认不触发）\n2. 解析层当前把 DSML 外壳视为推荐可执行调用：`\u003C|DSML|tool_calls>` → `\u003C|DSML|invoke name=\"...\">` → `\u003C|DSML|parameter name=\"...\">`；兼容旧式 canonical XML `\u003Ctool_calls>` → `\u003Cinvoke name=\"...\">` → `\u003Cparameter name=\"...\">`。DSML 只是外壳别名，内部仍以 XML 解析语义为准；旧式 `\u003Ctools>` \u002F `\u003Ctool_call>` \u002F `\u003Ctool_name>` \u002F `\u003Cparam>`、`\u003Cfunction_call>`、`tool_use` \u002F antml 变体与纯 JSON `tool_calls` 片段都会按普通文本处理\n3. `responses` 流式严格使用官方 item 生命周期事件（`response.output_item.*`、`response.content_part.*`、`response.function_call_arguments.*`）\n4. `responses` 支持并执行 `tool_choice`（`auto`\u002F`none`\u002F`required`\u002F强制函数）；`required` 违规时非流式返回 `422`，流式返回 `response.failed`\n5. 客户端请求哪种协议，就按该协议返回工具调用（OpenAI\u002FClaude\u002FGemini 各自原生结构）；模型侧优先约束输出规范 XML，再由兼容层转译\n\n> 说明：当前版本 parser 层以”尽量解析成功”为优先，所有格式合法的 XML 工具调用都会通过，不做工具名 allow-list 过滤。\n>\n> 想评估”把工具调用封装成 XML 再输入模型”的方案，可参考：`docs\u002Ftoolcall-semantics.md`。\n\n## 本地开发抓包工具\n\n用于定位「responses 思考流\u002F工具调用」等问题。开启后会自动记录最近 N 条 DeepSeek 对话上游请求体与响应体（默认 20 条，超出自动淘汰；单条响应体默认最多记录 5 MB）。\n\n启用示例：\n\n```bash\nDS2API_DEV_PACKET_CAPTURE=true \\\nDS2API_DEV_PACKET_CAPTURE_LIMIT=20 \\\ngo run .\u002Fcmd\u002Fds2api\n```\n\n查询\u002F清空（需 Admin JWT）：\n\n- `GET \u002Fadmin\u002Fdev\u002Fcaptures`：查看抓包列表（最新在前）\n- `DELETE \u002Fadmin\u002Fdev\u002Fcaptures`：清空抓包\n- `GET \u002Fadmin\u002Fdev\u002Fraw-samples\u002Fquery?q=关键词&limit=20`：按问题关键词查询当前内存抓包，并按 `chat_session_id` 归并 `completion + continue` 链\n- `POST \u002Fadmin\u002Fdev\u002Fraw-samples\u002Fsave`：把命中的某条抓包链保存为 `tests\u002Fraw_stream_samples\u002F\u003Csample-id>\u002F` 回放样本\n\n返回字段包含：\n\n- `request_body`：发送给 DeepSeek 的完整请求体\n- `response_body`：上游返回的原始流式内容拼接文本\n- `response_truncated`：是否触发单条大小截断\n\n保存接口支持用 `query`、`chain_key` 或 `capture_id` 选中目标。例如：\n\n```json\n{\"query\":\"广州天气\",\"sample_id\":\"gz-weather-from-memory\"}\n```\n\n## 文档索引\n\n| 文档 | 说明 |\n| --- | --- |\n| [API.md](API.md) \u002F [API.en.md](API.en.md) | API 接口文档（含请求\u002F响应示例） |\n| [DEPLOY.md](docs\u002FDEPLOY.md) \u002F [DEPLOY.en.md](docs\u002FDEPLOY.en.md) | 部署指南（本地\u002FDocker\u002FVercel\u002Fsystemd） |\n| [CONTRIBUTING.md](docs\u002FCONTRIBUTING.md) \u002F [CONTRIBUTING.en.md](docs\u002FCONTRIBUTING.en.md) | 贡献指南 |\n| [TESTING.md](docs\u002FTESTING.md) | 测试集使用指南 |\n\n## 测试\n\n详细测试指南请参阅 [docs\u002FTESTING.md](docs\u002FTESTING.md)。\n\n### 快速测试命令\n\n```bash\n# 本地 PR 门禁\n.\u002Fscripts\u002Flint.sh\n.\u002Ftests\u002Fscripts\u002Fcheck-refactor-line-gate.sh\n.\u002Ftests\u002Fscripts\u002Frun-unit-all.sh\nnpm run build --prefix webui\n\n# 端到端全链路测试（真实账号，生成完整请求\u002F响应日志）\n.\u002Ftests\u002Fscripts\u002Frun-live.sh\n```\n\n## Release 自动构建（GitHub Actions）\n\n工作流文件：`.github\u002Fworkflows\u002Frelease-artifacts.yml`\n\n- **触发条件**：默认仅在 GitHub Release `published` 时自动触发；也支持在 Actions 页面手动 `workflow_dispatch`，并填写 `release_tag` 复跑\u002F补发\n- **构建产物**：多平台二进制包（`linux\u002Famd64`、`linux\u002Farm64`、`linux\u002Farmv7`、`darwin\u002Famd64`、`darwin\u002Farm64`、`windows\u002Famd64`、`windows\u002Farm64`）、Linux Docker 镜像导出包 + `sha256sums.txt`\n- **容器镜像发布**：仅推送到 GHCR（`ghcr.io\u002Fcjackhwang\u002Fds2api`）\n- **每个二进制压缩包包含**：`ds2api` 可执行文件、`static\u002Fadmin`、`config.example.json`、`.env.example`、`README.MD`、`README.en.md`、`LICENSE`\n\n## 免责声明\n\n本项目基于逆向方式实现，仅供学习、研究、个人实验和内部验证使用，不提供任何商业授权、稳定性保证或可用性保证。\n作者及仓库维护者不对因使用、修改、分发、部署或依赖本项目而产生的任何直接或间接损失、账号封禁、数据丢失、法律风险或第三方索赔负责。\n\n请勿将本项目用于违反服务条款、协议、法律法规或平台规则的场景。商业使用前请自行确认 `LICENSE`、相关协议以及你是否获得了作者的书面许可。\n","DS2API 是一个用于将 DeepSeek Web 对话能力转换为与 OpenAI、Claude 以及 Gemini 兼容的 API 的中间件接口项目。该项目使用 Go 语言开发，专注于高并发协议适配，支持 Docker 和 Vercel 部署，并提供 React 前端管理界面。其核心功能包括通过模块化 HTTP 表面和 PromptCompat 内核实现不同平台间的协议转换，支持多种认证模式和工具调用适配。适用于需要整合或扩展多源 AI 服务的应用场景，如构建跨平台聊天机器人、增强现有应用的自然语言处理能力等。",2,"2026-06-11 03:27:41","top_topic"]