LangChain
Python SDK IntegrationAdd persistent MemoAir memory to LangChain agents and chains. Retrieve user or organization context before calling the model, then save the conversation turn after the response.
Install
pip install "memoair[langchain]" langchain-openaiThe LangChain dependency is optional, so core MemoAir SDK users do not install it unless they need this integration.
Use MemoAir as a Retriever
`MemoAirRetriever` implements LangChain's standard retriever interface and returns `Document` objects with MemoAir fact metadata.
from langchain_openai import ChatOpenAIfrom memoair import MemoAirfrom memoair.integrations.langchain import MemoAirRetriever client = MemoAir(api_key="memoair_sk_...")retriever = MemoAirRetriever( client=client, group_ids=["user:alice"], max_facts=5,) docs = retriever.invoke("What does Alice prefer for backend work?")context = "\n".join(doc.page_content for doc in docs) llm = ChatOpenAI(model="gpt-4o")response = llm.invoke( [ ("system", f"Use this MemoAir context when helpful:\n{context}"), ("user", "Which framework should I use?"), ])print(response.content)Conversation Memory
`MemoAirMemory` is a lightweight helper for the common retrieve, answer, save loop.
from langchain_openai import ChatOpenAIfrom memoair import MemoAirfrom memoair.integrations.langchain import MemoAirMemory client = MemoAir(api_key="memoair_sk_...")memory = MemoAirMemory(client=client, group_id="user:alice", max_facts=10)llm = ChatOpenAI(model="gpt-4o") def chat(message: str) -> str: context = memory.get_context(message) response = llm.invoke( [ ("system", f"You are a helpful assistant with memory:\n{context}"), ("user", message), ] ) memory.save_interaction( user_message=message, assistant_message=response.content, ) return response.contentLangChain-native Chat History
`MemoAirChatMessageHistory` implements LangChain's `BaseChatMessageHistory`, so it drops directly into `RunnableWithMessageHistory` and any LCEL component that consumes a chat history. Active turns are buffered in-memory while every turn is persisted to MemoAir for long-term memory.
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholderfrom langchain_core.runnables.history import RunnableWithMessageHistoryfrom langchain_openai import ChatOpenAIfrom memoair import MemoAirfrom memoair.integrations.langchain import MemoAirChatMessageHistory client = MemoAir(api_key="memoair_sk_...")prompt = ChatPromptTemplate.from_messages( [ ("system", "You are a helpful assistant with persistent MemoAir memory."), MessagesPlaceholder("history"), ("human", "{input}"), ])chain = prompt | ChatOpenAI(model="gpt-4o") with_history = RunnableWithMessageHistory( chain, lambda session_id: MemoAirChatMessageHistory(client=client, group_id=session_id), input_messages_key="input", history_messages_key="history",) with_history.invoke( {"input": "Use dark mode in all my apps."}, config={"configurable": {"session_id": "user:alice"}},)Use `auto_save=False` to buffer turns without persisting (useful for ephemeral previews), and call `history.get_context_messages(query)` to inject a `SystemMessage` of relevant facts into your prompt.
Function-calling Agent Tools
`MemoAirSearchTool` and `MemoAirSaveTool` are LangChain `BaseTool` subclasses that drop straight into `create_agent(tools=[...])`. Use `MemoAirMemory.as_tools()` to get both wrapped against the same client and group.
from langchain.agents import create_agentfrom memoair import MemoAirfrom memoair.integrations.langchain import MemoAirMemory client = MemoAir(api_key="memoair_sk_...")memory = MemoAirMemory(client=client, group_id="user:alice") agent = create_agent( model="openai:gpt-4o", tools=memory.as_tools(), # MemoAirSearchTool + MemoAirSaveTool system_prompt="Use MemoAir to recall facts and save anything worth remembering.",) result = agent.invoke({ "messages": [{"role": "user", "content": "Remember I prefer dark mode in all my apps."}]})print(result["messages"][-1].content)Tripartite Graph Retrieval
Use `MemoAirRetriever` for personal memory only. Use `MemoAirTripartiteRetriever` when the prompt should combine personal memory, organization knowledge, and ontology context in a single retrieval call.
from memoair import MemoAirfrom memoair.integrations.langchain import MemoAirTripartiteRetriever client = MemoAir(api_key="memoair_sk_...")retriever = MemoAirTripartiteRetriever( client=client, user_id="user:alice", org_id="org:acme", max_results=8, enable_hipporag=True,) docs = retriever.invoke("Who owns the Python runtime?")for doc in docs: print(doc.metadata["source_graph"], doc.page_content)Agent Template
The MemoAir SDK ships an opinionated LangChain agent template at sdk/examples/langchain_agent.py. It composes the retriever, chat history, and tripartite search into a single `LangChainMemoryAgent` class with three entry points: a manual `chat()` loop, a `runnable_with_history()` chain, and `retriever()` / `tripartite_retriever()` factories.
from langchain_agent import LangChainMemoryAgent agent = LangChainMemoryAgent(user_id="user:alice", org_id="org:acme") # Manual loop: retrieves MemoAir context, calls the LLM, persists the turn.print(agent.chat("What framework should I use for backend services?")) # LCEL chain: standard LangChain RunnableWithMessageHistory wiring.chain = agent.runnable_with_history()chain.invoke( {"input": "And for ML services?"}, config={"configurable": {"session_id": agent.user_id}},) # Tripartite retriever: personal + org + ontology graph in one call.docs = agent.tripartite_retriever().invoke("Who owns the Python runtime?")LangGraph note: MemoAir is intentionally not exposed as a `BaseCheckpointSaver`. Its API is fact-extraction oriented and does not provide the raw key-value state surface that LangGraph checkpointers require. Use `MemoAirChatMessageHistory` for conversation persistence and a separate checkpointer (for example the in-memory or SQLite saver) for graph state.