Files
LangBot/plugins/KnowledgeEngine/LongTermMemory/docs/issue-plan-zh.md
T

16 KiB
Raw Blame History

LongTermMemory issue planning

本文档记录 langbot-longterm-memory 插件后续优化计划。当前阶段的原则是:

  • 不要求修改 LangBot core 或 langbot-plugin-sdk。
  • 保持 LongTermMemory 作为插件实现,而不是把 memory 变成 LangBot 内置业务功能。
  • 保留当前 L1/L2 两层架构,不急于引入 L0 goals、L3 procedural memory 等新事实层。
  • 优先补齐生产可用性:写入策略、召回质量、治理、审计、整合、透明性。

Current position

当前实现已经满足核心长期记忆闭环:

  • L1 core profile:稳定事实,存储在 plugin storage,并注入 system prompt。
  • L2 episodic memory:事件记忆,写入 vector DB,通过 metadata 做 scope 隔离和检索。
  • 自动注入:PromptPreProcessing 阶段注入 L1,并基于当前消息自动召回少量 L2。
  • 主动工具:remember、recall_memory、update_profile、forget。
  • 管理命令:!memory、!memory profile、!memory search、!memory list、!memory forget、!memory export。
  • 纠正机制:带 correction / fact-update / clarification 标签的新 episode 会尝试 supersede 相似旧 episode,降低旧记忆权重。

当前不会自动删除记忆:

  • L1 profile 只有显式 remove 或覆盖才会改变。
  • L2 episode 只有 forget 或 !memory forget <episode_id> 才会删除。
  • superseded episode 仍然保留在 vector DB 中,只是 importance 降低并标记 superseded_by。
  • time decay 只影响召回排序,不会硬删除。

Design stance

不建议把插件对外模型扩成多层:

  • 不新增 L0 Active Goals 作为 LongTermMemory 的核心层。
  • 不新增 L3 Procedural Memory 作为 LongTermMemory 的核心层。
  • goals / tasks 更像独立任务管理或个人助手插件,不应塞进长期记忆插件第一阶段。
  • procedural knowledge 可暂时用 L1 notes、session profile 或 L2 summary episode 表达。

推荐模型仍然是:

  • L1:当前稳定事实和画像。
  • L2:可追溯事件和历史。
  • Derived views:摘要、索引、候选记忆、归档状态、审计日志、supersede 关系。这些是派生能力,不是新的事实来源。

Issue 1: Clarify L1/L2 memory write policy

Priority: P0

Background

当前工具已有基本说明,但模型仍可能过度调用 remember,或把稳定偏好写成 L2 episode,把短期事件写进 L1 profile。长期运行后,这会带来噪声和画像污染。

Goal

明确告诉模型:

  • 什么时候写 L1。
  • 什么时候写 L2。
  • 什么时候不要写。
  • 纠正类信息如何同时处理 profile 和 episode。

Scope

更新以下位置:

  • components/tools/remember.yaml
  • components/tools/update_profile.yaml
  • components/tools/recall_memory.yaml
  • components/event_listener/memory_injector.py 中的注入说明
  • README.md 的 usage / best practices 部分

Suggested policy

L1 profile 只保存稳定、低频、当前有效的事实:

  • 姓名、身份、长期偏好。
  • 长期沟通风格。
  • 群聊或会话长期约定。
  • 用户明确纠正后的当前事实。

L2 episode 保存有时间语义、历史价值或上下文价值的事件:

  • 计划、行程、近期状态。
  • 某次对话中的决定。
  • 用户明确希望以后参考的事件。
  • 纠正发生的历史记录。

不要保存:

  • 一次性寒暄。
  • 临时情绪,除非用户明确希望记住。
  • 敏感隐私、密钥、凭证、一次性验证码。
  • 可能伤害用户或他人的推断性标签。
  • 未经确认的群聊八卦或第三方隐私。

Acceptance criteria

  • Tool prompts 对 L1/L2 边界表述一致。
  • README 中有 When to write L1 / L2 / nothing 小节。
  • 至少包含中文群聊和个人私聊示例。
  • 纠正类信息的处理规则清晰:更新 L1,必要时写 L2 保留历史。

