preserve original chunk when expansion produces less content
This commit is contained in:
parent
e2bac1e887
commit
d3c8ed62a8
3 changed files with 68 additions and 2 deletions
|
|
@ -230,9 +230,11 @@ async def expand_with_items(
|
||||||
|
|
||||||
first = original_results[0]
|
first = original_results[0]
|
||||||
|
|
||||||
# If noise filtering removed all content, preserve the original
|
# Expansion should never return less content than the original chunk.
|
||||||
|
# This can happen when item texts are fragmented (e.g., docling splits
|
||||||
|
# formatted HTML list items into many small text nodes).
|
||||||
expanded_content = "\n\n".join(content_parts)
|
expanded_content = "\n\n".join(content_parts)
|
||||||
if not expanded_content:
|
if len(expanded_content) < len(first.content):
|
||||||
expanded_content = first.content
|
expanded_content = first.content
|
||||||
|
|
||||||
final_results.append(
|
final_results.append(
|
||||||
|
|
|
||||||
|
|
@ -56,6 +56,8 @@ def extract_items(
|
||||||
|
|
||||||
Runs iterate_items() and extracts the fields needed for context expansion:
|
Runs iterate_items() and extracts the fields needed for context expansion:
|
||||||
self_ref, label, pre-rendered text, and page numbers from provenance.
|
self_ref, label, pre-rendered text, and page numbers from provenance.
|
||||||
|
Items are stored as docling produces them — container items (e.g., list_item)
|
||||||
|
may have empty text with content in their children.
|
||||||
"""
|
"""
|
||||||
items: list[DocumentItem] = []
|
items: list[DocumentItem] = []
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -320,3 +320,65 @@ class TestExpandWithItems:
|
||||||
# with skip_noise crosses into the Introduction section which has
|
# with skip_noise crosses into the Introduction section which has
|
||||||
# real content — so we get expanded content, not the fallback.
|
# real content — so we get expanded content, not the fallback.
|
||||||
assert len(expanded[0].content) > 0
|
assert len(expanded[0].content) > 0
|
||||||
|
|
||||||
|
async def test_fragmented_items_preserve_chunk(self, temp_db_path):
|
||||||
|
"""When items are fragmented (e.g., list_item children), the original
|
||||||
|
chunk content is preserved if expansion produces less text."""
|
||||||
|
from haiku.rag.client import HaikuRAG
|
||||||
|
|
||||||
|
async with HaikuRAG(temp_db_path, create=True) as rag:
|
||||||
|
# Simulate docling's list_item structure: container with empty text,
|
||||||
|
# children with tiny fragments
|
||||||
|
items = [
|
||||||
|
DocumentItem(
|
||||||
|
document_id="doc-1",
|
||||||
|
position=0,
|
||||||
|
self_ref="#/texts/0",
|
||||||
|
label="section_header",
|
||||||
|
text="Steps",
|
||||||
|
),
|
||||||
|
DocumentItem(
|
||||||
|
document_id="doc-1",
|
||||||
|
position=1,
|
||||||
|
self_ref="#/texts/1",
|
||||||
|
label="list_item",
|
||||||
|
text="",
|
||||||
|
),
|
||||||
|
DocumentItem(
|
||||||
|
document_id="doc-1",
|
||||||
|
position=2,
|
||||||
|
self_ref="#/texts/2",
|
||||||
|
label="text",
|
||||||
|
text="Click",
|
||||||
|
),
|
||||||
|
DocumentItem(
|
||||||
|
document_id="doc-1",
|
||||||
|
position=3,
|
||||||
|
self_ref="#/texts/3",
|
||||||
|
label="text",
|
||||||
|
text="+",
|
||||||
|
),
|
||||||
|
DocumentItem(
|
||||||
|
document_id="doc-1",
|
||||||
|
position=4,
|
||||||
|
self_ref="#/texts/4",
|
||||||
|
label="text",
|
||||||
|
text="Add a New Service",
|
||||||
|
),
|
||||||
|
]
|
||||||
|
await rag.document_item_repository.create_items("doc-1", items)
|
||||||
|
|
||||||
|
# The chunk had properly assembled content from the chunker
|
||||||
|
result = SearchResult(
|
||||||
|
content="1. Click + Add a New Service in the dashboard.",
|
||||||
|
score=0.9,
|
||||||
|
document_id="doc-1",
|
||||||
|
doc_item_refs=["#/texts/1", "#/texts/2", "#/texts/3", "#/texts/4"],
|
||||||
|
)
|
||||||
|
expanded = await expand_with_items(
|
||||||
|
rag.document_item_repository, "doc-1", [result], 10, 5000
|
||||||
|
)
|
||||||
|
assert len(expanded) == 1
|
||||||
|
# Expansion produces "Steps\n\nClick\n\n+\n\nAdd a New Service" = 38 chars
|
||||||
|
# which is less than the chunk's 46 chars — fallback preserves the chunk
|
||||||
|
assert expanded[0].content == result.content
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue