docs(design): 新增 §8.8 channel 长会话上下文治理(Phase 1 / Phase 2-3 design)(bump 0.32.1)

记 channel 常驻会话上下文软重置的设计:根因、业界对照(OpenClaw/Hermes/
Claude Code)、「边界而非删除」心智、Phase 1 已落地(context_base_idx 软重置
+ gap 自动分段 + 新话题命令 + 否决的替代方案)、Phase 2(阈值结构化摘要,
对齐 Hermes 阶段③)/ Phase 3(sqlite-vec/FTS5 持久检索)design。
回链修 §8.7、§8.2 两处引用。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
caoqianming 2026-06-29 10:47:02 +08:00
parent b27cc9cd5b
commit 89062d99b3
2 changed files with 27 additions and 3 deletions

View File

@ -566,7 +566,7 @@ create index on usage_events (model_profile, created_at);
**选型**:Context Editing + Memory/File State + Cache Observability 混合。稳定 system/tools 前缀利于 provider cache;旧 tool result 移除或压缩;关键发现写 task summary / FS,需要时 `read` 重新拉。长上下文保留作少数全局推理的临时能力,非默认每轮成本。
**落地形态**:`core/context.py` 发送前压缩旧 tool / `load_skill` / assistant tool_call arguments(保 `role/tool_call_id/name` 协议完整),不改持久化历史;**上下文压力门槛**(2026-06-10):总 chars 未逼近上限则完全跳过压缩、原样发,护 DeepSeek 前缀缓存(短任务字节逐轮一致、命中 92-94%)。task summary(旧消息压成一条、区分硬约束/计划/文件路径/关键事实)为第二步,未做。
**落地形态**:`core/context.py` 发送前压缩旧 tool / `load_skill` / assistant tool_call arguments(保 `role/tool_call_id/name` 协议完整),不改持久化历史;**上下文压力门槛**(2026-06-10):总 chars 未逼近上限则完全跳过压缩、原样发,护 DeepSeek 前缀缓存(短任务字节逐轮一致、命中 92-94%)。task summary(旧消息压成一条、区分硬约束/计划/文件路径/关键事实)为第二步,未做 —— 已并入 §8.8 Phase 2(对齐 Hermes 结构化摘要)统一推进。channel 常驻会话的无限累积另由 §8.8 软重置分段治理(本节压缩挡不住跨时段累积)
### 8.3 PPTX 前端在线预览(2026-06-09,✅ 已落地 Stage 1)
@ -690,7 +690,7 @@ create index on usage_events (model_profile, created_at);
- **推送择优**:简报这类"必达" → 优先企业微信(无条件);ClawBot 作个人微信触达 + 聊天;两者都绑可多投或按用户偏好。
**第一期两处已定决策(评审通过)**:
- **入站对话 → 每用户一条 persistent「微信」task**(聊天要连续性;token 增长靠 §8.2 context 压缩;打标签与网页 task 区分)。**两渠道入站都落到这条 task**。
- **入站对话 → 每用户一条 persistent「微信」task**(聊天要连续性;token 增长靠 §8.8 channel 长会话治理 = 软重置分段 + §8.2 context 压缩;打标签与网页 task 区分)。**两渠道入站都落到这条 task**。
- **敏感凭据入库一律加密列**(`bot_token`/`latest_context_token`;企业微信 secret 走 env 不入库)——env `ZCBOT_WECHAT_SECRET_KEY` 派生密钥;绝不进沙箱/日志/API 响应(§3.4)。
**唯一现实卡点 = 微信灰度可用性**:仅**国内个人微信**、需 **8.0.70+** 且功能灰度推送中(设置→插件),**不支持企业微信**(`bot_type=3`)。目标用户没有插件入口就用不了——落地前要先核实目标用户在灰度内。腾讯另保留**限频 / 决定可连哪些 AI / 随时终止**的权力(政策风险)。
@ -756,6 +756,30 @@ create index on usage_events (model_profile, created_at);
**渠道 B(企业微信,紧随)改动面**:env `WECOM_CORPID/AGENTID/SECRET`;`tools/wecom_push.py`(access_token 缓存 + `message/send` + `media/upload` + 渠道实现);`send_to_user` / `deliver_notify` 接 wecom 渠道;绑定抽象加 wecom 侧 + migration `0013`;OAuth 起始/回调 2 端点 + 前端"绑定企业微信"。**两渠道共用 `send_to_user` 抽象与绑定层**,故渠道 B 主要是"多一个渠道实现 + 一种绑定方式",不重写主体。
### 8.8 channel 长会话上下文治理(2026-06-29,Phase 1 ✅ 落地 / Phase 2-3 design)
**根因**:微信/企业微信入站对话复用**同一条常驻 chat task**(§8.7,per-user-per-channel 一条,要连续性),`Session.load()` 全量装回每轮 LLM 调用。web 任务"做完即止"故有天然边界,IM 是"用户当常驻助手永远在聊"→ 这条 task 只增不减,越用越贵/慢,终撞 context window。§8.2 的压缩只摘旧 tool 正文、门槛高(可靠上下文 50%)、从不删消息,挡不住 IM 这种无限累积。
**业界对照(2026-06-29 调研:OpenClaw / Hermes(NousResearch)/ Claude Code)**:三家都是"阈值触发摘要 + 头尾保护 + 旧 tool 输出先剪枝"。Hermes 最清晰:双阈值(agent 内 50% + gateway 85% 兜底)+ 四阶段(剪枝→边界检测 protect 头3+尾N→结构化摘要中段→重组保 tool 配对),摘要**增量更新**且保留 file path/ID/数值原文(mem0 实测:摘要会静默丢精确值/硬约束/决策理由)。OpenClaw/Hermes 另配持久记忆层(sqlite-vec / FTS5 + 跨会话)。**但三家都是单次 coding session,不解"IM 用三个月"的跨时段累积** —— 那是 IM 独有、最高杠杆且零信息损失的「会话分段」,本库自补(Phase 1)。
**心智:边界而非删除**。沿用 §8.2「禁止把『只保留最近 N 条』当主策略」「保留可追溯原文」——本设计**一条消息都不删**,只移动"喂给模型的窗口起点",全历史留 DB、web `/messages` 不 gate 照旧翻完整记录。
**Phase 1(✅ 2026-06-29):context_base_idx 软重置**
- `tasks.context_base_idx`(migration 0019,NOT NULL DEFAULT 0,additive)= 喂给模型的窗口起点。`Session.load()` 只装 `idx >= base` 的消息进 LLM 上下文。
- **关键不变量**:`_db_idx`(append 续号锚点)取 messages **真实总条数**而非加载条数 —— 否则下次 append 复用已存在 idx,撞 `uq_messages_task_idx`/覆盖历史。
- 两个触发口(`core/wechat/service.py`,仅入站走、push 不触发):
- **自动 gap 分段**(`maybe_gap_reset`):入站时距上次消息超 `config.json` `channel.session_gap_hours`(默 6h,`<=0` 关闭)→ 软重置,`base = 最后一条 user 消息 idx`。**不是失忆墙**:新窗口仍带"上一轮"原文做续聊锚点(用户"接着刚才说"接得上),零额外 LLM 调用、零延迟。
- **手动新话题**(`reset_channel_context(hard=True)`):用户发「新话题/新会话/`/new`/清空上下文」→ `base = 总数`,彻底从零(回执提示已归档)。
- 二者本质同一操作(推进 base)的被动/主动两口:被动断开要续上(软)、主动换题要干净(硬)。
- `clear_messages`(web 端清空)全删消息后 `base` 归 0(idx 从 0 重起,否则窗口起点悬空)。存量 task / web 普通任务 base 恒 0 = 喂全量,行为不变(对外契约友好)。
- **不选「每次 gap 开新 chat_task_id」**:会堆 `wechat-xxx-2/-3…` 文件夹(`working_dir_from_name` slug 写死)+ web 一堆 task 卡片;软重置零新文件夹/零新 task。**不选「kind='boundary' 标记消息」**:要混进消息流处理 tool 配对 + "别喂模型",列是纯元数据零侵入。
**Phase 2(design):阈值结构化摘要(补全 Hermes 阶段③)**。现 `core/context.py` 只做剪枝(旧 tool 截 2000 字)+ 尾部保护,缺"中段轮做 LLM 结构化摘要"。补:到门槛时把「base 之后、头 N 条之后、最近 keep_recent 之前」压成固定模板(目标/约束偏好/进展/待办),增量更新而非重写,保留 path/ID/数值原文。门槛接 Hermes 双层(50% + 85% 兜底,`_COMPACT_CONTEXT_RATIO`)。工程坑(mem0 列):辅助模型返非 JSON 降级回原文、tool 配对别被切断(复用 `_repair_dangling_tool_calls`)。**A(分段)砍跨话题累积,B(摘要)兜单段超长,两者正交**。
**Phase 3(design):持久检索(解"问很久以前的精确内容")**。软边界拿"跨边界精确回忆"换成本——梗概不够时(问上个月让查的具体数据),上 OpenClaw sqlite-vec / Hermes FTS5:新消息进来先语义/全文检索本 task 历史,命中原文注入当前窗口。工程最重,待 Phase 1/2 跑稳、确认确有此类需求再做(数据没删,随时能补)。
**落地次序**:Phase 1 上线观察 token 曲线 → 再定 Phase 2 门槛/是否做 → Phase 3 视真实"长期精确回忆"需求。
---
## 附录:DeepSeek V4 关键事实(2026-04-24)

View File

@ -1,3 +1,3 @@
# zcbot 版本号单一事实源:web/app.py 的 FastAPI version、/healthz 返回、前端展示都引这里。
# 改版本只动这一行。
__version__ = "0.32.0"
__version__ = "0.32.1"