# `CMDCMemoryPg.EpisodicMemoryBackend`
[🔗](https://github.com/tupleyun/cmdc_memory_pg/blob/v0.1.0/lib/cmdc_memory_pg/episodic_memory_backend.ex#L1)

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 明示不含

- ❌ pgvector 真语义检索 — `similarity_search/3` 降级为 ILIKE
- ❌ 跨 user_id 全局检索（filters 中无 user_id 时返回空列表，避免误泄）
- ❌ Ecto Sandbox 之外的并发性能优化（v0.2 加 batch insert）

---

*Consult [api-reference.md](api-reference.md) for complete listing*
