☰
服务器部署Hermes【超详细版本】(三):知识库、定时任务与故障排查
2026/10/11 13:16:06 网站建设 项目流程

1. 知识库接入:让 Hermes 真正读懂你的面试题库

很多人把 Hermes 跑起来、微信能回消息之后,就卡在下一步:怎么让它读我自己的资料?我一开始也以为把文件丢进目录就行,结果 Hermes 要么说找不到文件,要么读出来一堆乱码。这一节把知识库目录、索引配置、编码处理一次讲清楚,你照着做就能让 Hermes 稳定读取/opt/data/interview下的题库。

先说清楚一个核心概念:Hermes 在容器里跑,它眼里的路径和你 SSH 登录后看到的路径不是一回事。这是 Docker volume 映射造成的,也是新手最容易翻车的地方。你的 Compose 文件里通常有这一行:

volumes: - /root/.hermes:/opt/data

它的意思是:宿主机的/root/.hermes目录,挂载成容器内的/opt/data。所以你在 SSH 里操作/root/.hermes/interview/questions.md,Hermes 在提示词里必须写成/opt/data/interview/questions.md。这两个路径指向同一个文件,但写错了 Hermes 就找不到。

我试过在提示词里写宿主机路径,Hermes 直接回我「文件不存在」,排查了半小时才反应过来是路径视角问题。记住这张对照表:

宿主机路径(SSH 用)容器内路径(Hermes 用)
/root/.hermes/opt/data
/root/.hermes/interview/opt/data/interview
/root/.hermes/interview/questions.md/opt/data/interview/questions.md
/root/.hermes/.env/opt/data/.env

建目录很简单,一条命令:

mkdir -p /root/.hermes/interview

-p的作用是父目录不存在就一起建,目录已存在也不报错。然后写一个测试题库文件,用 heredoc 一次写入:

cat > /root/.hermes/interview/questions.md <<'EOF' # 已看过的面试题 ## Java - 题目:HashMap 1.7 和 1.8 的主要区别? 答案要点:数组+链表/红黑树、头插/尾插、扩容机制、并发风险。 - 题目:synchronized 和 ReentrantLock 的区别? 答案要点:可重入、公平锁、条件队列、可中断、锁释放、实现机制。 ## MySQL - 题目:B+ 树索引为什么适合数据库? 答案要点:磁盘 IO、范围查询、叶子节点链表、树高低、稳定查询效率。 ## Redis - 题目:缓存穿透、击穿、雪崩分别是什么?怎么解决? 答案要点:布隆过滤器、空值缓存、互斥锁、逻辑过期、随机 TTL、多级缓存。 EOF

写完之后,从两个视角各验证一次。宿主机视角:

cat /root/.hermes/interview/questions.md

容器视角:

docker exec -it hermes sh -lc 'cat /opt/data/interview/questions.md'

如果两条命令都能看到内容,说明映射正常,知识库接入这一步就通了。这一步是整个定时任务的地基,地基不稳后面全是坑。

关于文件格式,Hermes 能读.md和.txt,但有两个隐藏问题必须提前处理。第一是编码,中文 txt 经常是 GBK 或 GB2312,Hermes 按 UTF-8 读会乱码。先用file命令确认:

file /root/.hermes/interview/你的文件.txt

如果显示ISO-8859或Non-ISO extended-ASCII,基本就是 GBK 系。转码:

iconv -f gbk -t utf-8 /root/.hermes/interview/原文件.txt > /root/.hermes/interview/转换后文件.txt

第二是安全审批。Hermes 读文件时可能调用python3 -c "open(...)"这类命令,它会认为需要人工批准,任务就暂停了。这时候你在微信里回/approve放行即可。但要注意,只有读取自己题库目录这种命令才放心批准;如果命令里出现rm -rf、curl ... | sh、cat /opt/data/.env、cat ~/.ssh/id_rsa这类,千万别随手/approve,尤其是读.env、API Key、私钥的,直接/deny。

