学习笔记 · Obsidian
Store:长期记忆、Namespace 与 TTL
Store 保存跨 Thread 可用的持久 JSON 文档。Item 的身份是 (namespace[], key);key 只需在 namespace 内唯一。它与 Thread/checkpointer 不同:Thread 保存一次会话的执行 state,Store 保存可跨会话复用的长期数据。
六个文档入口
| 方法与路径 | 请求/响应 | 语义 |
|---|---|---|
PUT /store/items | namespace、key、value 必填;成功 204 | 新建或覆盖 Item |
GET /store/items | key 必填 query,namespace 数组,可选 refresh TTL;成功 200 | 读取单个 Item;根文档与此页同操作 |
DELETE /store/items | body 中 key 必填,namespace | 删除,成功 204 |
POST /store/items/search | prefix/filter/query/分页 | 列表或语义检索,返回 Items |
POST /store/namespaces | prefix/suffix/depth/分页 | 列 namespace |
请求结构错误一般为 422;读取 namespace 组合无效还可能返回 400。
Item、索引与 TTL
Item 返回 namespace、key、value、created_at、updated_at。Put 还可设置:
index=null:使用默认索引策略;index=false:禁用搜索索引;index=[field paths]:只索引指定字段;ttl:从现在起的分钟数;null 表示不过期。
索引字段要最小化:不需要语义检索的秘密、PII 和大对象不要进入 embedding/search index。更新 Item 会替换相同键的值,API 未暴露版本条件,多个写入方应使用单写者、外部锁或在 value 中保存业务版本并做冲突检测。
列表与语义搜索
StoreSearchRequest 支持 namespace prefix、精确 KV filter、limit=10、offset=0、自然语言 query 和 refresh_ttl:
- 没有 query:按最近更新时间列出;
- 有 query:对 Item 内容做自然语言检索;
- refresh TTL 为 true 会因“被读到”延长生命周期,只应在明确的滑动过期场景使用,否则冷数据可能因后台搜索永不淘汰。
namespace 列表支持 prefix、suffix、max_depth、limit=100、offset=0,响应是 namespace 字符串数组的列表。
多租户与记忆治理
- namespace 由服务端用 tenant/user/application scope 构造,不能接受模型或客户端直接决定完整路径。
- 每个 get/search/put/delete 都叠加授权;prefix search 尤其要防止越过用户边界。
- 长期记忆写入前确认用户授权、来源、置信度、用途和保留期;支持更正、删除与导出。
- 自然语言 query 和返回 value 都是非可信数据,进入 prompt 前做长度限制、PII/注入防护与来源标注。
- TTL 清理、索引更新和主数据删除可能异步,监控积压与一致性;不要把 204 当作搜索索引已立刻收敛的证明。