mirror of
https://github.com/CJackHwang/ds2api.git
synced 2026-05-06 01:15:29 +08:00
239 lines
8.1 KiB
Markdown
239 lines
8.1 KiB
Markdown
# DS2API
|
||
|
||
[](LICENSE)
|
||

|
||

|
||
[](version.txt)
|
||
[](DEPLOY.md)
|
||
|
||
语言 / Language: [中文](README.MD) | [English](README.en.md)
|
||
|
||
将 DeepSeek Web 对话能力转换为 OpenAI 与 Claude 兼容 API。当前仓库后端为 **Go 全量实现**,前端保留 React WebUI(源码在 `webui/`,部署时自动构建到 `static/admin`)。
|
||
|
||
## 当前实现边界
|
||
|
||
- 后端:Go(`cmd/`, `api/`, `internal/`),不再依赖 Python 运行时
|
||
- 前端:React 管理台(源码在 `webui/`,运行时托管静态构建)
|
||
- 部署:本地运行、Docker、Vercel Serverless
|
||
|
||
## 核心能力
|
||
|
||
- OpenAI 兼容:`/v1/models`、`/v1/chat/completions`
|
||
- Claude 兼容:`/anthropic/v1/models`、`/anthropic/v1/messages`、`/anthropic/v1/messages/count_tokens`
|
||
- 多账号轮询与自动 token 刷新
|
||
- DeepSeek PoW(WASM)计算
|
||
- Admin API:配置管理、账号测试、导入导出、Vercel 同步
|
||
- WebUI:`/admin` 单页应用托管
|
||
- 运维探针:`/healthz`、`/readyz`
|
||
|
||
## 模型支持
|
||
|
||
### OpenAI 接口
|
||
|
||
| 模型 | thinking | search |
|
||
| --- | --- | --- |
|
||
| `deepseek-chat` | false | false |
|
||
| `deepseek-reasoner` | true | false |
|
||
| `deepseek-chat-search` | false | true |
|
||
| `deepseek-reasoner-search` | true | true |
|
||
|
||
### Claude 接口
|
||
|
||
| 模型 | 默认映射 |
|
||
| --- | --- |
|
||
| `claude-sonnet-4-20250514` | `deepseek-chat` |
|
||
| `claude-sonnet-4-20250514-fast` | `deepseek-chat` |
|
||
| `claude-sonnet-4-20250514-slow` | `deepseek-reasoner` |
|
||
|
||
可通过配置中的 `claude_mapping` 或 `claude_model_mapping` 覆盖映射。
|
||
|
||
## 快速开始
|
||
|
||
### 1) 本地运行
|
||
|
||
要求:Go 1.24+
|
||
|
||
```bash
|
||
git clone https://github.com/CJackHwang/ds2api.git
|
||
cd ds2api
|
||
|
||
cp config.example.json config.json
|
||
# 编辑 config.json
|
||
|
||
go run ./cmd/ds2api
|
||
```
|
||
|
||
默认地址:`http://localhost:5001`
|
||
|
||
本地默认会在启动时自动尝试构建 WebUI(需要本机有 Node.js/npm)。
|
||
若你想手动构建,也可执行:
|
||
|
||
```bash
|
||
./scripts/build-webui.sh
|
||
```
|
||
|
||
### 2) Docker 运行
|
||
|
||
```bash
|
||
cp .env.example .env
|
||
# 编辑 .env
|
||
|
||
docker-compose up -d
|
||
docker-compose logs -f
|
||
```
|
||
|
||
### 3) Vercel 部署
|
||
|
||
- 入口:`api/index.go`
|
||
- 路由重写:`vercel.json`
|
||
- `vercel.json` 会在构建阶段自动执行 `npm ci --prefix webui && npm run build --prefix webui`
|
||
- `/v1/chat/completions` 在 Vercel 上默认走 `api/chat-stream.js`(Node Runtime)以保证实时 SSE
|
||
- `api/chat-stream.js` 仅负责流式数据转发;鉴权、账号选择、会话/PoW 准备仍由 Go 内部 prepare 接口处理
|
||
- Go prepare 会下发 `lease_id`,Node 在流结束后调用 release,确保账号占用时长与 Go 原生流式一致
|
||
- WebUI 的“非流式测试”会直接请求 `?__go=1`,避免 Vercel 上 Node 中转导致长请求更易超时
|
||
- 至少配置:
|
||
- `DS2API_ADMIN_KEY`
|
||
- `DS2API_CONFIG_JSON`(JSON 字符串或 Base64)
|
||
|
||
说明:仓库不提交 `static/admin` 构建产物,Vercel 构建时自动生成并打包。
|
||
|
||
## Release 自动构建产物(GitHub Actions)
|
||
|
||
仓库内置工作流:`.github/workflows/release-artifacts.yml`
|
||
|
||
- 触发条件:仅在 GitHub Release `published` 时触发
|
||
- 不会在普通 `push` 时构建
|
||
- 构建内容:多平台二进制包(Linux/macOS/Windows)+ `sha256sums.txt`
|
||
- 每个压缩包包含:
|
||
- `ds2api` 可执行文件(Windows 为 `ds2api.exe`)
|
||
- `static/admin`(WebUI 构建产物)
|
||
- `sha3_wasm_bg.7b9ca65ddd.wasm`
|
||
- `config.example.json`、`.env.example`
|
||
- `README.MD`、`README.en.md`、`LICENSE`
|
||
|
||
维护者发布步骤:
|
||
|
||
1. 在 GitHub 创建并发布 Release(带 tag,如 `v1.7.0`)
|
||
2. 等待 Actions 工作流 `Release Artifacts` 完成
|
||
3. 在 Release 的 Assets 下载对应平台压缩包
|
||
|
||
下载后运行示例(Linux/macOS):
|
||
|
||
```bash
|
||
tar -xzf ds2api_v1.7.0_linux_amd64.tar.gz
|
||
cd ds2api_v1.7.0_linux_amd64
|
||
cp config.example.json config.json
|
||
./ds2api
|
||
```
|
||
|
||
## 配置说明
|
||
|
||
### `config.json` 示例
|
||
|
||
```json
|
||
{
|
||
"keys": ["your-api-key-1", "your-api-key-2"],
|
||
"accounts": [
|
||
{
|
||
"email": "user@example.com",
|
||
"password": "your-password",
|
||
"token": ""
|
||
},
|
||
{
|
||
"mobile": "12345678901",
|
||
"password": "your-password",
|
||
"token": ""
|
||
}
|
||
],
|
||
"claude_model_mapping": {
|
||
"fast": "deepseek-chat",
|
||
"slow": "deepseek-reasoner"
|
||
}
|
||
}
|
||
```
|
||
|
||
### 环境变量(核心)
|
||
|
||
| 变量 | 用途 |
|
||
| --- | --- |
|
||
| `PORT` | 服务端口,默认 `5001` |
|
||
| `LOG_LEVEL` | 日志级别:`DEBUG/INFO/WARN/ERROR` |
|
||
| `DS2API_ACCOUNT_MAX_INFLIGHT` | 每个账号最大并发 in-flight 请求数,默认 `2` |
|
||
| `DS2API_ACCOUNT_CONCURRENCY` | 同上别名(兼容旧写法) |
|
||
| `DS2API_ACCOUNT_MAX_QUEUE` | 等待队列上限,默认等于 `recommended_concurrency` |
|
||
| `DS2API_ACCOUNT_QUEUE_SIZE` | 同上别名(兼容旧写法) |
|
||
| `DS2API_ADMIN_KEY` | Admin 登录密钥,默认 `admin` |
|
||
| `DS2API_JWT_SECRET` | Admin JWT 签名密钥(可选) |
|
||
| `DS2API_JWT_EXPIRE_HOURS` | Admin JWT 过期小时数,默认 `24` |
|
||
| `DS2API_CONFIG_PATH` | 配置文件路径,默认 `config.json` |
|
||
| `DS2API_CONFIG_JSON` | 直接注入配置(JSON 或 Base64) |
|
||
| `DS2API_WASM_PATH` | PoW wasm 文件路径 |
|
||
| `DS2API_STATIC_ADMIN_DIR` | 管理台静态文件目录 |
|
||
| `DS2API_AUTO_BUILD_WEBUI` | 启动时缺失 WebUI 时是否自动执行 npm build(默认:本地开启,Vercel 关闭) |
|
||
| `DS2API_VERCEL_INTERNAL_SECRET` | Vercel 混合流式链路内部鉴权密钥(可选;未设置时回退用 `DS2API_ADMIN_KEY`) |
|
||
| `DS2API_VERCEL_STREAM_LEASE_TTL_SECONDS` | Vercel 流式 lease 过期秒数(默认 `900`) |
|
||
| `VERCEL_TOKEN` | Vercel 同步 token(可选) |
|
||
| `VERCEL_PROJECT_ID` | Vercel 项目 ID(可选) |
|
||
| `VERCEL_TEAM_ID` | Vercel 团队 ID(可选) |
|
||
|
||
## 鉴权与账号模式
|
||
|
||
调用业务接口时(`/v1/*`, `/anthropic/*`)支持两种模式:
|
||
|
||
1. 托管账号模式:`Bearer` 或 `x-api-key` 使用 `config.keys` 中的 key。
|
||
2. 直通 token 模式:当传入 token 不在 `config.keys` 中时,服务直接把它当作 DeepSeek token 使用。
|
||
|
||
可选请求头:`X-Ds2-Target-Account`,用于指定托管账号。
|
||
|
||
## 并发建议值
|
||
|
||
- 系统建议并发值按账号池动态计算:`账号数量 × 每账号并发上限`
|
||
- 默认每账号并发上限是 `2`,因此默认建议值是 `账号数量 × 2`
|
||
- 当 in-flight 槽位满时,请求会进入等待队列,不会立即 429
|
||
- 默认等待队列上限 = `recommended_concurrency`,因此默认总承载上限是 `账号数量 × 4`
|
||
- 超过总承载上限(in-flight + waiting)才返回 `429`
|
||
- 可通过 `DS2API_ACCOUNT_MAX_INFLIGHT`(或 `DS2API_ACCOUNT_CONCURRENCY`)手动覆盖每账号并发上限
|
||
- 可通过 `DS2API_ACCOUNT_MAX_QUEUE`(或 `DS2API_ACCOUNT_QUEUE_SIZE`)手动覆盖等待队列上限
|
||
- `GET /admin/queue/status` 会返回 `max_inflight_per_account`、`recommended_concurrency`、`waiting`、`max_queue_size`
|
||
|
||
## Tool Call 适配说明
|
||
|
||
当前实现对 toolcall 做了防泄漏处理:
|
||
|
||
- `tools` + `stream=true` 时,服务端会先缓冲正文片段
|
||
- 若识别到工具调用,会只输出结构化 `tool_calls`,不透传原始 JSON 文本
|
||
- 若最终不是工具调用,再一次性输出普通文本
|
||
- 解析器支持混合文本、fenced JSON、`function.arguments` 字符串等格式
|
||
|
||
## 文档与测试
|
||
|
||
- API 文档:`API.md` / `API.en.md`
|
||
- 部署文档:`DEPLOY.md` / `DEPLOY.en.md`
|
||
- 贡献指南:`CONTRIBUTING.md` / `CONTRIBUTING.en.md`
|
||
- 测试集文档:`TESTING.md`
|
||
|
||
```bash
|
||
go test ./...
|
||
```
|
||
|
||
一键真实账号全链路测试(会生成完整请求/响应日志):
|
||
|
||
```bash
|
||
./scripts/testsuite/run-live.sh
|
||
```
|
||
|
||
或使用可配置参数:
|
||
|
||
```bash
|
||
go run ./cmd/ds2api-tests \
|
||
--config config.json \
|
||
--admin-key admin \
|
||
--out artifacts/testsuite \
|
||
--timeout 120 \
|
||
--retries 2
|
||
```
|
||
|
||
## 免责声明
|
||
|
||
本项目基于逆向方式实现,仅供学习与研究使用。稳定性和可用性不作保证,请勿用于违反服务条款或法律法规的场景。
|