diff options
Diffstat (limited to 'apps')
| -rw-r--r-- | apps/docs/docs.json | 50 | ||||
| -rw-r--r-- | apps/docs/integrations/langchain.mdx | 388 |
2 files changed, 398 insertions, 40 deletions
diff --git a/apps/docs/docs.json b/apps/docs/docs.json index a97f9448..8610d948 100644 --- a/apps/docs/docs.json +++ b/apps/docs/docs.json @@ -3,11 +3,7 @@ "api": { "examples": { "defaults": "required", - "languages": [ - "javascript", - "python", - "curl" - ] + "languages": ["javascript", "python", "curl"] }, "openapi": "https://api.supermemory.ai/v3/openapi" }, @@ -17,12 +13,7 @@ "primary": "#1E3A8A" }, "contextual": { - "options": [ - "copy", - "view", - "chatgpt", - "claude" - ] + "options": ["copy", "view", "chatgpt", "claude"] }, "favicon": "/favicon.png", "fonts": { @@ -79,11 +70,7 @@ { "group": "Getting Started", "icon": "rocket", - "pages": [ - "intro", - "quickstart", - "vibe-coding" - ] + "pages": ["intro", "quickstart", "vibe-coding"] }, { "group": "Concepts", @@ -109,10 +96,7 @@ { "group": "Manage Content", "icon": "folder-cog", - "pages": [ - "document-operations", - "memory-operations" - ] + "pages": ["document-operations", "memory-operations"] }, "overview/use-cases" ] @@ -146,10 +130,7 @@ { "group": "From another provider", "icon": "truck", - "pages": [ - "migration/from-mem0", - "migration/from-zep" - ] + "pages": ["migration/from-mem0", "migration/from-zep"] } ] } @@ -158,10 +139,7 @@ { "anchor": "Supermemory MCP", "icon": "terminal", - "pages": [ - "supermemory-mcp/mcp", - "supermemory-mcp/setup" - ] + "pages": ["supermemory-mcp/mcp", "supermemory-mcp/setup"] } ], "tab": "Developer Platform" @@ -175,6 +153,7 @@ "integrations/supermemory-sdk", "integrations/ai-sdk", "integrations/openai", + "integrations/langchain", "integrations/memory-graph", "integrations/claude-memory", "integrations/pipecat", @@ -221,10 +200,7 @@ "memorybench/github", { "group": "Getting Started", - "pages": [ - "memorybench/installation", - "memorybench/quickstart" - ] + "pages": ["memorybench/installation", "memorybench/quickstart"] }, { "group": "Development", @@ -237,10 +213,7 @@ }, { "group": "Reference", - "pages": [ - "memorybench/cli", - "memorybench/integrations" - ] + "pages": ["memorybench/cli", "memorybench/integrations"] } ] } @@ -276,10 +249,7 @@ "anchors": [ { "anchor": "Changelog", - "pages": [ - "changelog/overview", - "changelog/developer-platform" - ] + "pages": ["changelog/overview", "changelog/developer-platform"] } ], "tab": "Changelog" diff --git a/apps/docs/integrations/langchain.mdx b/apps/docs/integrations/langchain.mdx new file mode 100644 index 00000000..6c9eee9a --- /dev/null +++ b/apps/docs/integrations/langchain.mdx @@ -0,0 +1,388 @@ +--- +title: "LangChain" +sidebarTitle: "LangChain" +description: "Build AI agents with persistent memory using LangChain and Supermemory" +icon: "link" +--- + +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 for context + profile_result = memory.profile(container_tag=user_id, q=message) + + # 2. Build context from profile + static_facts = profile_result.profile.static or [] + dynamic_context = profile_result.profile.dynamic or [] + search_results = profile_result.search_results.results if profile_result.search_results else [] + + 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( + content=f"User: {message}\nAssistant: {response.content}", + container_tag=user_id + ) + + 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 profile with optional search +result = memory.profile( + container_tag="user_123", + q="optional search query" # Also returns relevant memories +) + +print(result.profile.static) # ["User is a Python developer", "Prefers dark mode"] +print(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( + content="User asked about async Python patterns. Explained asyncio basics.", + container_tag="user_123", + metadata={"topic": "python", "type": "conversation"} +) + +# Store a document +memory.add( + content="https://docs.python.org/3/library/asyncio.html", + container_tag="user_123" +) +``` + +### Memory Search + +Search returns both extracted memories and document chunks: + +```python +results = memory.search.memories( + q="async programming", + container_tag="user_123", + 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 with search for similar code patterns + result = self.memory.profile( + container_tag=user_id, + q=code[:500], # Use code snippet for semantic search + threshold=0.6 + ) + + static = result.profile.static or [] + dynamic = result.profile.dynamic or [] + memories = result.search_results.results if result.search_results else [] + + 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}" 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( + content=f"Code review feedback: {response.content[:500]}", + container_tag=user_id, + metadata={"type": "code_review", "language": language} + ) + + return response.content + + def learn_preference(self, user_id: str, preference: str): + """Store a coding preference or style guideline.""" + self.memory.add( + content=f"Developer preference: {preference}", + container_tag=user_id, + metadata={"type": "preference"} + ) + + +# 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.""" + result = self.memory.profile( + container_tag=self.user_id, + q=query, + threshold=0.5 + ) + + profile = result.profile + memories = result.search_results.results if result.search_results else [] + + return f"""You are a helpful assistant with memory of past conversations. + +About this user: +{chr(10).join(profile.static) if profile.static else 'No profile yet.'} + +Current context: +{chr(10).join(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( + content=f"User: {message}\nAssistant: {response.content}", + container_tag=self.user_id + ) + + 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( + content="Discussed React hooks and state management", + container_tag="user_123", + metadata={ + "topic": "react", + "type": "discussion", + "project": "frontend-redesign" + } +) + +# Search with filters +results = memory.search.memories( + q="state management", + container_tag="user_123", + filters={ + "AND": [ + {"key": "topic", "value": "react"}, + {"key": "project", "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( + content=note, + container_tag="team_standup", + metadata={"date": "2024-01-15", "type": "decision"} + ) +``` + +--- + +## Next Steps + +<CardGroup cols={2}> + <Card title="User Profiles" icon="user" href="/user-profiles"> + Deep dive into automatic user profiling + </Card> + <Card title="Search API" icon="search" href="/search"> + Advanced search patterns and filtering + </Card> + <Card title="OpenAI SDK" icon="robot" href="/integrations/openai"> + Native OpenAI integration with memory tools + </Card> + <Card title="Vercel AI SDK" icon="triangle" href="/integrations/ai-sdk"> + Memory middleware for Next.js apps + </Card> +</CardGroup> |