ss22345 commited on
Commit
d41adbf
·
1 Parent(s): 701b56b

chore:ci&readme updates

Browse files
Files changed (2) hide show
  1. .github/workflows/docker-image.yml +1 -1
  2. README.md +272 -60
.github/workflows/docker-image.yml CHANGED
@@ -3,7 +3,7 @@ name: Build and Publish Docker Image
3
  on:
4
  push:
5
  branches:
6
- - main
7
  tags:
8
  - 'v*'
9
  workflow_dispatch:
 
3
  on:
4
  push:
5
  branches:
6
+ - master
7
  tags:
8
  - 'v*'
9
  workflow_dispatch:
README.md CHANGED
@@ -1,60 +1,106 @@
1
  # zai-proxy
2
 
3
- zai-proxy 是一个基于 Go 语言的代理服务,将 z.ai 网页聊天转换为 OpenAI API 兼容格式。用户使用自己的 z.ai token 进行调用。
4
 
5
  ## 功能特性
6
 
7
- - OpenAI API 兼容格式
8
- - 支持流式和非流式响应
9
- - 支持多种 GLM 模型
 
10
  - 支持思考模式 (thinking)
11
  - 支持联网搜索模式 (search)
12
- - 支持内置工具调用 (tools)
13
  - 支持多模态图片输入
14
  - 支持匿名 Token(免登录)
15
- - **自动生成签名**
16
- - **自动更新签名版本号**
17
 
18
  ## 快速开始
19
 
20
- ### 安装运行
 
 
21
 
22
  ```bash
23
- # 克隆项目
24
- git clone https://github.com/kao0312/zai-proxy.git
25
  cd zai-proxy
26
-
27
- # 安装依赖
28
  go mod download
29
-
30
- # 运行服务
31
  go run main.go
32
  ```
33
 
34
- ### Docker 一键部署
 
 
 
 
 
 
 
 
 
35
 
36
  ```bash
37
- docker run -d -p 8000:8000 ghcr.io/kao0312/zai-proxy:latest
38
  ```
39
 
40
  自定义端口和日志级别:
41
 
42
  ```bash
43
- docker run -d -p 8080:8000 -e LOG_LEVEL=debug ghcr.io/kao0312/zai-proxy:latest
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
44
  ```
45
 
46
  ## 环境变量
47
 
48
  | 变量名 | 说明 | 默认值 |
49
  |--------|------|--------|
50
- | PORT | 监听端口 | 8000 |
51
- | LOG_LEVEL | 日志级别 | info |
 
 
52
 
53
  ## 获取 z.ai Token
54
 
55
  ### 方式一:使用匿名 Token(免登录)
56
 
57
- 直接使用 `free` 作为 API key,服务会自动获取一个匿名 token:
58
 
59
  ```bash
60
  curl http://localhost:8000/v1/chat/completions \
@@ -71,52 +117,104 @@ curl http://localhost:8000/v1/chat/completions \
71
  4. 在 Cookies 中找到 `token` 字段
72
  5. 复制其值作为 API 调用的 Authorization
73
 
74
- ## 支持的模型
75
 
76
- | 模型名称 | 上游模型 |
77
- |----------|----------|
78
- | GLM-4.5 | 0727-360B-API |
79
- | GLM-4.6 | GLM-4-6-API-V1 |
80
- | GLM-4.7 | glm-4.7 |
81
- | GLM-4.5-V | glm-4.5v |
82
- | GLM-4.6-V | glm-4.6v |
83
- | GLM-4.5-Air | 0727-106B-API |
84
 
85
- ### 模型标签
86
 
87
- 模型名称支持以下后缀标签(可组合使用):
88
 
89
- - `-thinking`: 启用思考模式,响应会包含 `reasoning_content` 字段
90
- - `-search`: 启用联网搜索模式
91
- - `-tools`: 自动注入内置工具定义,模型会返回 `tool_calls` 进行函数调用
92
- - (TODO) `-deepsearch`: 启用多轮搜索,深入研究分析
93
 
94
- 标签可任意组合,顺序不限
95
 
96
- 示例:
 
 
 
 
 
 
 
 
 
97
 
98
- - `GLM-4.7-thinking`
99
- - `GLM-4.7-search`
100
- - `GLM-4.7-thinking-search`
101
- - `GLM-4.7-tools`
102
- - `GLM-4.7-tools-thinking`
103
 
104
- ## 使用示例
105
 
106
- ### curl 测试
107
 
108
  ```bash
