会话
Hermes Agent 会自动将每次对话保存为一个会话。会话功能支持对话续接、跨会话搜索以及完整的对话历史管理。
会话如何工作
无论通过 CLI、Telegram、Discord、Slack、WhatsApp、Signal、Matrix 还是其他任何消息平台发起的对话,都会被完整记录为一个会话,并保留全部消息历史。会话由两个互补系统共同追踪:
- SQLite 数据库(
~/.hermes/state.db)—— 结构化会话元数据,支持 FTS5 全文检索 - JSONL 转录文件(
~/.hermes/sessions/)—— 原始对话转录,包含工具调用(网关)
SQLite 数据库存储以下信息:
- 会话 ID、来源平台、用户 ID
- 会话标题(唯一、可读性强的名称)
- 模型名称与配置
- 系统提示快照
- 完整的消息历史(角色、内容、工具调用、工具结果)
- Token 统计(输入/输出)
- 时间戳(开始时间、结束时间)
- 父会话 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 | 企业微信(WeCom) |
weixin | 微信个人号(Weixin) |
bluebubbles | 通过 BlueBubbles macOS 服务器的 Apple iMessage |
qqbot | QQ Bot(腾讯QQ)通过官方 API v2 |
homeassistant | Home Assistant 对话 |
webhook | 入站 Webhook |
api-server | API 服务器请求 |
acp | ACP 编辑器集成 |
cron | 定时 Cron 任务 |
batch | 批量处理运行 |
CLI 中的会话续接
使用 hermes resume 或 hermes continue 命令从 CLI 续接之前的对话:
继续最近一次会话
hermes continue
此命令会从 SQLite 数据库中查找最近一次的会话,并加载其完整的对话历史。
按名称续接
如果你已为会话设置了标题(见下方 会话命名),可通过名称恢复:
hermes resume "项目需求分析"
恢复特定会话
hermes resume <session_id>
会话 ID 在退出 CLI 会话时显示,也可通过 hermes list 查看。
续接时的对话摘要
当你恢复一个会话时,Hermes 会在输入提示前以样式面板形式展示上次对话的简洁摘要:
续接模式会在返回实时输入提示前,显示一个紧凑的摘要面板,包含最近的用户与助手对话回合。
该摘要包含:
- 用户消息(金色
●)和 助手回复(绿色◆) - 截断长消息(用户消息最多 300 字符,助手回复最多 200 字符或 3 行)
- 折叠工具调用 为数量加工具名(如:
[3 tool calls: terminal, web_search]) - 隐藏 系统消息、工具结果和内部推理过程
- 上限 最近 10 次交互,并显示“... N 条更早的消息 ...”指示
- 使用 浅色样式 区分于当前活跃对话
若要禁用摘要,保持最小化的一行提示行为,请在配置中设置:
"show_recap": false
会话 ID 格式为 YYYYMMDD_HHMMSS_<8-char-hex>,例如 20250305_091523_a1b2c3d4。你可以通过 ID 或标题进行恢复 —— 两者均兼容 hermes resume 和 hermes continue 命令。
会话命名
为会话赋予人类可读的标题,以便轻松查找和恢复。
自动生成标题
Hermes 在首次交流后会自动为每个会话生成一个简短描述性标题(3–7 个词)。该过程在后台线程中使用快速辅助模型完成,不会引入延迟。你可以在使用 hermes list 或 hermes browse 浏览会话时看到自动生成的标题。
自动命名仅对每个会话执行一次,且若你已手动设置标题,则跳过。
手动设置标题
在任意聊天会话中(CLI 或网关)使用 /title 命令:
/title 项目需求分析
标题会立即生效。如果会话尚未创建数据库记录(例如你在发送第一条消息前运行 hermes start),则标题会被暂存,待会话启动后应用。
你也可以从命令行重命名现有会话:
hermes rename <session_id> "新标题"
标题规则
- 唯一性 —— 不能有两个会话共享相同标题
- 最大 100 个字符 —— 保持列表输出整洁
- 自动清理 —— 控制字符、零宽字符、RTL 覆盖等会被自动移除
- 正常 Unicode 可用 —— 表情符号、CJK 字符、带变音符号的字符均可使用
压缩时的自动继承链
当会话上下文被压缩(通过 /compress 手动触发或自动触发)时,Hermes 会创建一个新的延续会话。如果原会话有标题,新会话将自动获得编号标题:
项目需求分析 (1)
项目需求分析 (2)
当你通过名称恢复(hermes resume "项目需求分析")时,系统会自动选择该继承链中最新的会话。
消息平台中的 /title 命令
/title 命令在所有网关平台(Telegram、Discord、Slack、WhatsApp)中均可用:
title 项目需求分析—— 设置会话标题title—— 显示当前标题
会话管理命令
Hermes 提供了一整套会话管理命令,通过 hermes session 命令访问:
列出会话
hermes session list
当会话有标题时,输出显示标题、预览和相对时间戳:
ID: abc123 | Title: 项目需求分析 | Last: 2 小时前 | Preview: 用户要求增加权限控制...
当没有标题时,使用简化格式:
ID: abc123 | Source: Telegram | Last: 5 分钟前
导出会话
hermes session export <session_id>
导出文件每行包含一个 JSON 对象,包含完整的会话元数据和所有消息。
删除会话
hermes session delete <session_id>
重命名会话
hermes session rename <session_id> "新标题"
如果目标标题已被其他会话占用,将显示错误。
清理旧会话
hermes session prune --days=30
清理操作仅删除 已结束 的会话(即显式结束或自动重置的会话)。活跃会话永远不会被清理。
会话统计
hermes session stats
输出示例:
Total sessions: 142
Active sessions: 3
Sessions in last 7 days: 28
Average message count per session: 15.6
Total tokens used: 1,245,000
如需更深入的分析(Token 使用量、成本估算、工具使用分布、活动模式等),请使用 hermes insights 。
会话搜索工具
Agent 内置了 session_search 工具,利用 SQLite 的 FTS5 引擎对所有过往对话进行全文搜索。
工作原理
- FTS5 搜索匹配消息并按相关性排序
- 按会话分组,取前 N 个(默认 3 个)不重复的会话
- 加载每个会话的对话内容,截取约 10 万字符,聚焦于匹配位置
- 发送至快速摘要模型生成重点摘要
- 返回每个会话的摘要,附带元数据和上下文
FTS5 查询语法
搜索支持标准 FTS5 查询语法:
- 简单关键词:
项目需求 - 词组:
"权限控制流程" - 布尔运算:
项目 AND 需求,项目 NOT 测试 - 前缀匹配:
项目*
使用时机
Agent 会自动提示使用会话搜索:
"当用户提及过去对话中的内容,或你怀疑存在相关上下文时,请使用 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> | 所有线程参与者共享一个会话(默认)。使用 thread_sessions_per_user: true 可改为按用户独立会话。 |
| 频道 | agent:main:<platform>:channel:<chat_id>:<user_id> | 当平台暴露用户 ID 时,按用户独立会话 |
当 Hermes 无法获取共享聊天的参与者标识符时,将回退到该房间内使用单一共享会话。
共享 vs 隔离群组会话
默认情况下,Hermes 使用 group_sessions_per_user: true 在 config.yaml 中运行。这意味着:
- 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 模式,支持多个读取者和单个写入者,非常适合网关的多平台架构。
数据库结构
state.db 中的关键表:
- sessions — 会话元数据(id、来源、user_id、模型、标题、时间戳、token 数量)。标题字段具有唯一索引(允许 NULL 值,仅非 NULL 值需唯一)。
- messages — 完整的消息历史(角色、内容、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)。清理主要适用于移除不再需要用于搜索召回的旧对话。