Hermes Agent频频超时?一招教你解决API网络连通问题

0 阅读8分钟

你在本地或者云服务器上安装了 Hermes 或是龙虾等 agent,配置好了 Google AI Studio 的 API KEY 后,正当你想愉快的测试交流时,你发现了一个问题,那就是发出的对话迟迟得不到回应.....

这是因为,直接调用某些API 服务接口(比如 generativelanguage.googleapis.com)时,经常会遇到网络延迟或阻断的情况。程序就像在往一个无底洞里发送请求,由于没有收到明确的回复,所以它一直在等,最终导致超时。

废话不讲,直接开干

一、准备工作

准备一个属于自己的域名

二、原理

Cloudflare(CF)的边缘节点在常规网络环境下是可以稳定访问的。我们可以利用其 Serverless 平台写一小段代码(Worker)托管在 CF 上,让 CF 的云节点帮我们去请求目标接口,然后再把结果稳定地传回给本地应用。这也叫做接口代理或是请求转发。

三、步骤

我配置这个转发节点,主要是想体验 Hermes 调用大语言模型的功能。当然你也可以用来稳定访问其他由于网络波动难以直连的服务接口,原理都是相通的。下面是具体步骤:

(1)注册一个免费的 Cloudflare 账号。

在这里插入图片描述

(2)创建 Worker

  1. 在左侧菜单找到 Workers & Pages,点击 Create application,创建一个新的 Worker 在这里插入图片描述

  2. 点击 Start with Hello World!会给出一个示例 Worker 在这里插入图片描述

  3. Worker name 输入框保持默认(你也可以自己改一个好记的,比如 api-forwarder),Worker preview 先保持默认,点击 Deploy 在这里插入图片描述

  4. 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 中转 -> 目标服务 的网络链路就已经搭建打通了!

  1. 点击右上角的 "Deploy" (或者 Save and deploy) 按钮,将你的转发代码正式发布。 在这里插入图片描述

  2. 部署完成后,返回这个 Worker 的概览页面,你会看到一个系统分配给你的专属链接(格式大概是 https://项目名.xxx.workers.dev)。

  3. 大功告成?

是不是就直接可以通过 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 添加你的域名
  1. 登录你的 Cloudflare 控制台,在左侧导航栏点击 "Websites" (网站),然后点击右上角的蓝色按钮 "Add a Site" (添加站点)

  2. 输入你的根域名(比如 example.com ,不要加 www 也不要加 api),点击 Continue。 在这里插入图片描述

  3. 选择 "Free" (免费计划)在这里插入图片描述

  4. Cloudflare 会自动扫描你现有的 DNS 记录,不管它扫出了什么,或者什么都没有,直接点击底部 Continue to activation。然后点击 Confirm 在这里插入图片描述

  5. 关键一步:此时页面会显示出两个分配给你的 名称服务器 (Nameservers)(例如 kara.ns.cloudflare.compam.ns.cloudflare.com)。把这两个地址复制下来,页面先不要关。 在这里插入图片描述

🔵 第二阶段:去你的域名服务商修改 DNS 服务器
  1. 新开一个网页标签,登录你的域名提供商(如阿里云/腾讯云)控制台。在这里插入图片描述

  2. 找到你配置的域名,点击管理。

  3. 在左侧菜单中找到 “DNS修改”“修改DNS服务器”

  4. 将里面默认的提供商 DNS 地址删掉。

  5. 把刚才在 Cloudflare 复制的那两个 Cloudflare 名称服务器粘贴进去,保存确认。 在这里插入图片描述

🟣 第三阶段:等待生效与绑定 Worker

修改 DNS 后,全球解析同步需要一点时间(通常 5 分钟左右生效)。

  1. 回到刚才的 Cloudflare 页面,点击 "Check nameservers" (检查名称服务器)在这里插入图片描述

  2. 如果修改成功,你的域名状态会变成绿色的 "Active" (活跃)在这里插入图片描述

  3. 确认域名活跃后,点击左侧导航栏的 "Workers & Pages",进入你之前创建的那个转发项目。

  4. 点击 Settings (设置) -> Domains & Routes (域名和路由) -> **点击 + add ->点击Custom Domains (自定义域) 在这里插入图片描述

  5. 在输入框里,为你这个代理起一个子域名,比如:api.你的域名.com (强烈建议用 api 开头,易于区分)。

  6. 点击 "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 访问该接口,拦截其他一切来源”。

具体操作步骤(强烈建议配置):

  1. 登录控制台,进入你的域名管理面板。

  2. 在左侧菜单找到安全性相关配置,点击 Configure Web Application Firewall在这里插入图片描述

    不要点击左侧菜单中的 Application Security (安全性) 这是为企业准备的。

  3. 点击 Create rule (创建规则)

  4. 命名规则:填入规则名字,比如 WhiteList_Rules

  5. 配置触发条件

    • Field (字段): 选择 IP Source Address (源 IP 地址)
    • Operator (运算符): 选择 does not equal (不等于)
    • Value (值): 填入你本地电脑或云服务器的具体公网 IP
  6. 选择操作 (Choose action):在下方选择 Block (阻止)

  7. 点击右下角 Deploy (部署)在这里插入图片描述

这条规则的意思是:如果发出请求的设备 IP 不是我们设置自己专用的 IP,WAF 就直接将其流量掐断。 这样一来,就能从根源防止转发接口被他人滥用盗刷。

四、总结

到现在,我们成功解决了本地调用海外接口超时和延迟过高的问题。

这套打法思路跑通后,不仅仅能用于 Hermes 进行稳定的多轮会话测试,其他各类针对接口连通性要求高、受特定网络环境限制明显的开发调试工作,都可以采用同一套模型去构建专属的中转加速节点。

免责声明: 本文仅作为网络通信底层原理与 Serverless 技术架构的技术探讨。请读者遵守当地法律法规,切勿将相关技术用于非法用途或恶意突破网络安全管理规定。