Non-goals

  • 不引入自动记忆提取。
  • 不修改 LangBot core 或 SDK。

Issue 2: Add memory KB health check

Priority: P0

Background

L2 依赖 metadata filter 做隔离。README 已说明 Milvus / pgvector 等固定 schema 后端不适合当前实现,但用户仍可能误配。仅靠文档提醒不够。

Goal

增加运行时健康检查,帮助用户确认当前 pipeline 的 memory KB 是否可用且隔离可靠。

Proposed command

!memory health

Checks

  • memory KB 是否已创建。
  • memory KB 是否绑定到当前 pipeline。
  • embedding model 是否配置。
  • 当前 vector backend 是否能在写入后通过 user_key metadata filter 正确检索。
  • vector_list / vector_delete 是否能按 filter 工作。

Suggested probe

写入两条临时 probe:

  • user_key = health_probe_a
  • user_key = health_probe_b

然后分别按 user_key 查询,确认不会串 scope。最后删除 probe。

Acceptance criteria

  • !memory health 输出 OK、WARN 或 ERROR。
  • filter probe 失败时,明确提示该后端不适合 LongTermMemory。
  • health check 不会留下 probe 记忆。
  • README 安装步骤中增加 health check 建议。

Non-goals

  • 不要求 LangBot core 暴露 vector backend capability API。
  • 不强制阻止用户使用不兼容后端,但要给出明确风险提示。

Issue 3: Improve episodic recall with hybrid search and exact-match fallback

Priority: P1

Background

当前 L2 recall 主要依赖 vector similarity,再叠加 recency、importance、speaker、update signal。中文群聊、人名、ID、短标签、episode_id 等场景下,纯向量召回可能不稳定。

LangBot 的 vector API 已支持 search_type、query_text、vector_weight。Chroma 和 SeekDB 已有 hybrid / full-text 能力,插件可以优先使用,不需要改 core。

Goal

提升 recall 稳定性,特别是:

  • 中文短词。
  • 人名和群成员名。
  • sender_id / sender_name。
  • tags。
  • episode_id。
  • 精确事件名称。

Scope

  • MemoryStore.search_episodes
  • LongTermMemoryEngine.retrieve
  • recall_memory tool 参数和文档
  • memory_engine.yaml retrieval / creation schema

Proposed config

retrieval_strategy: vector | hybrid | auto
vector_weight: 0.7
exact_match_boost: true

Default should be auto:

  • use hybrid when backend supports it or when it succeeds;
  • fallback to vector when hybrid fails.

Acceptance criteria

  • Automatic L2 recall and recall_memory both support the configured strategy.
  • Hybrid mode passes query_text to vector_search.
  • Exact match on episode_id can find the episode without relying on embedding.
  • Exact match on sender_name / tags can boost or include results.
  • If hybrid search fails, recall falls back to vector and logs warning.

Non-goals

  • 不实现新的 CJK tokenizer。
  • 不引入外部 search service。

Issue 4: Add episode lifecycle status

Priority: P1

Background

当前只有 delete 和 supersede。旧记忆不会自动删除,superseded episode 仍可能被召回,只是权重降低。长期运行后,需要更清晰的生命周期。

Goal

为 L2 episode 增加生命周期状态,避免默认召回过期或被整合的记忆,同时保留可追溯性。

Proposed statuses

active
superseded
archived
deleted

Recommended semantics:

  • active: 默认可召回。
  • superseded: 默认不召回,或强降权;管理命令可查。
  • archived: 普通 recall 不返回;管理命令可查。
  • deleted: 物理删除或 tombstone,取决于审计策略。

Scope

  • episode metadata 增加 status
  • auto-supersede 时设置旧 episode status=superseded
  • recall 默认过滤 status=active
  • 管理命令支持 --include-superseded 和 --include-archived

Acceptance criteria

  • 新写入 episode 默认 status=active。
  • superseded episode 默认不会进入自动 recall。
  • !memory list --include-superseded 可以查看旧记忆。
  • !memory search 默认只查 active,可选包含 archived/superseded。

