跳到主要内容

会话

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

会话如何工作

每一次对话,无论来自 CLI、Telegram、Discord、Slack、WhatsApp、Signal、Matrix 还是其他任何消息平台,都会作为一个包含完整消息历史的会话保存下来。会话会同时记录在两套互补系统中:

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

SQLite 数据库存储的内容包括:

  • 会话 ID、来源平台、用户 ID
  • 会话标题(唯一、可读的名称)
  • 模型名称与配置
  • 系统提示快照
  • 完整消息历史(角色、内容、工具调用、工具结果)
  • token 统计(输入 / 输出)
  • 时间戳(started_atended_at
  • 父会话 ID(用于压缩触发时拆分出后续会话)

Session Sources

每个会话都会带有来源平台标签:

SourceDescription
cli交互式 CLI(hermeshermes chat
telegramTelegram
discordDiscord 服务器 / 私信
slackSlack 工作区
whatsappWhatsApp
signalSignal
matrixMatrix 房间与私信
mattermostMattermost 频道
email电子邮件(IMAP / SMTP)
sms通过 Twilio 发送的短信
dingtalk钉钉
feishu飞书 / Lark
wecomWeCom(企业微信)
weixin微信(个人微信)
bluebubbles通过 BlueBubbles macOS server 接入的 Apple iMessage
qqbot通过 Official API v2 接入的 QQ Bot(腾讯 QQ)
homeassistantHome Assistant 对话
webhook传入 webhook
api-serverAPI server 请求
acpACP 编辑器集成
cron定时 cron 作业
batch批处理运行

CLI 会话恢复

你可以在 CLI 中使用 --continue--resume 恢复之前的对话:

Continue Last Session

# Resume the most recent CLI session
hermes --continue
hermes -c

# Or with the chat subcommand
hermes chat --continue
hermes chat -c

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

Resume by Name

如果你给会话设置了标题(见下文 Session Naming),就可以按名称恢复:

# Resume a named session
hermes -c "my project"

# If there are lineage variants (my project, my project #2, my project #3),
# this automatically resumes the most recent one
hermes -c "my project" # → resumes "my project #3"

Resume Specific Session

# Resume a specific session by ID
hermes --resume 20250305_091523_a1b2c3d4
hermes -r 20250305_091523_a1b2c3d4

# Resume by title
hermes --resume "refactoring auth"

# Or with the chat subcommand
hermes chat --resume 20250305_091523_a1b2c3d4

退出 CLI 会话时会显示会话 ID,也可以通过 hermes sessions list 找到它们。

Conversation Recap on Resume

恢复会话时,Hermes 会在输入提示前用一个样式化面板展示上次对话的简要回顾:

Stylized preview of the Previous Conversation recap panel shown when resuming a Hermes session.

恢复模式会显示一个紧凑的回顾面板,列出最近的用户与 assistant 轮次,然后再回到实时输入提示。

这个回顾会:

  • 显示用户消息(金色 )与assistant 回复(绿色
  • 截断长消息(用户 300 字符;assistant 200 字符 / 3 行)
  • 工具调用折叠成数量与工具名(例如 [3 tool calls: terminal, web_search]
  • 隐藏系统消息、工具结果和内部推理
  • 最多显示最近 10 轮交互,并在前面用 ... N earlier messages ... 标示更早的内容
  • 使用弱化样式,以便与当前活动对话区分开

如果你想关闭这个回顾,恢复成最简的一行模式,可在 ~/.hermes/config.yaml 中设置:

display:
resume_display: minimal # default: full
提示

会话 ID 的格式为 YYYYMMDD_HHMMSS_<8-char-hex>,例如 20250305_091523_a1b2c3d4。你可以通过 ID 或标题来恢复,-c-r 都支持。

Session Naming

给会话设置可读标题,可以让你更容易查找和恢复它们。

Auto-Generated Titles

Hermes 会在第一次往返之后,自动为每个会话生成一个简短的描述性标题(3 到 7 个词)。这个过程在后台线程中用一个快速辅助模型完成,因此不会增加交互延迟。你在 hermes sessions listhermes sessions browse 中浏览会话时,就能看到这些自动生成的标题。

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

Setting a Title Manually

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

/title my research project

标题会立即应用。如果会话尚未写入数据库(例如你在发出第一条消息之前就先运行了 /title),这个标题会先排队,等会话真正开始后再应用。

你也可以通过命令行重命名已有会话:

hermes sessions rename 20250305_091523_a1b2c3d4 "refactoring auth module"

Title Rules

  • 唯一 - 两个会话不能拥有相同标题
  • 最多 100 个字符 - 保持列表输出整洁
  • 自动净化 - 控制字符、零宽字符和 RTL override 会被自动移除
  • 普通 Unicode 完全可用 - emoji、CJK、重音字符都支持

Auto-Lineage on Compression

当某个会话的上下文被压缩时(无论是手动执行 /compress,还是自动压缩),Hermes 会创建一个新的续接会话。如果原会话有标题,新会话会自动获得带编号的标题:

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

如果你按名称恢复(hermes -c "my project"),Hermes 会自动选择这个 lineage 中最新的那个会话。

/title in Messaging Platforms

/title 命令同样适用于所有网关平台(Telegram、Discord、Slack、WhatsApp):

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

Session Management Commands

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

List Sessions

# List recent sessions (default: last 20)
hermes sessions list

# Filter by platform
hermes sessions list --source telegram

# Show more sessions
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

Export Sessions

# Export all sessions to a JSONL file
hermes sessions export backup.jsonl

# Export sessions from a specific platform
hermes sessions export telegram-history.jsonl --source telegram

# Export a single session
hermes sessions export session.jsonl --session-id 20250305_091523_a1b2c3d4

导出的文件每一行都是一个 JSON 对象,包含完整的会话元数据以及所有消息。

Delete a Session

# Delete a specific session (with confirmation)
hermes sessions delete 20250305_091523_a1b2c3d4

# Delete without confirmation
hermes sessions delete 20250305_091523_a1b2c3d4 --yes

Rename a Session

# Set or change a session's title
hermes sessions rename 20250305_091523_a1b2c3d4 "debugging auth flow"

# Multi-word titles don't need quotes in the CLI
hermes sessions rename 20250305_091523_a1b2c3d4 debugging auth flow

如果标题已被其他会话占用,命令会报错。

Prune Old Sessions

# Delete ended sessions older than 90 days (default)
hermes sessions prune

# Custom age threshold
hermes sessions prune --older-than 30

# Only prune sessions from a specific platform
hermes sessions prune --source telegram --older-than 60

# Skip confirmation
hermes sessions prune --older-than 30 --yes
信息

prune 只会删除已结束的会话,也就是那些已显式结束或自动重置的会话。活动中的会话永远不会被 prune。

Session Statistics

hermes sessions stats

输出示例:

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

如果你需要更深入的分析,例如 token 使用量、成本估算、工具拆分和活跃模式,可使用 hermes insights

Session Search Tool

agent 内置了一个 session_search 工具,它会利用 SQLite 的 FTS5 引擎,对过去的所有对话执行全文搜索。

How It Works

  1. FTS5 搜索匹配消息,并按相关性排序
  2. 按会话分组结果,选取前 N 个唯一会话(默认 3 个)
  3. 加载每个会话的对话内容,并截取匹配点周围约 100K 字符
  4. 发送给快速摘要模型,生成聚焦摘要
  5. 返回按会话划分的摘要结果,附带元数据与上下文

FTS5 Query Syntax

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

  • 简单关键字:docker deployment
  • 短语:"exact phrase"
  • 布尔逻辑:docker OR kubernetespython NOT java
  • 前缀:deploy*

When It's Used

系统提示会自动引导 agent 在适当时使用会话搜索:

"When the user references something from a past conversation or you suspect relevant prior context exists, use session_search to recall it before asking them to repeat themselves."

Per-Platform Session Tracking

Gateway Sessions

在消息平台中,会话会根据消息来源构造出的确定性 session key 进行索引:

Chat TypeDefault Key FormatBehavior
Telegram DMagent:main:telegram:dm:<chat_id>每个私聊一个会话
Discord DMagent:main:discord:dm:<chat_id>每个私聊一个会话
WhatsApp DMagent:main:whatsapp:dm:<chat_id>每个私聊一个会话
Group chatagent:main:<platform>:group:<chat_id>:<user_id>如果平台能提供用户 ID,则群内按用户隔离
Group thread/topicagent:main:<platform>:group:<chat_id>:<thread_id>默认是线程参与者共享一个会话;若设置 thread_sessions_per_user: true 则按用户隔离
Channelagent:main:<platform>:channel:<chat_id>:<user_id>如果平台能提供用户 ID,则频道内按用户隔离

如果 Hermes 无法为共享聊天获取参与者标识,就会退回为该房间共用一个会话。

Shared vs Isolated Group Sessions

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

  • Alice 和 Bob 可以在同一个 Discord 频道中和 Hermes 对话,但不会共享转录历史
  • 一个用户的长时间、重工具任务不会污染另一个用户的上下文窗口
  • 中断处理也是按用户隔离的,因为 running-agent key 与隔离后的 session key 一一对应

如果你想让一个群组共享同一个“房间大脑”,可以设置:

group_sessions_per_user: false

这样 group / channel 会退回为每个房间共享一个会话,能够保留共享上下文,但同时也会共享 token 成本、中断状态和上下文增长。

Session Reset Policies

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

  • idle - 空闲 N 分钟后重置
  • daily - 每天固定时刻重置
  • both - 先满足哪个条件就按哪个重置
  • none - 从不自动重置

在会话自动重置之前,agent 会先得到一个机会,把这段对话中重要的记忆或技能保存下来。

如果某个会话中有活跃的后台进程,则无论策略如何都不会自动重置。

Storage Locations

WhatPathDescription
SQLite database~/.hermes/state.db所有会话元数据和消息,带 FTS5 搜索
Gateway transcripts~/.hermes/sessions/每个会话的 JSONL transcript,以及 sessions.json 索引
Gateway index~/.hermes/sessions/sessions.json将 session key 映射到活动 session ID

SQLite 数据库采用 WAL 模式,适合网关的多平台架构,因为它能很好地支持多个 reader 和单个 writer。

Database Schema

state.db 中的关键表包括:

  • sessions - 会话元数据(id、source、user_id、model、title、timestamps、token counts)。标题带唯一索引(允许 NULL,只有非 NULL 必须唯一)。
  • messages - 完整消息历史(role、content、tool_calls、tool_name、token_count)
  • messages_fts - 使用 FTS5 的虚拟表,用于对消息内容做全文搜索

Session Expiry and Cleanup

Automatic Cleanup

  • 网关会话会按配置的重置策略自动重置
  • 在重置之前,agent 会把即将过期会话中的记忆和技能保存下来
  • 可选启用自动 prune:当 sessions.auto_prunetrue 时,CLI / 网关 启动时会清理那些早于 sessions.retention_days(默认 90 天)的已结束会话
  • 如果本次 prune 实际删除了记录,则会对 state.db 执行 VACUUM 以回收磁盘空间(SQLite 普通 DELETE 不会缩小文件)
  • prune 最多每 sessions.min_interval_hours 执行一次(默认 24 小时);最后执行时间记录在 state.db 中,因此同一 HERMES_HOME 下的所有 Hermes 进程都会共享这份状态

默认是关闭的,因为会话历史对于 session_search 回忆过去对话非常有价值,而静默删除这些内容可能会让用户意外。你可以在 ~/.hermes/config.yaml 中启用它:

sessions:
auto_prune: true # opt in — default is false
retention_days: 90 # keep ended sessions this many days
vacuum_after_prune: true # reclaim disk space after a pruning sweep
min_interval_hours: 24 # don't re-run the sweep more often than this

无论过了多久,活动中的会话都不会被自动 prune。

Manual Cleanup

# Prune sessions older than 90 days
hermes sessions prune

# Delete a specific session
hermes sessions delete <session_id>

# Export before pruning (backup)
hermes sessions export backup.jsonl
hermes sessions prune --older-than 30 --yes
提示

数据库增长通常很慢,几百个会话一般也只有 10 到 15 MB,而会话历史还能为 session_search 提供跨对话回忆能力,因此默认关闭自动 prune。如果你在运行重负载的网关或 cron 任务,且 state.db 已明显影响性能(一个观察到的失败模式是大约 1000 个会话导致 state.db 增长到 384 MB,从而拖慢 FTS5 插入和 /resume 列表),再考虑启用它。对于一次性清理,也可以直接运行 hermes sessions prune,无需打开自动清扫。