109
- curl http://localhost:8000/v1/chat/completions \
110
- -H "Authorization: Bearer YOUR_ZAI_TOKEN" \
111
  -H "Content-Type: application/json" \
112
  -d '{
113
- "model": "GLM-4.7",
 
114
  "messages": [{"role": "user", "content": "hello"}],
115
  "stream": true
116
  }'
117
  ```
118
 
119
- ### 多模态请求
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
120
 
121
  ```json
122
  {
@@ -133,24 +231,59 @@ curl http://localhost:8000/v1/chat/completions \
133
  }
134
  ```
135
 
136
- ### 支持的图片格式:
137
  - HTTP/HTTPS URL
138
- - Base64 编码 (data:image/jpeg;base64,...)
139
 
140
- ## 工具调用 (Function Calling)
 
 
 
 
 
 
 
 
141
 
142
- 使用 `-tools` 后缀时,代理会自动注入 6 个内置工具定义。模型会根据用户输入决定是否调用工具。
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
143
 
144
  ### 内置工具
145
 
146
- | 工具名 | 描述 |
147
- |--------|------|
148
- | `get_current_time` | 获取当前时间 |
149
- | `calculate` | 执行数学计算 |
150
- | `search_web` | 搜索网络信息 |
151
- | `query_database` | 执行SQL查询 |
152
- | `file_operations` | 文件读写列表 |
153
- | `call_external_api` | 调用外部API |
 
 
154
 
155
  ### 基本调用
156
 
@@ -217,4 +350,83 @@ curl http://localhost:8000/v1/chat/completions \
217
  }
218
  ```
219
 
 
 
 
 
 
 
220
  两者可混合使用:`-tools` 模型名 + 自定义 `tools` 字段。**客户端自带的同名工具优先**,不会被内置工具覆盖。
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  # zai-proxy
2
 
3
+ zai-proxy 是一个基于 Go 语言的代理服务,将 z.ai 网页聊天转换为 **OpenAI API** 和 **Anthropic Messages API** 兼容格式。用户使用自己的 z.ai token 或 `free` 匿名令牌进行调用。
4
 
5
  ## 功能特性
6
 
7
+ - OpenAI `/v1/chat/completions` 兼容
8
+ - Anthropic `/v1/messages` 兼容(支持 Claude SDK 直连)
9
+ - 支持流式 (SSE) 和非流式响应
10
+ - 支持多种 GLM 模型,Claude 模型名自动映射
11
  - 支持思考模式 (thinking)
12
  - 支持联网搜索模式 (search)
13
+ - 支持工具/函数调用 (function calling)
14
  - 支持多模态图片输入
15
  - 支持匿名 Token(免登录)
16
+ - 自动生成请求签名
17
+ - 自动跟踪前端版本号
18
 
19
  ## 快速开始
20
 
21
+ ### 从源码运行
22
+
23
+ 要求 Go 1.21+:
24
 
25
  ```bash
26
+ git clone https://github.com/yurika0211/zai-proxy.git
 
27
  cd zai-proxy
 
 
28
  go mod download
 
 
29
  go run main.go
30
  ```
31
 
32
+ 编译为可执行文件:
33
+
34
+ ```bash
35
+ go build -o zai-proxy .
36
+ ./zai-proxy
37
+ ```
38
+
39
+ ### Docker 部署
40
+
41
+ #### 使用预构建镜像
42
 
43
  ```bash
44
+ docker run -d --name zai-proxy -p 8000:8000 ghcr.io/yurika0211/zai-proxy:latest
45
  ```
46
 
47
  自定义端口和日志级别:
48
 