题库内容建议按「题目 + 答案要点」的结构组织,并在提示词里告诉 Hermes 优先识别「题目」「问题」「面试题」「问:」「Q:」「Q:」这些关键词附近的内容。这样抽题时命中率更高,不会把答案要点当成题目发给你。整理得越规整,后面定时抽题的效果越稳定。

2. 定时任务编排:cron 表达式与微信投递配置

知识库通了之后,下一步是让 Hermes 定时抽题发微信。这里我踩过最大的坑,就是用自然语言在微信里创建任务。当时我发的是「请每隔一小时抽一道题发给我复习」,Hermes 自作主张设计成「先建脚本再建 cron」,结果脚本没写成功,cron 指向一个不存在的文件,报错Script not found: /opt/data/scripts/check_and_send.sh。

所以结论很明确:cron 任务用 SSH 命令行创建,别用微信自然语言创建。命令行可控、可复现、可排查。

先看 cron 支持哪些子命令:

docker run -it --rm \ -v /root/.hermes:/opt/data \ -e TZ=Asia/Shanghai \ nousresearch/hermes-agent cron --help

输出里能看到list、create、add、edit、pause、resume、run、remove、rm、delete、status、tick这些子命令。再看创建命令的参数:

docker run -it --rm \ -v /root/.hermes:/opt/data \ -e TZ=Asia/Shanghai \ nousresearch/hermes-agent cron create --help

关键参数对照:

参数作用
--name NAME任务名称,方便列表识别
--deliver DELIVER投递目标,决定结果发到哪
--repeat REPEAT重复次数
--skill SKILLS附加 skill
--script SCRIPT执行脚本
--no-agent跳过 LLM,只执行脚本
--workdir WORKDIR指定工作目录
schedulecron 表达式
prompt任务提示词

--deliver是最容易配错的地方。它的取值有local、origin、weixin:chat_id、telegram、discord等。我第一次创建时没加--deliver,cron list显示Deliver: local,任务创建成功了但微信一条都没收到。因为local表示只在本地输出,根本不发微信。要发微信必须写成weixin:你的chat_id。

chat_id 从哪来?微信/sethome成功后,日志或回复里会出现类似o9cq80y9HMRyFHDRQ5NMyWk8cYcc@im.wechat的字符串,这就是当前私聊会话的 chat_id。投递时写成weixin:o9cq80y9HMRyFHDRQ5NMyWk8cYcc@im.wechat。

cron 表达式是五段式:分 时 日 月 周。常用写法:

表达式含义
0 * * * *每小时整点
*/30 * * * *每 30 分钟
0 9 * * *每天 9:00
0 21 * * *每天 21:00
0 9 * * 1-5工作日每天 9:00
0 9,21 * * *每天 9:00 和 21:00

现在创建一个每小时抽一道题的完整任务:

docker run -it --rm \ -v /root/.hermes:/opt/data \ -e TZ=Asia/Shanghai \ nousresearch/hermes-agent cron create \ --name "面试题复习" \ --deliver "weixin:o9cq80y9HMRyFHDRQ5NMyWk8cYcc@im.wechat" \ "0 * * * *" \ "请阅读 /opt/data/interview/ 目录下的 txt、md 文件,从里面随机抽取一道我已看过的面试题发给我复习。要求:只发题目,不要直接发答案;如果无法读取文件,请明确告诉我原因。"

逐段解释:docker run -it --rm启动临时容器执行完就删;-v /root/.hermes:/opt/data挂载数据目录,保证 CLI 操作的是和 gateway 同一份数据;-e TZ=Asia/Shanghai用北京时间;nousresearch/hermes-agent cron create调用创建命令;后面依次是名称、投递目标、cron 表达式、提示词。

提示词必须自包含,写清楚读哪个目录、读什么类型、抽什么内容、发不发答案、失败怎么办。别指望 Hermes 猜你的意图。

再给两个实用模板。每天早上 9 点抽 3 道:

