会话
Hermes Agent 会自动将每次对话保存为一个会话。会话功能支持对话恢复、跨会话搜索以及完整的对话历史管理。
会话的工作原理
无论来自 CLI、Telegram、Discord、Slack、WhatsApp、Signal、Matrix 还是任何其他消息平台的对话,都会以完整消息历史的形式存储为一个会话。会话通过两个互补的系统进行追踪:
- SQLite 数据库(
~/.hermes/state.db)—— 使用 FTS5 全文搜索的结构化会话元数据 - JSONL 转录文件(
~/.hermes/sessions/)—— 包含工具调用(网关)的原始对话转录
SQLite 数据库存储以下内容:
- 会话 ID、来源平台、用户 ID
- 会话标题(唯一、人类可读的名称)
- 模型名称和配置
- 系统提示快照
- 完整的消息历史(角色、内容、工具调用、工具结果)
- Token 统计(输入/输出)
- 时间戳(
started_at、ended_at) - 父会话 ID(用于压缩触发的会话拆分)
会话来源
每个会话都标记了其来源平台:
| 来源 | 描述 |
|---|---|
cli | 交互式 CLI(hermes 或 hermes chat) |
telegram | Telegram 消息应用 |
discord | Discord 服务器/私信 |
slack | Slack 工作区 |
whatsapp | WhatsApp 消息应用 |
signal | Signal 消息应用 |
matrix | Matrix 房间和私信 |
mattermost | Mattermost 频道 |
email | 邮件(IMAP/SMTP) |
sms | 通过 Twilio 的短信 |
dingtalk | 钉钉消息应用 |
feishu | 飞书/Lark 消息应用 |
wecom | 企业微信 |
weixin | 个人微信 |
bluebubbles | 通过 BlueBubbles macOS 服务器的 Apple iMessage |
homeassistant | Home Assistant 对话 |
webhook | 入站 Webhook |
api-server | API 服务器请求 |
acp | ACP 编辑器集成 |
cron | 定时任务(cron) |
batch | 批处理运行 |
CLI 会话恢复
使用 --continue 或 --resume 从 CLI 恢复之前的对话:
继续最近的会话
# Resume the most recent CLI session
hermes --continue
hermes -c
# Or with the chat subcommand
hermes chat --continue
hermes chat -c
此命令会从 SQLite 数据库中查找最近的 cli 会话,并加载其完整的对话历史。
按名称恢复
如果你已为会话设置了标题(参见下方的 会话命名),可以通过名称恢复:
# 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 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
会话 ID 在退出 CLI 会话时显示,也可通过 hermes sessions list 查看。
恢复时的对话摘要
当你恢复一个会话时,Hermes 会在输入提示前以样式化面板的形式展示之前对话的紧凑摘要:
恢复模式会在返回实时提示前,显示一个包含最近用户和助手对话的紧凑摘要面板。
摘要内容包括:
- 显示 用户消息(金色
●)和 助手回复(绿色◆) - 截断 长消息(用户消息截断为 300 字符,助手消息截断为 200 字符或 3 行)
- 折叠 工具调用为数量和工具名称(例如
[3 次工具调用: terminal, web_search]) - 隐藏 系统消息、工具结果和内部推理
- 限制 最多显示最近 10 次交互,并以 "... N 条更早的消息 ..." 指示符结尾
- 使用 浅色样式 区分于当前活跃对话
如需禁用摘要,保持最小化的一行行为,可在 ~/.hermes/config.yaml 中设置:
display:
resume_display: minimal # default: full
会话 ID 的格式为 YYYYMMDD_HHMMSS_<8位十六进制>,例如 20250305_091523_a1b2c3d4。你可以通过 ID 或标题恢复会话——两者都支持 -c 和 -r 参数。
会话命名
为会话设置人类可读的标题,以便轻松查找和恢复。
自动生成的标题
Hermes 在首次交互后会自动为每个会话生成一个简短的描述性标题(3–7 个词)。该过程在后台线程中使用快速辅助模型执行,不会增加延迟。你可以在使用 hermes sessions list 或 hermes sessions browse 浏览会话时看到自动生成的标题。
自动命名仅在每个会话中触发一次,如果你已手动设置标题,则会跳过自动命名。
手动设置标题
在任意聊天会话(CLI 或网关)中使用 /title 斜杠命令:
/title my research project
标题会立即生效。如果会话尚未在数据库中创建(例如你在发送第一条消息前就运行了 /title),则会暂存标题,并在会话启动时应用。
你也可以从命令行重命名现有会话:
hermes sessions rename 20250305_091523_a1b2c3d4 "refactoring auth module"
标题规则
- 唯一性 —— 两个会话不能共享相同标题
- 最大 100 个字符 —— 保持列表输出整洁
- 已净化 —— 自动移除控制字符、零宽字符和 RTL 覆盖符
- 正常 Unicode 字符均可使用 —— 表情符号、CJK 字符、带重音符号的字符均支持
压缩时的自动继承链
当会话的上下文被压缩(通过 /compress 手动执行或自动触发)时,Hermes 会创建一个新的延续会话。如果原始会话有标题,新会话将自动获得编号标题:
"my project" → "my project #2" → "my project #3"
当你通过名称恢复会话(hermes -c "my project")时,系统会自动选择该会话 lineage 中最新的一个。
消息平台中的 /title 命令
/title 命令在所有网关平台(Telegram、Discord、Slack、WhatsApp)中均有效:
/title My Research— 设置会话标题/title— 显示当前标题
会话管理命令
Hermes 通过 hermes 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 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 specific session (with confirmation)
hermes sessions delete 20250305_091523_a1b2c3d4
# Delete without confirmation
hermes sessions delete 20250305_091523_a1b2c3d4 --yes
重命名会话
# 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
如果标题已被其他会话使用,将显示错误信息。
清理旧会话
# 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
清理操作仅删除 已结束 的会话(即显式结束或自动重置的会话)。活跃会话永远不会被清理。
会话统计信息
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 工具,使用 SQLite 的 FTS5 引擎对所有历史对话执行全文搜索。
工作原理
- FTS5 搜索匹配的消息,并按相关性排序
- 按会话分组,选取前 N 个唯一会话(默认为 3 个)
- 加载每个会话的对话内容,截取约 100K 字符,以匹配内容为中心
- 发送到快速摘要模型,生成聚焦摘要
- 返回每个会话的摘要,附带元数据和上下文信息
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
这将使群组/频道恢复为每个房间一个共享会话,从而保留共享对话上下文,但也会共享 token 成本、中断状态和上下文增长。
会话重置策略
网关会话根据可配置策略自动重置:
- idle — 空闲 N 分钟后重置
- daily — 每天特定时间重置
- both — 两者中任一条件先满足即重置(空闲或每日)
- none — 永不自动重置
在会话自动重置前,代理会获得一次机会,保存对话中的重要记忆或技能。
带有 活跃后台进程 的会话,无论策略如何,均不会被自动重置。
存储位置
| 项目 | 路径 | 描述 |
|---|---|---|
| SQLite 数据库 | ~/.hermes/state.db | 所有会话元数据 + 带 FTS5 的消息 |
| 网关对话记录 | ~/.hermes/sessions/ | 每个会话的 JSONL 格式对话记录 + sessions.json 索引文件 |
| 网关索引 | ~/.hermes/sessions/sessions.json | 将会话键映射到活跃会话 ID |
SQLite 数据库使用 WAL 模式,支持并发读取和单写入,非常适合网关的多平台架构。
数据库 Schema
state.db 中的关键表:
- sessions — 会话元数据(id、source、user_id、model、title、时间戳、token 数量)。标题字段具有唯一索引(允许 NULL 标题,但非 NULL 标题必须唯一)。
- messages — 完整的消息历史(role、content、tool_calls、tool_name、token_count)
- messages_fts — FTS5 虚拟表,用于在消息内容中进行全文搜索
会话过期与清理
自动清理
- 网关会话根据配置的重置策略自动重置
- 重置前,代理会保存即将过期会话的记忆和技能
- 结束的会话会保留在数据库中,直到被清理
手动清理
# 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)。清理主要适用于删除不再需要用于搜索召回的旧对话。