fix: 复用未变化文档的重解析产物#2000
Open
zlh123123 wants to merge 4 commits into
Open
Conversation
There was a problem hiding this comment.
Pull request overview
This PR addresses #1679 by making reparse of unchanged documents reuse previously computed artifacts (chunks, embeddings, VLM OCR/caption, wiki map, graph extraction, DocReader parse, summary, and question generation) via deterministic chunk IDs, diff-based chunk updates, and tenant/model/config/prompt-scoped caches.
Changes:
- Add new cache tables (PostgreSQL migration v65 + SQLite migrations/init schema) and repositories/types for embedding, image multimodal, graph extraction, wiki map, and generic reparse artifacts.
- Introduce stable, content-addressed IDs and hash normalization utilities to enable chunk reuse and cache key stability across reparses (including canonicalizing volatile image URLs).
- Update ingestion/postprocess stages to use cache lookups + upserts, and add tests for reparse reuse behavior and artifact compression round-trips.
Reviewed changes
Copilot reviewed 24 out of 24 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| migrations/versioned/000065_reparse_caches.up.sql | Adds PostgreSQL cache tables + indexes for reparse reuse. |
| migrations/versioned/000065_reparse_caches.down.sql | Drops the PostgreSQL cache tables. |
| migrations/sqlite/000001_reparse_caches.up.sql | Adds SQLite cache tables + indexes for reparse reuse. |
| migrations/sqlite/000001_reparse_caches.down.sql | Drops the SQLite cache tables. |
| migrations/sqlite/000000_init.up.sql | Adds cache tables to the SQLite initial schema. |
| internal/types/task.go | Extends manual processing payload to carry an API-allocated attempt. |
| internal/types/reparse_cache.go | Defines GORM models for the new cache tables. |
| internal/types/interfaces/reparse_cache.go | Adds repository interfaces for cache access. |
| internal/types/interfaces/chunk.go | Adds “list all chunks” + permanent delete methods to chunk interfaces. |
| internal/types/embedding.go | Adds support for passing precomputed embeddings through indexing flow. |
| internal/container/container.go | Registers new cache repositories in the DI container. |
| internal/application/service/wiki_ingest.go | Wires wiki ingest service to use wiki map cache repository. |
| internal/application/service/wiki_ingest_batch.go | Implements wiki map cache hit path and live-state reconciliation for deletes. |
| internal/application/service/retriever/keywords_vector_hybrid_indexer.go | Consumes precomputed embeddings and exports embedding helpers. |
| internal/application/service/reparse_reuse.go | Adds hashing/ID utilities, cache key builders, and diff planning helpers. |
| internal/application/service/reparse_reuse_test.go | Adds tests covering cache keys, stable IDs, diff planning, and artifact gzip round-trip. |
| internal/application/service/knowledge.go | Injects embedding/artifact cache repos into knowledge service. |
| internal/application/service/knowledge_process.go | Switches to diff-based chunk writes, stable IDs, and adds caching for parse/summary/questions/embeddings. |
| internal/application/service/knowledge_create.go | Passes attempt through manual processing enqueue path. |
| internal/application/service/image_multimodal.go | Adds VLM OCR/caption caching, stable IDs for image-derived chunks, and cached embeddings for indexing. |
| internal/application/service/extract.go | Adds graph extraction caching keyed by chunk/config/model fingerprints. |
| internal/application/service/chunk.go | Implements “list all” and permanent delete chunk service methods. |
| internal/application/repository/reparse_cache.go | Implements GORM repositories for the new cache tables. |
| internal/application/repository/chunk.go | Implements DB-side list-all and hard-delete chunk repository methods. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
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.
Description
本 PR 修复 #1679 中同一文档重解析时重复执行解析、向量化和 LLM 生成任务的问题。
此前,重解析会清理已有 Chunk 并重新创建派生数据。即使文档内容没有变化,系统仍会重复计算向量、图片 OCR/描述、问题和摘要,导致处理时间长、模型调用次数增加,Chunk ID 也无法稳定复用。
主要修改:
ReadResult,避免复用依赖本地临时图片文件的解析结果。source_id长度,确保不超过 PostgreSQLVARCHAR(64)。本次修改没有引入破坏性 API 变更。
Type of Change
Related Issue
Fixes #1679
Testing
自动化测试
执行命令:
执行结果:
完整
go test ./... -count=1 -timeout=20m也已执行。除依赖本地 DocReader(localhost:50051)以及被 SSRF 策略拦截的 localhost HTTP 测试外,其余 Go 包通过;上述 6 个与本 PR 及合并冲突直接相关的包全部通过。新增的
reparse_reuse_test.go覆盖以下场景:手动验证步骤
issue-1679-cache-validation-final.md,包含 2 个文本 Chunk 和 1 张内嵌截图。性能与缓存命中结果
两次不变重解析分别耗时 2.659 秒和 2.600 秒。向量、图片 OCR/描述、问题和摘要均复用了已有结果。
冷缓存首次写入后,后续两次重解析没有增加缓存记录:
embedding_cachesimage_multimodal_cachesreparse_artifact_cachesattempt 2 与 attempt 3 的有效 Chunk 数量和 ID 汇总哈希一致:
text7d03b5a81e9e80ccdc44429903b71b04parent_text9150bad92950b7fc3a37068c19e09468image_ocr8470948c90c571fd5b3901478bb1d011image_caption2519e97fd74ed1914e931ef139a0a095summary874daf7be1e9385a2543f994b3282292大文档补充验证
document_parse解析产物。llm_failed=0。环境检查
Checklist
make fmt && make lint && make testpass locally(未宣称全量通过,见下方说明)docs/, Swagger annotations, etc.)(本次无仓库文档变更)Screenshots / Recordings
本次没有修改用户界面。以下截图用于展示重解析配置和缓存命中后的 Trace 结果:
issue1679_final_trace.png:attempt 3 的 Trace 页面,5/5 个阶段全部完成,问题生成耗时 31 毫秒,摘要生成耗时 33 毫秒。issue1679_final_warm_config.png:不变重解析使用的配置,包括 qwen 多模态处理和每个 Chunk 生成 3 个问题。