docker run -it --rm \ -v /root/.hermes:/opt/data \ -e TZ=Asia/Shanghai \ nousresearch/hermes-agent cron create \ --name "每日面试题早练" \ --deliver "weixin:o9cq80y9HMRyFHDRQ5NMyWk8cYcc@im.wechat" \ "0 9 * * *" \ "请阅读 /opt/data/interview/ 目录下的 txt、md 文件,随机抽取 3 道我已看过的面试题发给我复习。只发题目,不发答案;题目按 1、2、3 编号;最后提醒我回复「批改面试题:我的答案是...」后你再根据题库内容批改。"

晚上 9 点复盘提醒:

docker run -it --rm \ -v /root/.hermes:/opt/data \ -e TZ=Asia/Shanghai \ nousresearch/hermes-agent cron create \ --name "面试题晚间复盘" \ --deliver "weixin:o9cq80y9HMRyFHDRQ5NMyWk8cYcc@im.wechat" \ "0 21 * * *" \ "提醒我复盘今天的面试题。请让我先回忆今天做过的题,不要直接给答案。提醒我可以回复「复盘:...」来让你帮我检查遗漏点。"

任务管理命令也一并给你。查看列表:

docker run -it --rm \ -v /root/.hermes:/opt/data \ -e TZ=Asia/Shanghai \ nousresearch/hermes-agent cron list

重点看[active]、Schedule、Next run、Deliver四项。删除任务:

docker run -it --rm \ -v /root/.hermes:/opt/data \ -e TZ=Asia/Shanghai \ nousresearch/hermes-agent cron remove 任务ID

暂停和恢复:

docker run -it --rm -v /root/.hermes:/opt/data -e TZ=Asia/Shanghai nousresearch/hermes-agent cron pause 任务ID docker run -it --rm -v /root/.hermes:/opt/data -e TZ=Asia/Shanghai nousresearch/hermes-agent cron resume 任务ID

手动触发:

docker run -it --rm \ -v /root/.hermes:/opt/data \ -e TZ=Asia/Shanghai \ nousresearch/hermes-agent cron run 任务ID

注意cron run不是立即执行,它只是把任务标记为「下一个 scheduler tick 执行」,输出类似It will run on the next scheduler tick.。所以要等一会儿,并盯 gateway 日志。

这里有个细节:别用docker exec hermes hermes cron list这种写法。之前执行docker exec -it hermes hermes pairing list报过exec: "hermes": executable file not found in $PATH。原因是docker run nousresearch/hermes-agent ...会走镜像 entrypoint,能正确执行 Hermes CLI,而docker exec直接找可执行文件会失败。统一用docker run那套模板最稳。

3. 可复制配置:.env 授权与 Compose 常驻

任务创建好了、deliver 也配成微信了,但微信还是收不到,这时候八成是授权问题。日志里会出现:

WARNING gateway.run: No user allowlists configured. All unauthorized users will be denied. WARNING gateway.run: Unauthorized user: o9cq80y9HMRyFHDRQ5NMyWk8cYcc@im.wechat

这说明 cron 没失败、deliver 没配错,而是微信用户被 gateway 判定为未授权。未授权会影响普通消息、slash command、cron 投递、主动推送全部链路。所以修授权是打通闭环的关键一步。

编辑.env:

nano /root/.hermes/.env

追加或确认这几行:

WEIXIN_ALLOWED_USERS=o9cq80y9HMRyFHDRQ5NMyWk8cYcc@im.wechat WEIXIN_DM_POLICY=pairing WEIXIN_GROUP_POLICY=disabled TZ=Asia/Shanghai

注意变量名可能因版本不同而不同。日志里还提示过一个全局开关GATEWAY_ALLOW_ALL_USERS=true,临时排查时可以用它确认问题是不是授权导致的:

GATEWAY_ALLOW_ALL_USERS=true

但长期千万别留着这个开关,它等于允许任何未授权用户调用你的 Hermes,会消耗你的 API Key。排查完立刻改回只允许自己的微信 ID。