49
  ```bash
50
+ docker run -d --name zai-proxy \
51
+ -p 8080:8000 \
52
+ -e LOG_LEVEL=debug \
53
+ ghcr.io/yurika0211/zai-proxy:latest
54
+ ```
55
+
56
+ > 镜像支持 `linux/amd64` 和 `linux/arm64` 双平台。
57
+
58
+ #### 可用镜像标签
59
+
60
+ | 标签 | 说明 |
61
+ |------|------|
62
+ | `latest` | 默认分支的最新构建 |
63
+ | `v*`(如 `v1.0.0`) | 语义化版本发布 |
64
+ | `<commit-sha>` | 特定 commit 的构建 |
65
+
66
+ #### 自行构建镜像
67
+
68
+ ```bash
69
+ docker build -t zai-proxy .
70
+ docker run -d --name zai-proxy -p 8000:8000 zai-proxy
71
+ ```
72
+
73
+ #### Docker Compose
74
+
75
+ ```yaml
76
+ services:
77
+ zai-proxy:
78
+ image: ghcr.io/yurika0211/zai-proxy:latest
79
+ ports:
80
+ - "8000:8000"
81
+ environment:
82
+ - LOG_LEVEL=info
83
+ restart: unless-stopped
84
+ ```
85
+
86
+ ```bash
87
+ docker compose up -d
88
  ```
89
 
90
  ## 环境变量
91
 
92
  | 变量名 | 说明 | 默认值 |
93
  |--------|------|--------|
94
+ | `PORT` | 监听端口 | `8000` |
95
+ | `LOG_LEVEL` | 日志级别 (`debug` / `info` / `warn` / `error`) | `info` |
96
+
97
+ 支持 `.env` 文件自动加载。
98
 
99
  ## 获取 z.ai Token
100
 
101
  ### 方式一:使用匿名 Token(免登录)
102
 
103
+ 直接使用 `free` 作为 API key,服务会自动获取匿名 token:
104
 
105
  ```bash
106
  curl http://localhost:8000/v1/chat/completions \
 
117
  4. 在 Cookies 中找到 `token` 字段
118
  5. 复制其值作为 API 调用的 Authorization
119
 
120
+ ## API 端点
121
 
122
+ ### `GET /v1/models`
 
 
 
 
 
 
 
123
 
124
+ 返回可用模型列表(OpenAI 兼容格式)。
125
 
126
+ ### `POST /v1/chat/completions`
127
 
128
+ OpenAI 兼容的聊天补全接口。
 
 
 
129
 
130
+ **认证方式** `Authorization: Bearer <token>` 或 `x-api-key: <token>`
131
 
132
+ ```bash
133
+ curl http://localhost:8000/v1/chat/completions \
134
+ -H "Authorization: Bearer YOUR_ZAI_TOKEN" \
135
+ -H "Content-Type: application/json" \
136
+ -d '{
137
+ "model": "GLM-4.7",
138
+ "messages": [{"role": "user", "content": "hello"}],
139
+ "stream": true
140
+ }'
141
+ ```
142
 
143
+ ### `POST /v1/messages`
 
 
 
 
144
 
145
+ Anthropic Messages API 兼容接口,可直接使用 Anthropic SDK 连接。
146
 
147
+ **认证方式:** `x-api-key: <token>` 或 `Authorization: Bearer <token>`
148
 
149
  ```bash
150
+ curl http://localhost:8000/v1/messages \
151
+ -H "x-api-key: free" \
152
  -H "Content-Type: application/json" \
153
  -d '{
154
+ "model": "claude-sonnet-4-6",
155
+ "max_tokens": 1024,
156
  "messages": [{"role": "user", "content": "hello"}],
157
  "stream": true
158
  }'
