一个免费的使用 ChatGPT 3.5 API 的方案
Saika 博主

自从 Pandora-Next 的作者 pengzhile (始皇)宣布 Pandora-Next 停止运营,愉快的享受免费不限量高并发的 ChatGPT 3.5 API 的日子也就结束了。虽然现在很多第三方 API 提供商也提供很多免费额度使用,甚至多的不一定用得完,但是这究其根本在中国大陆的法律上应该是违法行为,也不一定能保证这些第三方提供商的服务就一直稳定,就像始皇停止运营来的那么突然一样。靠谁都不如靠自己,自己部署一个 server 才更靠谱。

经过我的一段时间探索和使用,目前总算是找到了一套差不多算是可以平替的方案,使用到了三个开源仓库:

ninja

ninja 用于和 OpenAI 进行中转,把 chat 的接口转换 api 的接口,不过由于 ninja 作者开发 ninja 的理念是服务端不存储用户数据,所以 ninja 的 ChatGPT-to-API 接口需要使用 access_Token 做 API Keys ,受限于 access_Token 的有效时间太短以及 access_Token 过长的问题,并不能很愉快的使用。但是 ninja 有使用 refresh_token 获取 access_Token 的接口,因为 refresh_token 的长度很短,且永久有效,所以我在 ninja 的 issue 中提议,使用 refresh_token 当做 API Keys 进行请求,但是被作者因为与其不存储用户数据的理念相悖而被否决。

refresh-gpt-chat

refresh-gpt-chat 用于把 ninja 的 api 接口转换成使用 refresh_token 作为 API Keys 进行请求。实际上是 refresh-gpt-chat 先使用 refresh_token 请求 access_Token ,再使用获取到的 access_Token 请求 API ,并把这个 access_Token 存储下来,反复使用。当 access_Token 过期时,再重新使用 refresh_token 请求 access_Token 。

one-api

one-api 用于存储多个 refresh_token ,提高并发量。因为 ninja 提供的 API 功能还是基于 OpenAI 的 chat 的 web ,而 web 又无法并发,必须等一句话说完,才能响应下一次请求,所以对于某些需要高并发的使用场景来讲, ninja 配合 refresh-gpt-chat 是不够的。但是在 one-api 内新建多个渠道,每个都存放一个 refresh_token ,用于请求 refresh-gpt-chat ,再使用 one-api 提供的接口,就能解决高并发的问题,愉快使用。而且 refresh_token 如果泄露也不好, one-api 二次分发就能避免 refresh_token 泄露的问题,让我无后顾之忧的把自己的 API Keys 提供给他人使用。

部署

部署上述服务,需要准备:
1、一台在 OpenAI 封锁之外的 VPS ;
2、一定的智慧和解决问题的能力。

部署步骤也并不复杂,特别是 ninja 和 one-api ,几乎是开箱即用,refresh-gpt-chat只要部署好了 Java 环境,运行也很简单。当然如果 VPS 能够支持 Docker ,甚至只需要 docker-compose.yaml 直接跑就行了。

Docker compose

以下是我写的,把上述三个仓库的服务一口气跑起来的docker-compose.yaml,只需要修改最末 refresh-gpt-chat 部分的 getAccessTokenUrlchatUrl 两个参数配置即可直接 docker compose up -d 使用。

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
version: '3.4'

services:
ninja:
image: gngpp/ninja:latest
container_name: ninja
restart: unless-stopped
environment:
- TZ=Asia/Shanghai
command: run
ports:
- "8080:7999"

watchtower:
container_name: watchtower
image: containrrr/watchtower
volumes:
- /var/run/docker.sock:/var/run/docker.sock
command: --interval 3600 --cleanup
restart: unless-stopped

one-api:
image: justsong/one-api:latest
container_name: one-api
restart: always
command: --log-dir /app/logs
ports:
- "3000:3000"
volumes:
- /project/sandbox/data/oneapi:/data
- /project/sandbox/logs:/app/logs
environment:
- SQL_DSN=oneapi:123456@tcp(db:3306)/one-api # 修改此行,或注释掉以使用 SQLite 作为数据库
- REDIS_CONN_STRING=redis://redis
- SESSION_SECRET=random_string # 修改为随机字符串
- TZ=Asia/Shanghai
# - NODE_TYPE=slave # 多机部署时从节点取消注释该行
# - SYNC_FREQUENCY=60 # 需要定期从数据库加载数据时取消注释该行
# - FRONTEND_BASE_URL=https://openai.justsong.cn # 多机部署时从节点取消注释该行
depends_on:
- redis
- db
healthcheck:
test: [ "CMD-SHELL", "wget -q -O - http://localhost:3000/api/status | grep -o '\"success\":\\s*true' | awk -F: '{print $2}'" ]
interval: 30s
timeout: 10s
retries: 3

redis:
image: redis:latest
container_name: redis
restart: always

