ValueError: shapes (3,) and (0,) not aligned`。

该报错通常出现在 Dify「混合检索 + weighted rerank」处理外部知识库文档时:外部文档没有有效 score,或既无 score 也无 vector,导致 _calculate_cosine / 加权计算拿到 None 、 None 向量或空向量。优先排查外部知识库返回的 score

快速结论:该报错通常出现在 Dify「混合检索 + weighted rerank」处理外部知识库文档时:外部文档没有有效 score,或既无 score 也无 vector,导致 _calculate_cosine / 加权计算拿到 None、None 向量或空向量。优先排查外部知识库返回的 score 与 vector 字段是否有效。

适用环境:Issue 中确认的相关组件为 Dify(代码路径 api/core/rag/rerank/weight_rerank.py、api/core/rag/datasource/retrieval_service/dataset_retrieval.py);Issue 未提供具体 Dify 版本、操作系统、Python、CUDA、显卡或依赖版本信息,不做补充。

最快修复方案:暂无确认的一步修复方案。Issue 讨论中提出的思路是:在 _calculate_cosine 内、进行 np.dot / 范数运算之前先校验 score 与 document.vector,对无效数据按 0.0 兜底;讨论同时指出仅在 run() 加权前校验无法覆盖第二种崩溃,且该策略尚待维护者确认,可优先尝试。

注意事项:0.0 降级策略并未被维护者确认为最终方案;strict=True 只校验列表长度,不能替代分数与向量的数值校验,也不应替代此处修复。另需注意:#45518 的做法是显式抛出 ValueError,并不是跳过坏结果或降级,不能据此认定「无效数据不影响整次检索」已是既定约定。

问题场景

在 Dify 中开启混合检索并使用 weighted rerank(WeightRerankRunner),且知识库中包含外部知识库时触发。外部知识库文档在 dataset_retrieval.py 构造时被无条件写入 metadata["score"] = external_document.get("score"),当第三方服务未返回分数时该值为 None;另一种形态是 metadata 中没有 "score" 键、文档也没有向量。两种情况下一次检索会直接失败,用户看到的是 500 而非降级结果。

报错原文

doc.metadata = {"score": None, "title": "t", "dataset_id": "d"}
_calculate_cosine(...) -> [None]
run(...) -> TypeError: unsupported operand type(s) for *: 'float' and 'NoneType'

vec2 = np.array(document.vector)   # vector 是 list[float] | None = None
# 为空列表时:
ValueError: shapes (3,) and (0,) not aligned

原因分析

可能原因一:_calculate_cosine 仅判断 metadata 中是否存在 "score" 键就取用其值,不校验值是否为有效数值。外部知识库未返回分数时 metadata["score"] 为 None,随后在 run() 中参与 vector_weight * query_vector_score 运算,抛出 TypeError。

可能原因二:当 metadata 中没有 "score" 键时走向量分支,document.vector 在模型上可为 None,此时 np.array(None) 后续运算抛 TypeError;为 [] 时则在 np.dot 与范数计算处抛 ValueError: shapes (3,) and (0,) not aligned。由于该异常发生在 _calculate_cosine 返回分数列表之前,仅在 run() 加权前做校验无法覆盖。

此外,Issue 指出在无有效分数、也无向量的文档上,不应仅为返回兜底分数而触发 embedding 调用;当前 query embedding 的获取位于无 score 分支的向量检查之前。

环境排查

  • 确认 Dify 版本,并核对 api/core/rag/rerank/weight_rerank.py 与 api/core/rag/datasource/retrieval_service/dataset_retrieval.py 是否为对应代码路径。
  • 确认知识库检索配置:是否开启混合检索、是否启用 weighted rerank。
  • 确认是否接入了外部知识库,以及外部服务实际返回的 score、vector 字段形态(缺失 / None / 空列表 / 有效值)。
  • Issue 未提供 Python、CUDA、PyTorch、显卡与依赖版本,无需据此排查;如仍报错,可附上完整 traceback 定位具体分支。

解决步骤

  1. 先复现并定位分支:在外部知识库文档进入 rerank 前,检查其 metadata 中是否存在 "score" 键及其值;再检查 document.vector 是否为 None 或空列表。
  2. 若外部服务可配置,优先让第三方返回有效数值的 score(或有效向量),这是不改代码的临时规避思路;Issue 未验证此方式。
  3. 若需改代码:在 _calculate_cosine 内对 metadata["score"] 做数值有效性校验,仅接受有效数值分数;对无效或缺失分数且无有效向量的文档按 0.0 处理(可优先尝试)。
  4. 把向量分支的保护放在 np.array(document.vector)、np.dot 与范数计算之前,避免 None 或空列表进入计算。
  5. 调整逻辑顺序,使无有效分数、无向量的文档不会仅为返回兜底分数而触发 query embedding 调用。
  6. 关于 run() 中 zip(..., strict=False):可作为独立改动提审,是否合并以及是否改为 strict=True 需维护者确认;它不能替代数值与向量校验。
  7. 提交前与维护者确认边界:在 _calculate_cosine 内兜底还是在 run() 统一校验,以及 0.0 降级策略是否采纳。

验证方法

构造三类外部知识库文档并执行一次混合检索 + weighted rerank:metadata = {"score": None}、metadata 无 score 且 vector = None、metadata 无 score 且 vector = []。修复后应不再出现 TypeError 或 ValueError: shapes (3,) and (0,) not aligned,检索返回结果而非 500;同时确认这些文档未触发多余的 embedding 调用,且正常带有效 score 或向量的文档分数计算不受影响。

参考来源

langgenius/dify #45566

GamsGo AI

AI 工具推荐

想把多个 AI 模型放在一个入口?

GamsGo AI 集成 ChatGPT、DeepSeek、Gemini、Claude、Midjourney、Veo 等常用模型,适合写作、绘图、视频和日常 AI 工作流。

了解 GamsGo AI

推广链接:通过此链接购买,我可能获得佣金,不影响你的价格。

这个方案解决了吗?

celebrityanime
celebrityanime
文章: 32663

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注