Checkpointer solves the problem of "memory within a single conversation". But if you need to share data across different conversations β such as user preferences, learning progress β you need to use Store.
\\\\n\\\\n\\\\n\\\\n
Checkpointer vs Store
\\\\n\\\\n| Dimension | \\\\nCheckpointer | \\\\nStore | \\\\n
|---|---|---|
| Scope | \\\\nSingle conversation thread (thread_id) | \\\\nAcross all conversation threads | \\\\n
| Data Type | \\\\nAgent state snapshot (automatically managed) | \\\\nArbitrary key-value data (manually managed) | \\\\n
| Typical Use | \\\\nMulti-turn conversation memory | \\\\nUser preferences, knowledge base, configuration | \\\\n
| Data Organization | \\\\nthread_id β checkpoint | \\\\n(namespace, key) β value | \\\\n
\\\\n\\\\n
Basic Operations of Store
\\\\n\\\\nStore uses a hierarchical structure of namespace + key to organize data:
\\\\n\\\\nExample
\\\\n\\\\nfrom langgraph.store.memory import InMemoryStore\\\\n\\\\nstore = InMemoryStore()\\\\n\\\\n# Write data: put(namespace, key, value)\\\\n# namespace is a tuple, key is a string, value is a dictionary\\\\nstore.put(\\\\n ("users", "user_001"), # namespace\\\\n "preferences", # key\\\\n { # value\\\\n "theme": "dark",\\\\n "language": "zh-CN",\\\\n "level": "Getting Started",\\\\n }\\\\n)\\\\n\\\\nstore.put(\\\\n ("users", "user_001"),\\\\n "progress",\\\\n {\\\\n "completed_courses": ["HTML Basics, "Python Basics],\\\\n "total_hours": 35,\\\\n }\\\\n)\\\\n\\\\n# Read data: get(namespace, key)\\\\nprefs = store.get(("users", "user_001"), "preferences")\\\\nprint(f"Preferences: {prefs.value}")\\\\n\\\\nprogress = store.get(("users", "user_001"), "progress")\\\\nprint(f"Learning Progress: {progress.value}")\\\\n\\\\n# Search data: search(namespace)\\\\nall_user_data = store.search(("users", "user_001"))\\\\nprint(f"n Userall data ({len(all_user_data)} items):")\\\\nfor item in all_user_data:\\\\n print(f" {item.key}: {item.value}")\\\\n\\\\n# Delete data: delete(namespace, key)\\\\nstore.delete(("users", "user_001"), "preferences")\\\\ndeleted = store.get(("users", "user_001"), "preferences")\\\\nprint(f"n After deletion: {deleted}") # None\\\\n\\\\nRunning result:
\\\\n\\\\nPreferences: {'theme': 'dark', 'language': 'zh-CN', 'level': 'Getting Started'}\\\\nLearning Progress: {'completed_courses': ['HTML Basics', 'Python Basics'], 'total_hours': 35}\\\\n\\\\nUserall data (2 items):\\\\n preferences: {'theme': 'dark', 'language': 'zh-CN', 'level': 'Getting Started'}\\\\n progress: {'completed_courses': ['HTML Basics', 'Python Basics'], 'total_hours': 35}\\\\n\\\\nAfter deletion: None\\\\n\\\\n\\\\n\\\\n
Using Store in Agent
\\\\n\\\\nPass Store to create_agent(), and all tools in the Agent can access it through InjectedStore:
\\\\n\\\\nExample
\\\\n\\\\nfrom dotenv import load_dotenv\\\\nload_dotenv()\\\\n\\\\nfrom typing import Annotated\\\\nfrom langgraph.store.base import BaseStore\\\\nfrom langgraph.store.memory import InMemoryStore\\\\nfrom langchain.tools import tool, InjectedStore\\\\nfrom langchain.agents import create_agent\\\\nfrom langchain.chat_models import init_chat_model\\\\nfrom langchain.messages import HumanMessage\\\\n\\\\n# Create Store and pre-populate data\\\\nstore = InMemoryStore()\\\\n\\\\nstore.put(("tutorial", "courses"), "catalog", {\\\\n "Python3 BasicsTutorial": {"price": "Free", "hours": 20, "level": "Getting Started"},\\\\n "Python Data Analysis": {"price": "Member", "hours": 30, "level": "Advanced"},\\\\n "Java Object-Oriented": {"price": "Free", "hours": 25, "level": "Advanced"},\\\\n})\\\\n\\\\nstore.put(("tutorial", "users"), "user_vip_001", {\\\\n "name": "Xiaoming",\\\\n "membership": "VIP",\\\\n "joined": "2024-01-15",\\\\n})\\\\n\\\\n@tool\\\\ndef query_course_info(\\\\n course_name: str,\\\\n store: Annotated[BaseStore, InjectedStore()],\\\\n) -> str:\\\\n """Query detailed information about courses in TUTORIAL.\\\\n Args:\\\\n course_name: Course name\\\\n """\\\\n item = store.get(("tutorial", "courses"), "catalog")\\\\n catalog = item.value if item else {}\\\\n if course_name in catalog:\\\\n info = catalog\\\\n return (\\\\n f"γ{course_name}γ- Price:{info['price']}οΌ"\\\\n f"Duration:{info['hours']}hours, difficulty:{info['level']}"\\\\n )\\\\n return f"Course not found: "{course_name}γ"\\\\n\\\\n@tool\\\\ndef get_user_membership(\\\\n user_id: str,\\\\n store: Annotated[BaseStore, InjectedStore()],\\\\n) -> str:\\\\n """Query user membership information.\\\\n Args:\\\\n user_id: User ID\\\\n """\\\\n item = store.get(("tutorial", "users"), user_id)\\\\n if item is None:\\\\n return f"User not found {user_id}"\\\\n user = item.value\\\\n return (\\\\n f"User {user['name']}οΌ{user['membership']} MemberοΌ"\\\\n f"Registration Date {user['joined']}"\\\\n )\\\\n\\\\nmodel = init_chat_model("deepseek:deepseek-v4-flash", temperature=0)\\\\n\\\\nagent = create_agent(\\\\n model=model,\\\\n tools=[query_course_info, get_user_membership],\\\\n store=store,\\\\n system_prompt="You are the course advisor for TUTORIAL.",\\\\n)\\\\n\\\\n# Query course information (data from Store)\\\\nresult = agent.invoke({\\\\n "messages": [HumanMessage(content="Python3 BasicsHow much is the tutorial?")]\\\\n})\\\\nprint(f"Query Course: {result['messages'].content}")\\\\n\\\\n# Query user information (data from Store)\\\\nresult = agent.invoke({\\\\n "messages": [HumanMessage(content="Help me query the information for User user_vip_001")]\\\\n})\\\\nprint(f"Query User: {result['messages'].content}")\\\\n\\\\nRunning result:
\\\\n\\\\nQuery Course: γPython3 BasicsTutorialγIt is free, with a learning duration of about 20 hours, and a Getting Started difficulty level.\\\\nQuery User: UserXiaoMingis VIP MemberοΌRegistration Date for 2024Year1Month15Dayγ\\\\n\\\\n\\\\n\\\\n
Store Persistence
\\\\n\\\\nInMemoryStore data is lost after program restart. For production environments, you can use persistent solutions like PostgresStore:
\\\\n\\\\nExample
\\\\n\\\\n# Development stage\\\\nfrom langgraph.store.memory import InMemoryStore\\\\nstore = InMemoryStore()\\\\n\\\\n# Production environment (requires PostgreSQL)\\\\n# from langgraph.store.postgres import PostgresStore\\\\n# store = PostgresStore.from_conn_string("postgresql://...")\\\\n\\\\n\\\\n\\\\n
Store Usage Recommendations
\\\\n\\\\n| Scenario | \\\\nnamespace Example | \\\\nkey Example | \\\\nDescription | \\\\n
|---|---|---|---|
| User Preferences | \\\\n("users", user_id) | \\\\npreferences | \\\\nTheme, language, notification settings | \\\\n
| Learning Progress | \\\\n("users", user_id) | \\\\nprogress | \\\\nCompleted courses, learning hours | \\\\n
| Knowledge Base | \\\\n("kb", collection) | \\\\ndoc_id | \\\\nDocuments, FAQ, product information | \\\\n
| Session Summary | \\\\n("sessions", thread_id) | \\\\nsummary | \\\\nSummary of long conversations, for scenarios beyond Checkpointer | \\\\n
\\\\nCheckpointer is responsible for "where the conversation is at", while Store is responsible for "who the user is, what they know, what they like". Only by using both together can you build intelligent Agents with persistent memory.
\\\\n
YouTip