langchain-ai/langchain#39047 · index() 弃用警告把用户引向必然崩溃的 key_encoder · 2026-07-28 · W32 诊断 4/5
langchain_core.indexing.index() 的默认
key_encoder="sha1" 会发出 UserWarning,
官方建议用户切换到 "blake2b" / "sha256" / "sha512"。
但 _calculate_hash() 只有 sha1 分支把摘要包装成
uuid.uuid5(),其余三个分支返回 64/128 位裸 hexdigest——
遵循框架自己的弃用建议,会让所有 UUID 校验型 vectorstore(Qdrant 等)当场崩溃:
ValueError: Point id ... is not a valid UUID。
影响范围
langchain-core 1.5.1 · 所有听从 sha1 弃用警告 + UUID 校验型存储的用户
框架现状
⚠️ open · 4 位贡献者排队认领 · 修复方向已共识(全算法 uuid5 包装)
ARK 方案
✅ InputGuard ID 契约校验 + 迁移不变式
缺陷坐落在「弃用迁移路径」上——最不该有坑的地方:
_calculate_hash()(langchain_core/indexing/api.py):
sha1 分支 → uuid.uuid5(NAMESPACE_UUID, digest),输出 36 字符合法 UUIDhexdigest(),输出 64–128 字符裸十六进制,非 UUID 形状:memory: 本地模式)在 upsert 时强制校验 UUID → ValueError更隐蔽的第二层伤害(ID 契约漂移): 即使目标存储不校验 UUID(如 Chroma/FAISS 接受任意字符串),切换 key_encoder 也会让同一批文档拿到全新 ID, 增量索引(cleanup="incremental"/"full")的去重与清理逻辑将把旧数据视为无关数据—— 表面「迁移成功」,实际全量重复写入或误删。崩溃(Qdrant)反而是幸运的失败模式,静默的 ID 漂移才是更贵的那个。
ARK 将原 issue 的单点复现扩展为 4×1 全矩阵复现:同一份文档、同一个 :memory: Qdrant,仅变更 key_encoder。完全确定性、无外部依赖:
验证强度说明:矩阵式复现证明这不是某个算法的偶发问题,而是「除 sha1 外全部缺 uuid5 包装」的结构性缺陷;错误在首次 upsert 即触发,与数据内容无关。复现脚本:scripts/repros/repro_39047_key_encoder_uuid_break.py。
① InputGuard · 跨组件 ID 形状契约(写入前)
目标存储声明其 ID 契约(uuid-required / free-form);ARK 在文档进入写入管道前校验生成 ID 是否满足下游契约。
本例中 sha256 的 64 位 hexdigest 在进入 upsert 之前就被拦截并给出明确原因,
而非在 qdrant-client 深处抛一个用户看不懂来源的 ValueError。
② OutputValidator · 迁移不变式(换 encoder 时)
增量索引的核心不变式是「同一文档 → 同一 ID」。ARK 在 key_encoder 变更时对既有样本重算 ID 并对账:
检测到 ID(sha1) ≠ ID(sha256) 即告警「本次切换将使全部既有记录失去去重锚点」,
把静默的全量重写/误删风险变成迁移前的显式决策。
③ OTel 留痕
索引 span 记录 key_encoder → id_shape(uuid|hex64|hex128) → store_contract 链路。
「为什么换了个哈希算法索引就炸了」从数小时的跨库归因,变成一眼可见的契约不匹配。
归入 F8 · 语义反转 / 参数契约跨库漂移(第 2 例,与 #39052 同族同库接缝)。 共性:langchain-core 与 qdrant 各自内部一致,缺陷只存在于接缝处的隐式契约(ID 必须是 UUID / lambda 方向)。 本例的独特增量:漂移的引信是框架自己的弃用警告——「官方最佳实践」与「能跑的配置」精确互斥, 用户越守规矩越先崩溃。这把 F8 的边界从「参数语义」扩展到「迁移指引」。
ARK — Agent Reliability Kit · github.com/wzg0911/ark
诊断方法论:4P Framework(Pinpoint → Probe → Prescribe → Publish)· 所有结论基于实机验证,复现与未复现均如实披露
生成时间:2026-07-28 13:35 CST · W32 诊断报告 4/5