159
  ```
160
 
161
+ 支持的 Anthropic 特性
162
+ - `system` 字段(字符串或内容块数组)
163
+ - `thinking` 推理模式(`{"type": "enabled"}`)
164
+ - `tools` / `tool_choice` 工具调用
165
+ - 流式 SSE 事件(`message_start` / `content_block_delta` / `message_stop` 等)
166
+ - 非流式 JSON 响应
167
+
168
+ ## 支持的模型
169
+
170
+ ### GLM 模型
171
+
172
+ | 模型名称 | 上游模型 | 说明 |
173
+ |----------|----------|------|
174
+ | `GLM-4.5` | 0727-360B-API | |
175
+ | `GLM-4.6` | GLM-4-6-API-V1 | |
176
+ | `GLM-4.7` | glm-4.7 | 最新 |
177
+ | `GLM-4.5-V` | glm-4.5v | 视觉 |
178
+ | `GLM-4.6-V` | glm-4.6v | 视觉(最新) |
179
+ | `GLM-4.5-Air` | 0727-106B-API | 轻量 |
180
+
181
+ ### Claude 模型名映射
182
+
183
+ 通过 `/v1/messages` 端点使用 Claude 模型名时,会自动映射到对应的 GLM 模型:
184
+
185
+ | Claude 模型 | 映射到 | 备注 |
186
+ |-------------|--------|------|
187
+ | `claude-opus-4-6` | GLM-4.7 | 自动启用 thinking |
188
+ | `claude-opus-4-5-20250514` | GLM-4.7 | 自动启用 thinking |
189
+ | `claude-sonnet-4-6` | GLM-4.7 | |
190
+ | `claude-sonnet-4-5-20241022` | GLM-4.7 | |
191
+ | `claude-haiku-4-5` | GLM-4.5-Air | |
192
+ | `claude-haiku-4-5-20251001` | GLM-4.5-Air | |
193
+ | `claude-3-5-sonnet-20241022` | GLM-4.7 | |
194
+ | `claude-3-5-haiku-20241022` | GLM-4.5-Air | |
195
+
196
+ > Opus 系列模型始终自动启用 thinking 模式。未识别的模型名会回退到 GLM-4.7。
197
+
198
+ ### 模型标签
199
+
200
+ 模型名称支持以下后缀标签(可组合使用,顺序不限):
201
+
202
+ | 标签 | 说明 |
203
+ |------|------|
204
+ | `-thinking` | 启用思考模式,响应包含 `reasoning_content` 字段 |
205
+ | `-search` | 启用联网搜索,搜索结果自动转换为 markdown 引用 |
206
+ | `-tools` | 自动注入内置工具定义,模型可进行函数调用 |
207
+
208
+ 组合示例:
209
+ - `GLM-4.7-thinking`
210
+ - `GLM-4.7-search`
211
+ - `GLM-4.7-thinking-search`
212
+ - `GLM-4.7-tools`
213
+ - `GLM-4.7-tools-thinking`
214
+
215
+ ## 使用示例
216
+
217
+ ### 多模态请求
218
 
219
  ```json
220
  {
 
231
  }
232
  ```
233
 
234
+ 支持的图片格式:
235
  - HTTP/HTTPS URL
236
+ - Base64 编码 (`data:image/jpeg;base64,...`)
237
 
238
+ ### Anthropic SDK (Python)
239
+
240
+ ```python
241
+ import anthropic
242
+
243
+ client = anthropic.Anthropic(
244
+ api_key="free",
245
+ base_url="http://localhost:8000",
246
+ )
247
 
248
+ message = client.messages.create(
249
+ model="claude-sonnet-4-6",
250
+ max_tokens=1024,
251
+ messages=[{"role": "user", "content": "hello"}],
252
+ )
253
+ print(message.content[0].text)
254
+ ```
255
+
256
+ ### Anthropic SDK 思考模式
257
+
258
+ ```python
259
+ message = client.messages.create(
260
+ model="claude-opus-4-6",
261
+ max_tokens=8192,
262
+ thinking={"type": "enabled", "budget_tokens": 4096},
263
+ messages=[{"role": "user", "content": "解释量子纠缠"}],
264
+ )
265
+
266
+ for block in message.content:
267
+ if block.type == "thinking":
268
+ print("思考:", block.thinking)
269
+ elif block.type == "text":
270
+ print("回答:", block.text)
271
+ ```
272
+
273
+ ## 工具调用 (Function Calling)
274
 
275
  ### 内置工具
276
 
277
+ 使用 `-tools` 后缀时,代理会自动注入以下 6 个内置工具定义:
278
+
279
+ | 工具名 | 描述 | 主要参数 |
280
+ |--------|------|----------|
281
+ | `get_current_time` | 获取当前时间 | `timezone`, `format` |
282
+ | `calculate` | 执行数学计算 | `expression` |
283
+ | `search_web` | 搜索网络信息 | `query`, `num_results` |
284
+ | `query_database` | 执行 SQL 查询 | `sql`, `database` |
285
+ | `file_operations` | 文件读写列表 | `operation`, `path`, `content` |
286
+ | `call_external_api` | 调用外部 API | `url`, `method`, `headers`, `body` |
287
 
288
  ### 基本调用
289
 
 
350
  }
351
  ```
