Hermes Agent

Hermes Agent 会话搜索与 SQLite FTS5 原理

Hermes Agent 会话搜索直接从 SQLite FTS5 返回真实消息,不再额外调用辅助 LLM 生成可能失真的摘要。页面拆解 discovery、scroll、browse 等检索方式、中文双索引和头尾窗口设计,帮助你降低搜索历史对话的延迟、成本与摘要幻觉。并附关键选择建议。便于后续检查。

效率提升 进阶

📚 系列导航:上一篇 Hermes Agent 记忆系统教程 已经讲清“记忆系统教程:会话、持久记忆与 Skills”;本篇聚焦 Hermes Agent 会话搜索;下一篇 Hermes Agent Skills 系统教程 继续学习“Skills 系统教程:安装、加载与信任边界”。

先给结论:有明确原文可返回的检索,不该再让 LLM 做一次概率性转述。 新版直接从 SQLite FTS5 返回真实消息,减少了成本、延迟和摘要幻觉;所谓提速,主要来自删掉辅助 LLM,而不是 FTS5 本身突然变快。

ℹ️ 版本说明: 原稿基于 Hermes Agent v0.16.0(2026 年 6 月)源码整理。本文保留其版本化机制分析;命令、数量和界面请以 Hermes Agent 官方文档 与本地输出为准。

Hermes 会话搜索的性能变化

v0.15.0 这版的 release notes 里有一行,我读到的时候停了一下。它说 session_search 重写了,no LLM、nocost、4500×faster。

四千五百倍。这种数字一出现,我的第一反应是怀疑。AI 圈里「快了多少倍」的说法,大半是营销话术,换个 benchmark 就原形毕露。所以我去翻了源码,想看看这 4500×到底是怎么来的。

翻完之后我得承认,这次是真的。但真相比「快了 4500 倍」有意思得多。

旧版会话搜索的成本与幻觉问题

旧版的会话搜索是这么干的。你想找「上周那个聊数据库迁移的会话」,它先用 SQLite 的 FTS5 全文索引去召回几个候选会话,这一步本来很快。然后它做了一件多余的事:再喊一个辅助 LLM,把命中的几个会话「摘要」一遍给你看。

问题就出在这颗辅助 LLM 身上。每召回三个会话摘要一次,大约 30 秒、大约花掉 0.3 美元。更糟的是,当 FTS5 根本没召回到那个对的会话时,这个 LLM 不会说「没找到」,它会一本正经地编一段你从没说过的内容给你。

你品一下这个设计的拧巴:检索这件事,FTS5 已经给出了准确答案,哪几条消息命中了,清清楚楚躺在数据库里。结果非要再花一次钱、等 30 秒,让一个会幻觉的模型把这些真实消息「转述」一遍。明明手里有原文,偏要找个人复述给你听,复述的人还可能记错。

新版会话搜索为什么不再调用 LLM

新版的解法朴素到近乎无趣—直接返回数据库里的真实消息,全程不碰 LLM。

⚠️ 不推荐

旧版:FTS5 召回→喊辅助 LLM 摘要三个会话→约 30 秒、约 0.3 美元、可能编造→返回「转述版

💡 推荐

新版:FTS5 召回→直接从 DB 取出命中的真实消息→约 20ms、零成本、不可能编→返回原文

源码里这句话写得很硬气。session_search 的工具文件开头那段注释明明白白:所有模式都走 SQLite 的 FTS5 索引,「No LLM calls anywhere」,每种返回都是数据库里的真实消息。

discovery 这种带搜索的查询,从原来约 90 秒压到约 20 毫秒;纯翻页(scroll)更快,约 1 毫秒。所谓 4500×,就是 90 秒除以 20 毫秒算出来的,是端到端这一整套工具的延迟对比,不是 FTS5 引擎本身变快了 4500 倍。

这点我要替读者多说一句,免得被数字带偏。检索引擎从头到尾都是 FTS5,一行没换。变的只是删掉了最慢、最贵、最会胡编的那一环。本质上,这是把一件本不该用 LLM 干的活,从 LLM 手里要了回来。

个反直觉的判断:很多人下意识觉得「上了 LLM=更智能=更好」。但检索是个有标准答案的任务:命中就是命中,没命中就是没命中。给一个确定性任务套一层概率性的模型,换来的不是智能,是成本、延迟和幻觉。工程上最克制的进步,有时候是做减法。

会话头尾与命中窗口如何替代摘要

这是我最初的疑虑:LLM 摘要好歹给你「这个会话讲了啥」的概览,纯返回原文,不会一堆消息糊你一脸吗?新版的巧思在 discovery 这个形态里。它一次调用,就同时给你三样东西:会话开头的头几条消息(让你知道这事当初要干嘛)、命中点上下几条的窗口(让你看到关键那一段)、会话结尾的几条消息(让你知道最后聊出了什么结论)。

