Russ534

cross-platform-context-sync

Use when one user talks via multiple channels.

Russ534 0 Actualitzat fa 4 d
GitHub

Instal·la

npx skillscat add russ534/myopenclawbot/cross-platform-context-sync

Instal·la des del registre de SkillsCat.

SKILL.md

跨端对话上下文同步

问题

Hermes 的每个对话端(weixin / telegram / cli)各自是独立 session:

  • 同一 profile、同一 memory、同一 skills —— 但会话历史互不可见
  • 用户在微信说的事,TG 端的 agent 完全不知道
  • state.db 里三端数据都在,但没有任何机制把它们串起来

用户原话:“我两之间就不会出现信息不对称的问题了”。

方案(两层注入,零 LLM 成本)

层 文件 注入方式 覆盖端
紧凑摘要 $HERMES_HOME/AGENTS.md 的标记区块 每轮自动注入(cwd 链) 微信 / TG(gateway cwd=HERMES_HOME)
完整版 $HERMES_HOME/shared-context/DIGEST.md 按需主动读 全部(含 cwd 不在 HOME 的 CLI)
兜底指引 $HERMES_HOME/SOUL.md 每轮自动注入(与 cwd 无关) 全部

关键点:SOUL.md 从 HERMES_HOME 加载,不受 cwd 影响;AGENTS.md 走 cwd 目录链,cwd 不是 HOME 时加载不到。两个都要配。

实现步骤

1. 同步脚本 $HERMES_HOME/scripts/sync-digest.py

从 state.db 读三端最近对话,写两个文件。要点:

  • 只读连接:sqlite3.connect(f"file:{STATE_DB}?mode=ro", uri=True)
  • 会话表主键是 id 不是 session_id;source 字段区分平台
  • 每个平台只取「最近活跃的那一个 session」(seen_sources 去重)。一个端可能积了几十个历史 session,混在一起会把旧 session 的新消息插到前面,时间顺序直接乱掉 —— 这是实测踩到的 bug。
  • 对话分段:用户要的是“聊完(间隔 >15 分钟)才汇总”,不是把几小时前聊到一半的内容也拖进来。做法:消息按 timestamp 正序,从最后一条往前走,相邻间隔 > IDLE_MINUTES 就停 → 只保留最后一段。段只有一两条也照原样返回(宁可短,不掺旧内容)。
  • 状态标注:每段末尾消息距今 > IDLE_MINUTES → 标“已结束 N 分钟”,否则“进行中”。让人一眼看出哪个端刚聊过。
  • 消息配对:不要直接取最近 N 条 —— 工具调用说明会淹没正文。取 limit*6 条原始消息,然后只保留每条 user 消息 + 它之后的第一条 assistant 回复。
  • 噪音过滤:跳过 [OUT-OF-BAND USER MESSAGE、Gateway message origin、Your request was not processed、[System: 开头的消息
  • 体积硬上限:紧凑版 ≤3500 字符,完整版 ≤9000 字符,超了从最早段落丢
  • 只在内容变化时写盘(比较时剔除时间戳行),避免每 5 分钟刷 mtime

2. AGENTS.md 标记区块

<!-- CROSS-PLATFORM:BEGIN — 由 sync-digest.py 自动生成,勿手改 -->
_(等待首次同步)_
<!-- CROSS-PLATFORM:END -->

脚本用 find 定位两个标记后整段替换,找不到标记就跳过(不破坏手写内容)。

3. SOUL.md 加静态指引

写清:三端隔离、两个文件在哪、触发规则(用户说“刚才/上次/我跟你说过”而当前会话找不到 → 先读 DIGEST.md 再答)。这段必须在 SOUL.md 而不是只放 AGENTS.md,否则 CLI 端看不到。

同时要教它认自己在哪个端:每轮 system prompt 的 **Source:** 行就是当前平台(Weixin / Telegram / cli / local)。规则写成:先认端再说话;当前端的事直接答不用翻文件;只有指代不在当前会话里时才查共享文件;在某端做了影响全局的改动要说明“另外两端也会看到”。不写这条,agent 会把三端的事混在一起说“你刚才说…”。

4. 挂 cron(纯脚本,无 LLM)

hermes cron create "5m" --name "跨端记忆同步" \
  --script sync-digest.py --no-agent --deliver local

--no-agent 是关键:script stdout 直接投递,不启动 agent、不烧 token。--deliver local 避免每 5 分钟骚扰用户。

验证(必须真跑,别只看配置)

# 1. 脚本能出内容
/opt/hermes/.venv/bin/python $HERMES_HOME/scripts/sync-digest.py

# 2. AGENTS.md 注入真的生效(cwd 必须是 HERMES_HOME)
cd $HERMES_HOME && hermes chat --in $HERMES_HOME -q "不用工具,直接答:AGENTS.md 里 CROSS-PLATFORM 区块第一条是什么?"

# 3. SOUL.md 兜底生效(cwd 故意选非 HOME 目录)
cd /opt/hermes && hermes chat -q "不用工具,直接答:如果我问'上次在TG端说了什么',你该去哪找?"

# 4. cron 真的跑
hermes cron run <job_id> && hermes cron runs <job_id>

坑

  • cwd=None 的 gateway 会话 用 os.getcwd() 解析(prompt_builder.py 里 cwd_path = Path(cwd if cwd is not None else os.getcwd()))。gateway 进程 cwd 通常是 $HERMES_HOME,所以 AGENTS.md 生效;但 cli session 记录的 cwd 可能是 /opt/hermes(安装树),此时 AGENTS.md 不加载 —— 这就是必须配 SOUL.md 的原因。
  • 安装树内的 AGENTS.md 会被抑制(_project_context_suppressed),别指望往 /opt/hermes/AGENTS.md 塞东西。
  • CONTEXT_FILE_MAX_CHARS = 20000(prompt_builder.py),动态上限会更大。紧凑摘要控制在 3-4K 字符内,别把注入区撑成第二个上下文。
  • 凭据会进 DIGEST(用户贴的 key/token 会被摘要进去)。在 SOUL.md / AGENTS.md 里要求用 前缀...后缀 指代,别复述完整密钥。
  • 敏感信息多的场景,可在脚本里加正则脱敏再落盘。