Non-goals

  • 不默认自动物理删除。
  • 不要求历史数据迁移;缺失 status 的旧数据可视为 active。

Issue 5: Add L2 export/import and scoped deletion commands

Priority: P1

Background

当前 !memory export 只导出 L1 profiles。L2 可通过 KB UI 导入 JSON,但没有完整的命令式 export/import 和批量治理能力。

Goal

让管理员可以迁移、备份、清理当前 scope 的 L2 episodes。

Proposed commands

!memory export l2
!memory import l2 <json>
!memory delete --speaker <sender_id>
!memory delete --tag <tag>
!memory delete --before <timestamp>
!memory delete --status archived

Export fields

{
  "id": "episode_id",
  "content": "...",
  "tags": ["..."],
  "importance": 2,
  "timestamp": "2026-05-15T00:00:00Z",
  "user_key": "...",
  "sender_id": "...",
  "sender_name": "...",
  "source": "agent",
  "status": "active",
  "superseded_by": ""
}

Acceptance criteria

  • Export 只导出当前 user_key scope。
  • Import 默认写入当前 scope,不允许导入覆盖其他 scope。
  • 批量删除必须 scope-safe。
  • 删除前返回 preview 或至少返回将删除数量。
  • 批量删除写 audit log。

Non-goals

  • 不实现跨 scope 全量备份。
  • 不开放任意 raw metadata filter 给模型。

Issue 6: Add memory audit log

Priority: P1

Background

长期记忆涉及误写、误删、隐私和治理。当前 delete / update 没有独立 audit 记录,排查困难。

Goal

记录所有会改变 memory state 的操作。

Operations to audit

  • remember
  • update_profile
  • forget
  • L2 import
  • L2 export
  • bulk delete
  • consolidation apply
  • archive / restore

Storage

Audit log 存 plugin storage,不进入 L2 vector DB。

Proposed command

!memory audit [page]
!memory audit export

Audit fields

{
  "audit_id": "...",
  "operation": "remember",
  "scope_key": "...",
  "user_key": "...",
  "sender_id": "...",
  "sender_name": "...",
  "target_type": "episode",
  "target_id": "...",
  "summary": "...",
  "timestamp": "2026-05-15T00:00:00Z",
  "query_id": 123
}

Acceptance criteria

  • 单条删除和批量删除都有 audit。
  • profile 更新记录 field / action / scope。
  • audit list 支持分页。
  • audit export 不泄漏其他 scope。

Non-goals

  • 不做不可篡改日志。
  • 不要求外部 SIEM 集成。

Issue 7: Expose superseded and archived memories

Priority: P1

Background

supersede 机制已经存在,但管理员看不到旧记忆为什么不再优先召回,也不容易验证 correction 是否生效。

Goal

增强可解释性和可调试性。

Proposed commands

!memory show <episode_id>
!memory superseded [page]
!memory archived [page]
!memory restore <episode_id>
!memory archive <episode_id>

Acceptance criteria

  • !memory show 显示 status、superseded_by、timestamp、tags、importance、sender。
  • !memory superseded 能列出被替代的 episode。
  • !memory restore 可以把 archived episode 恢复为 active。
  • 所有 status 修改写 audit log。

Non-goals

  • 不实现复杂合并 UI。

Issue 8: Add consolidation preview and apply commands

Priority: P1

Background

当前只有 time decay,没有主动整合。长期运行后,L2 会积累重复、过期、被纠正的 episode。OpenClaw 的 dreaming 和 Hermes 的 post-turn sync 都说明长期记忆需要整理,但自动后台直接改写记忆风险较高。

Goal

增加安全的、管理员可控的 memory consolidation 流程。

Proposed commands

!memory consolidate preview
!memory consolidate run

第一版只做 preview-first,不默认后台自动执行。

Candidate selection:

  • older than configured age, e.g. 7 days;
  • same tag / high similarity duplicate;
  • already superseded;
  • low importance and rarely recalled;
  • many episodes from the same speaker/topic.

Preview output:

  • candidate episode IDs;
  • suggested summary episode;
  • suggested L1 profile updates;
  • suggested archive list;
  • risk notes.

