修复 Corpus chunks 计数严重偏离(Harness Engineering 849→14)— Phase 1 hotfix - #483
Closed
ThreeFish-AI wants to merge 1 commit into
Closed
修复 Corpus chunks 计数严重偏离(Harness Engineering 849→14)— Phase 1 hotfix#483ThreeFish-AI wants to merge 1 commit into
ThreeFish-AI wants to merge 1 commit into
Conversation
主因 A: list_corpora / get_corpus / update_corpus / get_dashboard 四处计数 SQL 没有 JOIN knowledge_documents 过滤 status='active',软删 doc 的全部父+子 chunks 仍被计入; 主因 B: 父子分片混算口径与文档详情 (chunk_role != 'child') 不一致,hierarchical 切片下放大近 6 倍偏差。两因叠加致 Harness Engineering Corpus 显示 849 vs 真实 14。 修复: - 抽取共享 helper _user_facing_chunk_filter_clauses / _user_facing_chunk_count_subquery 封装 chunk_role!=child + active doc 过滤 (含 source_uri IS NULL 的 KG 类直连放行) - 4 处端点改用相关子查询,与文档详情口径完全一致 - 业界对齐 LangChain ParentDocumentRetriever / LlamaIndex HierarchicalNodeParser / AWS Bedrock KB 的「用户面 chunks = 顶层 (非 child)」口径 - 集成测试 6 象限场景覆盖 hierarchical / 非 hierarchical / 软删 / 孤儿 / KG / 混合,单 test 多场景规避 conftest db_engine + asyncpg 跨循环边界 CorpusResponse / DashboardResponse 字段不变,UI 零改动;隐患 C (硬删未级联) 与 隐患 D (软删 chunks 仍可被检索) 留待 Phase 2/3 处理。 详见 docs/issue.md ISSUE-078。 🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist) Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>
This was referenced May 9, 2026
ThreeFish-AI
added a commit
that referenced
this pull request
Jul 5, 2026
…-2026-4372 处置) (#1057) * fix(deps): ts-deepmerge 补丁地板至 8.0.0 修复 GHSA-87mf-gv2c-c62c (#481); 🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist) Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com> * fix(negentropy): pydantic-settings 升 2.14.2 + joserfc>=1.6.7 补丁地板修复 #482/#488; 🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist) Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com> * fix(cognizes): joserfc/msgpack/python-socketio/python-engineio 补丁地板修复 #483/#486/#487/#490/#491; 🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist) Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com> * docs(perceives): ISSUE-092 增补 CVE-2026-4372 威胁模型;transformers 钉 4.x + dismiss #492(marker 5.x 不兼容实测); 🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist) Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
背景与问题
「Harness Engineering」Corpus 卡片显示
chunks: 849,但点开唯一文档详情仅14 Chunks,hierarchical 切片(parent: 3000 / child: 750),用户此前删除过一个 Document。两端口径相差近 60 倍。双重根因(事件级 RCA)
经代码核对,UI 默认走软删(
api.py:1684hard_delete: bool = Query(default=False));list_documents用status == "active"过滤(storage/service.py:338),所以软删 doc 在文档列表"消失",但 DB 行仍在(status='deleted')。主因 A — Corpus chunks 计数 SQL 没有 JOIN docs 过滤软删
apps/negentropy/src/negentropy/knowledge/api.py:613-637 / 664-688:完全没有过滤
KnowledgeDocument.status——软删 doc 的全部 chunks(父+子)仍记入 corpus 计数。这是 849 数字偏离的真正主因。主因 B — 父子 chunks 计数口径与文档详情不一致
api.py:618-619)(item.metadata or {}).get("chunk_role") != "child"仅算父/leaf (api.py:1939)隐患 C/D(本 PR 不解决,留待 Phase 2/3)
hard_delete=True) 未级联清理 Knowledge 行(FK 仅指向 Corpus,与 KnowledgeDocument 靠source_uri文本软关联),是潜在孤儿源头is_enabled=true+searchable=true+ 无archived标记)修复方案(Phase 1 hotfix · 零迁移、即时生效)
抽取共享 helper
apps/negentropy/src/negentropy/knowledge/api.py新增:_user_facing_chunk_filter_clauses()返回(not_child_clause, doc_active_or_kg_clause)_user_facing_chunk_count_subquery(corpus_id_expr)返回相关标量子查询语义:
coalesce(metadata->>'chunk_role', 'leaf') != 'child'排除 child(与文档详情口径一致)EXISTS(SELECT 1 FROM knowledge_documents d WHERE d.corpus_id=k.corpus_id AND d.app_name=k.app_name AND d.status='active' AND (d.gcs_uri=k.source_uri OR d.metadata->>'origin_url'=k.source_uri))或source_uri IS NULL:前者排除软删/孤儿,后者保留 KG 类直连知识4 处端点统一
list_corporaouterjoin + group_by→ 相关标量子查询get_corpusupdate_corpusget_dashboarddelete_corpus业界口径对齐
LangChain
ParentDocumentRetriever[1] / LlamaIndexHierarchicalNodeParser[2] / AWS Bedrock KB Hierarchical Chunking[3] 均以顶层(非 child)chunks 为统计粒度;child 是检索实现细节,不暴露到产品计数。本仓metadata.chunk_role已为该口径预留正交语义,无需新建字段。集成测试
新增
apps/negentropy/tests/integration_tests/knowledge/test_corpus_chunk_count_filter.py,6 象限场景串行覆盖:受现有
db_engine函数级 fixture 与 asyncpg 连接池跨事件循环边界限制,采用「单 test 函数 + 多场景子断言」模式,每场景独立app_name命名空间隔离。uv run pytest tests/integration_tests/knowledge/test_corpus_chunk_count_filter.py通过。影响面 & 兼容性
CorpusResponse/DashboardResponse的knowledge_count: int字段类型不变,UI 零改动delete_corpus审计日志仍记录物理 count(删除条数审计语义保持)Knowledge.metadata->>'chunk_role'JSONB 表达式 + 相关子查询;单 corpus chunks ≤ 万级无需新增索引(如未来体量大可参考0029加部分表达式索引)Phase 化交付路线(本 PR 仅 Phase 1)
delete_document硬删 chunks 级联清理 + 软删 archive chunks + reactivation 旧 chunks purge + 检索路径 archived 过滤复核Knowledge.document_idFK + ORM 同步 + 写入路径全量补丁 + 独立 CLIcleanup_orphan_knowledgedry-run/commit + 观测 metricTest plan
pytest tests/integration_tests/knowledge/test_corpus_chunk_count_filter.py6 象限场景全 passpytest tests/unit_tests/knowledge/test_api_corpus.py tests/unit_tests/knowledge/test_api_documents.py19 项既有用例无回归docs/issue.md追加 ISSUE-078 完整 RCA + 防范条款 + 同类问题影响Harness Engineeringold_count=849, new_count=14)Staging SQL 对比脚本
```sql
SELECT name,
(SELECT COUNT() FROM negentropy.knowledge k WHERE k.corpus_id = c.id) AS old_count,
(
SELECT COUNT() FROM negentropy.knowledge k
WHERE k.corpus_id = c.id
AND COALESCE(k.metadata->>'chunk_role', 'leaf') <> 'child'
AND (
k.source_uri IS NULL
OR EXISTS (
SELECT 1 FROM negentropy.knowledge_documents d
WHERE d.corpus_id = k.corpus_id AND d.app_name = k.app_name
AND d.status = 'active'
AND (d.gcs_uri = k.source_uri OR d.metadata->>'origin_url' = k.source_uri)
)
)
) AS new_count
FROM negentropy.corpus c WHERE c.name = 'Harness Engineering';
```
参考文献(IEEE)
[1] LangChain, "ParentDocumentRetriever," LangChain Python Documentation, https://python.langchain.com/docs/how_to/parent_document_retriever/, 2024.
[2] J. Liu, "HierarchicalNodeParser — Auto-Merging Retriever," LlamaIndex Documentation, https://docs.llamaindex.ai/en/stable/examples/retrievers/auto_merging_retriever/, 2024.
[3] Amazon Web Services, "Hierarchical chunking — Knowledge Bases for Amazon Bedrock," AWS Documentation, https://docs.aws.amazon.com/bedrock/latest/userguide/kb-chunking-parsing.html, 2024.
🤖 Generated with Claude Code