Skip to main content
Add persistent, per-user memory to a Haystack pipeline as two regular components: a retriever for the read side and a writer for the write side. Both drop into existing pipelines without restructuring.
Requires Python 3.11+.

Overview

This guide shows how to add Synap to a Haystack application to build pipelines that:
  • Retrieve user-scoped memories as standard Document objects in a RAG flow
  • Persist each conversation turn back to Synap so future runs benefit from it
  • Compose freely with any other Haystack component (rerankers, prompt builders, generators)
The Synap Haystack integration ships two drop-in pipeline components. Both follow Haystack’s component contract so you can wire them into pipelines exactly like any built-in component.

Setup

Install the package alongside Haystack:
The pip package is maximem-synap-haystack, but the import drops the maximem- prefix and uses underscores: from synap_haystack import ....
Configure your API key. Generate one from the Synap Dashboard.
.env
Initialize the SDK once at application startup:
See SDK Initialization for the full lifecycle and configuration options.

Basic integration

The smallest useful integration plugs SynapRetriever into a pipeline and routes its documents output to a prompt builder:
Retrieval failures degrade gracefully. SynapRetriever emits an empty documents list and logs an error, so the rest of the pipeline keeps running. To close the loop and persist new turns for future retrievals, add SynapMemoryWriter after the generator.

Core concepts

Retriever

SynapRetriever is a Haystack component that takes a query input and emits a documents output. Each returned Document has:
  • content: the memory text
  • meta["type"]: memory type (e.g. "fact", "preference")
  • meta["confidence"]: relevance score
The two retrieval modes trade latency against comprehensiveness: fast is lower-latency and suited to the hot path; accurate adds LLM-driven query decomposition and reranking for relationship-aware queries at a higher latency cost. Because the output shape matches Haystack’s standard Document, you can route it through any reranker, prompt builder, or filter that accepts documents.

Memory writer

SynapMemoryWriter is the write side. Place it at the end of a pipeline so each LLM reply is captured as a memory for future retrievals:
It accepts a replies input (matching the output of standard generators like OpenAIGenerator) and emits a result summary. Write failures surface explicitly. SynapMemoryWriter raises SynapIntegrationError so the pipeline knows if persistence failed.

Complete example: full RAG pipeline with memory loop

The following pipeline retrieves user-scoped memories, builds a prompt, generates a response, and writes the response back to Synap, in one pass:
Three things to notice in this pattern:
  1. Memory is just another retriever. SynapRetriever emits standard Document objects, so you can mix it with any document store retriever via a DocumentJoiner if you want corpus context too.
  2. The write loop closes itself. Each pipeline run ends by persisting the reply, so every subsequent run benefits from accumulating context.
  3. Scope is bound at construction. The retriever and writer carry the user/customer scope; the pipeline graph never needs to know about user identity.

Advanced patterns

Multi-tenant scoping

Both components accept the standard scoping triple: user_id (required), optional customer_id, optional conversation_id. customer_id is required on B2B Synap instances and ignored on single-tenant ones. See Memory Scopes.
For multi-tenant services, build the pipeline (or at least the retriever/writer components) per request so each invocation has the correct scope baked in.

Combining with document retrieval

SynapRetriever’s output is a standard Document list, so it slots into a DocumentJoiner next to your existing document store retriever:
User-specific facts and corpus chunks come back as a single ranked list to the prompt builder.

Failure semantics

The integration follows the Synap-wide contract:
  • SynapRetriever degrades gracefully: emits an empty documents list and logs an error if Synap is unreachable.
  • SynapMemoryWriter surfaces failures: raises SynapIntegrationError so the pipeline (and caller) know persistence failed.
This is by design: read failures shouldn’t break a user-facing turn, but silent write failures would let the memory drift away from reality.

Going further


Next steps

LangChain

Memory and retriever for LangChain.

LlamaIndex

BaseMemory and retriever for LlamaIndex.

Context Fetch

The retrieval API that powers SynapRetriever: modes, scopes, and response shapes.

Memory Scopes

How user_id, customer_id, and conversation_id interact across reads.