Apply output:

  • write summary episode;
  • update L1 profile if configured;
  • archive selected old episodes;
  • write audit log.

Proposed config

consolidation_enabled: false
consolidation_min_age_days: 7
consolidation_max_candidates: 20
consolidation_apply_profile_updates: false

Acceptance criteria

  • Preview does not modify memory.
  • Run modifies only current scope.
  • Run writes audit log for every profile update / episode archive / summary write.
  • Archived episodes are excluded from default recall.

Non-goals

  • 不做后台 cron。
  • 不默认自动整合。
  • 不新增 L3 procedural memory。

Issue 9: Add optional post-turn memory candidate extraction

Priority: P1 / P2

Background

当前 memory 写入主要依赖模型主动调用 remember / update_profile。这可控,但容易漏记。直接自动写入又可能污染 memory。

Goal

增加一个默认关闭的候选记忆提取流程,让管理员观察模型会建议记什么,再决定是否自动化。

Proposed behavior

Post-turn extraction 生成 candidates:

  • candidate L1 profile update
  • candidate L2 episode
  • ignore reason

默认只记录候选,不写入正式 memory。

Proposed commands

!memory candidates [page]
!memory candidate accept <candidate_id>
!memory candidate reject <candidate_id>

Proposed config

candidate_extraction_enabled: false
candidate_auto_apply: false
candidate_max_per_turn: 3

Acceptance criteria

  • 默认关闭。
  • 开启后不自动污染 L1/L2。
  • accept 后走正常 update_profile / remember 路径,并写 audit log。
  • reject 后候选可查。

Non-goals

  • 不要求修改 LangBot core 增加 TurnCompleted event。
  • 第一版可以基于现有 NormalMessageResponded 事件或命令触发。

Issue 10: Add richer memory management commands

Priority: P2

Background

OpenClaw / Hermes 的文件式 memory 透明性较强。LongTermMemory 不应改成文件主存储,但需要提供足够透明的管理入口。

Goal

用命令增强替代直接编辑 Markdown 文件的透明性。

Proposed commands

!memory show <episode_id>
!memory edit <episode_id>
!memory profile edit session
!memory profile edit speaker <sender_id>
!memory stats
!memory export all-current-scope

Acceptance criteria

  • 管理员能查看和编辑 L1/L2。
  • 所有 edit/delete/archive 操作写 audit。
  • 不允许跨 scope 操作,除非未来单独设计全局管理员权限。

Non-goals

  • 不做 Web UI 第一版。

Issue 11: Design optional global speaker profile scope

Priority: P2 design only

Background

当前 L1 speaker profile 绑定在 session_key 下。这适合群聊隔离,但不支持“同一个用户跨多个群共享画像”。

Goal

做设计预研,不急着实现。

Questions

  • 是否需要 speaker_global scope?
  • 如何识别同一个用户在不同平台/群的身份?
  • 默认是否关闭?
  • 用户如何授权跨群共享?
  • 与 bot L2 isolation 如何组合?
  • 冲突时 session speaker profile 和 global speaker profile 谁优先?

Acceptance criteria

  • 输出设计文档。
  • 明确默认关闭。
  • 明确隐私边界和迁移策略。

Non-goals

  • 不在第一阶段实现。

Suggested implementation order

  1. Issue 1: write policy.
  2. Issue 2: health check.
  3. Issue 4: lifecycle status.
  4. Issue 6: audit log.
  5. Issue 5: L2 export/import/delete.
  6. Issue 7: superseded / archived visibility.
  7. Issue 3: hybrid recall and exact-match fallback.
  8. Issue 8: consolidation preview/apply.
  9. Issue 9: post-turn candidates.
  10. Issue 10 / 11: management UI and global profile design.

What not to do yet

  • Do not move memory implementation into LangBot core.
  • Do not require LangBot SDK changes as a prerequisite.
  • Do not add active goals into this plugin in the first phase.
  • Do not add procedural memory as a first-class layer yet.
  • Do not automatically delete old memories by default.
  • Do not run background consolidation that modifies memory without preview or audit.