Repository navigation
fix(knowledge): 语义切分校验向量条数与句子一致 - #1147
Conversation
semantic_chunking_with_auto_clusters 在聚类后按位置配对句子、簇标签与 token 数, 而 labels 的长度等于 embeddings 的行数。zip 未加 strict,条数不等时按较短方截断, 后面的句子被静默丢弃:不进任何 chunk,也无日志或异常。 sklearn 不会因条数不匹配报错;进入该函数的 embed_fn 来自 select_embedding_model (...).encode,单次调用不经 batch_encode,调用方注入自定义 embed_fn 时更是完全 绕过模型层校验。 在聚类前校验条数,两处 zip 加 strict=True 兜底。 Fixes xerrors#1146
|
Friendly bump on this one — it is Quick recap of what it fixes:
The fix is a count check before clustering plus Happy to adjust the contract if you would rather degrade to "merge by budget" instead of raising. |
|
这个防御校验可以保留,自定义
调整现有用例即可,不需要再扩测试。 |
chunk_token_num=10 时簇数算成 4,sklearn 会先以「簇数多于样本数」拒绝, 测不到 zip 截断这条路径;改成 30 后簇数为 2,与返回的两条向量一致, 旧代码能正常聚类再静默丢掉后两句。
|
两处都改好了,谢谢实测。 1. 说明修正:你说得对。 2. 用例预算:也确认了。句子长度是 13/13/15/14,合计 55:
已把该用例改成 30,并在 docstring 里写清为什么是 30,方便以后不被人「优化」回 10。没有新增测试(f2eede58)。 |
修改内容
语义切分在向量条数与句子数不一致时会静默丢句,部分原文永远不进知识库。修改见
backend/yuxi/modules/knowledge/chunking/ragflow_like/utils/semantic_utils.py。semantic_chunking_with_auto_clusters在聚类后按位置配对:labels的长度等于embeddings的行数,而zip未加strict。条数不等时按较短方截断,后面的句子被直接丢弃——不报错、不告警,logger只记录输入长度。为什么会被触发
sklearn 不因条数不匹配报错。实测 4 句配 2 个向量:
且进入该函数的
embed_fn是semantic.py:56的select_embedding_model(...).encode——单次调用,不经batch_encode;调用方注入自定义embed_fn(单测、外部集成)时完全绕过模型层校验。这比
#1143修的向量错配更隐蔽:错配至少还能检索到错误文本,丢句是内容直接缺失。决策
len(embeddings) == len(sentences),不符抛出固定ValueError。zip均加strict=True兜底。校验放在切分工具内部而非模型层:无论
embed_fn来自模型还是调用方注入,契约都在此成立。#1143/#1145处理模型响应边界,本变更处理切分算法自身的输入契约,两者互补。不选择「不足时降级为按预算合并」:那会把部分失败伪装成成功,用户无从得知有句子未参与切分。
详情见
docs/develop-guides/decisions/implemented/2026-11-04-semantic-chunking-embedding-alignment.md。验证
backend/test/unit/knowledge/chunking/test_semantic_embedding_alignment.py,3 项:向量少于句子数报错、向量多于句子数报错、条数对齐时输出包含全部原文句子。test_semantic_chunking.py、test_semantic_tables.py合并运行:24 项通过。ruff check、ruff format --check、ruff check --select I均通过。未覆盖
test/unit需由 CI 执行。Fixes #1146