基于Cloudflare Workers搭建ChatGPT API代理:实现联网搜索与安全访问
反向代理是网络架构中的关键技术,通过在客户端与服务器之间建立中间层,实现请求转发、负载均衡和安全过滤。其核心原理是接收客户端请求,处理后转发至后端服务,再将响应返回给客户端。这一技术在现代Web开发中具有重要价值,能够有效解决跨域访问、API网关管理和网络优化等问题。在AI应用开发领域,结合无服务器计算平台,反向代理可以扩展为智能API网关,为大型语言模型服务提供增强功能。例如,在ChatGPT
1. 项目概述与核心价值
最近在折腾AI应用开发,发现直接调用OpenAI的官方API虽然稳定,但有时候会遇到一些网络访问上的小麻烦,尤其是在国内网络环境下,或者需要做一些定制化功能的时候。于是,我花了不少时间研究如何搭建一个属于自己的、功能更灵活的ChatGPT API代理。最终,我选择在Cloudflare Workers这个无服务器边缘计算平台上实现,因为它部署简单、全球节点访问快,而且免费额度对于个人开发者来说相当友好。
这个项目本质上是一个运行在Cloudflare全球网络边缘的反向代理。它扮演了一个“中间人”的角色,接收你从客户端(比如你自己的聊天机器人前端、脚本或者支持自定义API的工具)发来的请求,然后帮你转发给真正的ChatGPT API服务端(比如OpenAI官方或者第三方的兼容API),最后再把响应结果原路返回给你。这样做有几个显而易见的好处:首先,它能有效规避一些网络层面的访问限制,让你的应用访问更稳定;其次,你可以在代理层加入自己的逻辑,比如访问控制、请求日志、甚至像这个项目实现的“联网搜索”这样的增强功能;最后,把API密钥放在云端Worker的环境变量里,比直接暴露在前端代码中要安全得多。
这个代理项目特别适合以下几类朋友:一是独立开发者或小团队,想快速搭建一个稳定可用的ChatGPT接口给自己的产品用;二是AI爱好者,希望在不修改客户端代码的情况下,为ChatGPT增加联网搜索等额外能力;三是任何对Cloudflare Workers感兴趣,想通过一个实用项目来学习边缘函数开发的人。接下来,我会详细拆解这个项目的设计思路、部署步骤、使用技巧以及我踩过的一些坑。
2. 核心设计思路与架构解析
2.1 为什么选择Cloudflare Workers?
在决定技术方案时,我对比了几种常见的代理实现方式,比如用Nginx做反向代理、自己买VPS搭Node.js服务,或者使用Serverless框架。最终选择Cloudflare Workers,主要是基于以下几点考量:
1. 极致的性能与低延迟 :Workers运行在Cloudflare全球275个以上的数据中心边缘。这意味着你的请求会由离用户最近的节点处理并转发,大大减少了网络延迟。对于AI对话这种交互式应用,响应速度至关重要,边缘计算的优势非常明显。
2. 真正的无服务器与低成本 :你不需要关心服务器的维护、扩容、安全补丁。Cloudflare Workers提供了慷慨的免费套餐,每天有10万次请求额度,对于个人项目或中小流量应用完全足够。这比租用一台始终在线的VPS要经济得多。
3. 开发部署体验流畅 :整个开发、测试、部署流程可以通过Wrangler命令行工具或在线编辑器完成,非常便捷。代码修改后几乎秒级生效,非常适合快速迭代。
4. 内置的安全与可靠性 :Cloudflare网络天然具备DDoS防护、SSL证书管理等能力,为你的代理服务增加了一层保障。
当然,它也有局限,主要是运行环境和资源限制(如CPU执行时间、内存大小)。但这个项目的代码逻辑清晰,完全在限制范围内,因此是一个绝佳的应用场景。
2.2 代理的核心工作流程
这个Worker脚本的核心逻辑并不复杂,但设计得很巧妙。它主要处理以下几类请求:
- 路径路由 :根据请求的URL路径,决定将请求转发到哪个后端服务。
/v1/chat/completions: 转发到OpenAI官方的Chat Completions API。/kamiya/v1/chat/completions: 转发到第三方服务kamiya.dev提供的兼容API。
- 请求预处理 :
- 身份验证 :检查请求头中的
Authorization字段。如果配置了PASSWORD环境变量,则验证客户端提供的密钥是否在密码列表中。如果没配置密码,则可能直接将客户端提供的密钥用作后端API的密钥(具体逻辑取决于代码)。 - 请求体解析与增强 :这是实现“联网搜索”的关键。Worker会解析请求中的消息内容,寻找特定的标记(如
WS[搜索关键词])。当发现这种标记时,它会调用一个搜索服务(代码中可能是内置或指定的),获取搜索结果,并将这些结果作为新的上下文信息,附加到原有的用户消息之后,再发送给AI模型。这样,模型就能“看到”实时搜索到的信息并据此回答。 - 流式响应支持 :它完整地处理了OpenAI的流式响应(Server-Sent Events),确保客户端能像连接官方API一样,接收到一个字一个字蹦出来的体验。
- 身份验证 :检查请求头中的
- 请求转发与响应回传 :将处理后的请求(添加了正确的后端API密钥、修改后的消息体等)发送到真正的ChatGPT API端点,并将响应(无论是普通JSON还是流式数据)原样返回给客户端。
这种设计实现了 解耦 和 可扩展性 。你的客户端代码几乎不需要改动,只需要换一个API地址和密钥(即你设置的密码)。所有复杂的认证、增强逻辑都在云端Worker中完成。
2.3 环境变量配置策略解析
项目通过环境变量来管理敏感信息和配置,这是云函数的最佳实践。这里详细解释一下三个变量的用途和配置技巧:
PASSWORD:这是你暴露给 客户端 的密钥。你可以设置一个或多个(用逗号分隔)。客户端在调用你的代理时,需要在Authorization: Bearer <password>头中使用这个密码。它的存在不是为了调用OpenAI,而是为了保护你的代理端点不被滥用。即使有人拿到了这个密码,他也不知道你背后真正的OpenAI Key是什么。API_KEY:这是你真实的 OpenAI API密钥 。Worker在向api.openai.com转发请求时,会使用这个密钥来替换掉客户端请求中的Authorization头。 非常重要: 永远不要把这个密钥直接交给前端或不可信的客户端。在这里,它被安全地存储在Cloudflare的环境变量中。KAMIYA_TOKEN:这是为备用API端点准备的密钥。如果你配置了/kamiya路由,并且希望使用kamiya.dev的服务,就需要在这里填入他们提供的密钥。
重要安全提示 :在Cloudflare Workers仪表盘设置环境变量时,务必区分“加密”和“明文”。对于
API_KEY和KAMIYA_TOKEN这类高度敏感的密钥,应该使用“加密的文本”方式添加,这样它们在日志和代码中都不会被明文暴露。PASSWORD相对可以宽松一些,但出于安全习惯,也建议加密。
3. 从零开始的详细部署指南
3.1 前期准备与工具安装
在开始部署之前,你需要准备好以下几样东西:
- 一个Cloudflare账户 :如果你还没有,去Cloudflare官网注册一个,免费计划即可。
- 一个域名(可选但推荐) :虽然Cloudflare Workers提供免费的
*.workers.dev子域名,但使用自己的域名会更专业,也便于管理。你需要将这个域名的DNS托管到Cloudflare。 - Node.js与npm环境 :用于安装部署工具。建议安装最新的LTS版本。
- OpenAI API密钥 :从OpenAI平台获取。如果你打算使用
kamiya.dev的服务,也需要去其官网获取相应的令牌。
接下来,安装Cloudflare的命令行部署工具 Wrangler 。打开你的终端(命令行),执行以下命令:
npm install -g wrangler
安装完成后,运行 wrangler login ,按照提示在浏览器中完成对Cloudflare账户的授权。这一步会将你的本地环境与Cloudflare账户关联起来。
3.2 获取与配置项目代码
这个项目的代码托管在GitHub上。你不需要克隆整个仓库,只需要获取核心的JavaScript文件。
-
访问项目页面,找到
index.js(源代码,便于阅读和自定义)或production.js(压缩后的代码,体积更小)。 -
将文件内容复制下来,在你本地创建一个新文件,例如命名为
chatgpt-proxy.js,并将代码粘贴进去。 -
(关键步骤)初始化Wrangler项目 :在存放
chatgpt-proxy.js文件的目录下,打开终端,运行:wrangler init这个命令会创建一个
wrangler.toml配置文件。你可以删除它自动生成的其他文件,只保留这个配置文件和我们刚才创建的JS文件。 -
编辑
wrangler.toml文件 :用文本编辑器打开它,进行如下配置:name = "my-chatgpt-proxy" # 给你的Worker起个名字,全局唯一 main = "chatgpt-proxy.js" # 指定入口文件为我们的JS文件 compatibility_date = "2024-08-01" # 使用一个较新的兼容日期 [vars] # 这里可以定义环境变量,但生产环境建议在Dashboard设置 # PASSWORD = "your_secret_password_here" # API_KEY = "sk-your-real-openai-key" # 如果你使用自己的域名,需要配置路由 # [[routes]] # pattern = "chatgpt.yourdomain.com/*" # zone_name = "yourdomain.com"注意,我在这里的
[vars]部分注释掉了环境变量。 我更推荐的做法是,先在本地测试时用这里定义,测试无误后,在部署到生产环境前,删除这里的明文密钥,转而在Cloudflare Dashboard上设置加密的环境变量。 这是避免将密钥意外提交到Git等版本控制系统的最佳实践。
3.3 本地开发与测试
在部署到云端之前,强烈建议先在本地进行测试。Wrangler提供了出色的本地开发服务器。
-
在项目根目录下,创建一个
.dev.vars文件。这个文件用于定义本地开发时的环境变量,它不会被提交到版本库。# .dev.vars PASSWORD="my_test_password" API_KEY="sk-your-real-openai-key-for-test" -
启动本地开发服务器:
wrangler dev终端会输出一个本地地址,通常是
http://localhost:8787。 -
测试代理功能 :使用
curl或Postman等工具进行测试。- 测试基础代理 :
你应该能收到一个正常的ChatGPT回复。curl http://localhost:8787/v1/chat/completions \ -H "Content-Type: application/json" \ -H "Authorization: Bearer my_test_password" \ -d '{ "model": "gpt-3.5-turbo", "messages": [{"role": "user", "content": "你好,世界!"}], "stream": false }' - 测试流式输出 :将请求体中的
"stream": false改为true,你会看到一段段的数据流。 - 测试联网搜索 :
观察响应,看AI的回答是否包含了基于搜索结果的实时信息。curl http://localhost:8787/v1/chat/completions \ -H "Content-Type: application/json" \ -H "Authorization: Bearer my_test_password" \ -d '{ "model": "gpt-3.5-turbo", "messages": [{"role": "user", "content": "告诉我今天的天气。WS[北京 今天 天气]"}], "stream": false }'
本地测试能帮你快速验证代码逻辑和环境变量是否正确,避免直接部署到云端后排查困难。
- 测试基础代理 :
3.4 生产环境部署与配置
本地测试通过后,就可以部署到生产环境了。
-
发布Worker :在终端运行以下命令,将你的代码部署到Cloudflare全球网络。
wrangler deploy部署成功后,你会得到一个形如
https://my-chatgpt-proxy.<你的子域名>.workers.dev的访问地址。这就是你的代理API的基础URL。 -
配置生产环境变量 :
- 登录Cloudflare Dashboard,进入“Workers & Pages”页面。
- 找到你刚刚部署的Worker(
my-chatgpt-proxy)。 - 点击进入“设置”(Settings) -> “变量”(Variables)。
- 在“环境变量”部分,添加
PASSWORD、API_KEY等变量。 务必为API_KEY和KAMIYA_TOKEN选择“加密的文本” 。 - 点击“保存”。
-
绑定自定义域名(可选) :
- 在Worker的“设置”页面,找到“触发器”(Triggers) -> “自定义域”(Custom Domains)。
- 点击“添加自定义域”,输入你已托管在Cloudflare的域名,例如
chatgpt-api.yourdomain.com。 - 按照提示完成DNS记录的自动添加。绑定成功后,你就可以通过
https://chatgpt-api.yourdomain.com/v1/...来访问你的代理了,这比workers.dev的域名更简洁专业。
4. 客户端集成与使用实战
部署好代理后,最关键的一步就是在你的客户端应用中使用它。这里以几种常见场景为例。
4.1 在ChatGPT WebUI类工具中配置
许多基于Web的ChatGPT开源前端(如ChatGPT-Next-Web, LibreChat)都支持自定义API地址。
- 配置API地址 :在设置页面,找到“API地址”或“Base URL”的配置项。将默认的
https://api.openai.com替换为你的Worker地址,例如https://my-chatgpt-proxy.your-subdomain.workers.dev或https://chatgpt-api.yourdomain.com。 - 配置API密钥 :在“API密钥”配置项中,填入你在Worker环境变量里设置的
PASSWORD(访问密码),而不是你的真实OpenAI Key。 - 模型列表(可选) :有些前端需要手动配置模型列表。你可以填写
gpt-3.5-turbo, gpt-4等。如果前端支持从接口自动获取模型列表,但你的代理没有实现/v1/models端点,可能会报错。这时你可能需要在前端配置中关闭“自动获取模型”的选项,或者为你的Worker添加一个简单的/v1/models路由,返回一个固定的模型列表。
配置完成后,你就可以在前端界面中正常聊天了。当你需要联网搜索时,只需在问题中插入 WS[关键词] 即可。
4.2 在编程中直接调用API
如果你在编写Python、JavaScript等脚本,调用方式与调用官方API几乎无异,只需修改 base_url 和 api_key 。
Python示例(使用OpenAI官方库):
from openai import OpenAI
# 初始化客户端,指向你的代理
client = OpenAI(
api_key="your_proxy_password_here", # 填写PASSWORD
base_url="https://chatgpt-api.yourdomain.com/v1", # 注意这里只到/v1
)
# 发起普通对话
response = client.chat.completions.create(
model="gpt-3.5-turbo",
messages=[{"role": "user", "content": "你好!"}],
stream=False,
)
print(response.choices[0].message.content)
# 发起带联网搜索的对话
search_response = client.chat.completions.create(
model="gpt-3.5-turbo",
messages=[{"role": "user", "content": "马斯克最近有什么新闻?WS[Elon Musk news]"}],
stream=False,
)
print(search_response.choices[0].message.content)
JavaScript/Node.js示例(使用原生fetch):
async function callProxyChatGPT() {
const response = await fetch('https://chatgpt-api.yourdomain.com/v1/chat/completions', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer your_proxy_password_here` // 填写PASSWORD
},
body: JSON.stringify({
model: 'gpt-3.5-turbo',
messages: [{ role: 'user', content: '解释一下量子计算。WS[quantum computing basics]' }],
stream: false // 设为true可处理流式响应
})
});
const data = await response.json();
console.log(data.choices[0].message.content);
}
callProxyChatGPT();
4.3 联网搜索功能深度使用指南
项目的联网搜索功能是其一大亮点,但使用上有一些细节需要注意:
- 触发语法 :在用户消息的任何位置插入
WS[搜索查询词]即可。Worker会识别这个模式,提取括号内的内容进行搜索,并将搜索结果整理后附加到原始消息后。例如:“帮我总结一下WS[2024年人工智能大会]的主要议题。” - 搜索次数限制 :代码中默认设置了限制, 当前提问中最多触发2次搜索 ,并且会 附带上次提问的搜索请求 ,因此 单次回答总共最多进行4次搜索 。这是为了防止滥用和避免Worker执行时间超限。如果你需要更多次搜索,必须修改Worker源代码,找到对应的限制变量(通常是一个计数器或数组长度检查)进行调整。
- 性能影响 :每一次搜索都意味着Worker需要额外发起一个网络请求到搜索引擎(如Bing或Google的API),等待返回,然后解析结果。这会显著增加整个请求的响应时间,从几百毫秒可能增加到几秒甚至更久。 在要求低延迟的交互场景中慎用 。
- 搜索质量 :最终的回答质量高度依赖于底层搜索服务的准确性和Worker对搜索结果的摘要能力。有时搜索结果可能包含无关或过时信息,从而影响AI的回答。对于关键信息,最好能提供更精确的搜索关键词。
5. 高级配置、问题排查与优化
5.1 自定义与扩展
这个Worker项目是一个很好的起点,你可以基于它进行各种自定义:
- 修改默认密码和密钥 :直接在Cloudflare Dashboard的环境变量中修改即可,无需改动代码。
- 增加新的API提供商 :如果你想接入除了OpenAI和Kamiya之外的其他大模型API(如Anthropic Claude、Google Gemini),可以在代码的请求路由部分添加新的判断分支,并配置对应的环境变量(如
ANTHROPIC_KEY)。 - 修改搜索逻辑 :默认的搜索实现可能比较简单。你可以替换成更强大的搜索API(如Serper API、SerpAPI),或者修改结果的处理方式,比如只提取摘要、只取前N条结果等。
- 添加请求日志与监控 :在代码开头或结尾添加日志记录,将请求的元信息(时间、IP、模型、Token用量)发送到日志服务(如Cloudflare自身的Workers Analytics、或第三方如Logtail),便于监控使用情况和排查问题。
- 实现更复杂的鉴权 :目前的密码鉴权比较简单。你可以集成更复杂的机制,如JWT令牌验证、基于IP的访问限制等。
5.2 常见问题与排查清单
在实际使用中,你可能会遇到以下问题。这里提供一个排查思路:
| 问题现象 | 可能原因 | 排查步骤与解决方案 |
|---|---|---|
| 返回 401 Unauthorized | 1. 客户端未提供 Authorization 头。 2. 提供的密码不在 PASSWORD 环境变量列表中。 3. 环境变量未正确加载或Worker未重启。 |
1. 检查客户端请求头是否包含 Authorization: Bearer <password> 。 2. 登录Cloudflare Dashboard,确认 PASSWORD 变量值是否正确,密码间用英文逗号分隔,无空格。 3. 在Dashboard上轻微修改并保存环境变量,或重新部署Worker以触发更新。 |
| 返回 5xx 错误 (如 524, 500) | 1. Worker执行超时(默认10秒)。 2. 后端API(OpenAI)服务不稳定或超时。 3. Worker代码运行时错误。 |
1. 检查是否进行了过于复杂或耗时的操作(如多次联网搜索)。尝试简化请求。 2. 检查OpenAI服务状态。可以在本地用真实密钥直接调用官方API测试。 3. 查看Cloudflare Dashboard中Worker的“日志”(Logs)页面,查看详细的错误信息。 |
| 流式输出中断或不完整 | 1. 网络连接不稳定。 2. Worker处理流式响应时出现错误。 3. 客户端处理流的方式有问题。 |
1. 检查网络。 2. 查看Worker日志,看是否有未捕获的异常。 3. 使用 curl 或简单的测试脚本验证代理的流式响应是否正常: curl -N -X POST ... -H \"Accept: text/event-stream\" ... 。 |
| 联网搜索功能不生效 | 1. 搜索语法错误。 2. 搜索服务不可用或返回错误。 3. 搜索次数已达上限。 |
1. 确认请求内容中包含了正确的 WS[查询词] 格式,括号为英文半角。 2. 查看Worker日志,搜索请求是否发出,返回状态码是什么。可能需要检查搜索服务API密钥和额度。 3. 检查代码中的搜索限制逻辑。 |
| 响应速度非常慢 | 1. 启用了联网搜索。 2. 模型负载高(如使用GPT-4)。 3. Worker冷启动。 |
1. 这是搜索功能的预期行为。如非必要,避免使用。 2. 尝试切换到 gpt-3.5-turbo 模型对比。 3. 对于免费Worker,不活跃时会进入“休眠”,首次请求会有冷启动延迟。保持一定频率的请求可以缓解。 |
5.3 性能优化与成本控制建议
- 合理设置超时与重试 :在Worker代码中,当你向后端API(OpenAI)发起
fetch请求时,可以设置一个合理的超时(例如30秒),并考虑加入简单的重试逻辑(针对网络波动导致的5xx错误),但注意不要触发Cloudflare Worker自身的超时限制(免费版为10秒CPU时间,付费版更长)。 - 缓存常用结果 :对于一些通用、不常变的问题,可以考虑使用Cloudflare的KV(键值存储)或Cache API来缓存AI的回复。例如,将“用户问题+模型”作为键,将回复内容作为值缓存一段时间,可以极大减少对OpenAI API的调用,节省成本并提升响应速度。
- 监控API用量与成本 :定期查看OpenAI平台的使用仪表盘,监控Token消耗和费用。同时,可以在Worker代码中粗略计算每次请求的Token数(通过分析请求和响应体),并记录到日志中,以便分析。
- 使用压缩代码 :项目提供的
production.js是压缩后的版本,体积更小,加载和执行更快。在生产环境部署时,建议使用这个文件。 - 考虑备用路由 :如果
/v1路由对应的OpenAI API出现故障,可以快速在客户端将请求切换到/kamiya/v1路由(如果已配置),实现简单的故障转移。
部署并运行这个ChatGPT代理Worker几个月下来,最大的体会是它将复杂的基础设施问题简化了。你不再需要维护服务器,全球访问速度有保障,还能灵活地加入自己的业务逻辑。对于独立开发者和小型项目来说,这是一个性价比极高的解决方案。当然,它也要求你对Cloudflare Workers和JavaScript有一定的了解,以便在出现问题时能够自主排查和调整。希望这篇详细的指南能帮你顺利搭建起自己的AI代理网关。
更多推荐



所有评论(0)