学习笔记 · Obsidian
键值存储与语义缓存
结论
BaseStore<K,V>是批量键值接口,主要用于 embedding cache,也可保存其他 typed value;本地实现只适合开发或单机受控场景。- Semantic Cache 按 embedding 相似度复用 LLM 响应,不是精确缓存。阈值、模型、prompt、工具、权限和时效不纳入 key 就会返回语义相近但业务错误的结果。
/stores与/stores/index、/llm_caching与/llm_caching/index各自是同正文别名;本组共覆盖 7 条原始路由。
BaseStore 契约
所有 BaseStore 都是 generic:
mget(keys):按输入顺序返回 value 或undefined;mset([[key,value], ...]):批量写;mdelete(keys):批量删;yieldKeys(prefix?):异步枚举 key,可按 prefix 过滤。
批量 API 的目的在于减少网络 round-trip,并让底层利用批处理。调用方仍需定义最大 batch、部分失败、重试和顺序语义。
InMemoryStore
InMemoryStore<T> 位于 @langchain/core/stores,可保存任意泛型值,例如 BaseMessage。它支持全部 BaseStore 操作和 prefix yield,但:
- 进程退出即丢失;
- 多实例不共享;
- 无持久化、跨进程锁或容量治理;
- 适合测试、短生命周期 cache 和接口原型。
若把它用作聊天历史,重启/扩容会导致会话不一致,应使用真正的持久存储或 checkpointer。
LocalFileStore
LocalFileStore 是 Node-only,对 fs 的 byte-value 包装。fromPath() 参数必须是目录,每个 key 对应目录下一个文件;值通常用 TextEncoder/TextDecoder 转为 Uint8Array。
官方明确警告它可修改目标目录及其子目录中的文本文件。因此:
- 使用专用空目录,绝不指向项目、Vault、用户 HOME 或共享目录;
- key 做规范化,拒绝绝对路径、
..、分隔符和符号链接逃逸; - 采用原子写/rename、文件权限、磁盘配额和进程锁;
- 不保存凭据或未加密敏感内容;
- prefix 枚举在大目录上可能昂贵,不能当数据库查询。
Azure Cosmos DB NoSQL Semantic Cache
AzureCosmosDBNoSQLSemanticCache 基于 AzureCosmosDBNoSQLVectorStore 存 prompt embedding,用相似度 threshold 找缓存响应。可用 connection string 或 Managed Identity;RBAC 模式不能建 database/container,资源要预创建。
文档示例阈值为 0.5,这只是演示值。生产必须用真实请求评估 false hit/false miss,并至少在 namespace 或 metadata 隔离:
- tenant/用户权限;
- model 与 API/version;
- system prompt、tool schema、structured-output schema;
- locale、业务规则、知识库/index version;
- temperature/seed 等影响输出的参数;
- 安全策略与数据时效窗口。
否则两个表面相似的问题可能复用错误、过期或越权答案。
缓存一致性与安全
- 精确 cache 用规范化请求 hash;semantic cache 只适合可容忍近似复用的读场景。
- 工具调用、写操作、个性化/权限相关回答默认不做 semantic cache。
- 缓存命中也保留来源和生成版本;知识库、prompt 或安全策略更新时按 namespace 失效,而不是逐条扫描。
- 存储 response 前做敏感数据分类;共享 cache 不得含用户私有内容。
- 观测 hit rate、false-hit 抽检、latency、embedding cost、eviction 和过期数据命中。