集成AgentHermes Agent

用 Litefuse 追踪 Hermes Agent

Hermes Agent 是 Nous Research 的终端 AI 助手,采用可插拔的工具调用和网关架构。本集成以 Hermes 插件 形式安装到 ~/.hermes/plugins/litefuse/。插件在 Hermes 的 Python 解释器中以同进程方式运行,订阅生命周期 hook 事件(pre_llm_callpost_api_requestpre_tool_callpost_tool_callpost_llm_call 等),为每个用户回合生成一条 Litefuse trace,使用真实的 wall-clock 逐事件时间戳。

该插件适用于 Hermes 的所有界面 —— CLI(hermes chat -q)、Gateway(飞书、Discord、Slack、Telegram、WhatsApp、IRC),以及(在合并了 PR #24237 之后的)TUI。

给 AI —— 自动安装

如果你正在和 Hermes Agent 对话,把下面这段 prompt 粘贴过去,Agent 会端到端完成整个安装:

Read https://litefuse.ai/SKILL.md and follow the instructions to install and configure Litefuse for Hermes Agent.

skill 会向你索取 Litefuse 的 API Key(如果还没有账号,会引导你注册),然后在本地完成全部配置。如果你想手工一步步配置,请继续往下看。

会捕获哪些数据

数据捕获方式备注
用户 prompttrace input + user message event在回合开始时刷新,让 Litefuse 立刻显示 trace 名称 / session / input
每次 LLM API 调用api: <model> #N generation observation单次 API 调用的延迟 + token 用量 + provider + base_url + finish_reason
token 用量(input_tokensoutput_tokens、cache 读/写)每个 api generation 的 usage_details来自 post_api_request.usage;使用 Anthropic 风格 key,让 Litefuse 成本映射可用
工具调用tool: <name> (#N) tool observationinput = 工具参数,output = 工具结果,duration_ms
工具错误tool observation,level=ERROR启发式判断:结果开头出现 error / "error": / "success": false
助手最终回复assistant response generation observation同时传播到 trace 级别的 output
模型名称每个 generation 上的 model,trace tag model:<name>Litefuse 用它来计算成本
会话分组trace 的 session_idHermes 的 YYYYMMDD_HHMMSS_<6or8hex> session id
用户身份trace 的 user_id$LITEFUSE_USER_ID,回退到 $USER
回合编号trace 的 nameHermes Agent — Turn N)+ hermes_agent.turn_number从 1 开始,按会话单调递增
Hermes 专属 metadatametadata.hermes_agent.*provider / base_url / api_mode / api_duration / finish_reason / message_count / step_index / platform / is_first_turn / history_messages

Trace 结构

一个典型的多工具回合产生的 trace 形如:

Hermes Agent — Turn 7                (SPAN, root, real duration)
├── user message                     (EVENT, flushes trace metadata immediately)
├── api: MiniMax-M2.7 #1             (GENERATION, usage_details, real latency)
├── tool: web_search (#1)            (TOOL, real duration)
├── api: MiniMax-M2.7 #2             (GENERATION, usage_details)
├── tool: web_extract (#2)           (TOOL, real duration)
├── api: MiniMax-M2.7 #3             (GENERATION, usage_details)
└── assistant response               (GENERATION, final answer)

设计说明:

  • 真实 wall-clock 时间戳。 每个 observation 的 start/end 都来自 hook 回调触发的那一刻,所以 Litefuse 时间线反映真实的 LLM 延迟、工具执行时间和调用之间的间隔 —— 没有合成网格。
  • 唯一根父节点。 容器 span 是唯一的 trace 根;每个 api / tool / response observation 都嵌套在它下面。即便回合超过 50 步,时间线视图也保持整洁。
  • Trace header 稳定。 Trace 名称 / input / session_id 在回合 START 时就刷新到 Litefuse(通过带真实 wall-clock end 的 user message event + lf.flush()),并且不会在新 observation 到达时被中途覆盖。
  • 工具编号。 tool: observation 名称上的 (#N) 后缀消除同一个工具在一回合内被多次调用的歧义。
  • 命名空间化的 metadata。 所有 Hermes 专属字段都放在 metadata.hermes_agent.* 下,让顶层 metadata 字典只保留 Litefuse 标准 key。

快速开始

前置条件

  • https://litefuse.cloud 创建一个 Litefuse 项目,拿到 public + secret key。
  • 已安装 Hermes Agent —— 用 hermes --version 检查。建议使用合并了 PR #24237 的最新版本,这样插件 hook 在 TUI 中也能触发;否则 CLI + Gateway 也能完整工作。

把 Langfuse SDK v4 安装到 Hermes 自己的 venv

插件在 Hermes 的 Python 解释器中以同进程方式运行,所以 SDK 必须装在 Hermes 的 venv 中(不能放到单独的 venv):

~/.hermes/hermes-agent/venv/bin/pip install 'langfuse>=4,<5'
 
# Verify
~/.hermes/hermes-agent/venv/bin/python3 -c "import langfuse; print(langfuse.__version__)"
# Expect: 4.x.y

把插件文件放进 ~/.hermes/plugins/litefuse/

mkdir -p ~/.hermes/plugins/litefuse
curl -fsSL https://litefuse.ai/integrations/hermes-agent/plugin.yaml \
  -o ~/.hermes/plugins/litefuse/plugin.yaml
curl -fsSL https://litefuse.ai/integrations/hermes-agent/__init__.py \
  -o ~/.hermes/plugins/litefuse/__init__.py

插件源码也在同一 URL 上 —— 部署前可以先读一遍。

把 Litefuse 凭据加到 ~/.hermes/.env

插件从 Hermes 自己的 .env 文件读取凭据(Hermes 启动时会自动加载):

cat >> ~/.hermes/.env <<'EOF'
 
# Litefuse observability
LANGFUSE_PUBLIC_KEY=pk-lf-xxx
LANGFUSE_SECRET_KEY=sk-lf-xxx
LANGFUSE_HOST=https://litefuse.cloud
EOF

把占位值替换成真实值。为了和其他 Litefuse 集成兼容,插件也接受 LANGFUSE_BASE_URL 作为 LANGFUSE_HOST 的别名。

启用插件

需要在 Hermes 中显式开启:

hermes plugins enable litefuse
hermes plugins list   # confirm: status = enabled

重启正在运行的 gateway

gateway 守护进程在启动时会缓存自己的插件管理器,因此需要重启来加载新插件:

hermes gateway restart  # only if you have `hermes gateway` running

CLI 调用(hermes chat -q "...")每次运行都会重新加载插件 —— 不用重启。

验证

hermes chat -q "say hello in five words exactly"
tail -3 ~/.hermes/state/litefuse_plugin.log
# Expected: "turn complete session=YYYYMMDD_HHMMSS_xxxxxx turn=1 api_calls=1 tool_calls=0"

打开 https://litefuse.cloud,看名为 Hermes Agent — Turn 1 的最新 trace。它应当包含:

  • 立即填充的正确 name / sessionId / input
  • 一个携带用户 prompt 的子 [EVENT] user message
  • [GENERATION] api: <model> #N,已填好 token 用量
  • (如果你的 prompt 用到了工具)[TOOL] tool: <name> (#1),带 input 参数和 output 结果
  • 带最终回答的 [GENERATION] assistant response

环境变量

变量必填说明
LANGFUSE_PUBLIC_KEYLitefuse 项目 public key(pk-lf-...)。
LANGFUSE_SECRET_KEYLitefuse 项目 secret key(sk-lf-...)。
LANGFUSE_HOST默认 https://cloud.langfuse.com。设为 https://litefuse.cloud(或你的自托管 URL)。别名 LANGFUSE_BASE_URL
LITEFUSE_USER_ID覆盖 trace 的 user_id。回退到 $USER,再回退到 "hermes-user"
HERMES_LITEFUSE_DEBUG设为 "true" 启用 ~/.hermes/state/litefuse_plugin.log 中的详细插件日志。
HERMES_LITEFUSE_MAX_CHARSspan 输入/输出的截断阈值(字符数)。默认 1000000(约 1MB 文本)。

工作原理

插件通过 ctx.register_hook(...) 订阅九个 Hermes 插件 hook 事件:

Hook作用
on_session_start缓存 session 的 model / platform 元数据。
pre_llm_call为本回合开启长生命周期的容器 span。发出一个 user message event,立即把 trace 元数据(name / session / user / input / tags)刷新到 Litefuse,让 trace header 不必等到回合结束就显示出来。
post_api_request为每次 LLM API 调用发出一个 api: <model> #N generation,携带 usage_details(input_tokens / output_tokens / cache tokens)以便 Litefuse 进行成本映射。
pre_tool_call在容器下打开一个 tool: <name> (#N) span。
post_tool_call用 output + duration_ms 关闭对应的 tool span。由于 Hermes v0.12 在 run_agent.py 中调用 pre_tool_call 时不传 session_id / tool_call_id,只传 task_id,所以使用了一个按 session 分隔的 FIFO 队列。
post_llm_call发出 assistant response generation 并用最终输出关闭容器。
on_session_end防御性地清理被中断的回合(Hermes 在每个回合结束时都会触发,而不仅在 session 结束时)。
on_session_reset / on_session_finalize在 session 真正销毁时清空内存状态。

该插件是 fail-open 的:任何意外错误都会写入 ~/.hermes/state/litefuse_plugin.log,回调静默返回,所以永远不会阻塞 Hermes 的主循环。一个 Langfuse 客户端在模块级状态中跨 Hermes 进程整个生命周期保留(gateway 守护进程、CLI 调用、TUI 子进程),并由线程锁保护,多个并发的 gateway 会话可以安全共享。

Trace metadata 参考

Trace 级 metadata(位于 metadata.hermes_agent.*):

  • turn_number —— 从 1 开始,按 session 生命周期单调递增
  • platform —— cligatewaytuifeishu 等(由 Hermes 设置)
  • model —— 回合开始时的模型名称
  • is_first_turnhistory_messages —— 回合在 session 中的位置

Generation observation 元数据api: ...,位于 metadata.hermes_agent.*):

  • providerbase_urlapi_moderesponse_model —— provider 配置
  • api_call_countapi_durationfinish_reasonmessage_count —— 单次调用的统计
  • assistant_content_charsassistant_tool_call_count —— 输出形态
  • step_index —— (#N) 步骤计数

Tool observation 元数据(位于 metadata.hermes_agent.*):

  • tool_nametask_idtool_call_id
  • duration_msis_error
  • step_index

故障排查

Litefuse 中没有出现 trace。 用 tail 查看 ~/.hermes/state/litefuse_plugin.log

tail -20 ~/.hermes/state/litefuse_plugin.log

期望:启动时出现 "litefuse plugin registered (9 hooks)",每个回合出现 "Litefuse client ready""turn complete session=... turn=N api_calls=N tool_calls=N"。如果文件是空的,说明插件没加载。

hermes plugins list           # confirm: litefuse → enabled
hermes plugins enable litefuse  # if not enabled
hermes gateway restart        # if gateway is running

插件日志显示 Litefuse credentials not set 插件没在 os.environ 中找到 LANGFUSE_PUBLIC_KEY / LANGFUSE_SECRET_KEY。把它们加到 ~/.hermes/.env

cat >> ~/.hermes/.env <<'EOF'
LANGFUSE_PUBLIC_KEY=pk-lf-...
LANGFUSE_SECRET_KEY=sk-lf-...
LANGFUSE_HOST=https://litefuse.cloud
EOF

然后重新执行任何 hermes chat -q "..." 或重启 gateway。

插件日志显示 langfuse SDK not importable Langfuse SDK 没装在 Hermes 的 venv 中:

~/.hermes/hermes-agent/venv/bin/pip install --upgrade 'langfuse>=4,<5'

长回合中 trace 名称 / session / input 没出现。 这是我们修复过的真实 bug,办法是发出一个小的 user message observation(类型为 event,结构上像一个 span,让 Langfuse 传播 AS_ROOT + TRACE_* 属性),并在回合开始时强制 flush。如果你看到这种现象,很可能在用旧版本的 __init__.py —— 从 https://litefuse.ai/integrations/hermes-agent/__init__.py 重新拉取。

TUI 会话不产生 trace。 Hermes v0.12 在 TUI 进程中不加载插件(tui_gateway/entry.py)。可以选择:

  • 升级到合并了 PR #24237 的 Hermes 版本,或
  • 在本地给 ~/.hermes/hermes-agent/tui_gateway/entry.py 打一个三行的补丁(hermes update 时会被覆盖 —— 每次更新后再打一次)。

CLI(hermes chat -qhermes -z)和 Gateway(飞书、Slack、Discord、Telegram 等)不打补丁也能工作。

hermes -z "..."(oneshot 模式)也不产生 trace。 同样的根因 —— oneshot 的入口没有调用 discover_plugins。请改用 hermes chat -q "..."(完整的 CLI 路径,会加载插件),或者给 hermes_cli/oneshot.py 打同样的三行补丁。我们会为此再提一个配套 PR。

局限

  • 不会捕获助手的 reasoning Hermes 插件 hook 回调不直接暴露模型的 reasoning / chain-of-thought 文本 —— post_api_request 只给我们 assistant_content_chars(字符数)。思考文本存在于 Hermes 的对话历史中,但要采集它需要订阅当前还不可用的逐消息事件。
  • 不汇总图片 block。 如果回合涉及图片输入,插件会把它们以 JSON 扁平化的文本形式写入 trace 输入;不会单独把媒体类型或数量作为 metadata 暴露出来。

资源

这个页面对你有帮助吗?