supermemory/apps/docs/integrations/langchain.mdx
MaheshtheDev 672defc08b docs: move SDK snippets to the shipped v5 call shape and finish the namespace rename (#1772)
Rewrites 339 TypeScript calls across 50 pages from the rc.5 `method({ namespace, body })` form to the shipped `method(namespace, { ... })` form, and aligns field names with the live v5 spec: `attach` to `include`, `authUrl` to `authorization`, `lastSync` to `latestRun`, `deletedCount` to `count`, and the paginated `namespaces.list()`.

Renames container tags to namespaces across concepts, connectors, integrations and snippets. The namespace pages keep container tag in the description, search keywords and a rename note so old searches still land, and the v3 reference page points at v5.

The migration guide's SDK table now covers both 5.0.0 SDKs, and the SDK integration page uses the real client options (`baseUrl`, `timeoutInSeconds`, `maxRetries`) and error classes.
2026-10-06 17:06:38 +00:00

389 lines
11 KiB
Text

---
title: "LangChain"
sidebarTitle: "LangChain"
description: "Build AI agents with persistent memory using LangChain and Supermemory"
icon: "/icons/hugeicons/link-01.svg"
---
Build AI applications with LangChain that remember context across conversations. Supermemory handles memory storage, retrieval, and user profiling while LangChain manages your conversation flow.
## Overview
This guide shows how to integrate Supermemory with LangChain to create AI agents that:
- Maintain user context through automatic profiling
- Store and retrieve relevant memories semantically
- Personalize responses based on conversation history
## Setup
Install the required packages:
```bash
pip install langchain langchain-openai supermemory python-dotenv
```
Configure your environment:
```bash
# .env
SUPERMEMORY_API_KEY=your-supermemory-api-key
OPENAI_API_KEY=your-openai-api-key
```
<Note>Get your Supermemory API key from [console.supermemory.ai](https://console.supermemory.ai).</Note>
## Basic integration
Initialize both clients and set up a simple chat function with memory:
```python
import os
from langchain_openai import ChatOpenAI
from langchain_core.messages import SystemMessage, HumanMessage
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from supermemory import Supermemory
from dotenv import load_dotenv
load_dotenv()
# Initialize clients
llm = ChatOpenAI(model="gpt-4o")
memory = Supermemory()
def chat(user_id: str, message: str) -> str:
# 1. Get user profile and relevant memories
profile_result = memory.profile(user_id)
search_result = memory.search(user_id, query=message)
# 2. Build context from profile
static_facts = [m.memory for m in profile_result.profile.static]
dynamic_context = [m.memory for m in profile_result.profile.dynamic]
search_results = search_result.results
context = f"""
User Background:
{chr(10).join(static_facts) if static_facts else 'No profile yet.'}
Recent Context:
{chr(10).join(dynamic_context) if dynamic_context else 'No recent activity.'}
Relevant Memories:
{chr(10).join([r.memory or r.chunk for r in search_results]) if search_results else 'None found.'}
"""
# 3. Generate response
prompt = ChatPromptTemplate.from_messages([
SystemMessage(content=f"You are a helpful assistant. Use this context to personalize your response:\n{context}"),
HumanMessage(content=message)
])
chain = prompt | llm
response = chain.invoke({})
# 4. Store the interaction as memory
memory.add(
user_id,
content=f"User: {message}\nAssistant: {response.content}",
dreaming="instant"
)
return response.content
```
---
## Core concepts
### User profiles
Supermemory automatically maintains user profiles with two types of information:
- **Static facts**: Long-term information about the user (preferences, expertise, background)
- **Dynamic context**: Recent activity and current focus areas
```python
# Fetch the profile for a namespace
result = memory.profile("user_123")
print([m.memory for m in result.profile.static]) # ["User is a Python developer", "Prefers dark mode"]
print([m.memory for m in result.profile.dynamic]) # ["Currently working on API integration", "Debugging auth issues"]
```
### Memory storage
Content you add is automatically processed into searchable memories:
```python
# Store a conversation
memory.add(
"user_123",
content="User asked about async Python patterns. Explained asyncio basics.",
metadata={"topic": "python", "type": "conversation"},
dreaming="instant"
)
# Store a document
memory.add(
"user_123",
content="https://docs.python.org/3/library/asyncio.html",
dreaming="instant"
)
```
### Memory search
Search returns both extracted memories and document chunks:
```python
results = memory.search(
"user_123",
query="async programming",
search_mode="hybrid", # Searches memories + document chunks
limit=5
)
for r in results.results:
print(r.memory or r.chunk, r.similarity)
```
---
## Complete example: Code review assistant
Here's a full example of a code review assistant that learns from past reviews and adapts to the user's coding style:
```python
import os
from typing import Optional
from langchain_openai import ChatOpenAI
from langchain_core.messages import SystemMessage, HumanMessage, AIMessage
from langchain_core.prompts import ChatPromptTemplate
from supermemory import Supermemory
from dotenv import load_dotenv
load_dotenv()
class CodeReviewAssistant:
def __init__(self):
self.llm = ChatOpenAI(model="gpt-4o", temperature=0.3)
self.memory = Supermemory()
def get_context(self, user_id: str, code: str) -> str:
"""Retrieve user profile and relevant past reviews."""
# Get profile, then search for similar code patterns
profile = self.memory.profile(user_id).profile
memories = self.memory.search(
user_id,
query=code[:500], # Use code snippet for semantic search
threshold=0.6
).results
static = [m.memory for m in profile.static]
dynamic = [m.memory for m in profile.dynamic]
return f"""
## Developer Profile
{chr(10).join(f"- {fact}" for fact in static) if static else "New developer, no profile yet."}
## Current Focus
{chr(10).join(f"- {ctx}" for ctx in dynamic) if dynamic else "No recent context."}
## Relevant Past Reviews
{chr(10).join(f"- {m.memory or m.chunk}" for m in memories[:3]) if memories else "No similar reviews found."}
"""
def review(self, user_id: str, code: str, language: Optional[str] = None) -> str:
"""Review code with personalized feedback."""
context = self.get_context(user_id, code)
prompt = ChatPromptTemplate.from_messages([
SystemMessage(content=f"""You are a code review assistant. Provide constructive feedback
tailored to the developer's experience level and preferences.
{context}
Guidelines:
- Reference past feedback when relevant patterns appear
- Adapt explanation depth to the developer's expertise
- Focus on issues that matter most to this developer"""),
HumanMessage(content=f"Review this {language or 'code'}:\n\n```\n{code}\n```")
])
chain = prompt | self.llm
response = chain.invoke({})
# Store the review for future context
self.memory.add(
user_id,
content=f"Code review feedback: {response.content[:500]}",
metadata={"type": "code_review", "language": language},
dreaming="instant"
)
return response.content
def learn_preference(self, user_id: str, preference: str):
"""Store a coding preference or style guideline."""
self.memory.add(
user_id,
content=f"Developer preference: {preference}",
metadata={"type": "preference"},
dreaming="instant"
)
# Usage
if __name__ == "__main__":
assistant = CodeReviewAssistant()
user_id = "dev_alice"
# Teach the assistant about preferences
assistant.learn_preference(user_id, "Prefers functional programming patterns")
assistant.learn_preference(user_id, "Values descriptive variable names over comments")
# Review some code
code = """
def calc(x, y):
r = []
for i in x:
if i in y:
r.append(i)
return r
"""
review = assistant.review(user_id, code, language="python")
print(review)
```
---
## Advanced patterns
### Conversation history with memory
Maintain multi-turn conversations while building long-term memory:
```python
from langchain_core.messages import BaseMessage
class ConversationalAgent:
def __init__(self, user_id: str):
self.user_id = user_id
self.llm = ChatOpenAI(model="gpt-4o")
self.memory = Supermemory()
self.messages: list[BaseMessage] = []
def _build_system_prompt(self, query: str) -> str:
"""Build system prompt with user context."""
profile = self.memory.profile(self.user_id).profile
memories = self.memory.search(self.user_id, query=query, threshold=0.5).results
return f"""You are a helpful assistant with memory of past conversations.
About this user:
{chr(10).join(m.memory for m in profile.static) if profile.static else 'No profile yet.'}
Current context:
{chr(10).join(m.memory for m in profile.dynamic) if profile.dynamic else 'No recent context.'}
Relevant memories:
{chr(10).join(m.memory or m.chunk for m in memories[:5]) if memories else 'None.'}
Use this context to provide personalized, contextual responses."""
def chat(self, message: str) -> str:
"""Process a message and return response."""
# Add user message to conversation
self.messages.append(HumanMessage(content=message))
# Build prompt with memory context
system = SystemMessage(content=self._build_system_prompt(message))
# Generate response
response = self.llm.invoke([system] + self.messages)
self.messages.append(response)
# Store interaction for long-term memory
self.memory.add(
self.user_id,
content=f"User: {message}\nAssistant: {response.content}",
dreaming="instant"
)
return response.content
def clear_session(self):
"""Clear conversation but keep long-term memory."""
self.messages = []
```
### Metadata filtering
Use metadata to organize and filter memories:
```python
# Store with metadata
memory.add(
"user_123",
content="Discussed React hooks and state management",
dreaming="instant",
metadata={
"topic": "react",
"type": "discussion",
"project": "frontend-redesign"
}
)
# Search with filters
results = memory.search(
"user_123",
query="state management",
filter={
"operator": "and",
"operands": [
{"field": "topic", "operator": "eq", "value": "react"},
{"field": "project", "operator": "eq", "value": "frontend-redesign"}
]
}
)
```
### Batch memory operations
Efficiently store multiple memories:
```python
# Store meeting notes as separate memories
notes = [
"Decided to use PostgreSQL for the new service",
"Timeline: MVP ready by end of Q2",
"Alice will lead the database migration"
]
for note in notes:
memory.add(
"team_standup",
content=note,
metadata={"date": "2024-01-15", "type": "decision"},
dreaming="instant"
)
```
---
## Next steps
<CardGroup cols={2}>
<Card title="User profiles" icon="/icons/hugeicons/user.svg" href="/recall/user-profiles">
Deep dive into automatic user profiling
</Card>
<Card title="Search API" icon="/icons/hugeicons/search-01.svg" href="/recall/search">
Advanced search patterns and filtering
</Card>
<Card title="OpenAI SDK" icon="/icons/hugeicons/robotic.svg" href="/integrations/openai">
Native OpenAI integration with memory tools
</Card>
<Card title="Vercel AI SDK" icon="/icons/hugeicons/triangle.svg" href="/integrations/ai-sdk">
Memory middleware for Next.js apps
</Card>
</CardGroup>