﻿# Update RAG documents without leaving stale chunks and citations

Version RAG documents and their chunks explicitly, remove superseded search evidence, and retain citation provenance without confusing historical and active content.

Author: Retrivium team
Updated: 2026-11-03
Canonical URL: https://retrivium.ai/journal/rag-document-updates-stale-chunk-citations/
Language: en

Replacing a document in a RAG system can leave old fragments searchable even when the upload appears successful. The risk is greater when edits change the chunk boundaries or shorten the source. Treat a document update as publication of a new evidence version, rather than a collection of unrelated vector inserts.

## Define document and chunk identities

Keep a stable document identity, an explicit source revision and identities for the chunks belonging to that revision. A chunk's ordinal position alone is not a reliable description of its meaning: inserting a paragraph near the beginning can shift later boundaries.

The [pgvector repository](https://github.com/pgvector/pgvector) documents ordinary row insertion, updating and deletion alongside vector search. Those primitives are useful, but they do not decide the application's document-version policy. Record which rows form one complete source revision before designing the update procedure.

## Preserve evidence provenance

The [Docling document model](https://docling-project.github.io/docling/concepts/docling_document/) describes structured content and provenance information. Keep the source location, extracted text and transformation revision associated with a chunk. A vector without that relationship is insufficient to reconstruct a trustworthy citation after the source changes.

For a document with moved sections, compare the old and new evidence locations. Do not assume a page number or character offset still refers to the same passage after reflow. A historical citation can remain valid as a reference to an older source, while that older source is excluded from current search.

## Do not confuse upsert with complete replacement

PostgreSQL's [INSERT reference](https://www.postgresql.org/docs/current/sql-insert.html) describes `ON CONFLICT` behavior for conflicting rows. Updating matching identities does not automatically delete other rows belonging to an earlier document revision. That cleanup is a separate application responsibility.

Consider an illustrative document that previously produced four chunks and now produces two. Updating the first two rows can leave the remaining two searchable. A successful database operation has not established a clean active corpus. Compare the resulting row set with the new document manifest, not only the number of successful insert calls.

## Publish a complete revision boundary

Prepare new chunks and embeddings under the new revision, validate their manifest, then make the intended version eligible for search. Choose the database transaction or application publication mechanism appropriate to the deployment. Do not claim atomic replacement across independent services unless the actual procedure provides it.

Check retrieval during the transition, including a request arriving between ingestion steps. A result assembled from mixed revisions can contain contradictory evidence. Keep old state available for the defined recovery window without accidentally leaving it eligible for ordinary active retrieval.

## Test edits, deletions and old citations

Use a fixture that changes a fact, removes a section and moves another section. Search for both the current fact and the removed wording. Inspect the returned source revision and citation target, rather than accepting a plausible generated summary as proof of cleanup.

Then open a citation from an earlier answer under the stated historical-resolution policy. Keep that behavior distinct from what new questions can retrieve. A useful update procedure can explain the complete active chunk set, handle deleted evidence and resolve retained historical references without silently rewriting their original meaning.

## Related reading

[A local RAG server: placing components around the GPU](/journal/rag-server-local-architecture/), [PostgreSQL and pgvector for RAG on an existing server](/journal/pgvector-rag-server/).
