学习笔记 · Obsidian

键值存储与语义缓存

LangChainTypeScript

结论

  • 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。

官方明确警告它可修改目标目录及其子目录中的文本文件。因此:

  1. 使用专用空目录,绝不指向项目、Vault、用户 HOME 或共享目录;
  2. key 做规范化,拒绝绝对路径、..、分隔符和符号链接逃逸;
  3. 采用原子写/rename、文件权限、磁盘配额和进程锁;
  4. 不保存凭据或未加密敏感内容;
  5. 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 和过期数据命中。