Hindsight 接入Hermes 多用户方案

清夏晚风 Lv7

适用环境:Hermes Agent(provider: hindsight),飞书(Feishu)网关,Hindsight 本地 local_external 模式(http://101.35.23.33:8888
方案结论:飞书原生适配,无需改源码,仅改一个配置文件即可实现 per-user 物理隔离

一、需求

  • 用户隔离记忆:每个用户使用自己的用户 ID 作为独立记忆库
  • 群聊场景(暂不做群共享记忆,按用户维度隔离即可)
  • 尽量不改写源码

二、结论(已实测验证)

飞书完全适配,且是原生支持的一等公民功能,无需 hack、无需改源码
✅ 仅需在 Hindsight 配置文件加一行 bank_id_template,即可让每个飞书用户自动获得独立记忆 bank
✅ 多用户隔离通过物理 bank 维度实现,完全不可能串台

三、核心机制(均有源码行号佐证)

机制 代码位置 作用
插件 initialize() 接收 user_id plugins/memory/hindsight/__init__.py:1245 self._user_id = kwargs.get("user_id") 网关会话的 platform user id(飞书 open_id)自动传入
bank_id_template 支持 {user} 占位符 :985(schema)/ :1288(读取) 动态生成 per-user bank,如 hermes-ou_4303...
_resolve_bank_id_template :584-614 占位符渲染+消毒;user 为空时安全回退 fallback
agent_init.py 转发 user_id agent_init.py:1197-1200 _init_kwargs["user_id"] = agent._user_id 把 agent 层 user_id 喂给 memory provider
飞书适配器解析 sender plugins/platforms/feishu/adapter.py:3919-3950 open_id / user_id / union_id 映射为 Hermes user_id

飞书 ID 优先级(adapter.py:3927-3940 注释):

  1. user_idu_xxx,tenant-scoped,需 contact:user.employee_id:readonly 权限)
  2. 回退 open_idou_xxx,app-scoped,始终可用

适配器明确说明(adapter.py:40-45):single-bot 模式下 open_id 即为稳定的用户唯一标识。无论走哪个,都是稳定唯一 ID,隔离均生效。

四、完整数据链路(已逐环验证)

飞书事件 payload.sender.open_id = “ou_4303…”

adapter.py:3920 _resolve_sender_profile()
primary_id = user_id or open_id # :3940
return {“user_id”: primary_id, …} # :3946-3949

adapter.py:2847 MessageEvent(user_id=sender_profile[“user_id”])

agent_init.py:1197 _init_kwargs[“user_id”] = agent._user_id

hindsight/init.py:1245 self._user_id = kwargs.get(“user_id”)

hindsight/init.py:1289 _resolve_bank_id_template(“hermes-{user}”, user=self._user_id)

生成的 bank = hermes-ou_4303d0342138149983bf020dc365cecb

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

## 五、落地配置

### 文件:`$HERMES_HOME/hindsight/config.json`

当前实际路径:`/opt/data/hindsight/config.json`

```json
{
"mode": "local_external",
"apiKey": "",
"timeout": 120,
"idle_timeout": 300,
"retain_tags": "",
"observation_scopes": "",
"retain_source": "",
"retain_user_prefix": "User",
"retain_assistant_prefix": "Assistant",
"banks": {
"hermes": {
"bankId": "hermes",
"budget": "mid",
"enabled": true
}
},
"api_url": "http://101.35.23.33:8888",
"bank_id": "hermes",
"bank_id_template": "hermes-{user}",
"recall_budget": "mid"
}

唯一新增行"bank_id_template": "hermes-{user}"
(其余字段均为原有配置,原样保留;bank_id: hermes 作为 fallback 保留,不破坏旧链路)

六、生效效果

场景 实际 bank
你(ou_4303…)发消息 hermes-ou_4303d0342138149983bf020dc365cecb(个人,隔离)
未来其他人在群里 hermes-ou_xxxx(各自独立,不串)
未来其他人私聊 hermes-ou_yyyy(各自独立,不串)
user 解析失败/为空 回退 hermes(安全兜底)

模板渲染实测验证(调用插件内部 _resolve_bank_id_template):

1
2
user bank  => hermes-ou_4303d0342138149983bf020dc365cecb
empty user => hermes

七、群共享记忆(本次明确暂不做)

  • 不做的原因:群级共享记忆需 {chat} 占位符,而插件当前只支持 {profile} {workspace} {platform} {user} {session} 五个(无 {chat})。加 {chat} 需改插件源码,违背”尽量不改源码”原则。
  • 当前行为:群里每个人仍按 ou_xxx 隔离进各自的 hermes-{user} bank,没有群级共享层。
  • 将来若要做群共享,两条路:
    1. 改插件加 group_bank_id_template + {chat} 占位符(最小改动,约 2 处插件内扩展,不改核心)
    2. 群共享核心知识降级进 L1(MEMORY.md),由全用户注入——即官方 L1+L2 双层设计的本意

八、必须注意的 3 个事项

  1. 需重启 Hermes 进程:插件在 initialize() 时读取 config.json,新增 bank_id_template 不会热加载。重启前新记忆仍进 hermes bank,重启后才进 hermes-ou_4303...
  2. 旧记忆不自动迁移:原有 35 条记忆在 hermes bank,启用 template 后新记忆进 hermes-ou_4303...旧条不会自动搬。需手动迁移(用户自行处理)。
  3. 个人 vs 群共享分类:由于暂不做群记忆,无需分类;若将来引入群共享,需先界定”个人记忆”与”群共享记忆”边界。

九、验证方法(重启后)

  • 发一条带个人偏好的消息 → 调用 hindsight_recall 确认命中 hermes-ou_4303...
  • 让群里另一个用户发消息 → 确认其记忆进入各自 hermes-ou_xxxx,不串入你的 bank
  • 观察插件日志:Hindsight bank resolved from template ... user=ou_4303... -> bank=hermes-ou_4303...

方案制定日期:2026-07-11|基于运行实例 /opt/hermes(而非源码仓库 /opt/data/hermes-agent)的插件源码逐行验证

  • Title: Hindsight 接入Hermes 多用户方案
  • Author: 清夏晚风
  • Created at : 2026-07-11 11:07:57
  • Updated at : 2026-07-19 01:57:11
  • Link: https://blog.yuil.cn/2026/07/11/AI相关工具/AI Agent/Hermes Agent/长期记忆、灵魂、用户画像/Hindsight 外挂记忆/Hindsight 接入Hermes 多用户方案/
  • License: This work is licensed under CC BY-NC-SA 4.0.
Comments