跳到主要内容

会话

Hermes Agent 会自动将每次对话保存为一个会话。会话支持对话恢复、跨会话搜索以及完整的对话历史管理。

会话工作原理

每一次对话——无论是来自 CLI、Telegram、Discord、WhatsApp 还是 Slack——都会作为包含完整消息历史的会话被存储。会话通过两个互补的系统进行追踪:

  1. SQLite 数据库 (~/.hermes/state.db) —— 存储结构化的会话元数据,并支持 FTS5 全文搜索
  2. JSONL 转录文件 (~/.hermes/sessions/) —— 存储原始的对话转录,包括工具调用(网关)

SQLite 数据库存储:

  • 会话 ID、来源平台、用户 ID
  • 会话标题(唯一的、人类可读的名称)
  • 模型名称和配置
  • 系统提示快照
  • 完整的消息历史(角色、内容、工具调用、工具结果)
  • 令牌计数(输入/输出)
  • 时间戳(开始时间、结束时间)
  • 父会话 ID(用于因压缩而触发的会话拆分)

会话来源

每个会话都会根据其来源平台进行标记:

来源描述
cli交互式 CLI (hermeshermes chat)
telegramTelegram 即时通讯
discordDiscord 服务器/私信
whatsappWhatsApp 即时通讯
slackSlack 工作区

CLI 会话恢复

使用 --continue--resume 从 CLI 恢复之前的对话:

继续上一个会话

# 恢复最近的一个 CLI 会话
hermes --continue
hermes -c

# 或者使用 chat 子命令
hermes chat --continue
hermes chat -c

这会从 SQLite 数据库中查找最近的 cli 会话并加载其完整的对话历史。

按名称恢复

如果你给会话设置了标题(见下面的会话命名),你可以按名称恢复它:

# 恢复一个已命名的会话
hermes -c "my project"

# 如果存在衍生版本(my project, my project #2, my project #3),
# 这会自动恢复最新的一个
hermes -c "my project" # → 恢复 "my project #3"

恢复特定会话

# 通过 ID 恢复特定会话
hermes --resume 20250305_091523_a1b2c3d4
hermes -r 20250305_091523_a1b2c3d4

# 通过标题恢复
hermes --resume "refactoring auth"

# 或者使用 chat 子命令
hermes chat --resume 20250305_091523_a1b2c3d4

会话 ID 会在你退出 CLI 会话时显示,也可以通过 hermes sessions list 命令找到。

恢复时的对话摘要

当你恢复一个会话时,Hermes 会在输入提示符之前,在一个样式化的面板中显示先前对话的紧凑摘要:

恢复 Hermes 会话时显示的‘先前对话’摘要面板的样式化预览。

恢复模式会显示一个紧凑的摘要面板,包含最近的用户和助手对话轮次,然后将你带回实时提示符。

