Skip to content

Commit 7887c03

Browse files
authored
Merge pull request #6 from YuJunZhiXue/trae
完善修改,稳定
2 parents b7d9cc9 + 97bfd54 commit 7887c03

36 files changed

Lines changed: 3385 additions & 1148 deletions

Dockerfile

Lines changed: 35 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,39 +10,67 @@ RUN npm run build
1010
FROM python:3.10-slim
1111
WORKDIR /workspace
1212

13-
# Install system dependencies required for headless browser (Camoufox/Firefox)
14-
RUN apt-get update && apt-get install -y \
13+
# Install system dependencies required for headless Firefox (Camoufox)
14+
RUN apt-get update && apt-get install -y --no-install-recommends \
1515
wget \
1616
curl \
17+
ca-certificates \
1718
libx11-xcb1 \
19+
libx11-6 \
20+
libxcb1 \
21+
libxrandr2 \
22+
libxcomposite1 \
23+
libxdamage1 \
24+
libxfixes3 \
25+
libxext6 \
26+
libxkbcommon0 \
1827
libdbus-glib-1-2 \
28+
libdbus-1-3 \
1929
libxt6 \
2030
libgtk-3-0 \
2131
libasound2 \
2232
libpulse0 \
2333
libdrm2 \
2434
libgbm1 \
2535
libxshmfence1 \
36+
libatk1.0-0 \
37+
libatk-bridge2.0-0 \
38+
libpangocairo-1.0-0 \
39+
libcups2 \
40+
libnss3 \
41+
libnspr4 \
42+
libglib2.0-0 \
2643
fonts-liberation \
44+
fonts-noto-cjk \
2745
&& rm -rf /var/lib/apt/lists/*
2846

47+
ENV PYTHONIOENCODING=utf-8
48+
ENV PYTHONUNBUFFERED=1
49+
ENV PYTHONDONTWRITEBYTECODE=1
50+
2951
COPY backend/requirements.txt ./backend/
3052
RUN pip install --no-cache-dir -r backend/requirements.txt
53+
54+
# Download Camoufox browser at build time
3155
RUN python -m camoufox fetch
3256

3357
COPY backend/ ./backend/
3458
COPY start.py ./
3559
COPY --from=frontend-builder /app/dist ./frontend/dist
3660

37-
# The API gateway port
38-
EXPOSE 8080
61+
# Create data directory
62+
RUN mkdir -p /workspace/data /workspace/logs
3963

40-
# Environment defaults
41-
ENV PORT=8080
64+
EXPOSE 7860
65+
66+
ENV PORT=7860
4267
ENV FRONTEND_DIST_DIR=/workspace/frontend/dist
4368
ENV ACCOUNTS_FILE=/workspace/data/accounts.json
4469
ENV USERS_FILE=/workspace/data/users.json
4570
ENV CAPTURES_FILE=/workspace/data/captures.json
4671
ENV PYTHONPATH=/workspace
4772

48-
CMD ["python", "-m", "backend.main"]
73+
HEALTHCHECK --interval=30s --timeout=10s --start-period=120s --retries=3 \
74+
CMD curl -f http://localhost:${PORT}/healthz || exit 1
75+
76+
CMD ["python", "-m", "uvicorn", "backend.main:app", "--host", "0.0.0.0", "--port", "7860", "--workers", "1"]

README.md

Lines changed: 180 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
[![Release](https://img.shields.io/github/v/release/YuJunZhiXue/qwen2API?style=flat-square)](https://github.com/YuJunZhiXue/qwen2API/releases)
77
[![Docker Pulls](https://img.shields.io/docker/pulls/yujunzhixue/qwen2api?style=flat-square)](https://hub.docker.com/r/yujunzhixue/qwen2api)
88

9-
[![Deploy on Zeabur](https://zeabur.com/button.svg)](https://zeabur.com/templates/XXXXXX)
9+
[![Deploy on Zeabur](https://zeabur.com/button.svg)](https://zeabur.com/templates/qwen2api)
1010
[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2FYuJunZhiXue%2Fqwen2API)
1111

1212
语言 / Language: [中文](./README.md) | [English](./README.en.md)
@@ -17,7 +17,7 @@
1717

1818
## 架构概览
1919

20-
qwen2API 2.x(企业级模块化版)
20+
qwen2API
2121

2222
```mermaid
2323
flowchart LR
@@ -31,6 +31,7 @@ flowchart LR
3131
OA["OpenAI 兼容接口\n/v1/chat/completions"]
3232
CA["Claude 兼容接口\n/anthropic/v1/messages"]
3333
GA["Gemini 兼容接口\n/v1beta/models/*"]
34+
IA["图片生成接口\n/v1/images/generations"]
3435
Admin["Admin API\n/api/admin/*"]
3536
WebUI["Admin Dashboard\n(React + Shadcn)"]
3637
end
@@ -42,17 +43,18 @@ flowchart LR
4243
ClientCore["Qwen Client\n(SSE 流解析与重试机制)"]
4344
Tool["Tool Sieve\n(##TOOL_CALL## 拦截与解析)"]
4445
TokenCalc["Token Calculator\n(Tiktoken 精准计费)"]
45-
GC["Garbage Collector\n(15分钟定时清理孤儿会话)"]
46+
GC["Garbage Collector\n(15分钟定时清理孤儿会话\n活跃会话受保护不被删除)"]
4647
DB["Async JSON DB\n(带锁持久化)"]
4748
end
4849
end
4950
5051
Client --> Router
51-
Router --> OA & CA & GA
52+
Router --> OA & CA & GA & IA
5253
Router --> Admin
5354
Router --> WebUI
5455
5556
OA & CA & GA --> Tool
57+
IA --> ClientCore
5658
Tool --> ClientCore
5759
ClientCore -.无感重试.-> Pool
5860
ClientCore -.精确计费.-> TokenCalc
@@ -87,9 +89,11 @@ flowchart LR
8789

8890
| 能力类型 | 接口/路径支持 | 详细说明 |
8991
|---|---|---|
90-
| **OpenAI 兼容** | `GET /v1/models``POST /v1/chat/completions``POST /v1/embeddings` | 完整支持 Stream 响应与函数调用;Embeddings 使用伪 Hash 模拟。 |
92+
| **OpenAI 兼容** | `GET /v1/models``POST /v1/chat/completions``POST /v1/embeddings` | 完整支持 Stream 响应与函数调用;支持图片意图自动识别(见下文);Embeddings 使用伪 Hash 模拟。 |
9193
| **Claude 兼容** | `POST /anthropic/v1/messages` | 原生兼容 Anthropic SDK,处理复杂的 Block 结构与系统级 Prompt。 |
9294
| **Gemini 兼容** | `POST /v1beta/models/{model}:generateContent``...:streamGenerateContent` | 拦截 Google AI SDK 的专有协议体并平滑转换至底层。 |
95+
| **图片生成(标准接口)** | `POST /v1/images/generations` | 兼容 OpenAI DALL-E 接口规范,底层调用千问 Wan 系列 T2I 模型(`wanx2.1-t2i-plus`)。 |
96+
| **图片生成(意图识别)** | `POST /v1/chat/completions` | 在 Chat 请求中自动检测"生成图片/draw/generate image"等关键词,无缝切换到 T2I 管道,非流式响应额外附带 `images[]` 字段。 |
9397
| **多账号并发轮询** | - | 自动 Token 刷新,支持手机号/邮箱/临时验证码等多路径登录自愈,内建负载均衡器。 |
9498
| **并发队列控制** | - | 为每个账号设定 In-flight 上限与排队槽位,防范封禁风险。 |
9599
| **Tool Calling** | - | 完美对齐 OpenAI 流式标准;支持带思考过程的工具调度;支持非法 JSON 自我纠错机制。 |
@@ -120,19 +124,160 @@ flowchart LR
120124
| 客户端请求传入的模型名 (Alias) | 实际调用的底层目标模型 |
121125
|---|---|
122126
| `gpt-4o` / `gpt-4-turbo` / `o1` / `o3` | **`qwen3.6-plus`** |
123-
| `gpt-4o-mini` / `gpt-3.5-turbo` / `o1-mini` | **`qwen3.5-flash`** |
124-
| `claude-3-5-sonnet` / `claude-opus-4-6` | **`qwen3.6-plus`** |
125-
| `claude-3-haiku` / `claude-3-5-haiku-latest` | **`qwen3.5-flash`** |
127+
| `gpt-4o-mini` / `gpt-3.5-turbo` / `o1-mini` | **`qwen3.6-plus`** |
128+
| `claude-3-5-sonnet` / `claude-opus-4-6` / `claude-sonnet-4-6` | **`qwen3.6-plus`** |
129+
| `claude-3-haiku` / `claude-3-5-haiku` / `claude-haiku-4-5` | **`qwen3.6-plus`** |
126130
| `gemini-2.5-pro` / `gemini-1.5-pro` | **`qwen3.6-plus`** |
127131
| `deepseek-chat` / `deepseek-reasoner` | **`qwen3.6-plus`** |
128132

129-
> **提示**:如果未命中上述映射表,系统默认将 fallback 回落到 `qwen3.6-plus`
133+
> **提示**:所有别名统一路由至 `qwen3.6-plus`(chat.qwen.ai 当前最新旗舰模型,支持 t2t / t2i / t2v / 深度搜索等全部能力)。如果未命中映射表,系统同样 fallback 到 `qwen3.6-plus`
134+
135+
---
136+
137+
## 图片生成 (Text-to-Image)
138+
139+
网关提供兼容 OpenAI `images/generations` 规范的图片生成接口,底层调用通义千问 Web 版内置的 **Wan** 系列 T2I 模型。
140+
141+
**接口地址**`POST /v1/images/generations`
142+
143+
**图片模型路由**
144+
145+
| 请求传入的 model 名 | 实际调用的底层模型 |
146+
|---|---|
147+
| `dall-e-3` / `qwen-image` / `qwen-image-plus` | **`wanx2.1-t2i-plus`**(高质量,默认) |
148+
| `dall-e-2` / `qwen-image-turbo` | **`wanx2.1-t2i-turbo`**(快速版) |
149+
| `wanx2.1-t2i-plus` | **`wanx2.1-t2i-plus`** |
150+
| `wanx2.1-t2i-turbo` | **`wanx2.1-t2i-turbo`** |
151+
152+
**请求示例(curl)**
153+
154+
```bash
155+
curl http://127.0.0.1:7860/v1/images/generations \
156+
-H "Content-Type: application/json" \
157+
-H "Authorization: Bearer YOUR_API_KEY" \
158+
-d '{
159+
"model": "dall-e-3",
160+
"prompt": "一只赛博朋克风格的猫,霓虹灯背景,超写实",
161+
"n": 1,
162+
"size": "1024x1024"
163+
}'
164+
```
165+
166+
**返回示例**
167+
168+
```json
169+
{
170+
"created": 1712345678,
171+
"data": [
172+
{
173+
"url": "https://wanx.alicdn.com/wanx/...",
174+
"revised_prompt": "一只赛博朋克风格的猫,霓虹灯背景,超写实"
175+
}
176+
]
177+
}
178+
```
179+
180+
**OpenAI SDK 调用示例(Python)**
181+
182+
```python
183+
from openai import OpenAI
184+
185+
client = OpenAI(
186+
api_key="YOUR_API_KEY",
187+
base_url="http://127.0.0.1:7860/v1"
188+
)
189+
190+
response = client.images.generate(
191+
model="dall-e-3",
192+
prompt="一只赛博朋克风格的猫,霓虹灯背景,超写实",
193+
n=1,
194+
size="1024x1024"
195+
)
196+
print(response.data[0].url)
197+
```
198+
199+
> **注意**:由于使用千问 Web 版内部 T2I 接口,生成耗时约 15–45 秒,生成的图片 URL 有效期较短(阿里云 OSS 临时签名链接),请及时下载保存。
200+
201+
---
202+
203+
## Chat 接口图片意图自动识别
204+
205+
`/v1/chat/completions` 现在具备**图片生成意图自动识别**能力。无需单独调用图片接口,只需在普通 Chat 请求中提及生成图片的需求,系统即可自动路由到 T2I 管道并返回图片结果。
206+
207+
**触发关键词**(中英文均支持):
208+
209+
| 意图 | 触发词示例 |
210+
|---|---|
211+
| **生成图片 (t2i)** | 生成图片、画一张、画个、draw、generate image、create image、make image、文生图 |
212+
| **生成视频 (t2v)** | 生成视频、文生视频、generate video、make video(链路预留,待验证) |
213+
214+
**非流式响应**`"stream": false`)额外返回 `images[]` 字段:
215+
216+
```json
217+
{
218+
"id": "chatcmpl-xxx",
219+
"object": "chat.completion",
220+
"choices": [{
221+
"message": {
222+
"role": "assistant",
223+
"content": "![generated](https://wanx.alicdn.com/...)"
224+
},
225+
"finish_reason": "stop"
226+
}],
227+
"images": ["https://wanx.alicdn.com/..."]
228+
}
229+
```
230+
231+
**示例(curl)**
232+
233+
```bash
234+
curl http://127.0.0.1:7860/v1/chat/completions \
235+
-H "Content-Type: application/json" \
236+
-H "Authorization: Bearer YOUR_API_KEY" \
237+
-d '{
238+
"model": "gpt-4o",
239+
"stream": false,
240+
"messages": [{"role": "user", "content": "帮我画一张赛博朋克猫咪的图片"}]
241+
}'
242+
```
130243

131244
---
132245

133246
## 快速开始
134247

135-
### 方式一:本地运行
248+
### 推荐:Docker Compose 一键部署
249+
250+
```bash
251+
cp .env.example .env
252+
# 必改:ADMIN_KEY
253+
# 按需修改:BROWSER_POOL_SIZE / MAX_INFLIGHT / ACCOUNT_MIN_INTERVAL_MS
254+
255+
docker compose up -d --build
256+
```
257+
258+
启动后:
259+
- WebUI / API: `http://127.0.0.1:7860`
260+
- 健康检查: `GET /healthz`
261+
- 就绪检查: `GET /readyz`
262+
263+
### 推荐安全默认值(单账号)
264+
265+
- `ENGINE_MODE=hybrid`
266+
- `BROWSER_POOL_SIZE=2`
267+
- `MAX_INFLIGHT=1`
268+
- `ACCOUNT_MIN_INTERVAL_MS=1200`
269+
- `REQUEST_JITTER_MIN_MS=120`
270+
- `REQUEST_JITTER_MAX_MS=360`
271+
- `MAX_RETRIES=2`
272+
- `TOOL_MAX_RETRIES=2`
273+
- `EMPTY_RESPONSE_RETRIES=1`
274+
275+
说明:
276+
- 主聊天请求、建会话、删会话现在都优先走浏览器环境,httpx 只做兜底。
277+
- 上述默认值偏保守,目标是降低单账号在 Claude Code 工具链下的自动化痕迹与封控风险。
278+
- `data/``logs/` 需要持久化挂载,账号、用户和配置都保存在这里。
279+
280+
### 本地开发启动
136281

137282
**前置环境要求**
138283
- Python 3.10+
@@ -143,24 +288,15 @@ flowchart LR
143288
git clone https://github.com/YuJunZhiXue/qwen2API.git
144289
cd qwen2API
145290

146-
# 2. 安装后端核心依赖
147-
cd backend
148-
pip install -r requirements.txt
149-
python -m camoufox fetch # 必须执行:下载无头浏览器内核
150-
151-
# 3. 安装并构建前端界面
152-
cd ../frontend
153-
npm install
154-
npm run build # 编译后的静态资源会自动放入后端服务目录
155-
156-
# 4. 退回根目录,启动服务
157-
cd ..
291+
# 2. 一键启动(自动安装依赖、下载浏览器内核、构建前端)
158292
python start.py
159293
```
160294

161295
启动后:
162-
- **WebUI 控制台**:通过 `http://localhost:8080` 访问。
163-
- **API 网关地址**:默认绑定 `http://localhost:8080`
296+
- **WebUI 控制台**:通过 `http://127.0.0.1:7860` 访问。
297+
- **API 网关地址**:默认绑定 `http://127.0.0.1:7860`
298+
299+
> 首次启动需要下载 Camoufox 浏览器内核与构建前端,耗时较长,请耐心等待。
164300
165301
### 方式二:Docker / Docker Compose (推荐)
166302

@@ -172,25 +308,37 @@ git clone https://github.com/YuJunZhiXue/qwen2API.git
172308
cd qwen2API
173309

174310
# 2. 启动服务编排
175-
docker-compose up -d
311+
docker compose up -d
176312

177313
# 3. 实时查看日志
178-
docker-compose logs -f
314+
docker compose logs -f
179315
```
180-
启动完成后,默认会将容器的 `8080` 端口映射至宿主机。通过 `http://localhost:8080` 即可进入控制台。更新镜像可执行 `docker-compose up -d --build`
316+
317+
启动完成后,服务采用前后端分离部署:
318+
- **后端 API 网关**`http://127.0.0.1:7860`(API 调用入口)
319+
- **前端 WebUI 控制台**`http://127.0.0.1:7861`(管理界面)
320+
321+
更新镜像可执行 `docker compose up -d --build`
322+
323+
> **注意**:容器内无头浏览器需要共享内存,`docker-compose.yml` 已配置 `shm_size: 256m`,如遇浏览器崩溃可适当增大该值。
181324
182325
### 方式三:Zeabur 一键部署
183326

184327
1. 点击页面顶部的 **Deploy on Zeabur** 徽章按钮,开启托管流程。
185328
2. 部署完成后,访问生成的域名进入管理台。
186329
3. 默认需配置环境变量 `ADMIN_KEY` 作为后台登录鉴权。
187330

188-
### 方式四:Vercel 代理部署
331+
### 方式四:Vercel 前端 + 独立后端
332+
333+
由于 Serverless 架构限制,Vercel 无法长驻无头浏览器,通常作为**纯前端代理层**配合独立部署的后端节点使用。
189334

190-
1. Fork 仓库至个人 GitHub。
191-
2. 在 Vercel 工作台导入项目。
192-
3. 配置必要环境变量(注:由于 Serverless 架构限制,无法内部长驻无头浏览器,此方案通常作为代理层接入外部独立部署的无头节点)。
193-
4. 部署并绑定域名。
335+
1. Fork 仓库至个人 GitHub,进入 `frontend/` 目录。
336+
2. 在 Vercel 工作台导入 `frontend/` 子目录。
337+
3. 配置环境变量:
338+
```
339+
VITE_API_BASE_URL=https://your-backend-domain.com
340+
```
341+
4. 部署并绑定域名。后端节点需单独部署(Docker 或云服务器),确保可公网访问。
194342

195343
---
196344

0 commit comments

Comments
 (0)