ZyphrZero commited on
Commit
130b143
·
1 Parent(s): 1ba1e5f

✨ feat(models):引入 GLM-4.5-Air 模型支持

Browse files

- 为 GLM-4.5-Air 添加新的 AIR_MODEL 配置选项
- 根据请求的模型实现动态上游模型 ID 映射
- 更新模型列表,包含 GLM-4.5-Air 和 0727-106B-API 上游 ID
- 增强模型架构,支持多种上游模型映射

✨ feat(config):添加跳过身份验证令牌选项

- 添加 SKIP_AUTH_TOKEN 环境变量以绕过 API 密钥验证
- 更新配置设置,包含新的身份验证绕过选项
- 修改身份验证逻辑,以便有条件地验证 API 令牌

📝 docs(readme):更新文档,添加新功能

- 添加显示 1.1.0 版本的版本徽章
- 在高亮显示中包含多模型架构功能
- 更新模型表,包含上游 ID 列和 GLM-4.5-Air 模型
- 记录模型配置的新环境变量
- 在配置表中添加 SKIP_AUTH_TOKEN 和 BACKUP_TOKEN

.env.example CHANGED
@@ -8,6 +8,8 @@
8
  # 客户端认证密钥(OpenAI 和 Anthropic 共用)
9
  # 客户端调用时需要使用此密钥进行认证
10
  AUTH_TOKEN=sk-your-api-key
 
 
11
 
12
  # Anthropic API 客户端认证密钥(可选)
13
  # 如果未设置,将使用 AUTH_TOKEN 的值
 
8
  # 客户端认证密钥(OpenAI 和 Anthropic 共用)
9
  # 客户端调用时需要使用此密钥进行认证
10
  AUTH_TOKEN=sk-your-api-key
11
+ # 是否跳过api key验证
12
+ SKIP_AUTH_TOKEN=false
13
 
14
  # Anthropic API 客户端认证密钥(可选)
15
  # 如果未设置,将使用 AUTH_TOKEN 的值
README.md CHANGED
@@ -3,6 +3,7 @@
3
  ![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)