摘要内容:

  • 显示用户消息(金色 )和助手回复(绿色
  • 截断长消息(用户消息 300 字符,助手消息 200 字符 / 3 行)
  • 折叠工具调用为数量统计和工具名称(例如 [3 tool calls: terminal, web_search]
  • 隐藏系统消息、工具结果和内部推理
  • 限制为最近 10 次对话轮次,并带有 "... N earlier messages ..." 指示器
  • 使用暗淡样式以区别于活跃对话

要禁用摘要并保持简洁的单行行为,请在 ~/.hermes/config.yaml 中设置:

display:
resume_display: minimal # 默认值:full
提示

会话 ID 遵循格式 YYYYMMDD_HHMMSS_<8-char-hex>,例如 20250305_091523_a1b2c3d4。你可以通过 ID 或标题恢复——两者都适用于 -c-r 参数。

会话命名

为会话设置人类可读的标题,以便轻松查找和恢复它们。

自动生成的标题

Hermes 会在第一次对话交换后,自动为每个会话生成一个简短的描述性标题(3-7 个词)。这使用一个快速的辅助模型在后台线程中运行,因此不会增加延迟。当你使用 hermes sessions listhermes sessions browse 浏览会话时,会看到自动生成的标题。

自动命名每个会话只触发一次,如果你已经手动设置了标题,则会跳过。

手动设置标题

在任何聊天会话(CLI 或网关)中使用 /title 斜杠命令:

/title my research project

标题会立即生效。如果会话尚未在数据库中创建(例如,你在发送第一条消息之前运行了 /title),它会被排队并在会话开始时应用。

你也可以从命令行重命名现有会话:

hermes sessions rename 20250305_091523_a1b2c3d4 "refactoring auth module"

标题规则

  • 唯一性 —— 任何两个会话都不能共享相同的标题
  • 最多 100 个字符 —— 保持列表输出整洁
  • 已清理 —— 控制字符、零宽字符和 RTL 覆盖符会被自动剥离
  • 正常的 Unicode 字符都可以 —— 表情符号、中日韩文字、带重音符号的字符都可以使用

压缩时的自动衍生

当会话的上下文被压缩时(手动通过 /compress 或自动触发),Hermes 会创建一个新的延续会话。如果原始会话有标题,新会话会自动获得一个带编号的标题:

"my project" → "my project #2" → "my project #3"

当你按名称恢复时(hermes -c "my project"),它会自动选择该衍生系列中最新的会话。

消息平台中的 /title 命令

/title 命令在所有网关平台(Telegram、Discord、Slack、WhatsApp)中都有效:

  • /title My Research —— 设置会话标题
  • /title —— 显示当前标题

会话管理命令

Hermes 通过 hermes sessions 提供了一套完整的会话管理命令:

列出会话

# 列出最近的会话(默认:最近 20 个)
hermes sessions list

# 按平台筛选
hermes sessions list --source telegram

# 显示更多会话
hermes sessions list --limit 50

当会话有标题时,输出会显示标题、预览和相对时间戳:

Title                  Preview                                  Last Active   ID
────────────────────────────────────────────────────────────────────────────────────────────────
refactoring auth Help me refactor the auth module please 2h ago 20250305_091523_a
my project #3 Can you check the test failures? yesterday 20250304_143022_e
— What's the weather in Las Vegas? 3d ago 20250303_101500_f

当没有会话有标题时,会使用更简单的格式:

Preview                                            Last Active   Src    ID
──────────────────────────────────────────────────────────────────────────────────────
Help me refactor the auth module please 2h ago cli 20250305_091523_a
What's the weather in Las Vegas? 3d ago tele 20250303_101500_f

导出会话

# 将所有会话导出到 JSONL 文件
hermes sessions export backup.jsonl

# 导出特定平台的会话
hermes sessions export telegram-history.jsonl --source telegram

# 导出单个会话
hermes sessions export session.jsonl --session-id 20250305_091523_a1b2c3d4

导出的文件每行包含一个 JSON 对象,其中包含完整的会话元数据和所有消息。

删除会话

# 删除特定会话(带确认)
hermes sessions delete 20250305_091523_a1b2c3d4

# 删除时不确认
hermes sessions delete 20250305_091523_a1b2c3d4 --yes

重命名会话

# 设置或更改会话标题
hermes sessions rename 20250305_091523_a1b2c3d4 "debugging auth flow"

# 多词标题在 CLI 中不需要引号
hermes sessions rename 20250305_091523_a1b2c3d4 debugging auth flow

如果标题已被其他会话使用,则会显示错误。

清理旧会话

# 删除超过 90 天(默认)的已结束会话
hermes sessions prune

# 自定义时间阈值
hermes sessions prune --older-than 30

# 仅清理特定平台的会话
hermes sessions prune --source telegram --older-than 60

# 跳过确认
hermes sessions prune --older-than 30 --yes
信息

清理操作只删除已结束的会话(已明确结束或自动重置的会话)。活跃的会话永远不会被清理。

会话统计

hermes sessions stats

输出:

Total sessions: 142
Total messages: 3847
cli: 89 sessions
telegram: 38 sessions
discord: 15 sessions
Database size: 12.4 MB

要进行更深入的分析——令牌使用情况、成本估算、工具使用细分和活动模式——请使用 hermes insights

会话搜索工具

该代理内置了一个 session_search 工具,可以使用 SQLite 的 FTS5 引擎对所有过去的对话进行全文搜索。

工作原理

  1. FTS5 搜索匹配的消息并按相关性排序
  2. 按会话分组结果,取前 N 个唯一的会话(默认 3 个)
  3. 加载每个会话的对话,截取到约 100K 字符,内容围绕匹配项展开
  4. 发送给一个快速的摘要模型进行聚焦摘要
  5. 返回每个会话的摘要,包含元数据和周围上下文

FTS5 查询语法

搜索支持标准的 FTS5 查询语法:

  • 简单关键词:docker deployment
  • 短语:"exact phrase"
  • 布尔运算:docker OR kubernetes, python NOT java
  • 前缀:deploy*

使用时机

代理会被提示自动使用会话搜索:

“当用户引用过去对话中的内容,或者你怀疑存在相关的先前上下文时,请使用 session_search 来回忆它,而不是要求用户重复他们说过的话。”

各平台的会话追踪

网关会话

在消息平台上,会话通过一个从消息来源构建的确定性会话密钥来标识:

聊天类型默认密钥格式行为
Telegram 私信agent:main:telegram:dm:<chat_id>每个私信聊天一个会话
Discord 私信agent:main:discord:dm:<chat_id>每个私信聊天一个会话
WhatsApp 私信agent:main:whatsapp:dm:<chat_id>每个私信聊天一个会话
群组聊天agent:main:<platform>:group:<chat_id>:<user_id>当平台暴露用户 ID 时,群组内每个用户一个会话
群组线程/主题agent:main:<platform>:group:<chat_id>:<thread_id>:<user_id>该线程/主题内每个用户一个会话
频道agent:main:<platform>:channel:<chat_id>:<user_id>当平台暴露用户 ID 时,频道内每个用户一个会话

当 Hermes 无法获取共享聊天的参与者标识符时,它会回退到为该房间使用一个共享会话。

共享会话与隔离的群组会话

默认情况下,Hermes 在 config.yaml 中使用 group_sessions_per_user: true。这意味着:

  • Alice 和 Bob 可以在同一个 Discord 频道中与 Hermes 对话,而无需共享转录历史
  • 一个用户长时间、大量使用工具的任务不会污染另一个用户的上下文窗口
  • 中断处理也保持按用户进行,因为运行中的代理密钥与隔离的会话密钥相匹配

如果你想要一个共享的“房间大脑”模式,可以设置:

group_sessions_per_user: false

这将使群组/频道恢复到每个房间一个共享会话的模式,这会保留共享的对话上下文,但也会共享令牌成本、中断状态和上下文增长。

会话重置策略

网关会话会根据可配置的策略自动重置:

  • 空闲 —— 在 N 分钟不活动后重置
  • 每日 —— 每天在特定小时重置
  • 两者 —— 以先到者为准(空闲或每日)重置
  • —— 从不自动重置

在会话被自动重置之前,代理会被给予一个轮次来保存对话中任何重要的记忆或技能。

具有活跃后台进程的会话永远不会被自动重置,无论策略如何。

存储位置

内容路径描述
SQLite 数据库~/.hermes/state.db所有会话元数据 + 附带 FTS5 的消息
Gateway 对话记录~/.hermes/sessions/每个会话的 JSONL 格式记录 + sessions.json 索引文件
Gateway 索引~/.hermes/sessions/sessions.json将会话密钥映射到活动会话 ID

SQLite 数据库使用 WAL(预写式日志)模式来支持并发读取和单一写入,这非常适合网关的多平台架构。

数据库模式

state.db 中的关键表:

  • sessions — 会话元数据(id、source、user_id、model、title、时间戳、令牌计数)。标题有唯一索引(允许 NULL 标题,仅非 NULL 标题必须唯一)。
  • messages — 完整的消息历史记录(角色、内容、工具调用、工具名称、令牌计数)
  • messages_fts — 用于跨消息内容进行全文搜索的 FTS5 虚拟表

会话过期与清理

自动清理

  • Gateway 会话会根据配置的重置策略自动重置
  • 在重置之前,智能体会保存即将过期会话中的记忆和技能
  • 已结束的会话会保留在数据库中,直到被清理

手动清理

# 清理超过 90 天的会话
hermes sessions prune

# 删除特定会话
hermes sessions delete <session_id>

# 在清理前导出(备份)
hermes sessions export backup.jsonl
hermes sessions prune --older-than 30 --yes
提示

数据库增长缓慢(典型情况:数百个会话占用 10-15 MB)。清理功能主要用于删除那些你不再需要用于搜索回忆的旧对话。