改完.env必须重启 gateway 才生效:

docker compose -f /root/compose.hermes.yml restart hermes

重启会中断当前任务,微信可能收到Gateway shutting down — Your current task will be interrupted.,这是正常提示。

Compose 文件本身也给你一份参考结构,重点是 volume 映射和常驻:

services: hermes: image: nousresearch/hermes-agent container_name: hermes restart: unless-stopped environment: - TZ=Asia/Shanghai volumes: - /root/.hermes:/opt/data command: gateway

restart: unless-stopped保证服务器重启后 Hermes 自动拉起,这是长期稳定运行的基础。启动用:

docker compose -f /root/compose.hermes.yml up -d

看日志:

docker compose -f /root/compose.hermes.yml logs -f hermes

只看最近 300 行里和 cron、微信、授权、错误相关的:

docker compose -f /root/compose.hermes.yml logs --tail=300 hermes | grep -Ei "cron|weixin|deliver|auth|unauthorized|error|scheduler|job"

这里要澄清一个误导性提示。执行 CLI 的cron list时可能看到:

Gateway is not running — jobs won't fire automatically. Start it with: hermes gateway install

别慌。我们不是宿主机原生安装 Hermes,而是用 Compose 跑 gateway。CLI 临时容器看不到另一个 Compose 容器里的 gateway 状态,所以误报。判断 gateway 是否真在运行,看两个东西:docker ps里有没有hermes Up ...,以及微信普通聊天能不能用。这两个正常,gateway 就是好的。

如果你用的是 Claude Code 或 Cline 这类工具配合 Hermes 做编码任务,配置三件套要写全:Base URL、Key、Model ID。以 TaoToken 为例,Base URL 填https://taotoken.net/api,Key 在控制台生成,Model ID 按你选的模型填。这三样缺一个都会报 401 或模型找不到。配置片段参考:

{ "base_url": "https://taotoken.net/api", "api_key": "你的Key", "model": "你的Model ID" }

Codex 的auth.json也是同样逻辑,Base URL、Key、Model ID 三件套齐全才能正常调用。Cline 的 MCP 配置同理,别只填一半。

4. 验证请求:从手动触发到微信收到题目

配置都齐了,怎么确认整条链路真的通了?别等整点,直接手动触发最快。先确认任务存在且 deliver 正确:

docker run -it --rm \ -v /root/.hermes:/opt/data \ -e TZ=Asia/Shanghai \ nousresearch/hermes-agent cron list

正常输出类似:

97c0d4aef80d [active] Name: 面试题复习 Schedule: 0 * * * * Repeat: ∞ Next run: 2026-05-08T17:00:00+08:00 Deliver: weixin:o9cq80y9HMRyFHDRQ5NMyWk8cYcc@im.wechat

重点看Deliver那行,必须是weixin:...,如果是local就删了重建。

然后手动触发:

docker run -it --rm \ -v /root/.hermes:/opt/data \ -e TZ=Asia/Shanghai \ nousresearch/hermes-agent cron run 97c0d4aef80d

输出类似:

Triggered job: 面试题复习 (97c0d4aef80d) Next run: 2026-05-08T16:10:13.316515+08:00 It will run on the next scheduler tick.

这时候别急着看微信,先盯日志:

docker compose -f /root/compose.hermes.yml logs -f hermes

等 scheduler tick 处理完,日志里应该能看到任务执行、读取文件、投递微信的记录。如果一切正常,微信会收到一道题目,只有题目没有答案。

验证成功的结果长这样:微信收到类似「题目:HashMap 1.7 和 1.8 的主要区别?」的消息,没有答案要点。同时日志里没有Unauthorized user,没有Script not found,没有reading choices之类的报错。

如果想让验证更彻底,可以分三步走。第一步,微信发/status,确认普通命令可用。第二步,微信发「你好」,确认普通聊天可用。第三步,手动触发 cron,确认定时投递可用。三步都过,闭环就成立了。