4
  ![Python: 3.8+](https://img.shields.io/badge/python-3.8+-green.svg)
5
  ![FastAPI](https://img.shields.io/badge/framework-FastAPI-009688.svg)
 
6
 
7
  为 Z.AI 提供 OpenAI 和 Anthropic API 兼容接口的轻量级代理服务,支持 GLM-4.5 系列模型的完整功能。
8
 
@@ -17,6 +18,7 @@
17
  - 🐳 **Docker 部署** - 一键容器化部署
18
  - 🛡️ **会话隔离** - 匿名模式保护隐私
19
  - 🔧 **高度可配置** - 环境变量灵活配置
 
20
 
21
  ## 🚀 快速开始
22
 
@@ -101,11 +103,12 @@ docker-compose up -d
101
 
102
  ### 支持的模型
103
 
104
- | 模型 | 描述 | 特性 |
105
- |------|------|------|
106
- | `GLM-4.5` | 标准模型 | 通用对话,平衡性能 |
107
- | `GLM-4.5-Thinking` | 思考模型 | 显示推理过程,透明度高 |
108
- | `GLM-4.5-Search` | 搜索模型 | 实时网络搜索,信息更新 |
 
109
 
110
  ### Function Call 功能
111
 
@@ -161,12 +164,20 @@ for chunk in response:
161
  | 变量名 | 默认值 | 说明 |
162
  |--------|--------|------|
163
  | `AUTH_TOKEN` | `sk-your-api-key` | 客户端认证密钥(OpenAI 和 Anthropic 共用) |
 
164
  | `API_ENDPOINT` | `https://chat.z.ai/api/chat/completions` | 上游 API 地址 |
165
  | `LISTEN_PORT` | `8080` | 服务监听端口 |
 
 
 
 
166
  | `DEBUG_LOGGING` | `true` | 调试日志开关 |
167
  | `THINKING_PROCESSING` | `think` | 思考内容处理策略 |
168
  | `ANONYMOUS_MODE` | `true` | 匿名模式开关 |
169
  | `TOOL_SUPPORT` | `true` | Function Call 功能开关 |
 
 
 
170
 
171
  ### 思考内容处理策略
172
 
@@ -199,7 +210,7 @@ def chat_with_ai(message):
199
  ### 2. 多模型对比测试
200
 
201
  ```python
202
- models = ["GLM-4.5", "GLM-4.5-Thinking", "GLM-4.5-Search"]
203
 
204
  for model in models:
205
  response = client.chat.completions.create(
@@ -248,26 +259,79 @@ A: 支持聊天完成、模型列表、流式响应、工具调用等核心功
248
  **Q: 支持 Anthropic API 的哪些功能?**
249
  A: 支持 messages 创建、流式响应、系统提示等核心功能。
250
 
 
 
 
 
 
 
 
251
  **Q: 如何自定义配置?**
252
  A: 通过环境变量配置,推荐使用 `.env` 文件。
253
 
254
  ## 🏗️ 技术架构
255
 
256
  ```
257
- ┌──────────────┐ ┌─────────────┐ ┌─────────────┐
258
- │ OpenAI │
259
- │ Client │────▶│ Proxy │────▶│ Z.AI
260
- └──────────────┘ Server │ API
261
- ┌──────────────┐
262
- │ Anthropic │────▶│
263
- │ Client │
264
- └──────────────┘ └─────────────┘ └─────────────┘
 
 
 
 
 
 
 
265
  ```
266
 
267
- - **FastAPI** - 高性能 Web 框架
268
- - **Pydantic** - 数据验证和序列化
269
- - **Uvicorn** - ASGI 服务器
270
- - **Requests** - HTTP 客户端
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
271
 
272
  ## 🤝 贡献指南
273
 
 
3
  ![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)
4
  ![Python: 3.8+](https://img.shields.io/badge/python-3.8+-green.svg)
5
  ![FastAPI](https://img.shields.io/badge/framework-FastAPI-009688.svg)
6
+ ![Version: 1.1.0](https://img.shields.io/badge/version-1.1.0-brightgreen.svg)
7
 
8
  为 Z.AI 提供 OpenAI 和 Anthropic API 兼容接口的轻量级代理服务,支持 GLM-4.5 系列模型的完整功能。
9
 
 
18
  - 🐳 **Docker 部署** - 一键容器化部署
19
  - 🛡️ **会话隔离** - 匿名模式保护隐私
20
  - 🔧 **高度可配置** - 环境变量灵活配置
21
+ - 📊 **多模型架构** - 灵活的上游模型映射机制
22
 
23
  ## 🚀 快速开始
24
 
 
103
 
104
  ### 支持的模型
105
 
106
+ | 模型 | 上游ID | 描述 | 特性 |
107
+ |------|--------|------|------|
108
+ | `GLM-4.5` | 0727-360B-API | 标准模型 | 通用对话,平衡性能 |
109
+ | `GLM-4.5-Thinking` | 0727-360B-API | 思考模型 | 显示推理过程,透明度高 |
110
+ | `GLM-4.5-Search` | 0727-360B-API | 搜索模型 | 实时网络搜索,信息更新 |
111
+ | `GLM-4.5-Air` | 0727-106B-API | 轻量模型 | 快速响应,高效推理 |
112
 
113
  ### Function Call 功能
114
 
 
164
  | 变量名 | 默认值 | 说明 |
165
  |--------|--------|------|
166
  | `AUTH_TOKEN` | `sk-your-api-key` | 客户端认证密钥(OpenAI 和 Anthropic 共用) |
167
+ | `ANTHROPIC_API_KEY` | `sk-your-api-key` | Anthropic API 认证密钥(默认使用 AUTH_TOKEN) |
168
  | `API_ENDPOINT` | `https://chat.z.ai/api/chat/completions` | 上游 API 地址 |
169
  | `LISTEN_PORT` | `8080` | 服务监听端口 |
170
+ | `PRIMARY_MODEL` | `GLM-4.5` | 主要模型名称 |
171
+ | `THINKING_MODEL` | `GLM-4.5-Thinking` | 思考模型名称 |
172
+ | `SEARCH_MODEL` | `GLM-4.5-Search` | 搜索模型名称 |
173
+ | `AIR_MODEL` | `GLM-4.5-Air` | Air 模型名称 |
174
  | `DEBUG_LOGGING` | `true` | 调试日志开关 |
175
  | `THINKING_PROCESSING` | `think` | 思考内容处理策略 |
176
  | `ANONYMOUS_MODE` | `true` | 匿名模式开关 |
177
  | `TOOL_SUPPORT` | `true` | Function Call 功能开关 |
178
+ | `SKIP_AUTH_TOKEN` | `false` | 跳过认证令牌验证 |
179
+ | `SCAN_LIMIT` | `200000` | 扫描限制 |
180
+ | `BACKUP_TOKEN` | `eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9...` | 备用认证令牌 |
181
 
182
  ### 思考内容处理策略
183
 
 
210
  ### 2. 多模型对比测试
211
 
212
  ```python
213
+ models = ["GLM-4.5", "GLM-4.5-Thinking", "GLM-4.5-Search", "GLM-4.5-Air"]
214
 
215
  for model in models:
216
  response = client.chat.completions.create(
 
259
  **Q: 支持 Anthropic API 的哪些功能?**
260
  A: 支持 messages 创建、流式响应、系统提示等核心功能。
261
 
262
+ **Q: 如何选择合适的模型?**
263
+ A:
264
+ - **GLM-4.5**: 通用场景,性能和效果平衡
265
+ - **GLM-4.5-Thinking**: 需要了解推理过程的场景
266
+ - **GLM-4.5-Search**: 需要实时信息的场景
267
+ - **GLM-4.5-Air**: 高并发、低延迟要求的场景
268
+
269
  **Q: 如何自定义配置?**
270
  A: 通过环境变量配置,推荐使用 `.env` 文件。
271
 
272
  ## 🏗️ 技术架构
273
 
274
  ```
275
+ ┌──────────────┐ ┌─────────────────────────┐ ┌─────────────────┐
276
+ │ OpenAI │
277
+ │ Client │────▶│ FastAPI Router │────▶│ Z.AI API
278
+ └──────────────┘ │ │
279
+ ┌──────────────┐ ┌─────────────────────┐ ┌─────────────┐
280
+ │ Anthropic │────▶│ OpenAI Endpoint │ │0727-360B-API│ │
281
+ │ Client │ └─────────────────────┘ └─────────────┘
282
+ └──────────────┘ │ ┌─────────────────────┐ │ │ ┌─────────────┐ │
283
+ │ │ Anthropic Endpoint │ │────▶│ │0727-106B-API│ │
284
+ │ └─────────────────────┘ │ │ └─────────────┘ │
285
+ │ ┌─────────────────────┐ │ │ │
286
+ │ │ Models Endpoint │ │ └─────────────────┘
287
+ │ └─────────────────────┘ │
288
+ └─────────────────────────┘
289
+ Proxy Server
290
  ```
291
 
292
+ ### 核心组件
293
+
294
+ - **FastAPI** - 高性能 Web 框架,支持异步处理
295
+ - **Pydantic** - 数据验证和序列化,确保 API 兼容性
296
+ - **Uvicorn** - ASGI 服务器,提供高性能服务
297
+ - **Requests** - HTTP 客户端,与上游 API 通信
298
+
299
+ ### 架构特点
300
+
301
+ - **模块化设计** - 清晰的目录结构,易于维护和扩展
302
+ - **多协议支持** - 同时支持 OpenAI 和 Anthropic API 协议
303
+ - **动态路由** - 根据请求模型自动选择上游服务
304
+ - **流式处理** - 完整支持 SSE 流式响应
305
+ - **类型安全** - 基于 Pydantic 的严格类型检查
306
+
307
+ ### 项目结构
308
+
309
+ ```
310
+ z.ai2api_python/
311
+ ├── app/
312
+ │ ├── api/
313
+ │ │ ├── __init__.py
314
+ │ │ ├── openai.py # OpenAI API 路由
315
+ │ │ └── anthropic.py # Anthropic API 路由
316
+ │ ├── core/
317
+ │ │ ├── __init__.py
318
+ │ │ ├── config.py # 配置管理
319
+ │ │ └── response_handlers.py # 响应处理器
320
+ │ ├── models/
321
+ │ │ ├── __init__.py
322
+ │ │ └── schemas.py # 数据模型定义
323
+ │ ├── utils/
324
+ │ │ ├── __init__.py
325
+ │ │ ├── helpers.py # 工具函数
326
+ │ │ ├── tools.py # Function Call 处理
327
+ │ │ └── sse_parser.py # SSE 解析器
328
+ │ └── __init__.py
329
+ ├── tests/ # 测试文件
330
+ ├── deploy/ # 部署配置
331
+ ├── main.py # 应用入口
332
+ ├── requirements.txt # 依赖列表
333
+ └── README.md # 项目文档
334
+ ```
335
 
336
  ## 🤝 贡献指南
337
 
app/api/anthropic.py CHANGED
@@ -115,18 +115,21 @@ async def handle_anthropic_message(
115
  """Handle Anthropic message requests"""
116
  debug_log("收到 Anthropic message 请求")
117
 
118
- # 验证 API key
119
- api_key = None
120
- if x_api_key:
121
- api_key = x_api_key
122
- elif authorization and authorization.startswith("Bearer "):
123
- api_key = authorization[7:]
124
-
125
- if not api_key or api_key != settings.ANTHROPIC_API_KEY:
126
- debug_log(f"无效的 API key: {api_key}")
127
- raise HTTPException(status_code=401, detail="Invalid API key")
128
-
129
- debug_log(f"API key 验证通过")
 
 
 
130
  debug_log(f"请求解析成功 - 模型: {req.model}, 流式: {req.stream}, 消息数: {len(req.messages)}")
131
 
132
  # 确定上游模型和功能
 
115
  """Handle Anthropic message requests"""
116
  debug_log("收到 Anthropic message 请求")
117
 
118
+ # 验证 API key (skip if SKIP_AUTH_TOKEN is enabled)
119
+ if not settings.SKIP_AUTH_TOKEN:
120
+ api_key = None
121
+ if x_api_key:
122
+ api_key = x_api_key
123
+ elif authorization and authorization.startswith("Bearer "):
124
+ api_key = authorization[7:]
125
+
126
+ if not api_key or api_key != settings.ANTHROPIC_API_KEY:
127
+ debug_log(f"无效的 API key: {api_key}")
128
+ raise HTTPException(status_code=401, detail="Invalid API key")
129
+
130
+ debug_log(f"API key 验证通过")
131
+ else:
132
+ debug_log("SKIP_AUTH_TOKEN已启用,跳过API key验证")
133
  debug_log(f"请求解析成功 - 模型: {req.model}, 流式: {req.stream}, 消息数: {len(req.messages)}")
134
 
135
  # 确定上游模型和功能
app/api/openai.py CHANGED
@@ -41,6 +41,11 @@ async def list_models():
41
  created=current_time,
42
  owned_by="z.ai"
43
  ),
 
 
 
 
 
44
  ]
45
  )
46
  return response
@@ -55,17 +60,20 @@ async def chat_completions(
55
  debug_log("收到chat completions请求")
56
 
57
  try:
58
- # Validate API key
59
- if not authorization.startswith("Bearer "):
60
- debug_log("缺少或无效的Authorization头")
61
- raise HTTPException(status_code=401, detail="Missing or invalid Authorization header")
62
-
63
- api_key = authorization[7:]
64
- if api_key != settings.AUTH_TOKEN:
65
- debug_log(f"无效的API key: {api_key}")
66
- raise HTTPException(status_code=401, detail="Invalid API key")
67
-
68
- debug_log(f"API key验证通过,AUTH_TOKEN={api_key[:8]}......")
 
 
 
69
  debug_log(f"请求解析成功 - 模型: {request.model}, 流式: {request.stream}, 消息数: {len(request.messages)}")
70
 
71
  # Generate IDs
@@ -95,14 +103,23 @@ async def chat_completions(
95
  # Determine model features
96
  is_thinking = request.model == settings.THINKING_MODEL
97
  is_search = request.model == settings.SEARCH_MODEL
 
98
  search_mcp = "deep-web-search" if is_search else ""
99
 
 
 
 
 
 
 
 
 
100
  # Build upstream request
101
  upstream_req = UpstreamRequest(
102
  stream=True, # Always use streaming from upstream
103
  chat_id=chat_id,
104
  id=msg_id,
105
- model="0727-360B-API", # Actual upstream model ID
106
  messages=upstream_messages,
107
  params={},
108
  features={
@@ -116,8 +133,8 @@ async def chat_completions(
116
  },
117
  mcp_servers=[search_mcp] if search_mcp else [],
118
  model_item=ModelItem(
119
- id="0727-360B-API",
120
- name="GLM-4.5",
121
  owned_by="openai"
122
  ),
123
  tool_servers=[],
 
41
  created=current_time,
42
  owned_by="z.ai"
43
  ),
44
+ Model(
45
+ id=settings.AIR_MODEL,
46
+ created=current_time,
47
+ owned_by="z.ai"
48
+ ),
49
  ]
50
  )
51
  return response
 
60
  debug_log("收到chat completions请求")
61
 
62
  try:
63
+ # Validate API key (skip if SKIP_AUTH_TOKEN is enabled)
64
+ if not settings.SKIP_AUTH_TOKEN:
65
+ if not authorization.startswith("Bearer "):
66
+ debug_log("缺少或无效的Authorization")
67
+ raise HTTPException(status_code=401, detail="Missing or invalid Authorization header")
68
+
69
+ api_key = authorization[7:]
70
+ if api_key != settings.AUTH_TOKEN:
71
+ debug_log(f"无效的API key: {api_key}")
72
+ raise HTTPException(status_code=401, detail="Invalid API key")
73
+
74
+ debug_log(f"API key验证通过,AUTH_TOKEN={api_key[:8]}......")
75
+ else:
76
+ debug_log("SKIP_AUTH_TOKEN已启用,跳过API key验证")
77
  debug_log(f"请求解析成功 - 模型: {request.model}, 流式: {request.stream}, 消息数: {len(request.messages)}")
78
 
79
  # Generate IDs
 
103
  # Determine model features
104
  is_thinking = request.model == settings.THINKING_MODEL
105
  is_search = request.model == settings.SEARCH_MODEL
106
+ is_air = request.model == settings.AIR_MODEL
107
  search_mcp = "deep-web-search" if is_search else ""
108
 
109
+ # Determine upstream model ID based on requested model
110
+ if is_air:
111
+ upstream_model_id = "0727-106B-API" # AIR model upstream ID
112
+ upstream_model_name = "GLM-4.5-Air"
113
+ else:
114
+ upstream_model_id = "0727-360B-API" # Default upstream model ID
115
+ upstream_model_name = "GLM-4.5"
116
+
117
  # Build upstream request
118
  upstream_req = UpstreamRequest(
119
  stream=True, # Always use streaming from upstream
120
  chat_id=chat_id,
121
  id=msg_id,
122
+ model=upstream_model_id, # Dynamic upstream model ID
123
  messages=upstream_messages,
124
  params={},
125
  features={
 
133
  },
134
  mcp_servers=[search_mcp] if search_mcp else [],
135
  model_item=ModelItem(
136
+ id=upstream_model_id,
137
+ name=upstream_model_name,
138
  owned_by="openai"
139
  ),
140
  tool_servers=[],
app/core/config.py CHANGED
@@ -20,6 +20,7 @@ class Settings(BaseSettings):
20
  PRIMARY_MODEL: str = os.getenv("PRIMARY_MODEL", "GLM-4.5")
21
  THINKING_MODEL: str = os.getenv("THINKING_MODEL", "GLM-4.5-Thinking")
22
  SEARCH_MODEL: str = os.getenv("SEARCH_MODEL", "GLM-4.5-Search")
 
23
 
24
  # Server Configuration
25
  LISTEN_PORT: int = int(os.getenv("LISTEN_PORT", "8080"))
@@ -30,6 +31,7 @@ class Settings(BaseSettings):
30
  ANONYMOUS_MODE: bool = os.getenv("ANONYMOUS_MODE", "true").lower() == "true"
31
  TOOL_SUPPORT: bool = os.getenv("TOOL_SUPPORT", "true").lower() == "true"
32
  SCAN_LIMIT: int = int(os.getenv("SCAN_LIMIT", "200000"))
 
33
 
34
  # Browser Headers
35
  CLIENT_HEADERS: Dict[str, str] = {
 
20
  PRIMARY_MODEL: str = os.getenv("PRIMARY_MODEL", "GLM-4.5")
21
  THINKING_MODEL: str = os.getenv("THINKING_MODEL", "GLM-4.5-Thinking")
22
  SEARCH_MODEL: str = os.getenv("SEARCH_MODEL", "GLM-4.5-Search")
23
+ AIR_MODEL: str = os.getenv("AIR_MODEL", "GLM-4.5-Air")
24
 
25
  # Server Configuration
26
  LISTEN_PORT: int = int(os.getenv("LISTEN_PORT", "8080"))
 
31
  ANONYMOUS_MODE: bool = os.getenv("ANONYMOUS_MODE", "true").lower() == "true"
32
  TOOL_SUPPORT: bool = os.getenv("TOOL_SUPPORT", "true").lower() == "true"
33
  SCAN_LIMIT: int = int(os.getenv("SCAN_LIMIT", "200000"))
34
+ SKIP_AUTH_TOKEN: bool = os.getenv("SKIP_AUTH_TOKEN", "false").lower() == "true"
35
 
36
  # Browser Headers
37
  CLIENT_HEADERS: Dict[str, str] = {
deploy/docker-compose.yml CHANGED
@@ -11,6 +11,8 @@ services:
11
  environment:
12
  # Auth Configuration
13
  - AUTH_TOKEN=sk-your-api-key
 
 
14
  # Server Configurations
15
  - DEBUG_LOGGING=true
16
  # Feature Configuration
 
11
  environment:
12
  # Auth Configuration
13
  - AUTH_TOKEN=sk-your-api-key
14
+ # 是否跳过api key验证
15
+ - SKIP_AUTH_TOKEN=false
16
  # Server Configurations
17
  - DEBUG_LOGGING=true
18
  # Feature Configuration