CMDCMemoryPg.EpisodicMemoryBackend (cmdc_memory_pg v0.1.2)

Copy Markdown View Source

PostgreSQL 实现 CMDC.Memory behaviour — 与 cmdc 主库 CMDC.Plugin.Builtin.EpisodicMemory Plugin 直接对接。

让 EpisodicMemory Plugin 在生产场景可用(默认 CMDC.Memory.ETS 进程退出数据丢失)。

v0.1 范围

实现 5 个 CMDC.Memory callback:

callback行为
store/3写入 cmdc_episodic_memories 表(按 :user_id filter 隔离)
search/3文本 ILIKE 匹配(v0.1 不含 pgvector
similarity_search/3同上(降级为关键词搜索,行为与 ETS 一致)
list/1全表按插入时间倒序
delete/2按 id 删除

多租户隔离

EpisodicMemory Plugin 通过 filters: [user_id: uid]search/3 时按 ctx.user_data[:user_id] 过滤。本 backend 在 store/3 时把 data[:user_id] 落到 cmdc_episodic_memories.user_id 列,search/3 按 filters 注入 WHERE 子句。

使用

# config/runtime.exs
config :cmdc, :memory_backend, CMDCMemoryPg.EpisodicMemoryBackend

# Plugin 配置
plugins: [
  {CMDC.Plugin.Builtin.EpisodicMemory,
   memory_store: :cmdc_episodic,            # store 参数(这里被忽略,因为 PG 不需要)
   memory_module: CMDCMemoryPg.EpisodicMemoryBackend,
   top_k: 3}
]

多租户保护(v0.1.1+)

search/3 / similarity_search/3filters未传 :user_id 时的行为, 由调用方通过 :on_missing_tenant opt 控制:

opt 值行为
:return_empty默认返回 {:ok, []},强制空结果防泄漏
:return_error返回 {:error, :missing_tenant_filter},严格模式

v0.1.0 → v0.1.1 行为变化提示:v0.1.0 注释声称"返回空列表"但代码实际 不过滤,存在跨租户读出全部记录的安全风险。v0.1.1 修复为真返空(默认)或 报错(严格)。多租户集成方升级 0.1.0 → 0.1.1 时强烈建议显式传 opts[:on_missing_tenant] = :return_error 让调用栈尽早暴露漏传 user_id 的代码。

list/1(无 query 的全表枚举)保持原行为不变(用于运维 / 调试), 多租户场景应改用 search/3 带 user_id filter。

v0.1 明示不含

  • ❌ pgvector 真语义检索 — similarity_search/3 降级为 ILIKE(v0.2 加)
  • ❌ Ecto Sandbox 之外的并发性能优化(v0.2 加 batch insert)

Summary

Functions

返回当前 backend 的 entry schema 版本(v0.1.2 起)。

Functions

schema_version()

@spec schema_version() :: pos_integer()

返回当前 backend 的 entry schema 版本(v0.1.2 起)。

0.1.2 引入 :tags :: [String.t()] 字段,但 SQL 列 default [],老数据零 ETL, schema 版本号保持 1tags 不算"破坏老 entry 的字段变更"。