记忆层查询谓词
wesgine 记忆系统中 LayerOf 与 LayerClauses 的双向生成设计。
判层与筛层是同一张表的两个方向
| 方向 | 函数 | 问题 |
|---|---|---|
| 判层 | LayerOf(entry) | 这一行是哪层? |
| 筛层 | LayerClauses(layer) | 哪些行是这层? |
两者必须由同一份定义生成——分别手写的两份表必然漂移。
为什么两个方向不能独立实现
Scope + Actor 是层的超集:
- L2(
consensus):ScopeGlobal+ 无 Actor - L3(
about_me):ScopeGlobal+ 有 Actor
两者共用 ScopeGlobal,所以没有任何 scope 值能单独命名"关于我"。
拿超集查 L3 会把 L2 的部门共识一起装进 LIMIT 窗口。
筛层必须精确
-- 错误:超集查询
WHERE scope = 'global' AND actor = ?
-- 这会把 consensus(无 actor)也装进来
-- 正确:精确谓词
WHERE scope = 'global' AND actor = ? AND actor != ''
且必须在 LIMIT 之内——页外过滤在两行数据的测试里看不出差别,共享分区一大,用户自己的行就掉出窗口底部。
Layer 与 Scope 互斥
同时给出 ?layer= 和 ?scope= 时返回 ErrMemoryLayerScopeConflict(400),不做交集。
两者只在调用方糊涂时才分歧,返回交集是在回答没人问过的问题。
七值闭域
AllMemoryLayers() = [
"environment", // L1
"consensus", // L2
"about_me", // L3
"agent_memory", // L4
"session",
"working",
"unknown",
]
unknown 是兜底出口,新增 scope 落到 unknown 而不是塞进某个真实层。
ListOptions.Layer 下推
type ListOptions struct {
Layer string // 直接下推到 SQL
Scope string // 不可与 Layer 同时给出
// ...
}
backend.layerPredicate(layer) 生成 SQL WHERE 子句,不是 Go 侧后过滤。
CountByLayer
func CountByLayer(actor, namespace string) map[string]int
返回键覆盖 AllMemoryLayers() 全部层含 0。
缺键会让消费方渲染成"什么都没有"——没有 tab、没有 0、没有报错。
属性测试
LayerOf 与 ActorVisible 由属性测试锁死同向:
- 带 actor 的
ScopeSystem行:LayerOf读作非共享层,ActorVisible同样读作非共享 - 两者不同向时,有些行在列表里出现但不被计数,或反之
相关不变量
- INV-MEM-49:层判定单点
LayerOf - INV-MEM-52:计数按层按人
- INV-MEM-53:写、清、取单条都按层
相关文档
- 记忆层概览 →
memory-layer-overview.md - 记忆写入层 API →
memory-write-layer-api.md - 记忆计数统计 →
memory-count-stats.md