用 Cloudflare Workers 定时启停 Hermes Cloud 完整教程
Hermes Cloud 可以在自己的 Nous 托管平台托管 Agent,不过与 OD 等提供hermes 托管的云服务商家收取定额月付不一样,Hermes 在 Nous Portal 常驻运行时会计入计算费和存储费;实例停止后只保留存储费。对于每天只在固定时段使用的实例,定时停止能把非使用时段从运行计费切换为停止计费。
实例每天运行 8 小时、停止 16 小时。没有全天在线需求时,这 16 小时不必继续承担计算时间。后文的定时规则不是为了让 Hermes 更方便地开关,而是为了稳定地执行这段运行/停止计费切换。实例费用按日、按实际运行时间计;停止后仅收存储费。停止实例的公开价格是 $0.03/天,连续保留 30 天约 $0.90;这属于持续保留实例的实际最低成本,不是合同式“最低月供”。Small 实例持续运行则约 $0.29/天,30 天约 $8.70,还不含模型推理和工具调用。Nous Plus 的 $20/月 是可选订阅,不是为了使用 Hermes Cloud 而必须购买;云托管会从 Credits 单独扣除。
Hermes Cloud 支持在 Nous Portal 手动启动和停止实例,但后台暂时不能按多个时段自动切换服务器状态。通过用 Cloudflare Workers 的免费资源做云实例级启停,电脑关机或离线也不影响执行。
相关阅读Hermes Agent 搭配官方自有Nous Portal,API、云端工具与 Hermes Cloud 托管,Plus 邀请首月 5 美元这并不适合所有实例。Telegram、Webhook、全天 Cron 或需要随时响应的 Hermes 任务,必须安排在运行时段内;如果这些工作不能中断,就不应按本文方式停止整台实例。
定时表
| 北京时间 | 实例动作 | 下一时段 |
|---|---|---|
| 08:00 | 启动 | 运行到 10:00 |
| 10:00 | 停止 | 停止到 17:00 |
| 17:00 | 启动 | 运行到 23:00 |
| 23:00 | 停止 | 停止到次日 08:00 |
这里停止的不是 Hermes 里的某个任务,而是承载 Hermes 的云实例。实例停止后,聊天、Cron、消息渠道和其他依赖在线进程的任务都会停下;重新启动后,持久化数据仍会保留。