这里补充一个模型调用验证的小技巧。如果你怀疑是模型侧的问题(比如返回空、报reading choices错误),可以先用模型对话功能单独测一下模型是否正常。TaoToken 的模型对话入口可以直接发一条测试消息,确认 Base URL、Key、Model ID 三件套没问题,再回来排查 Hermes 侧。这样能把「模型不通」和「Hermes 配置不通」两类问题分开,排查效率高很多。

验证通过后,最小可用闭环就是这五步:

# 1. 确认 gateway 正在运行 docker ps # 2. 确认微信普通聊天正常(微信发送 /status) # 3. 确认 cron 任务 deliver 到微信 docker run -it --rm -v /root/.hermes:/opt/data -e TZ=Asia/Shanghai nousresearch/hermes-agent cron list # 4. 手动触发 cron docker run -it --rm -v /root/.hermes:/opt/data -e TZ=Asia/Shanghai nousresearch/hermes-agent cron run 任务ID # 5. 查看日志 docker compose -f /root/compose.hermes.yml logs -f hermes

这五步都正常,就可以放心让它长期跑了。

5. 常见报错排查:401、Script not found、Unauthorized 对照清单

这一节把部署过程中真实遇到的报错逐个对照,给你一份能直接查的清单。每个报错都写清楚现象、原因、解决动作。

报错一:401 Unauthorized(模型侧)

现象:Hermes 回复报 401,或者日志里出现鉴权失败。原因通常是 Base URL、Key、Model ID 三件套没配全或配错。排查动作:确认 Base URL 是https://taotoken.net/api,Key 没有多余空格,Model ID 和你在控制台选的模型一致。三样都对还报 401,就去控制台重新生成 Key。

报错二:Script not found: /opt/data/scripts/check_and_send.sh

现象:cron 任务执行时报脚本不存在。原因:用自然语言创建任务时,Hermes 设计成「先建脚本再建 cron」,但脚本没真正写入磁盘。宿主机对应路径是/root/.hermes/scripts/check_and_send.sh,容器内是/opt/data/scripts/check_and_send.sh。解决:删掉这个任务,用cron create重建一个纯 prompt 型任务,不依赖脚本。命令:

docker run -it --rm -v /root/.hermes:/opt/data -e TZ=Asia/Shanghai nousresearch/hermes-agent cron remove 任务ID

然后按第 2 节的模板重建。

报错三:Unauthorized user: xxx@im.wechat

现象:cron deliver 是微信,但微信收不到,日志出现未授权。原因:微信用户没进 allowlist。解决:编辑/root/.hermes/.env,加WEIXIN_ALLOWED_USERS=你的chat_id,重启 gateway。临时排查可加GATEWAY_ALLOW_ALL_USERS=true,确认后立刻关掉。

报错四:Unknown command: /cron

现象:微信里发/cron remove xxx,回复未知命令。原因:Weixin Gateway 没把/cron识别为管理命令,可能是平台不支持全部 slash command、用户未授权、命令注册不完整或版本差异。解决:别用微信管理 cron,用 SSH 管理。微信只负责聊天和接收提醒,SSH 负责 cron 增删改查,这是目前最稳的分工。

报错五:Gateway is not running — jobs won't fire automatically

现象:CLI 的cron list提示 gateway 没运行。原因:CLI 临时容器看不到 Compose 容器里的 gateway,误报。解决:用docker ps看hermes Up ...,用微信普通聊天验证,别被这条提示带偏。

报错六:reading choices 相关错误

现象:模型返回解析异常,日志出现reading choices字样。原因:通常是模型返回结构不符合预期,或 Base URL/Model ID 配错导致返回了非预期内容。排查:先用模型对话单独测模型,确认返回正常;再检查 Hermes 里的模型配置是否和测试时一致。

报错七:local proxy failed