开头加结尾的这种「书挡」式截取,加上命中点的上下文窗口,主模型自己就能拼出「这个会话讲了什么」。LLM 摘要本来想给你的那个概览,用结构化的头、尾、命中窗就能让主模型重建出来,不用再单独花一次 LLM 的钱。目标、命中、结论,一次拿齐。

Hermes 会话搜索的四种检索方式

release notes 说有三种模式(discovery/scroll/browse),但我翻源码发现其实是四种。而且没有所谓的 mode 参数让你选。传了哪些参数,它自己推断你想干什么。

形态你传什么它给你什么用 LLM 吗
DISCOVERY 搜关键词 queryFTS5 命中按会话去重,每条带摘录片段、命中点上下窗、头尾书挡
SCROLL 翻会话 id + 锚点消息 id以锚点为中心上下若干条(默认 5,最多 20),不搜不书挡
READ 读只传会话 id整段会话(太长就取头 20+尾 10)
BROWSE 逛什么都不传最近若干会话的标题、预览、时间戳

这种「没有模式开关,看参数办事」的设计,我挺欣赏。一个工具承担四件事,对调用它的 Agent 来说认知负担最小,不用先想清楚自己处在哪个 mode,传它手头有的东西就行。READ 这个形态还多干一件实事:你在聊天里贴一个会话链接进来,它能跨 profile 只读地把那段会话翻出来给你看,这是「跨身份记忆互通」的入口。

Hermes 中文会话的 FTS5 索引

这一点旧书完全没提,但对中文读者来说很值钱。

FTS5 默认的分词器(unicode61)有个老毛病:碰到中文会逐字切开。你搜「大别山项目」,它内部变成「大 AND 别 AND 山 AND 项 AND 目」,既容易误报,又匹配不到精确短语。日文、韩文、泰文也是同一个坑。

新版建了两张 FTS5 虚拟表来解决。一张是默认的 unicode61,伺候英文;另一张专门给 CJK,用的是 trigram(三字符重叠)分词,让任意文字的子串匹配天然可用。

Hermes Agent 使用 SQLite FTS5 检索真实会话消息

路由逻辑是源码确认的:英文走主表,BM25 排序加高亮;中文且每个词够三个汉字,走 trigram 表;中文但词太短(像「桂林 OR 漓江」这种两字词,trigram 要够三个汉字才匹配得上),就退回 LIKE 按时间倒序兜底。这套东西全部跑在本地、零成本,这就是「为什么 Hermes 的会话搜索对中文也好用」的真正答案。

确定性检索任务为什么应减少 LLM

去 LLM 化是真删了代码。但我在翻的时候,发现周边的文档和配置没全跟上,留下两处自相矛盾。

一处在配置示例文件里,旧版那套给「会话摘要」用的 LLM 配置块还原封不动留着,provider、model、timeout、并发数全在。可新代码根本不读这些。这是一段已经死掉的配置。

另一处更直接。README 的特性表里还写着「FTS5 session search with LLM summarization」,而源码注释白纸黑字写着「No LLM calls anywhere」。一个文件说带 LLM,另一个文件说全程没 LLM,就在同一个仓库里打架。

⚠️ 注意

README 说「带 LLM 摘要」,源码说「全程零 LLM」,信哪个?信源码。代码是会运行的事实,文档是可能过期的说法。这个矛盾本身,就是「别信二手解读,去读源码」最好的教学案例。

我把这个彩蛋单拎出来,是因为它指向一件比 session_search 本身更重要的事。AI 工具迭代太快,文档永远滞后于代码。你看到的教程、别人转述的「它有什么功能」,可能描述的是三个版本之前的样子。真要搞清楚一个工具现在到底怎么干活,唯一可靠的来源是它正在跑的那份源码。

这一节我愿意当成全书「工程克制」的范本来读。它没加任何新东西,反而拿走了一颗看似高级的 LLM。换来的是免费、即时、不幻觉,外带对中文的原生友好。下一节我们离开记忆,去看 Hermes 怎么把一身本事拆成可加载、可共享的 Skill。

常见问题

Hermes Agent 会话搜索会调用大模型吗?

原稿分析的新版实现由 SQLite FTS5 直接返回真实消息,不需要额外的摘要模型。主 Agent 可以根据命中窗口、会话开头和结尾理解上下文。

Hermes Agent 能搜索中文会话吗?

原稿所述实现为中文搜索准备了对应的 FTS5 处理方式。实际分词和命中效果仍需用你的本地数据与当前版本验证。

这篇教程里的版本数字会变化吗?

会。原稿以 Hermes Agent v0.16.0 为分析基线,平台、工具、命令参数和默认配置可能继续变化;实际操作前请核对当前官方文档和本地命令帮助。