操作思路
操作不复杂:
- Cloudflare Cron Triggers 到点唤醒 Worker。
- Worker 按实际 UTC 小时判断目标状态,不直接依赖可能延迟到达的触发事件。
- Worker 使用加密保存的 OAuth 刷新令牌连接 Nous Portal MCP。
- Worker 只对预先固定的实例执行
start或stop,随后同时核对 Hermes 状态和底层计算状态。
Cloudflare Pages 适合托管静态网页,不负责执行这类定时控制任务;这里用的是 Workers。Cron Trigger 会调用 Worker 的 scheduled() 处理器,Cron 时间统一按 UTC 解释。
开始前需要准备什么
- Cloudflare 账户,免费 Workers 计划即可。
- 已创建的 Hermes Cloud 实例。
- 能登录 Nous Portal 的浏览器。
- 本地 Node.js 18 或更高版本,仅用于首次 OAuth 授权。
- 目标实例的 ID 和名称。
Nous 官方 MCP 可以读取实例状态,也能启动、停止、重启、创建和销毁实例。OAuth 权限面比本文的用途更宽,因此示例将目标 ID 与名称固定,控制入口也只接受 start、stop 两个动作。查看 Hermes Cloud MCP 官方说明
第一步:创建 Worker、KV 和两个密钥
在 Cloudflare 后台打开“Workers 和 Pages”,新建一个 Worker,例如 hermes-cloud-scheduler。
创建一个 Workers KV 命名空间,例如 HERMES_SCHEDULER_STATE,再回到 Worker 的“设置”页面添加 KV 绑定:
变量名:STATE
KV 命名空间:HERMES_SCHEDULER_STATE
然后添加两个加密密钥:
ADMIN_KEY
ENCRYPTION_KEY
在本地生成两个随机值:
openssl rand -hex 32
openssl rand -base64 32
第一行结果用于 ADMIN_KEY,第二行结果用于 ENCRYPTION_KEY。不要把真实值写进 Worker 源码、文章、截图、URL 或公开代码仓库。
KV 用于保存 OAuth 客户端、访问令牌、刷新令牌、启用状态和最近一次执行结果。示例 Worker 先用 AES-GCM 加密,再写入 KV;加密密钥只保存在 Cloudflare Secret 中。
第二步:部署 Worker 代码
部署前先在示例 Worker 中填入这两个值:
const TARGET_ID = 'REPLACE_WITH_YOUR_INSTANCE_ID';
const TARGET_NAME = 'REPLACE_WITH_YOUR_INSTANCE_NAME';
将代码粘贴到 Cloudflare 的 Worker 编辑器并部署。示例已做了这些限制:
- 公共首页只能看到服务版本、时区和时间表,不能控制实例。
- 管理请求必须在
Authorization请求头中携带ADMIN_KEY。 - 不接受从 URL 查询参数传入管理员密钥。
- 目标实例同时校验 ID 与名称。
- 只允许启动和停止,不开放创建、销毁或任意实例 ID。
- 每次执行前读取状态,执行后继续轮询计算状态,失败最多重试三次。
- OAuth 访问令牌接近过期时自动刷新。
程序按实际执行时的当前时间决定目标状态。某次触发即使延迟到达,也不会在错误时段把实例重新启动。
第三步:完成一次 OAuth 授权
Nous Portal MCP 使用 OAuth、PKCE 和动态客户端注册。首次连接需要在浏览器中授权,之后由刷新令牌续期,电脑无需持续在线。
本次部署时,OAuth 客户端注册只接受 localhost 或 127.0.0.1 回调,不能直接使用 Cloudflare Worker 地址。做法是让本机接收一次回调,再把授权结果传给 Worker 的受保护 /bootstrap 入口。
将以下三个文件放进同一目录:
- OAuth 初始化脚本(其中保存 Worker 地址)
- 本地密钥配置文件,复制后改名为
setup-secrets.json - 已部署的 Worker 地址
编辑 oauth-setup-example.mjs 中的 Worker 地址,并在 setup-secrets.json 填入刚才生成的两个值。然后运行:
node oauth-setup-example.mjs
脚本会在 127.0.0.1:18764 启动一次性回调,并生成 authorize-url.txt。在浏览器中打开该地址,登录 Nous Portal,选择目标实例所在的组织并授权。完成后,脚本会把 OAuth 客户端和令牌传给 Worker,由 Worker 加密写入 KV。
完成后删除本地的 authorize-url.txt、oauth-checkpoint.json 和包含真实密钥的 setup-secrets.json,或至少将它们移动到受保护的密码库。/bootstrap 在已有令牌时会拒绝重复导入。
第四步:启用调度配置
OAuth 导入成功后,使用管理员请求启用调度:
export WORKER_URL="https://你的Worker.workers.dev"
export ADMIN_KEY="你的管理员密钥"
curl -X POST "$WORKER_URL/configure" \
-H "Authorization: Bearer $ADMIN_KEY" \
-H "Content-Type: application/json" \
--data '{"enabled":true}'
启用前,Worker 会先检查目标实例身份。ID 或名称不匹配时会报错,不保存启用状态。
第五步:添加北京时间定时规则
Cloudflare Cron 使用 UTC。北京时间是 UTC+8,因此需要这样换算:
| 北京时间 | UTC | 动作 |
|---|---|---|
| 08:00 | 00:00 | 启动 |
| 10:00 | 02:00 | 停止 |
| 17:00 | 09:00 | 启动 |
| 23:00 | 15:00 | 停止 |
进入 Worker 的“设置”→“触发事件”→“Cron 触发器”,添加一条规则:
0 0,2,9,15 * * *
一条表达式即可覆盖每天四个时间点,无需建立四条规则。新增或修改 Cron 后,Cloudflare 最多可能需要 15 分钟完成传播。

第六步:先手动验证,再等待定时触发
先访问 Worker 公共首页,确认版本、时区和时间表。该页面不返回实例 ID、令牌或控制接口。

