一个纯 Node.js 的 DeepSeek Web 控制台 + OpenAI 兼容桥接服务。
它把本地用户体系、DeepSeek 账号绑定、API Key 管理、DeepSeek 原生代理调试和 OpenAI 兼容接口放进同一个可直接运行的项目里。
| 模块 | 能力 |
|---|---|
| 控制台 UI | 注册 / 登录、本地用户隔离、DeepSeek 账号绑定、API Key 管理 |
| OpenAI 兼容层 | GET /v1/models、POST /v1/chat/completions、POST /v1/responses、GET /v1/responses/:id |
| 工具调用 | 仅适配 chat / responses 协议;按 API Key 单独开关 |
| 原生代理层 | 提供 /proxy/* 白名单转发,便于调试和复用 DeepSeek Web 接口 |
| 管理后台 | 注册开关、邀请码、用户启用 / 禁用 / 删除、并发 / 速率限制 |
| 无痕模式 | 支持全局或用户级无痕,请求完成后自动清理会话 |
| 部署形态 | 无第三方运行时依赖,npm start 即可启动 |
- 纯 Node.js 原生 HTTP 服务,无 Express、无数据库、无构建步骤
- 前后端都在同一个仓库里,静态资源由服务端直接托管
- 运行状态统一保存在
data/app.json - DeepSeek token 失效时会自动重新登录并刷新
- 遇到 PoW 保护接口时会自动获取 wasm 并求解挑战
- OpenAI 兼容层同时支持流式和非流式响应
deepseek-reasoner-*模型会把思维内容包在<think>...</think>- API Key 请求会在当前用户可见账号之间轮询
- Node.js 18+
- 服务端能够访问 https://chat.deepseek.com
- 浏览器在绑定 DeepSeek 账号时需要访问 https://cdn.deepseek.com
- 如触发 PoW 校验,服务端还需要访问 https://fe-static.deepseek.com
npm start默认监听地址:
http://127.0.0.1:3000
仓库不自带 .env。如需启用管理员入口或修改端口,可参考 .env.example 手动创建:
cp .env.example .envWindows PowerShell:
Copy-Item .env.example .env.env.example 内容:
PORT=3000
APP_ADMIN_USERNAME=
APP_ADMIN_PASSWORD=浏览器访问 http://127.0.0.1:3000,然后按下面流程使用:
- 注册本地用户,或使用管理员账号登录
- 在“账号”页绑定 DeepSeek 账号
- 在“密钥”页创建 API Key
- 如需工具调用,为该 API Key 单独打开“工具调用”开关
- 使用内置聊天工作区,或通过 OpenAI 兼容接口接入客户端
| 变量 | 默认值 | 说明 |
|---|---|---|
PORT |
3000 |
服务监听端口 |
APP_ADMIN_USERNAME |
空 | 管理员用户名 |
APP_ADMIN_PASSWORD |
空 | 管理员密码 |
只有同时设置 APP_ADMIN_USERNAME 和 APP_ADMIN_PASSWORD 时,管理员入口才会启用。
- 绑定 / 删除 DeepSeek Web 账号
- 为当前用户创建多个 API Key
- API Key 可指定自定义明文,留空则自动生成
- API Key 可单独开启或关闭“工具调用”
- 创建 API Key 时可直接设置工具调用开关
- OpenAI 兼容请求会在当前用户可见账号之间轮询
- 管理本地注册开关
- 控制是否必须使用邀请码注册
- 生成、删除、批量删除邀请码
- 禁用、启用、删除本地用户
- 为用户设置并发上限和每分钟请求上限
- 管理员可开启全局无痕
- 普通用户可只为自己开启无痕
- 开启后,请求完成后会自动清理相关 DeepSeek 会话
GET /v1/modelsPOST /v1/chat/completionsPOST /v1/responsesGET /v1/responses/:id
- 默认模型:
deepseek-chat-fast - 联网能力通过模型后缀
-search控制 - 不支持
web_search_options,请改用*-search模型
支持的模型 ID:
deepseek-chat-fastdeepseek-chat-fast-searchdeepseek-reasoner-fastdeepseek-reasoner-fast-searchdeepseek-chat-expertdeepseek-chat-expert-searchdeepseek-reasoner-expertdeepseek-reasoner-expert-search
curl http://127.0.0.1:3000/v1/chat/completions \
-H "Authorization: Bearer <YOUR_API_KEY>" \
-H "Content-Type: application/json" \
-d '{
"model": "deepseek-chat-fast",
"messages": [
{ "role": "user", "content": "hello" }
]
}'curl http://127.0.0.1:3000/v1/responses \
-H "Authorization: Bearer <YOUR_API_KEY>" \
-H "Content-Type: application/json" \
-d '{
"model": "deepseek-chat-fast",
"input": "hello"
}'- 工具调用仅适配
chat/completions和responses - 协议入口始终存在;是否允许工具调用由 API Key 的开关决定
- API Key 未开启工具调用时:
- 普通请求可正常使用
- 带
tools、tool_choice、工具历史消息的请求会直接返回400
- API Key 开启工具调用时:
- 服务会把工具 schema 注入提示词
- 再把模型输出中的工具 XML 解析回 OpenAI 兼容的工具调用结构
- 当前实现本质上是“提示词注入 + 输出解析”,不是上游原生 tool calling
- 提示词允许模型在工具调用前、后或前后都输出普通文本
- 普通文本是否出现、出现在哪一侧,由模型自己决定,不做强制
chat/completions非流式:- 如果识别到工具调用,响应会同时返回
message.tool_calls - 如果模型在工具调用前后还输出了普通文本,文本会保留在
message.content
- 如果识别到工具调用,响应会同时返回
chat/completions流式:- 普通文本继续走
delta.content - 工具调用走
delta.tool_calls - 工具调用事件出现的位置不固定,取决于模型实际输出顺序
- 普通文本继续走
responses非流式:- 混合输出会按顺序拆成
output数组中的多个 item - 典型形态是
message -> function_call -> message
- 混合输出会按顺序拆成
responses流式:- 文本段会逐段生成独立的 message item
- 工具调用会生成 function_call item
- 事件顺序与模型实际输出顺序一致
- 只识别 XML / Markup 风格的工具调用块
- 不识别把
"tool_calls": [...]当普通文本吐出来的 JSON 片段 previous_response_id目前不支持- 混合输出是否稳定出现,和所选模型强相关;
deepseek-reasoner-*通常比deepseek-chat-*更容易产出“文本 + 工具调用”的混合结果
GET /proxy/...POST /proxy/...
/proxy/*走的是登录态会话,不是 API Key 鉴权- 如果存在多个可用账号,可通过请求头
x-proxy-account-id指定账号 - 只允许转发白名单路径,白名单定义在
src/config.js
当前白名单包含:
/api/v0/chat/completion/api/v0/chat/continue/api/v0/chat/create_pow_challenge/api/v0/chat/edit_message/api/v0/chat/history_messages/api/v0/chat/message_feedback/api/v0/chat/regenerate/api/v0/chat/resume_stream/api/v0/chat/stop_stream/api/v0/chat_session/create/api/v0/chat_session/delete/api/v0/chat_session/delete_all/api/v0/chat_session/fetch_page/api/v0/chat_session/update_pinned/api/v0/chat_session/update_title/api/v0/client/settings/api/v0/download_export_history/api/v0/export_all/api/v0/file/fetch_files/api/v0/file/preview/api/v0/file/upload_file/api/v0/share/content/api/v0/share/create/api/v0/share/delete/api/v0/share/fork/api/v0/share/list/api/v0/users/current/api/v0/users/settings/api/v0/users/update_settings
GET /api/meGET /api/discoveryPOST /api/auth/loginPOST /api/auth/registerPOST /api/auth/logout
GET /api/accountsPOST /api/accountsDELETE /api/accounts/:idPOST /api/incognitoGET /api/api-keysPOST /api/api-keysPATCH /api/api-keys/:idDELETE /api/api-keys/:id
POST /api/admin/registrationPOST /api/admin/invitesPOST /api/admin/invites/batch-deleteDELETE /api/admin/invites/:idPATCH /api/admin/users/:idDELETE /api/admin/users/:idPOST /api/admin/users/batch-disablePOST /api/admin/users/batch-delete
.
├─ data/ # 运行时数据目录
├─ public/ # 前端控制台静态资源
├─ src/
│ ├─ routes/ # 公共 / 私有 / 管理 / OpenAI / 代理路由
│ ├─ services/ # 账号、用户、桥接、PoW、限流等核心逻辑
│ ├─ storage/ # JSON 文件存储
│ └─ utils/ # HTTP、SSE、ID、Prompt 等工具
├─ .env.example
├─ package.json
└─ README.md
This project is licensed under the MIT License.