db:
image: mysql:8.2.0
restart: always
container_name: mysql
volumes:
- /project/sandbox/data/mysql:/var/lib/mysql # 挂载目录,持久化存储
ports:
- '3306:3306'
environment:
TZ: Asia/Shanghai # 设置时区
MYSQL_ROOT_PASSWORD: 'OneAPI@justsong' # 设置 root 用户的密码
MYSQL_USER: oneapi # 创建专用用户
MYSQL_PASSWORD: '123456' # 设置专用用户密码
MYSQL_DATABASE: one-api # 自动创建数据库

refresh-gpt-chat:
# 该服务使用的 Docker 镜像
image: yangclivia/refresh-gpt-chat:latest
# Java 的环境变量 (可适当调节,用copilot可以适当调大点,具体可问gpt了解)
environment:
- JAVA_OPTS=-XX:+UseParallelGC -Xms64m -Xmx64m -XX:MaxMetaspaceSize=64m
# 为该服务创建的容器的名称
container_name: refresh-gpt-chat
# 容器总是重新启动
restart: always
# 容器运行的用户
user: root
# 容器的网络模式
ports:
- "8082:8082"
command:
- --log=info
#自定义端口号
- --server.port=8082
#自定义前缀
# - --server.servlet.context-path=/tokensTool
# ninja获取accessToken的Url
- --getAccessTokenUrl=http(s)://ninja的外部访问地址/auth/refresh_token
# ninja或者chat2api API接口
- --chatUrl=http(s)://ninja的外部访问地址/v1/chat/completions

手动部署

ninja 和 one-api 都可以直接下载可执行文件直接启动,无需配置其他环境,这里不做过多介绍,仅仅记录一下启动的命令。

ninja:

在仓库中直接下载对应自己的 VPS 系统的可执行二进制文件即可。

1
2
3
4
5
6
7
8
9
10
# 添加可执行权限
chmod +x ninja
# 启动ninja
./ninja run
# 后台启动ninja
./ninja start
# 停止后台ninja
./ninja stop
# pm2管理启动ninja
pm2 start ./ninja --name ninja -- run

one-api

在仓库中直接下载对应自己的 VPS 系统的可执行二进制文件即可。

1
2
3
4
5
6
7
8
# 添加可执行权限
chmod u+x one-api
# 设置缓存路径为当前路径(适合无root用户)
export TIKTOKEN_CACHE_DIR="$PWD"
# 启动one-api(把PORT改成自己想用的端口)
./one-api --port PORT --logs-dir ./logs
# pm2管理启动one-api
pm2 start ./one-api --name one-api -- --port PORT --logs-dir ./logs

refresh-gpt-chat

需要配置 OpenJDK , 前文在 hax 的免费主机上已经安装过 OpenJDK ,这里不再赘述。在仓库中下载 .jar 结尾的 fat jar 包即可直接启动:

1
2
3
4
# 直接启动(把 PORT 替换成自己希望的端口,并填写ninja的访问地址, jar 包文件名替换成自己下载的文件名)
java -jar refresh-gpt-chat-0.0.1-SNAPSHOT.jar --server.port=PORT --server.servlet.context-path=/ --getAccessTokenUrl=http(s)://ninja的访问地址/url/auth/refresh_token --chatUrl=http(s)://ninja的访问地址/v1/chat/completions
# 使用pm2管理启动
pm2 start java --name refresh-gpt-chat -- -jar refresh-gpt-chat-0.0.1-SNAPSHOT.jar --server.port=PORT --server.servlet.context-path=/ --getAccessTokenUrl=http(s)://ninja的访问地址/url/auth/refresh_token --chatUrl=http(s)://ninja的访问地址/v1/chat/completions

使用

进入 one-api 渠道选项卡中,添加新的渠道,类型选择自定义渠道, Base URL 填写 refresh-gpt-chat 的地址,模型选择 gpt-3.5 相关的全部模型。模型重定向中填入以下内容:

1
2
3
4
5
6
7
8
{
"gpt-3.5-turbo-0301": "gpt-3.5-turbo",
"gpt-3.5-turbo-0613": "gpt-3.5-turbo",
"gpt-3.5-turbo-16k": "gpt-3.5-turbo",
"gpt-3.5-turbo-16k-0613": "gpt-3.5-turbo",
"gpt-3.5-turbo-1106": "gpt-3.5-turbo",
"gpt-3.5-turbo-instruct": "gpt-3.5-turbo"
}

勾选中秘钥下方的批量创建,然后在秘钥中填入 refresh_token ,一行一个,最后点击提交。再去令牌选项卡中添加新的令牌,按照自己的喜好填写并提交即可。

再使用 one-api 生成的令牌作为 API Keys , one-api 的地址作为端点即可。

有多高并发取决于有多少 refresh_token 被存储在 one-api 中,如果需要使用沉浸式翻译这样的高并发应用,建议存入 20-100 个 refresh_token 进行请求。

获取 refresh_token 的网址:xyhelperfreegpts(这两个都是第三方服务,不能保证账号数据安全,也不能保证其服务一直有效,酌情使用,后果自负)

亦或者可以使用 Apple 设备抓包获取 refresh_token ,具体可以自己搜索。不过这种方式容易导致 Apple 设备被 OpenAI 封禁,请酌情使用。

由 Hexo 驱动 & 主题 Keep
本站由 提供部署服务
访问量