你有没有想过这样一个问题:

当你对 AI 说一句"哈喽"的时候,它到底在想什么?

别看只是一个简单的打招呼,背后却是一次完整的技术长征。今天我想和大家聊聊 Hermes Agent 是怎么处理的——看完你会发现,一个简单的"哈喽",竟然触发了好几次大模型调用。

[[IMG: AI robot thinking process]]


一、先说说 Hermes 是什么

Hermes 是一个多模态 AI Agent 框架,由 AIAgent 驱动。它的核心任务就是:接收用户的输入,经过一系列处理后,给出最合适的响应

整个系统分为四层:

接入层负责接收各种输入,CLI、Gateway、Web TUI 都可以作为入口。Agent 层是整个系统的核心,包括对话循环、提示词构建、记忆管理等模块。工具层提供各种可调用的工具能力。存储层则负责持久化对话历史、记忆等数据。

和传统的单轮问答不同,Hermes 采用的是多轮对话循环机制。用户的每一条消息都会进入一个循环,Agent 反复思考、调用工具、获取结果,直到得到最终响应。

[[IMG: Hermes architecture overview]]


二、你说"哈喽"的时候,Hermes 到底做了什么

好,重点来了。当你说一句"哈喽",Hermes 会经历这样的处理流程:

第一步,消息预处理。 你的输入首先被加上时间戳,然后进入记忆预取阶段。系统会调用 memory_manager.prefetch_all(),把相关的记忆片段都捞出来,准备好上下文。这还没完,紧接着是系统提示词的构建,prompt_builder 会把所有这些信息组装成一个大一统的 Prompt,为后续的 LLM 调用做准备。

第二步,进入主对话循环。 这是最关键的一步。代码会进入一个 while 循环,只要 API 调用次数还没超过上限,就会一直循环下去。在循环内部,系统调用 LLM,让它根据当前的上下文判断下一步该做什么。

第三步,后处理。 当主循环结束,返回了最终响应之后,系统还有一堆收尾工作要做。记忆要同步、轨迹要保存、会话要持久化。如果满足条件,还会触发标题生成和后台审查。

[[IMG: Conversation loop flow]]


三、关键问题来了:调用了几次大模型?

这是今天的核心问题。我来逐一拆解。

主对话循环中的调用。这是最核心的一次调用。当你的"哈喽"进入循环后,系统会构建好 API 消息(包括系统提示词、对话历史、用户输入),然后调用 client.chat.completions.create()。这是第 1 次 LLM 调用

关键在于,这次调用会检查返回结果中是否有 tool_calls。对于"哈喽"这样的简单问候,LLM 的判断是:不需要调用任何工具,直接返回文本响应。所以循环就此结束,这就是全部的主调用。

标题生成中的调用。对话结束后,系统会检查是否需要生成会话标题。逻辑在 maybe_auto_title() 这个函数里。它会启动一个后台线程(daemon=True),在线程内部调用 generate_title()。这又是一次 LLM 调用,而且是异步的,不影响主流程的响应速度。这是第 2 次 LLM 调用

后台审查中的调用。除了标题生成,Hermes 还有一套后台审查机制。background_review.py 会定期检查记忆和技能的使用情况。如果触发了审查条件(通常是间隔 N 轮对话后),就会启动后台线程进行审查。这里也可能涉及 LLM 调用,用于分析和总结。这是第 3 次 LLM 调用,但它是条件触发的,不是每次都会发生。

所以,最终的答案是:最少 2 次,最多 3 次 LLM 调用

[[IMG: LLM call sequence diagram]]


四、为什么简单问候也需要这么多调用?

你可能会问,不就是打个招呼吗,至于这么复杂吗?

其实每一层调用都有它的意义。

主调用的必要性。即使你说的是"哈喽",Agent 也需要判断:这真的只是一句问候吗?还是一个隐藏的指令?比如"哈喽,能帮我查一下天气吗?"和"哈喽"看起来差不多,但意图完全不同。所以必须让 LLM 来做这个判断。

标题生成的价值。你有没有遇到过这种情况:聊了很久之后,回头想找之前的对话,但记不清是哪个了。标题生成就是为了解决这个问题。它会自动给会话起一个概括性的名字,比如"讨论天气查询功能"。虽然是个小功能,但很实用。

后台审查的意义。这套机制是为了让 Agent 越来越懂你。系统会定期回顾之前调用过的工具、使用过的记忆,分析有没有可以优化的地方。比如某个工具你从来不用,是不是可以移除?某个记忆片段对你帮助很大,是不是可以多引用?

[[IMG: Multi-layer processing explanation]]


五、和传统方案的对比

可能有读者会问:为什么不让 Agent 直接回复"你好",非要用大模型?

这是一个很好的问题。传统做法可能是硬编码关键词:if "哈喽" in text: return "你好"。这样确实快,但有几个明显的问题。

缺乏灵活性。用户说"嗨"、“你好”、“在吗”,你得把所有变体都列出来。永远有遗漏。

无法处理上下文。如果用户说"哈喽,刚才说的那个功能还有问题",Agent 必须知道"刚才说的那个功能"是什么。这需要上下文管理能力。

无法扩展。随着功能增加,关键词会越来越多,维护成本急剧上升。

用 LLM 做意图判断,虽然增加了一些开销,但换来了灵活性、可扩展性和上下文理解能力。对于现代 AI Agent 来说,这是值得的。

[[IMG: Traditional vs LLM comparison]]


六、技术细节:调用链长什么样?

如果你想深入了解具体实现,这里是完整的调用链:

用户输入 "哈喽"
    │
    ▼
conversation_loop.run_conversation()
    │
    ├─► memory_manager.prefetch_all()
    │      (预取记忆,不涉及 LLM)
    │
    ├─► prompt_builder.build_system_prompt()
    │      (构建提示词,不涉及 LLM)
    │
    ▼
while (api_call_count < max_iterations):
    │
    ├─► _call_model(api_messages)
    │      └─► LLM #1: 主对话调用
    │      │
    │      ▼
    │   检查 response.tool_calls
    │      │
    │      ├─► 无 tool_calls → 直接返回 → 退出循环
    │      │
    │      └─► 有 tool_calls → 执行工具 → 继续循环
    │
    ▼
处理最终响应
    │
    ├─► memory_manager.sync_all()
    │
    ├─► maybe_auto_title()
    │      └─► 后台线程 → LLM #2: 标题生成
    │
    └─► _spawn_background_review()
           └─► 后台线程 → LLM #3: 后台审查(条件触发)

七、总结一下

说了这么多,来个核心总结:

Hermes 处理"哈喽"这个简单输入,总共涉及 2-3 次 LLM 调用。主调用 1 次,判断意图并生成回复。标题生成调用 1 次,后台异步执行。后台审查调用 0-1 次,条件触发时执行。

每一层调用都有它的价值:主调用是核心,后台调用是增强。这种设计让 Agent 既能快速响应简单请求,又能优雅地处理复杂任务,还能持续学习和优化。

下次你再和 AI 打招呼的时候,不妨想想:这背后有多少代码在默默运行。

[[IMG: Summary concept illustration]]


本文基于公开资料整理,仅供参考


更多推荐