再使用管理员请求查看内部状态:
curl "$WORKER_URL/status" \
-H "Authorization: Bearer $ADMIN_KEY"
正式启用前,分别执行一次真实停止和启动:
curl -X POST "$WORKER_URL/control" \
-H "Authorization: Bearer $ADMIN_KEY" \
-H "Content-Type: application/json" \
--data '{"action":"stop"}'
curl -X POST "$WORKER_URL/control" \
-H "Authorization: Bearer $ADMIN_KEY" \
-H "Content-Type: application/json" \
--data '{"action":"start"}'
验证时不要只看 RUNNING 或 STOPPED,还要确认底层计算状态已经变为 Running 或 Stopped。实例状态和云计算状态之间可能相差数秒。
这套方案每天消耗多少模型 token
部署过程和日常运行的用量需要分开看。
| 环节 | 模型 token 消耗 |
|---|---|
| Cloudflare 每天四次 Cron 唤醒 | 0 |
| Worker 查询实例状态 | 0 |
| Worker 调用 MCP 启动或停止实例 | 0 |
| OAuth 刷新令牌 | 0 |
| 实例启动后,Hermes 执行聊天、Cron、搜索或其他 AI 任务 | 按实际模型和工具用量计费 |
| 使用 Codex 或其他 AI 帮助首次写代码、排错和部署 | 不固定,取决于对话长度、上下文和返工次数 |
定时 Worker 直接调用 Nous Portal 的 MCP 生命周期接口,不向模型发送提示词,也不要求模型生成回答。因此,自动启停本身不产生模型 token。Cloudflare 记录的是 Worker 请求和计算用量,不是 LLM token。
本次搭建使用了 Codex 协助,但当前任务没有可核验的单次对话 token 明细,不能根据代码长度反推准确数字。手动照本文部署不需要额外 AI token;如果交由 Codex 全程操作,用量会随所用模型、上下文长度和排错次数变化。
Cloudflare 免费额度够不够
以这套用量看,免费额度足够。每天只有四次计划触发,再加少量人工状态检查。Cloudflare Workers Free 当前提供每天 100,000 次请求、每账户 5 个 Cron 触发器;网络等待时间不计入 Worker CPU 时间。
本方案只占一条 Cron 规则。若账户中已有其他 Worker 定时任务,先检查全账户的 Cron 数量;免费额度按账户统计,并非每个 Worker 各有 5 条。
Hermes Cloud 一天大约能省多少
Nous 的公开计费说明为:运行状态按实际在线秒数收取计算费和存储费,停止状态只收存储费;账单按 UTC 日汇总,模型推理和工具调用另计。查看 Hermes Cloud 计费说明
每天运行 8 小时、停止 16 小时,可以用下面的公式估算:
每日实例费用 = 运行日价 × 8/24 + 停止日价 × 16/24
设运行日价为 R、停止日价为 S,本文时段的每日费用就是 R/3 + 2S/3;连续 30 天约为 10R + 20S。这只是实例费用,不含模型和工具用量。Nous 的公开介绍页目前没有列出固定规格价目表,账户后台也可能显示 Standard 等不同规格,计算时请使用自己账单中的运行价和停止价。
暂停或修改自动化
临时停用可以调用配置接口:
curl -X POST "$WORKER_URL/configure" \
-H "Authorization: Bearer $ADMIN_KEY" \
-H "Content-Type: application/json" \
--data '{"enabled":false}'
也可以在 Cloudflare 删除 Cron 触发器。两种方式都只会停止后续的自动操作,不会改变实例当前的运行状态。
修改时段时,同时调整 Cloudflare Cron 表达式和 Worker 中 desiredAction() 的运行时间窗口。只改 Cron、不改目标状态判断,延迟触发或人工补跑时可能得到错误结果。
常见问题与排查
Cron 保存失败并提示达到上限
检查账户下其他 Worker 的 Cron 规则。免费计划每个账户最多 5 个 Cron 触发器,旧 Worker 即使不再使用,只要规则还在就会占用名额。
授权完成后仍显示未连接
检查本机回调是否仍在监听 127.0.0.1:18764,OAuth 的 state 是否匹配,以及 /bootstrap 请求是否使用请求头而不是 URL 参数传递 ADMIN_KEY。
实例显示 STOPPED,但云计算状态还没停止
继续轮询底层 machine.state,直到进入 Stopped、Deallocated 等停止状态。示例 Worker 已包含轮询与重试,不要只依据 Hermes 的状态文字判断结果。
到点没有马上执行
新建或修改的 Cron 可能需要最多 15 分钟传播。进入 Cloudflare 的 Cron Events 和 Workers Logs 查看实际触发与错误记录。
实例停止后 Hermes 的定时任务还会运行吗
不会。本文停止的是承载 Hermes 的云实例,依赖在线进程的任务在停止时段无法执行。需要全天运行的任务应避开停止时段,或改由另一台持续在线的执行环境处理。
这套方案把每天固定的启停操作交给轻量 Worker。电脑离线不影响调度,日常启停也不产生模型 token;Hermes Cloud 只在需要的时段保持在线。







发表评论