qiwei-agent-memory-context.md 8.1 KB

企微客服记忆与上下文架构

1. 目标

客服回复不能把无限增长的 Claude Code Session 当作客户长期记忆。本方案借鉴 Hermes Agent 的分层记忆、按需召回、冻结核心快照和 Session 搜索思想,同时保持企微客户数据本地优先、证据可追溯和人工审核边界。

设计目标:

  • Workbench DB 是客户事实与消息的唯一权威来源;
  • Claude Code Session 只保存短期推理轨迹和审阅记录;
  • 每轮上下文有明确容量上限,不随客户生命周期无限增长;
  • 明确事实与模型推断分开保存;
  • 所有客户记忆必须能追溯到原始消息;
  • 记忆故障不阻塞草稿生成和人工处理。

2. 分层模型

层级 数据源 生命周期 注入方式
企业人格与规则 knowledge/*.md、运行时 system prompt 项目级 每轮固定注入
结构化业务状态 profiles、tasks、alerts、recommendations 客户级 每轮注入当前状态
核心长期记忆 customer_memory_items / snapshots 客户级 限长快照注入
情景记忆 messages 客户级完整历史 相关时按需召回
工作记忆 最近消息 当前任务 近期窗口注入
Session 轨迹 Claude Code JSONL 单个 Epoch 仅用于推理连续性和审阅

项目级固定上下文由 QIWEI_AGENT_CONTEXT_FILES 控制,默认加载 personality.mdcontext.mdrules.md,总字符数受 QIWEI_AGENT_CONTEXT_CHAR_LIMIT 限制。上下文文件可使用独占一行的 @context relative.md#标题 引用同一知识库内的片段;解析基于已索引 Markdown,不允许越过知识库目录读取任意文件。

3. 记忆类型和证据

customer_memory_items.type

  • fact:客户明确表达且可核验的事实;
  • preference:明确偏好,例如“更喜欢地铁附近”;
  • constraint:明确排除项,例如“不考虑顶楼”;
  • event:具有后续价值的历史事件;
  • hypothesis:模型推断,只能用于询问确认,不能作为已知事实。

每条记忆包含 source_message_ids_jsonconfidenceimportancestatusdirectioncreated_by。当前自动写入仅接受:

  1. 现有 grounding 规则确认的 profileUpdates
  2. 从当前客户原话中通过明确句式提取的偏好、约束和称呼;
  3. 通过提示注入与凭证模式扫描的安全内容。

人工确认的记忆允许没有客户原消息 ID,但必须标记 created_by=human 并写入审计。人工修改结构化客户主档时,对应的稳定记忆键 profile:<field> 同步更新;清空字段会把旧记忆标记为 superseded,避免画像与长期记忆互相冲突。

3.1 生命周期治理

后台治理接口支持以下操作,默认不在客服工作台提供可视化入口:

操作 结果
添加 创建高重要性的人工确认事实
编辑 覆盖内容并标记 created_by=human
确认 hypothesis 转为 fact,置信度设为 1
拒绝 状态改为 rejected,不再进入上下文
过期 expires_at 到期后自动改为 superseded
遗忘 物理删除记忆条目并重建快照

每次治理操作均生成新快照(内容未变化时复用原版本)并写入审计。记忆遗忘与原始消息保留是两个独立策略;如需满足客户完整删除请求,还必须同时执行消息和客户主档的数据删除流程。

4. 上下文组装

上下文由 AgentContextBuilder 统一构建,模型客户端不再直接拼接画像、记忆和历史消息。Builder 对指令、结构化状态和权威会话分别分配字符预算,并在总预算不足时从较早历史开始裁剪,保证最新客户消息保留。

每轮生成顺序:

  1. 企业客服身份、规则和安全边界;
  2. 当前客户核心记忆快照;
  3. 与最新消息相关的较早历史片段;
  4. 当前画像、未完成待办、预警和业务反馈;
  5. 近期有效会话和最新客户消息;
  6. 结构化输出约束。

默认限制:

配置 默认值 说明
QIWEI_AGENT_MEMORY_CORE_CHAR_LIMIT 4000 核心记忆字符上限;运行时允许配置 500–8000
QIWEI_AGENT_MEMORY_RECALL_LIMIT 6 单轮相关历史上限
QIWEI_AGENT_MEMORY_RECENT_MESSAGES 12 不参与远期召回的近期消息数
QIWEI_AGENT_MEMORY_HISTORY_SCAN_LIMIT 240 本地相关性扫描范围

相关历史以字符二元组、英文词和数字重叠计算本地相关性。该实现不发送额外外部请求,后续可替换为本地 embedding 或 provider hybrid search。

5. Claude Session Epoch

Session 不再永久续接。达到以下任一条件时创建新 Epoch:

  • CLAUDE_CODE_SESSION_MAX_TURNS,默认 12 次生成;
  • CLAUDE_CODE_SESSION_MAX_AGE_MS,默认 24 小时;
  • Session 无效或单次预算超限。

新 Epoch 记录 parentSessionIdmemoryVersion、开始时间和轮次。当前映射保留最近 50 个已关闭 Epoch 的元数据。客户长期记忆不依赖 Session,因此轮换不会丢失画像、偏好、约束、任务或完整消息。

6. 故障与安全边界

  • 记忆召回或写入失败只记录 memory_recall_failed / memory_capture_failed 审计,不阻塞草稿;
  • 召回的历史消息被标记为客户或客服原话,不作为系统指令;
  • hypothesis 不进入已确认核心事实;
  • 客户数据按企微账号数据库和 conversation ID 隔离;
  • Claude Code 保持 --bare 和只读工具,避免隐式 auto-memory 造成不可审计写入;
  • 自动发送仍由白名单、会话模式、置信度和 requiresHuman 共同控制。

7. Provider 扩展

后续外部记忆提供者统一实现:

prefetch(context)
capture(turn)
search(query, scope)
conclude(conversationId)
getProfile(conversationId)
forget(memoryId)

当前仅使用 Workbench SQLite 本地记忆,不接入外部记忆 provider。Provider 接口保留为未来扩展边界,但不包含云端实现或客户数据外发逻辑。

8. 验证

node scripts/agent-console-smoke-test.js 覆盖:

  • 明确事实、偏好和约束写入;
  • 注入/凭证模式不进入记忆;
  • 较早相关历史按需召回;
  • 核心快照容量限制;
  • Epoch 按轮次轮换并保留父 Session 和历史元数据;
  • 原有审核、白名单、发送幂等和 grounding 行为不回归。
  • 人工新增、编辑、确认、拒绝和遗忘;
  • 临时记忆到期退出 active 快照;
  • 既有画像和明确客户原话幂等回填;
  • 人工清空画像字段后稳定记忆失效。

8.1 实施状态

阶段 状态 说明
Memory Store 与数据表 已完成 本地 SQLite、快照、治理 API;按产品决定不提供 Dashboard 记忆面板
AgentContextBuilder 已完成 Claude Code 与其他 provider 统一使用 Builder
本地检索与预算 已完成 核心记忆、相关历史、项目上下文和总 prompt 均有限额
异步提取、证据、冲突与过期 已完成 持久化异步提取、重试恢复、证据闸门、冲突修订历史和过期均已实现
Session Epoch 已完成 按轮次/时长轮换并保留父子关系和审计元数据
外部记忆 provider 不实施 当前本地记忆已满足客服需求,不引入额外云服务、成本和隐私边界

9. Dashboard 离线可用性

长期记忆和上下文治理依赖本地 Workbench DB,不应被 Fmode 登录状态探测阻塞。Dashboard 的「智能会话」页面因此采用以下启动顺序:

  1. 立即按当前 origin 中保存的账号绑定加载本地会话、记忆、任务和审计;
  2. 通过 /api/status?fast=true 读取登录和订阅状态缓存,前端探测上限为 2.5 秒;
  3. 在后台补全服务端账号绑定,并更新在线状态;
  4. 上游不可达时保留本地工作台能力,仅禁用依赖真实企微连接的收发操作。

浏览器账号列表按 origin 隔离。正式 Dashboard 固定使用 http://127.0.0.1:4320/;其他临时端口拥有独立的 localStorage,不能据此判断正式账号已退出登录。