From 9a78882b5a294fa7de824197d08a743810a6e777 Mon Sep 17 00:00:00 2001 From: Trenton H <797416+stumpylog@users.noreply.github.com> Date: Wed, 13 May 2026 09:01:34 -0700 Subject: [PATCH] Fix: Don't embed the metadata which is already embedded into the context (#12795) --- src/paperless_ai/indexing.py | 10 +++++++++- src/paperless_ai/tests/test_ai_indexing.py | 20 ++++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/src/paperless_ai/indexing.py b/src/paperless_ai/indexing.py index 9293633a3..d596805fa 100644 --- a/src/paperless_ai/indexing.py +++ b/src/paperless_ai/indexing.py @@ -116,7 +116,15 @@ def build_document_node(document: Document) -> list["BaseNode"]: from llama_index.core import Document as LlamaDocument from llama_index.core.node_parser import SimpleNodeParser - doc = LlamaDocument(text=text, metadata=metadata) + # Exclude all metadata keys from the embedding text — build_llm_index_text + # already encodes this info in the body, so prepending it again would double + # the token count and exceed embedding models with small context windows + # (e.g. nomic-embed-text via Ollama defaults to num_ctx=2048). + doc = LlamaDocument( + text=text, + metadata=metadata, + excluded_embed_metadata_keys=list(metadata.keys()), + ) parser = SimpleNodeParser( chunk_size=RAG_CHUNK_SIZE, chunk_overlap=get_rag_chunk_overlap(), diff --git a/src/paperless_ai/tests/test_ai_indexing.py b/src/paperless_ai/tests/test_ai_indexing.py index 09fbc2038..aba9e2f7f 100644 --- a/src/paperless_ai/tests/test_ai_indexing.py +++ b/src/paperless_ai/tests/test_ai_indexing.py @@ -58,6 +58,26 @@ def test_build_document_node(real_document) -> None: assert nodes[0].metadata["document_id"] == str(real_document.id) +@pytest.mark.django_db +def test_build_document_node_excludes_metadata_from_embedding(real_document) -> None: + """Metadata keys must not be prepended to the embedding text. + + build_llm_index_text already encodes all metadata in the body text, so + including it again via llama_index's default MetadataMode.EMBED would + double the token count and exceed embedding models with small context + windows (e.g. nomic-embed-text via Ollama defaults to num_ctx=2048). + """ + from llama_index.core.schema import MetadataMode + + nodes = indexing.build_document_node(real_document) + for node in nodes: + embed_text = node.get_content(metadata_mode=MetadataMode.EMBED) + for key in node.metadata: + assert key not in embed_text, ( + f"Metadata key '{key}' should not appear in embedding text" + ) + + @pytest.mark.django_db def test_build_document_node_uses_rag_chunk_settings(real_document) -> None: with patch("llama_index.core.node_parser.SimpleNodeParser") as mock_parser: