File size: 11,379 Bytes
f0cacfe
 
 
 
 
 
 
 
 
 
 
 
 
 
02896ca
f0cacfe
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4f0ca4d
7561cf7
4f0ca4d
 
 
 
 
 
 
f0cacfe
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7561cf7
f0cacfe
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4f0ca4d
f0cacfe
02896ca
 
 
 
 
 
 
 
 
 
 
 
7561cf7
02896ca
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
ee092c1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4f0ca4d
ee092c1
 
 
 
f0cacfe
 
 
 
4f0ca4d
7561cf7
4f0ca4d
 
 
 
 
 
 
 
 
f0cacfe
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
ec35fcf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389

## 项目简介

这是一个为 Z.ai 提供 OpenAI API 兼容接口的 Python 代理服务,允许开发者通过标准的 OpenAI API 格式访问 Z.ai 的 GLM-4.5 模型。

## 主要特性

- **OpenAI API 兼容**:完整支持 `/v1/chat/completions``/v1/models` 端点
- **流式响应支持**:完整实现 Server-Sent Events (SSE) 流式传输
- **思考内容处理**:提供多种策略处理模型的思考过程(`<details>` 标签)
- **匿名会话支持**:可选使用匿名 token 避免共享对话历史
- **多种模型支持**:支持 GLM-4.5 基础版、思考版和搜索版
- **调试模式**:详细的请求/响应日志记录,便于开发调试
- **CORS 支持**:内置跨域资源共享支持
- **Function Call 支持**:完整支持 OpenAI 格式的工具调用功能,通过智能提示注入实现,支持流式响应时的工具调用缓冲机制

## 使用场景

- 将 Z.ai 集成到支持 OpenAI API 的应用程序中
- 开发需要同时使用多个 AI 服务的应用
- 测试和评估 GLM-4.5 模型的能力
- 需要流式响应或思考内容的 AI 应用开发

## 快速开始

### 使用 uv (推荐)

1. 安装 uv:
   ```bash
   # macOS/Linux
   curl -LsSf https://astral.sh/uv/install.sh | sh
   # Windows (PowerShell)
   powershell -c "irm https://astral.sh/uv/install.sh | iex"
   ```

2. 同步依赖:
   ```bash
   uv sync
   ```

3. 运行服务:
   ```bash
   uv run python main.py
   ```

### 使用 pip

1. 安装依赖:
   ```bash
   pip install -r requirements.txt
   ```

2. 配置服务(可选):
   编辑 `main.py` 中的 `ServerConfig` 类以调整服务行为:
   - `AUTH_TOKEN`: 客户端 API Key 密钥
   - `API_ENDPOINT`: Z.ai 上游 API 地址
   - `BACKUP_TOKEN`: 固定认证 token(匿名模式失败时使用)
   - `LISTEN_PORT`: 服务监听端口
   - `DEBUG_LOGGING`: 调试模式开关
   - `THINKING_PROCESSING`: 思考内容处理策略
   - `ANONYMOUS_MODE`: 匿名模式开关
   - `TOOL_SUPPORT`: Function Call 功能开关

3. 运行服务:
   ```bash
   python main.py
   ```

   服务启动后,可以访问 http://localhost:8080/docs 查看自动生成的 Swagger API 文档

4. 使用 OpenAI 客户端库调用:
   ```python
   import openai

   # 初始化客户端
   client = openai.OpenAI(
       base_url="http://localhost:8080/v1",
       api_key="sk-your-api-key"
   )

   # 流式调用示例
   response = client.chat.completions.create(
       model="GLM-4.5",  # 可选: "GLM-4.5-Thinking", "GLM-4.5-Search"
       messages=[{"role": "user", "content": "你好"}],
       stream=True
   )

   for chunk in response:
       content = chunk.choices[0].delta.content
       reasoning = chunk.choices[0].delta.reasoning_content
       if content:
           print(content, end="")
       if reasoning:
           print(f"\n[思考] {reasoning}\n")
   ```

   注意:请将 `api_key` 替换为您在 `main.py` 中配置的 `AUTH_TOKEN` 值。

### Function Call 使用示例

本项目完整支持 OpenAI 格式的工具调用功能,包括流式和非流式响应。实现原理是将 OpenAI 的工具定义转换为特殊的系统提示,让模型理解并生成符合格式的工具调用。

#### 基本工具调用

```python
import openai

# 初始化客户端
client = openai.OpenAI(
    base_url="http://localhost:8080/v1",
    api_key="sk-your-api-key"
)

# 定义天气查询工具
tools = [
    {
        "type": "function",
        "function": {
            "name": "get_weather",
            "description": "获取指定城市的天气信息",
            "parameters": {
                "type": "object",
                "properties": {
                    "city": {
                        "type": "string",
                        "description": "城市名称"
                    },
                    "unit": {
                        "type": "string",
                        "enum": ["celsius", "fahrenheit"],
                        "description": "温度单位",
                        "default": "celsius"
                    }
                },
                "required": ["city"]
            }
        }
    }
]

# 使用工具调用
response = client.chat.completions.create(
    model="GLM-4.5",
    messages=[{"role": "user", "content": "北京今天天气怎么样?"}],
    tools=tools,
    tool_choice="auto"
)

message = response.choices[0].message
if message.tool_calls:
    print("模型请求调用工具:")
    for tool_call in message.tool_calls:
        print(f"工具名称: {tool_call.function.name}")
        print(f"参数: {tool_call.function.arguments}")
        print(f"调用ID: {tool_call.id}")
else:
    print(f"回复: {message.content}")
```

#### 流式工具调用

```python
# 流式工具调用示例
response = client.chat.completions.create(
    model="GLM-4.5",
    messages=[{"role": "user", "content": "帮我计算 2 的 10 次方"}],
    tools=[{
        "type": "function",
        "function": {
            "name": "calculate",
            "description": "执行数学计算",
            "parameters": {
                "type": "object",
                "properties": {
                    "expression": {
                        "type": "string",
                        "description": "数学表达式"
                    }
                },
                "required": ["expression"]
            }
        }
    }],
    stream=True
)

# 注意:工具调用模式下,流式响应会缓冲所有内容,
# 在最后一次性返回工具调用信息
tool_calls = None
content = ""

for chunk in response:
    delta = chunk.choices[0].delta
    if delta.tool_calls:
        tool_calls = delta.tool_calls
    if delta.content:
        content += delta.content

if tool_calls:
    print("工具调用:")
    for tool_call in tool_calls:
        print(f"函数: {tool_call.function.name}")
        print(f"参数: {tool_call.function.arguments}")
else:
    print("回复:", content)
```

#### 强制使用特定工具

```python
# 强制使用特定工具
response = client.chat.completions.create(
    model="GLM-4.5",
    messages=[{"role": "user", "content": "今天是什么日子"}],
    tools=[{
        "type": "function",
        "function": {
            "name": "get_current_date",
            "description": "获取当前日期和时间",
            "parameters": {
                "type": "object",
                "properties": {},
                "required": []
            }
        }
    }],
    tool_choice={"type": "function", "function": {"name": "get_current_date"}}
)

message = response.choices[0].message
print(f"完成原因: {response.choices[0].finish_reason}")  # tool_calls
if message.tool_calls:
    print("工具调用结果:", message.tool_calls[0].function.arguments)
```

#### 多工具协作

```python
# 定义多个工具
tools = [
    {
        "type": "function",
        "function": {
            "name": "search_web",
            "description": "搜索网络信息",
            "parameters": {
                "type": "object",
                "properties": {
                    "query": {
                        "type": "string",
                        "description": "搜索关键词"
                    }
                },
                "required": ["query"]
            }
        }
    },
    {
        "type": "function",
        "function": {
            "name": "summarize_text",
            "description": "总结文本内容",
            "parameters": {
                "type": "object",
                "properties": {
                    "text": {
                        "type": "string",
                        "description": "要总结的文本"
                    },
                    "max_length": {
                        "type": "integer",
                        "description": "最大长度",
                        "default": 100
                    }
                },
                "required": ["text"]
            }
        }
    }
]

# 使用多工具
response = client.chat.completions.create(
    model="GLM-4.5",
    messages=[{"role": "user", "content": "搜索一下最新的 AI 新闻并总结"}],
    tools=tools,
    tool_choice="auto"
)

message = response.choices[0].message
if message.tool_calls:
    for tool_call in message.tool_calls:
        print(f"调用工具: {tool_call.function.name}")
        # 在实际应用中,这里需要执行相应的函数
        # 并将结果通过工具消息返回给模型
```

