
How to add persistent memory to a LangGraph agent with FishMem
August 23, 2026Guides

A production document pipeline for immutable uploads, checksums, lossless extraction, deterministic chunks, citations, retries, and deletion.
Most RAG tutorials begin at chunking because chunks are the first artifact a retriever sees. Production systems should begin one step earlier: with a source that can still be inspected after the parser, chunker, embedding model, and ranking strategy have all changed.
A chunk is useful precisely because it is lossy. It selects a small region for matching and prompt assembly. That makes it a projection, not a safe archival format.
Chunk text may omit page structure, adjacent paragraphs, tables, captions, headers, or images. Even plain text can lose the difference between a list, a warning, and a footnote. If chunks are the only stored artifact, changing the parser or split strategy cannot recover what was removed.
| Artifact | Purpose | Can it be rebuilt? |
|---|---|---|
| Original asset or exact text | Evidence and reprocessing authority | No; preserve it |
| Lossless structured extraction | Pages, blocks, tables, ordering | Yes, from the original |
| Markdown or normalized text | Readable downstream representation | Yes |
| Chunks | Bounded retrieval units | Yes |
| Embeddings and indexes | Candidate selection | Yes |
A source descriptor should include a stable source key, title, media type, byte length, structural scope, metadata, and a checksum when bytes are available. The system should distinguish three cases:
This prevents an upload retry from silently becoming a second document and prevents a changed file from overwriting the evidence behind prior citations.
PDF, Office, EPUB, email, image, and large text extraction can outlive an ordinary request. A queue message alone is not enough: it can be duplicated or lost, and it rarely carries the complete audit state needed for cancellation and repair.
FishMem records an operation with attempts, lease, status, error, source version, and result. The original object is written before extraction begins. A pinned extraction adapter emits normalized Markdown and structure back through the same canonical document writer. Queue delivery is only a wakeup, while scheduled repair finds missed or expired tasks.
Given the same source version and chunker configuration, the system should produce the same chunk identities and ordering. Determinism makes retries safe, lets tests compare projections, and turns an index rebuild into a normal operation instead of a migration gamble.
Record enough configuration to explain a chunk:
A useful result includes the matched chunk, its owning document and version, its position, and the exact indexed content. Neighbor expansion can recover context around the hit. The application can then decide whether to quote, summarize, or open the source.
Provenance must survive derived structure. If an entity, fact, or summary is built from several source regions, keep all supporting associations rather than only the first. When sources merge, update, or invalidate a derived claim, lineage should grow with the claim instead of being overwritten.
If a retrieval result cannot lead back to inspectable evidence, it may still be relevant, but it is not yet trustworthy enough for a citation.
Vector metadata is useful for narrowing candidates, but it should not be the final security boundary. Candidate IDs should be rehydrated through the canonical database and checked against the full namespace and source filters before their content is returned.
This matters when an index is stale, a document's access metadata changes, or a backend cannot express the complete policy. A fast candidate lookup is not permission to bypass authoritative scope checks.
Deleting one document version should account for every artifact derived from it: original object, extraction output, chunks, vectors, entity associations, cached context, and operation state. Shared derived artifacts need reference-aware deletion; an entity or fact supported by another source should not disappear just because one document is removed.
Deletion should be replay-safe. If object storage removal succeeds but the database transaction fails, or the reverse, the operation journal needs enough state to repair the incomplete family without resurrecting unauthorized content.
| Failure | Expected behavior |
|---|---|
| Upload interrupted after object write | Durable operation resumes or removes the orphan safely |
| Parser returns malformed output | Source remains preserved; no false ready state |
| Chunk commit succeeds, vector write fails | Repair the projection without duplicating document versions |
| Same key reused for different content | Explicit conflict |
| Source access policy changes | Canonical recheck prevents stale index leakage |
| Deletion retries after partial success | Converge on one deleted source family |
FishMem's Document corpus retains versioned source content and treats normalized text, chunks, and indexes as rebuildable. It is separate from compact durable memory records. Applications may derive memories from documents, but those records should carry provenance and should not replace the source that justified them.