352
 
353
+ `tool_choice` 支持:
354
+ - `"auto"` — 模型自行决定是否调用工具
355
+ - `"required"` — 强制调用工具
356
+ - `"none"` — 禁用工具调用
357
+ - `{"type": "function", "function": {"name": "xxx"}}` — 强制调用指定工具
358
+
359
  两者可混合使用:`-tools` 模型名 + 自定义 `tools` 字段。**客户端自带的同名工具优先**,不会被内置工具覆盖。
360
+
361
+ ### Anthropic 格式工具调用
362
+
363
+ 通过 `/v1/messages` 端点同样支持工具调用:
364
+
365
+ ```bash
366
+ curl http://localhost:8000/v1/messages \
367
+ -H "x-api-key: free" \
368
+ -H "Content-Type: application/json" \
369
+ -d '{
370
+ "model": "claude-sonnet-4-6",
371
+ "max_tokens": 1024,
372
+ "messages": [{"role": "user", "content": "北京天气怎么样?"}],
373
+ "tools": [{
374
+ "name": "get_weather",
375
+ "description": "获取天气信息",
376
+ "input_schema": {
377
+ "type": "object",
378
+ "properties": {
379
+ "city": {"type": "string", "description": "城市名称"}
380
+ },
381
+ "required": ["city"]
382
+ }
383
+ }]
384
+ }'
385
+ ```
386
+
387
+ `tool_choice` 映射关系:
388
+
389
+ | Anthropic | OpenAI 等价 |
390
+ |-----------|-------------|
391
+ | `{"type": "auto"}` | `"auto"` |
392
+ | `{"type": "any"}` | `"required"` |
393
+ | `{"type": "none"}` | `"none"` |
394
+ | `{"type": "tool", "name": "xxx"}` | `{"type": "function", ...}` |
395
+
396
+ ## 项目结构
397
+
398
+ ```
399
+ zai-proxy/
400
+ ├── main.go # 入口,路由注册
401
+ ├── internal/
402
+ │ ├── auth/ # 认证与签名
403
+ │ │ ├── anonymous.go # 匿名 token 获取
404
+ │ │ ├── jwt.go # JWT 解码
405
+ │ │ └── signature.go # HMAC-SHA256 请求签名
406
+ │ ├── config/ # 配置加载 (.env)
407
+ │ ├── filter/ # 响应处理过滤器
408
+ │ │ ├── prompttool.go # 提取 prompt 注入的 tool call
409
+ │ │ ├── toolcall.go # 解析 JSON 格式的 tool call
410
+ │ │ ├── thinking.go # 思考/推理内容处理
411
+ │ │ └── search.go # 搜索结果引用转换
412
+ │ ├── handler/ # HTTP 处理器
413
+ │ │ ├── chat.go # /v1/chat/completions
414
+ │ │ ├── anthropic.go # /v1/messages
415
+ │ │ └── models.go # /v1/models
416
+ │ ├── logger/ # 日志系统
417
+ │ ├── model/ # 类型定义
418
+ │ │ ├── types.go # OpenAI 兼容类型
419
+ │ │ ├── anthropic.go # Anthropic API 类型
420
+ │ │ └── mapping.go # 模型名映射与解析
421
+ │ ├── tools/ # 内置工具定义
422
+ │ │ ├── builtin.go # 6 个内置工具
423
+ │ │ └── prompt.go # 工具系统提示词构建
424
+ │ ├── upstream/ # 上游 z.ai 客户端
425
+ │ │ ├── client.go # 请求构建与发送
426
+ │ │ └── upload.go # 图片上传
427
+ │ └── version/ # 前端版本号跟踪
428
+ ├── scripts/
429
+ │ └── test_tool_call.sh # 工具调用集成测试
430
+ ├── Dockerfile
431
+ └── .github/workflows/ # CI/CD
432
+ ```