返回博客
HermesDebuggingObservabilityAI Agents

如何调试 Hermes Agent:日志、追踪与盲点

Hermes Agent 调试实战指南:日志在哪里、先看哪一份、如何阅读追踪树,以及可观测性目前仍然欠缺的部分。

作者:Hermify Team||阅读约 3 分钟
深色背景下的终端窗口,显示彩色的 Hermes Agent 审计日志树,高亮工具调用与错误

你的智能体行为怪异,该去哪里看?

Hermes Agent 有两种令人头疼的失败模式。第一种很吵:抛出带堆栈的异常,或启动即崩溃。第二种很安静:智能体给出一段看似连贯却错误的回复,调用了错误的工具,或在工具返回后径直沉默。吵的那种会出现在 errors.log 里。安静的那种才是真正的难题,它藏在那一次翻车会话的审计日志里。

本文是一份实用地图:日志在哪里、哪个文件对应哪种症状,以及周围那些能把 800 行 JSONL 变成人类可读内容的小工具。它同时点名当前仍然存在的盲点,让你清楚今天 Hermes 不会告诉你什么。

日志的位置

Hermes 写出的所有日志都落在你的 Hermes 主目录里,默认是 ~/.hermes/logs/(非默认 profile 则在 <profile>/logs/)。四个文件值得关注:

文件 级别 存放内容
agent.log INFO+ 智能体、工具与会话主活动。默认入口。
errors.log WARNING+ 仅告警和错误。用于快速定位"出事了"。
gateway.log INFO+ 仅 gateway 事件,Telegram/Discord/Slack 中每个用户的会话生命周期。
gui.log INFO+ 控制台、websocket 和 TUI-gateway 事件。

四个文件都由 Python 的 RotatingFileHandler 写入。当某个文件达到大小上限时,会滚动为 agent.log.1agent.log.2,直到配置的 backup_count。当前活跃文件永远是没有后缀名的那个。当你追查昨天的 bug 时,这一点很关键,因为"昨天"可能已经被滚动出去了。请把编号文件也一起拿走,不要只看当前的。

所有这一切的入口是 hermes_logging.setup_logging()。gateway 启动时以 mode="gateway" 调用它,只挂接文件 handler,从不挂控制台 handler。所以 hermes gateway start 按设计就是安静的。如果 gateway 看上去没反应,其实并没有。请对 gateway.log 做 tail。

先打开哪一份日志

由症状决定文件,而不是反过来。一个粗略的决策树:

  • 智能体启动崩溃,或请求返回 500。hermes logs errors --since 30m -f 打开 errors.log。堆栈最先落在这里。
  • 智能体回了话,但答案是错的。 跳过 errors.log。产生这条错回复的工具调用都在那次会话的 JSONL 会话转录里(见下一节的 trace-tree)。
  • Telegram 或 Discord 用户说"它不出声了"。 打开 gateway.log,按其会话过滤。hermes logs gateway --session abc123 可以收敛范围。
  • 控制台不刷新。 gui.log。websocket 掉线和 TUI-gateway 同步错误会最先在这里显现。
  • 完全不知道发生了什么。agent.log 执行 hermes logs -f,另开一个窗口盯 errors.log。绝大多数"我的智能体在做什么"的答案,都在一次 tail -f 之内。

hermes logs 这个 CLI 是你的伙伴。在实时调试时,下面这些 flag 物有所值:

hermes logs                              # agent.log 的最后 50 行
hermes logs -f                           # 实时跟踪 agent.log
hermes logs gateway -n 100               # gateway.log 的最后 100 行
hermes logs --level WARNING --since 1h   # 最近 1 小时的告警与错误
hermes logs --session abc123             # 按会话 id 收敛
hermes logs errors --since 30m -f        # 从 30 分钟前开始跟踪 errors.log
hermes logs list                         # 列出文件清单与大小

把会话读成一棵树,而不是一堵 JSONL 墙

会话结束后,它的完整轨迹会以每行一条 JSON 的形式写入会话转录文件。这是调试"看似连贯但错误"这一类 bug 最有用的产物,因为每一次模型调用、每一次工具调用及其结果都按顺序连带参数一起被记录下来。而它的原始形态也确实无法阅读。一个中等复杂度的会话产生 800 行审计日志是常态。

