你在本地或者云服务器上安装了 Hermes 或是龙虾等 agent,配置好了 Google AI Studio 的 API KEY 后,正当你想愉快的测试交流时,你发现了一个问题,那就是发出的对话迟迟得不到回应.....
这是因为,直接调用某些API 服务接口(比如 generativelanguage.googleapis.com)时,经常会遇到网络延迟或阻断的情况。程序就像在往一个无底洞里发送请求,由于没有收到明确的回复,所以它一直在等,最终导致超时。
废话不讲,直接开干
一、准备工作
准备一个属于自己的域名
二、原理
Cloudflare(CF)的边缘节点在常规网络环境下是可以稳定访问的。我们可以利用其 Serverless 平台写一小段代码(Worker)托管在 CF 上,让 CF 的云节点帮我们去请求目标接口,然后再把结果稳定地传回给本地应用。这也叫做接口代理或是请求转发。
三、步骤
我配置这个转发节点,主要是想体验 Hermes 调用大语言模型的功能。当然你也可以用来稳定访问其他由于网络波动难以直连的服务接口,原理都是相通的。下面是具体步骤:
(1)注册一个免费的 Cloudflare 账号。
(2)创建 Worker
-
在左侧菜单找到 Workers & Pages,点击 Create application,创建一个新的 Worker
-
点击 Start with Hello World!会给出一个示例 Worker
-
Worker name 输入框保持默认(你也可以自己改一个好记的,比如
api-forwarder),Worker preview 先保持默认,点击 Deploy -
Deploy 之后,点击右上角的 Edit code,把示例 Worker 里的默认代码删掉,替换成一段 API 请求转发脚本(在 GitHub 上能找到很多极简代码)
这里给出一段我使用的 js 脚本代码(你想访问其他 API 接口,就修改 targetHostname 的值):
export default {
async fetch(request, env, ctx) {
const url = new URL(request.url);
// 目标域名始终指向 Google API
const targetHostname = "generativelanguage.googleapis.com";
// ==========================================
// 1. 处理标准的 HTTP 请求 (Hermes 默认使用的模式)
// ==========================================
if (request.headers.get("Upgrade") !== "websocket") {
const targetUrl = `https://${targetHostname}${url.pathname}${url.search}`;
// 创建一个新的请求对象,继承原请求的所有方法、Header 和 Body
const proxyRequest = new Request(targetUrl, request);
// 直接把 Google 的 HTTP 响应透传回去
return fetch(proxyRequest);
}
// ==========================================
// 2. 处理 WebSocket 请求
// ==========================================
const targetUrl = `wss://${targetHostname}${url.pathname}${url.search}`;
console.log('Target WebSocket URL:', targetUrl);
const [client, proxy] = new WebSocketPair();
proxy.accept();
let pendingMessages = [];
const connectPromise = new Promise((resolve, reject) => {
const targetWebSocket = new WebSocket(targetUrl);
targetWebSocket.addEventListener("open", () => {
console.log('Connected to target server');
for (const message of pendingMessages) {
try { targetWebSocket.send(message); }
catch (error) { console.error('Error sending pending message:', error); }
}
pendingMessages = [];
resolve(targetWebSocket);
});
proxy.addEventListener("message", async (event) => {
if (targetWebSocket.readyState === WebSocket.OPEN) {
try { targetWebSocket.send(event.data); }
catch (error) { console.error('Error sending to gemini:', error); }
} else {
pendingMessages.push(event.data);
}
});
targetWebSocket.addEventListener("message", (event) => {
try {
if (proxy.readyState === WebSocket.OPEN) { proxy.send(event.data); }
} catch (error) { console.error('Error forwarding to client:', error); }
});
targetWebSocket.addEventListener("close", (event) => {
if (proxy.readyState === WebSocket.OPEN) { proxy.close(event.code, event.reason); }
});
proxy.addEventListener("close", (event) => {
if (targetWebSocket.readyState === WebSocket.OPEN) { targetWebSocket.close(event.code, event.reason); }
});
targetWebSocket.addEventListener("error", (error) => {
console.error('Gemini WebSocket error:', error.message);
});
});
ctx.waitUntil(connectPromise);
return new Response(null, {
status: 101,
webSocket: client,
});
},
};
代码粘贴上去之后,右侧显示 404 是没有问题的,这正是目标服务器真实返回的页面,因为你调用的是纯净 API 接口并没有网页前端,所以接口给你返回 404,这是正常的,不用担心 。
本地应用 -> Cloudflare 中转 -> 目标服务 的网络链路就已经搭建打通了!
-
点击右上角的 "Deploy" (或者 Save and deploy) 按钮,将你的转发代码正式发布。
-
部署完成后,返回这个 Worker 的概览页面,你会看到一个系统分配给你的专属链接(格式大概是
https://项目名.xxx.workers.dev)。 -
大功告成?
是不是就直接可以通过 https://项目名.xxx.workers.dev 在云服务器上调用相关的 API 服务了呢
于是你配置好了 API KEY 和 BASE_URL, 格式如下:
GOOGLE_API_KEY=AI....
GEMINI_BASE_URL=https://项目名.xxx.workers.dev/v1beta/openai
或者使用 cur 命令在终端调用
curl -v https://项目名.xxx.workers.dev/v1beta/openai/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <你的真实谷歌API密钥>" \
-d '{
"model": "gemini-1.5-flash",
"messages": [
{
"role": "user",
"content": "hello"
}
]
}'
如果你尝试一下的话,大概率会发现还是请求卡住并最终超时。这是因为 .workers.dev 这个域名后缀属于公共共享后缀,有时在个别网络环境下由于节点压力可能会出现连接重置的情况。所以我们需要绑定自己的域名。
(3)为你的 Workers 添加自定义域名
只需要简单配置,就可以让 Cloudflare 接管你的域名,自动生成安全证书,并把流量稳定路由到你的转发代码上。
🟢 第一阶段:在 Cloudflare 添加你的域名
-
登录你的 Cloudflare 控制台,在左侧导航栏点击 "Websites" (网站),然后点击右上角的蓝色按钮 "Add a Site" (添加站点)。
-
输入你的根域名(比如
example.com,不要加www也不要加api),点击 Continue。 -
选择 "Free" (免费计划)。
-
Cloudflare 会自动扫描你现有的 DNS 记录,不管它扫出了什么,或者什么都没有,直接点击底部 Continue to activation。然后点击 Confirm
-
关键一步:此时页面会显示出两个分配给你的 名称服务器 (Nameservers)(例如
kara.ns.cloudflare.com和pam.ns.cloudflare.com)。把这两个地址复制下来,页面先不要关。
🔵 第二阶段:去你的域名服务商修改 DNS 服务器
-
新开一个网页标签,登录你的域名提供商(如阿里云/腾讯云)控制台。
-
找到你配置的域名,点击管理。
-
在左侧菜单中找到 “DNS修改” 或 “修改DNS服务器”。
-
将里面默认的提供商 DNS 地址删掉。
-
把刚才在 Cloudflare 复制的那两个 Cloudflare 名称服务器粘贴进去,保存确认。
🟣 第三阶段:等待生效与绑定 Worker
修改 DNS 后,全球解析同步需要一点时间(通常 5 分钟左右生效)。
-
回到刚才的 Cloudflare 页面,点击 "Check nameservers" (检查名称服务器)。
-
如果修改成功,你的域名状态会变成绿色的 "Active" (活跃)。
-
确认域名活跃后,点击左侧导航栏的 "Workers & Pages",进入你之前创建的那个转发项目。
-
点击 Settings (设置) -> Domains & Routes (域名和路由) -> **点击
+ add->点击Custom Domains (自定义域) -
在输入框里,为你这个代理起一个子域名,比如:
api.你的域名.com(强烈建议用api开头,易于区分)。 -
点击 "Add Custom Domain"。平台会自动帮你搞定解析映射。
(4)🚀 唤醒你的 Hermes Agent
现在,回到你的云服务器终端, 重新配置好你的 BASE_URL:
GOOGLE_API_KEY=AI....
GEMINI_BASE_URL=https://api.example.com/v1beta/openai
此时再运行,即可丝滑畅快地得到回应!
(5)可能遇到的问题:为什么请求被返回 403 / 400?
在接入 Hermes Agent 或者自动化脚本时,你可能会发现,请求被服务端拦截了。重点排查方向在 "User-Agent" 上!
由于 Hermes 或是很多 Python SDK 发送请求时会携带诸如 OpenAI/Python x.x.x 这样的包标识。WAF看到这类标识且有频次特征时,可能会启动严格模式判定请求来源并非真实浏览器用户,从而进行拦截拦截。
解决方案很简单:在 Cloudflare 控制台对应域名的「安全性」(Security) 设置里,把 “Bot Fight Mode” (机器人攻击模式) 以及 Block AI bots (屏蔽 AI 机器人) 开关临时关掉,或配置通行白名单即可。
(6)如何给你的转发接口上锁?
因为链路是公开在互联网上的,如果别人知道了你分配的二级域名,是不是也可以蹭你的网络通道请求数据?
既然你的域名托管在具有强大防护能力的 Cloudflare 上,我们可以善用自带的 **WAF ** 功能限制访问权限。你可以设置一条简单规则:“仅允许我设定的 IP 访问该接口,拦截其他一切来源”。
具体操作步骤(强烈建议配置):
-
登录控制台,进入你的域名管理面板。
-
在左侧菜单找到安全性相关配置,点击 Configure Web Application Firewall。
不要点击左侧菜单中的 Application Security (安全性) 这是为企业准备的。
-
点击 Create rule (创建规则)。
-
命名规则:填入规则名字,比如
WhiteList_Rules。 -
配置触发条件:
- Field (字段): 选择
IP Source Address(源 IP 地址) - Operator (运算符): 选择
does not equal(不等于) - Value (值): 填入你本地电脑或云服务器的具体公网 IP。
- Field (字段): 选择
-
选择操作 (Choose action):在下方选择 Block (阻止)。
-
点击右下角 Deploy (部署)。
这条规则的意思是:如果发出请求的设备 IP 不是我们设置自己专用的 IP,WAF 就直接将其流量掐断。 这样一来,就能从根源防止转发接口被他人滥用盗刷。
四、总结
到现在,我们成功解决了本地调用海外接口超时和延迟过高的问题。
这套打法思路跑通后,不仅仅能用于 Hermes 进行稳定的多轮会话测试,其他各类针对接口连通性要求高、受特定网络环境限制明显的开发调试工作,都可以采用同一套模型去构建专属的中转加速节点。
免责声明: 本文仅作为网络通信底层原理与 Serverless 技术架构的技术探讨。请读者遵守当地法律法规,切勿将相关技术用于非法用途或恶意突破网络安全管理规定。