What LangGraph already keeps
Checkpointers save graph state so a thread can resume; stores hold key–value documents across threads. Both persist what you put in them, but reconciling a changed fact, keeping its history and attaching sources is left to your code.
Where Auld fits
Add a load_memory node at the start of the graph that recalls for the incoming message and writes the result into state, and a save_memory node after the response that ingests the turn. The checkpointer keeps the thread; Auld keeps the facts.
| Concern | LangGraph | Auld |
|---|---|---|
| Current conversation | Yes | Not needed |
| Facts across sessions and channels | Your code | Yes |
| Which fact is current after a change | Your code | Yes, with history |
| What was true on a date | Your code | Yes (asOf) |
| Who may see a memory | Your code | Identities and audiences |
| Source for each statement | Your code | Returned with every memory |
Implementation sequence
Extend the state
Add a
memorystring field to your state schema.Recall in a node
The first node calls recall with the latest user message and the user id from config.
Use memory in the model node
Prepend the recalled memories to the system message.
Ingest after responding
A final node sends the user turn as a record with its timestamp; it does not block the reply if you run it asynchronously.
Example
import os, requests
AULD = os.environ["AULD_API_BASE"] # e.g. https://YOUR-AULD-HOST
HEADERS = {"Authorization": f"Bearer {os.environ['AULD_API_KEY']}"}
def auld_post(path: str, body: dict) -> dict:
r = requests.post(f"{AULD}/v1/{path}", json=body, headers=HEADERS, timeout=30)
r.raise_for_status()
return r.json()
def remember(text: str, user_id: str, source_id: str, occurred_at: str) -> str:
"""Store a dated record for one user. Returns the job id."""
return auld_post("records", {"sourceId": source_id, "text": text,
"occurredAt": occurred_at, "author": user_id,
"visibility": f"user:{user_id}"})["jobId"]
def recall(query: str, user_id: str, max_tokens: int = 2000) -> str:
"""Current memories with sources, formatted for a prompt."""
res = auld_post("recall", {"query": query, "viewer": user_id, "maxTokens": max_tokens})
return "\n".join(f"- {m['text']} ({m['sources'][0]['title']}, {m['sources'][0]['occurredAt'][:10]})"
for m in res["memories"]) or "No relevant memory."from typing import TypedDict
from datetime import datetime, timezone
from langgraph.graph import StateGraph, START, END
from memory_client import remember, recall
class State(TypedDict):
user_id: str
message: str
memory: str
reply: str
def load_memory(state: State) -> dict:
return {"memory": recall(state["message"], state["user_id"])}
def respond(state: State) -> dict:
prompt = f"Known context:\n{state['memory']}\n\nUser: {state['message']}"
return {"reply": llm.invoke(prompt).content}
def save_memory(state: State) -> dict:
now = datetime.now(timezone.utc).isoformat()
remember(state["message"], state["user_id"], f"turn-{state['user_id']}-{now}", now)
return {}
g = StateGraph(State)
g.add_node("load_memory", load_memory); g.add_node("respond", respond); g.add_node("save_memory", save_memory)
g.add_edge(START, "load_memory"); g.add_edge("load_memory", "respond")
g.add_edge("respond", "save_memory"); g.add_edge("save_memory", END)
graph = g.compile()Illustrative example · standard HTTP · check the framework’s current docs for exact signatures
Or connect the MCP server
If your LangGraph setup can use MCP tools, point it at the Auld MCP endpoint instead of writing wrappers. The model gets remember, recall, forget and memory_status. Use wrappers when you need to inject the user id yourself or post-process results; use MCP for speed of setup.
Custom integration recipe using standard HTTP/MCP tools
- This recipe wires LangGraph’s own tool interface to the Auld REST API or MCP server; there is nothing Auld-specific to install.
- Bind the viewer id from your authentication layer, not from model output.
- Ingestion is asynchronous — poll the job before depending on a just-sent fact in tests.
- Recall returns up to your plan’s token limit (8,000 on Pay as you go and Flex).
Frequently asked questions
Fixed node or tool?
A fixed recall node guarantees context on every turn and is easier to test. A tool lets the model decide and saves calls on turns that don’t need history. Many graphs use a node for the first turn and a tool afterwards.
What about the LangGraph store?
It is a good place for agent configuration and scratch data. Use Auld when you need supersession, point-in-time questions and sources.