GoodMemGoodMem
IntegrationsAgent Frameworks

LangGraph

Search GoodMem from LangGraph nodes and agents with scoped retrieval, source metadata, and Document ingestion.

Stable· Python (3.10+)

GoodMem gives LangGraph applications persistent, searchable content. It handles chunking, embedding, vector search, and optional reranking. The integration shares its tools, retriever, and ingestion functions with LangChain, so both packages receive the same SDK fixes.

Installation

pip install "langgraph-goodmem>=0.2.0,<0.3.0"

This page describes the 0.2 API. See the migration notes when upgrading from 0.1.

Set GOODMEM_BASE_URL, GOODMEM_API_KEY, and GOODMEM_SPACE_ID for an existing server and space. Tools and the retriever read the endpoint and key from the environment; the space is supplied explicitly by your application.

Search from a graph

This complete example searches your space without an LLM. The retrieval node adds Document objects, including source metadata, to the graph's state.

import os
from typing import TypedDict

from langchain_core.documents import Document
from langchain_core.runnables import RunnableConfig
from langgraph.graph import END, START, StateGraph
from langgraph_goodmem import GoodMemRetriever

class State(TypedDict):
    question: str
    documents: list[Document]

retriever = GoodMemRetriever(space_ids=[os.environ["GOODMEM_SPACE_ID"]], k=5)

def search(state: State, config: RunnableConfig):
    return {"documents": retriever.invoke(state["question"], config=config)}

builder = StateGraph(State)
builder.add_node("search", search)
builder.add_edge(START, "search")
builder.add_edge("search", END)
graph = builder.compile()
result = graph.invoke({"question": "What is the refund policy?", "documents": []})
for document in result["documents"]:
    print(document.metadata["source"], document.page_content, sep="\n")

The same graph supports await graph.ainvoke(...), batching, and streaming. The shared retriever currently runs synchronous SDK calls in a thread executor for async invocations. For explicit sync and async node implementations, see the retrieval-node example.

Use an agent

The agent example gives create_agent a scoped search tool built with create_retriever_tool. You can also use that tool in ToolNode([search]) within your own agent graph. The model supplies a query; your code controls the spaces, filter, and reranker. Give different searches distinct names and descriptions so the agent can choose the right one. Tool results contain readable text with sources and an artifact holding the retrieved Documents.

Install langgraph-goodmem[agents] and your model provider's LangChain package, configure its credentials, and set GOODMEM_CHAT_MODEL=provider:model. The integration does not select or install a model provider for you.

Ingest Documents

import os
from goodmem import Goodmem
from langchain_core.documents import Document
from langgraph_goodmem import add_documents

with Goodmem(base_url=os.environ["GOODMEM_BASE_URL"],
             api_key=os.environ["GOODMEM_API_KEY"]) as client:
    memory_ids = add_documents(client, os.environ["GOODMEM_SPACE_ID"], [
        Document(page_content="Refunds are available within 30 days.",
                 metadata={"source": "https://example.com/refunds"})
    ])

add_documents preserves metadata and waits for the memories it created to finish indexing. Use wait=False to return accepted IDs immediately. If waiting fails, GoodMemIngestionError.created_memory_ids retains successful writes; use wait_for_memory(client, memory_id) to check them without uploading again. Searching an empty space returns immediately.

Filters and reranking

retriever = GoodMemRetriever(
    space_ids=[os.environ["GOODMEM_SPACE_ID"]],
    filter="CAST(val('$.department') AS TEXT) = 'support'",
    reranker_id=os.environ["GOODMEM_RERANKER_ID"],
    k=5,
    fetch_k=20,
)

Filters use GoodMem filter expressions. Keep the space, filter, and reranker configuration in application code. Reranking does not require an LLM. Retrieval preserves the server's ordering and scores; vector and reranker scores do not share a universal 0–1 scale.

Connections and administrative tools

Pass client=Goodmem(...) to the retriever or tools to use a caller-owned SDK client. Close it after graph execution finishes. For local development with a self-signed certificate, configure Goodmem(..., verify=False) or set GOODMEM_VERIFY_SSL=false when using environment-based connections. Keep TLS verification enabled for deployed servers.

All eleven administrative tools remain available from langgraph_goodmem.tools. They use the SDK's argument names and return native dictionaries or lists; LangChain serializes the results into tool messages. They retain the configured client's authority, including local file uploads, so give agents only the tools their task requires. The scoped search in the agent example exposes only a query to the model.

GoodMemRetrieveMemories provides raw SDK events for applications that need summaries or retrieval diagnostics. It preserves chunks alongside status events. Inspect those statuses before treating a request as fully successful. The native retriever reports known failures as errors and tolerates unfamiliar status codes.

GoodMem stores searchable content. Use a LangGraph checkpointer to persist graph execution state; this package does not implement a checkpointer or BaseStore.