现象:请求发不出去,日志出现 local proxy failed。原因:网络出口或代理配置问题。排查:确认服务器能正常访问https://taotoken.net/api,检查环境变量里有没有残留的代理设置干扰。清掉无关代理变量后重启 gateway。

报错八:OAuth 相关报错

现象:日志出现 OAuth 字样。原因:某些工具链的鉴权方式没配对。排查:确认你用的是 API Key 方式而不是 OAuth 方式,Base URL 和 Key 按第 3 节配置。如果工具强制走 OAuth,检查它的配置文件路径和字段名是否和文档一致。

报错九:任务卡住,微信提示 Agent is running

现象:当前 Agent 正在执行,其他命令进不来。解决:微信回/stop停止当前任务,或重启 gateway:

docker compose -f /root/compose.hermes.yml restart hermes

重启会中断当前任务,属正常。

报错十:cron run 后微信没马上收到

现象:手动触发后微信迟迟没消息。原因:cron run只是标记任务在下一个 scheduler tick 执行,不是立即执行。解决:等一会儿,盯日志:

docker compose -f /root/compose.hermes.yml logs -f hermes

报错十一:txt 文件读取乱码

现象:Hermes 读出来是乱码。原因:文件编码不是 UTF-8。解决:用file确认编码,用iconv -f gbk -t utf-8转码。

报错十二:安全审批卡住任务

现象:微信提示Command requires approval。解决:读取自己题库目录的命令可以/approve;涉及rm -rf、curl | sh、读.env、读私钥的,/deny或/stop。

排查顺序建议固定下来:先确认任务存在,再确认 deliver 不是 local,再确认 gateway 容器在跑,再确认微信普通聊天可用,再看日志有没有 unauthorized,最后手动触发。按这个顺序走,基本不会漏。

6. 长期稳定运行:把 Hermes 变成你的定时复习助手

前面五节把知识库、定时任务、授权、验证、排障都走了一遍。这一节说长期怎么用,让它真正变成每天帮你复习的工具,而不是部署完就吃灰。

先说文件管理。所有面试题统一放/root/.hermes/interview,支持.md和.txt,尽量用 UTF-8。题库格式建议统一成「题目 + 答案要点」,并在提示词里让 Hermes 优先识别「题目」「问题」「面试题」「问:」「Q:」「Q:」这些关键词。格式越规整,抽题越准。

再说服务管理。Hermes Gateway 用 Compose 常驻,restart: unless-stopped保证服务器重启后自动拉起。日常不用管它,需要重启时:

docker compose -f /root/compose.hermes.yml restart hermes

任务管理统一走 SSH,别用微信。查看所有任务:

docker run -it --rm \ -v /root/.hermes:/opt/data \ -e TZ=Asia/Shanghai \ nousresearch/hermes-agent cron list

重点检查[active]、Schedule、Next run、Deliver四项。删除、暂停、恢复、手动触发都用第 2 节的模板。

微信侧只做三件事:聊天、接收定时推送、回答题目请求批改。比如收到题目后回复「批改面试题:我的答案是...」,Hermes 会根据题库内容帮你检查遗漏点。这个闭环用起来很顺。

如果你想把 Hermes 的能力扩展到编码和 Agent 场景,长期跑的话建议用 Coding Plan,比按量调用更划算,适合每天都有定时任务和编码需求的场景。配置入口在控制台的 Coding Plan 页面,Base URL 和 Key 按第 3 节的三件套配齐。

最后给你一个我踩过的坑作为收尾。有次我改了.env里的 allowlist,忘了重启 gateway,结果排查了半天以为配置没生效。记住:改.env必须重启 gateway。还有一次我把--deliver写成了local,任务跑得好好的就是不发微信,删了重建才对。这两个坑记住,能省你不少时间。

现在你的 Hermes 应该已经能每天定时从题库抽题发微信了。接下来可以扩展的方向:根据你的回答自动批改、追问薄弱知识点、按知识点分类抽题、每周生成复习报告。这些都可以用同样的 cron + prompt 模式实现,把提示词写清楚就行。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询