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]
|
||||
|
||||
# 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)
|
||||
if not expanded_content:
|
||||
if len(expanded_content) < len(first.content):
|
||||
expanded_content = first.content
|
||||
|
||||
final_results.append(
|
||||
|
|
|
|||
|
|
@ -56,6 +56,8 @@ def extract_items(
|
|||
|
||||
Runs iterate_items() and extracts the fields needed for context expansion:
|
||||
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] = []
|
||||
|
||||
|
|
|
|||
|
|
@ -320,3 +320,65 @@ class TestExpandWithItems:
|
|||
# with skip_noise crosses into the Introduction section which has
|
||||
# real content — so we get expanded content, not the fallback.
|
||||
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