记忆系统
wesgine 的记忆系统为 Agent 提供跨会话的持久化知识存储,按四层模型组织,兼顾共享与隔离。
四层记忆模型
| 层 | 名称 | 谁写入 | 谁可见 | 生命周期 |
|---|---|---|---|---|
| L1 | 环境信息 environment | 引擎感知器 | 全 Cell | 进程启动时采集 |
| L2 | 部门共识 consensus | Admin | 全 Cell | 长期有效 |
| L3 | 关于我 about_me | Agent | 仅本人 | 长期有效 |
| L4 | 角色记忆 agent_memory | Agent | 按 Agent 隔离 | 长期有效 |
另有三个运行时层:session(会话上下文)、working(工作缓存)、unknown(兜底),不属于"记忆"但参与引擎内部流转。
记忆的写入
Agent 工具写入
Agent 通过 memory 工具主动写入记忆:
{
"tool": "memory",
"action": "save",
"layer": "about_me",
"content": "用户偏好 Vim 键位配置",
"kind": "preference"
}
认知结算写入
每次 Run 结束时,引擎执行 CognitiveSettlement(认知结算),由主对话模型总结本轮对话中值得记住的信息,自动写入记忆。这是 Run 生命周期的强制阶段,不可跳过。
记忆的召回
记忆通过三条路径自动注入到 Agent 的上下文中:
| 注入面 | 时机 | 说明 |
|---|---|---|
| Eager(系统提示词) | 每轮 | Constraint / Instruction 等高优先条目 |
| Lazy(当轮 overlay) | 每轮 | 根据当前话题语义召回 |
| Cold-start | 新会话首轮 | 跨会话摘要重放 |
召回经过质量门控:被 Digest 标记为 stale 或 conflicted 的条目自动排除。
记忆种类(Kind)
| Kind | 含义 | 耐久性 |
|---|---|---|
constraint | 硬约束,始终注入 | 持久 |
instruction | 工作指令 | 持久 |
preference | 偏好 | 持久 |
fact | 事实 | 持久 |
correction | 纠正 | 持久 |
convention | 惯例 | 持久 |
lesson | 教训 | 持久 |
context | 上下文片段 | 临时(会话级) |
安全扫描
每条记忆写入前必须通过安全扫描(INV-MEM-24):
- 凭据泄漏检测 — 5 条正则匹配 API Key、密码等
- 不可见字符检测 — 防止 unicode 混淆攻击
- 匹配时拒绝写入,返回
ErrThreatPatternDetected
内容质量门控
拦截引擎状态前缀(如 PLAN_STATE:、TASK_STATE:)进入记忆,防止内部调度信息污染知识库。
记忆维护
GC(垃圾回收)
基于 RetentionScore(recall-frequency weighted)淘汰低价值条目,而非纯 LRU。
Digest(语义去重)
定期运行语义分析:
| 操作 | 说明 |
|---|---|
| 去重 | 合并语义相同的条目 |
| 冲突检测 | 发现互相矛盾的条目并标记 |
| 过期标记 | 30 天零召回的条目标为 stale |
| 取代检测 | 新条目明确否定旧条目时标记旧条目 |
HTTP API
| 方法 | 端点 | 说明 |
|---|---|---|
| GET | /cells/{id}/memory | 列出记忆(?layer=&actor=) |
| POST | /cells/{id}/memory | 保存记忆条目 |
| POST | /cells/{id}/memory/search | 语义搜索 |
| GET | /cells/{id}/memory/counts | 每层条数 |
| DELETE | /cells/{id}/memory/{mid} | 删除单条 |
| POST | /cells/{id}/memory/gc | 触发 GC |
| POST | /cells/{id}/memory/digest | 触发 Digest |