社区工具 trace-tree(参见 Mukunda Katta 在 dev.to 的文章)读取这份 JSONL,然后在终端打印一棵树。会话变成根节点,每次工具调用是子节点,被拒绝的调用作为子节点出现,并附带其错误信息。打开它,读完这棵树,然后关闭。无需登录,无需上传,无供应商锁定。把它指向某个会话文件即可:

trace-tree ~/.hermes/logs/sessions/2026-07-21T09-42-11.jsonl

需要更深入的诊断时,你也可以把同一份 JSONL 管道传给 jq,按工具名、耗时或错误状态做过滤。会话转录在版本之间的稳定性比 agent.log 好得多,所以做临时查询时请针对转录,而不是针对人类可读日志做 grep。

对于"智能体没声,是不是卡住了"这个消息渠道相关的排查,我们的 Telegram 排障指南 会先带你走投递侧的症状(bot token、webhook、群组权限),这些常常就是真正的根因,甚至根本用不到追踪树。

提高日志级别而不泄露密钥

verbose 模式只差一个 flag。hermes chat --verbose(或 -v)会把 AIAgent 上的 verbose_logging 置为 True,随后调用 setup_verbose_logging(),在文件 handler 之上再加一个 DEBUG 级别的控制台 StreamHandler。你能实时看到智能体所看到的一切。

关键细节是:每一条日志记录,无论级别,都会先经过 agent/redact.py 中的 RedactingFormatter 再落盘。这个 formatter 能识别已知的凭据形态(sk-sk-or-sk-ant-、常见的 OAuth 模式,以及环境变量形态的秘密),并就地替换其值。实践上这意味着你可以在生产环境里提高日志级别,或把脱敏后的 agent.log 粘进 bug 报告,而不会泄露你的 OpenRouter 密钥。

有一个坑值得点名。如果你写了自己的 logger 或自己的 formatter 而跳过了这条流水线,脱敏就不生效。作为 issue #8090 报告的 gateway 启动崩溃 NameError: name 'RedactingFormatter' is not defined,其实是同一类错误的反面版本。请把 formatter 视为承重的组件,不要绕过它;如果一定要写自定义日志,请通过 hermes_logging.setup_logging() 包裹进去,而不是绕着它走。

目前仍然存在的可观测性盲点

Hermes 对自己现阶段做不到的事很诚实。两个开放的 feature request 描述了当前上限:

  • 带起止时间戳的结构化 span。 目前大多数日志行只带一个时间戳,部分工具输出里带有临时的 duration_seconds。整条轨迹上没有稳定的 start_tsend_tsduration_msparent_id 模式。这是 issue #6741,会话变慢时你想要的那种清爽的"按工具看延迟"仪表盘因此被挡住。
  • 对进行中的 gateway 会话做实时 attach。 在当前版本,一旦某个 gateway 会话已经在跑,你就无法从外部实时观察它。agent.log 会在会话结束时补上,但没有"边发生边看这个用户会话"的钩子。这是 issue #18127,也是把 Hermes 当作共享服务运行的团队面临的最大缺口。

在此期间有两种可以填补部分缺口的绕行方案。第一种是把 OpenTelemetry 风格的追踪送到 SigNoz 这样的后端,即便 Hermes 没有原生 span 发射,也可以在下游把它的活动翻译成 span。第二种是 Langfuse(issue #1501),一些团队按每一轮把它作为手动埋点层接进去。两者目前都不是官方一等公民,但今天都在某处的生产环境里跑着。

如果你干脆不想拥有这套日志层

以上都建立在"你自己在跑智能体"这个前提上。如果这一部分正是你想外包出去的,Hermify 会在 Telegram 上为你运行一个托管的 Hermes Agent,底层容器上的同款日志与审计跟踪同样具备。你能拿到持久化记忆、会话转录,以及把某个具体问题升级给我们的通道,而无需在自己的 VPS 上一直挂着 hermes logs -f。如果你在自托管和托管方案之间摇摆,其中一部分理由是可观测性带来的运维负担,我们那篇 托管 Hermes 与自托管 Hermes 对比 把利弊讲得很完整。

从 Hermify 开始,把日志轮转与可观测性工作整块省掉。或者继续保留本地日志,下次智能体沉默时把这份指南翻出来对照。两条路都成立,且同一份审计跟踪在两条路上都存在。

Sources

运行你自己的 Hermes Agent

自带 API 密钥,连接 Telegram,60 秒内即可上线一个自我改进的 AI 智能体。

立即开始