### 运行 Function Call 演示

项目包含一个完整的 Function Call 演示脚本:

```bash
python function_call_demo.py
```

该脚本将演示:
1. 基本的工具调用
2. 数学计算工具
3. 强制使用特定工具
4. 流式工具调用响应

### 使用 Docker Compose

1. 启动服务:
   ```bash
   # 在 deploy 目录下运行
   cd deploy
   docker-compose up -d
   ```

![744X487/QQ20250903-145750.png](https://tc.z.wiki/autoupload/f/KTO6-pUlsq3zQ-YJ9ppdgtiO_OyvX7mIgxFBfDMDErs/20250903/DkjD/744X487/QQ20250903-145750.png)

2. 停止服务:
   ```bash
   docker-compose down
   ```

3. 查看日志:
   ```bash
   docker-compose logs -f
   ```

4. 重新构建并启动:
   ```bash
   docker-compose up -d --build
   ```

注意:如需修改配置参数(如 API 密钥、端口等),请直接编辑 `main.py` 文件中的 `ServerConfig` 类。

![1830X875/微信图片_20250903145327_21624_1.png](https://tc-new.z.wiki/autoupload/f/KTO6-pUlsq3zQ-YJ9ppdgtiO_OyvX7mIgxFBfDMDErs/20250903/AF2F/1830X875/%E5%BE%AE%E4%BF%A1%E5%9B%BE%E7%89%87_20250903145327_21624_1.png)


## 配置选项

| 配置项 | 描述 | 默认值 |
|--------|------|--------|
| `API_ENDPOINT` | Z.ai 的上游 API 地址 | `https://chat.z.ai/api/chat/completions` |
| `AUTH_TOKEN` | 下游客户端鉴权 key | `sk-your-api-key` |
| `BACKUP_TOKEN` | 上游 API 的 token (匿名模式失败时使用) | JWT token |
| `PRIMARY_MODEL` | 默认模型名称 | `GLM-4.5` |
| `THINKING_MODEL` | 思考模型名称 | `GLM-4.5-Thinking` |
| `SEARCH_MODEL` | 搜索模型名称 | `GLM-4.5-Search` |
| `LISTEN_PORT` | 服务监听端口 | `8080` |
| `DEBUG_LOGGING` | 调试模式开关 | `true` |
| `THINKING_PROCESSING` | 思考内容处理策略 | `think` (可选: `strip`, `raw`) |
| `ANONYMOUS_MODE` | 是否使用匿名 token | `true` |
| `TOOL_SUPPORT` | 是否启用 Function Call 功能 | `true` |

### 思考内容处理策略说明

- **think**: 将 `<details>` 标签转换为 `<thinking>` 标签,适合 OpenAI 兼容格式
- **strip**: 完全移除 `<details>` 标签及其内容
- **raw**: 保留原始格式,不做任何处理

## 架构说明

本项目采用以下技术栈:

- **FastAPI**: 现代、快速的 Web 框架,提供自动 API 文档生成
- **Pydantic**: 数据验证和序列化,确保 API 兼容性
- **uvicorn**: ASGI 服务器,提供高性能服务

项目通过异步编程模型实现高效的并发处理,支持流式和非流式两种响应模式。

## 贡献指南

欢迎提交 Issue 和 Pull Request!请确保:
1. 遵循 PEP 8 规范
2. 提交前运行测试(如果有)
3. 更新相关文档

## 许可证

MIT LICENSE

## 免责声明

本项目与 Z.ai 官方无关,使用前请确保遵守 Z.ai 的服务条款。请勿将此服务用于商业用途或违反 Z.ai 使用条款的场景。