Hello @AdamSobieski welcome to the langchain community.
I would suggest using a layered approach: not one of the five options alone:
- Session / dialogue context uses Graph state + checkpointer as its mechanism, and is used for messages, current turn, and working hypotheses within a thread.
- Persistent user model uses Store (long-term memory) as its mechanism, and is used for profiles, preferences, and facts that survive across threads.
- Runtime dependencies uses Runtime / context_schema as its mechanism, and is used for user_id, DB clients, and user-model service handles.
- Avoid global singletons, as they break concurrency, testing, and deployment.
How to evaluate the five approaches
-
Global object: Avoid. Not thread-safe, hard to test, doesn’t work with parallel invocations or LangGraph Server.
-
State: Good for simple, serializable, session-scoped data (e.g. current explanation level). Not for complex or large user models: state is checkpointed every step, must be JSON-serializable, and is thread-scoped unless you also use a Store.
-
Configuration /
context: Good for injecting identity and services (user_id, aUserModelService, DB connection), not for storing the evolving model itself. Passuser_idviacontext; read/write the model viaruntime.storeor an injected service. -
Memory (Store + checkpointer): This is the primary best practice for dynamic user modeling. The Store holds cross-thread, namespaced data (e.g.
("memories", user_id)). Nodes and tools access it viaruntime.store.search()/runtime.store.put(). -
New dedicated parameter: You don’t need one;
Runtimealready exposescontext,store, and execution metadata to nodes and tools.
For complex user models (graphs, FSMs, cognitive architectures)
- Keep the canonical model outside graph state (external DB, graph DB, or Store as serialized JSON/docs).
- Put only summaries or pointers in state when the graph needs them for routing.
- Inject a service via
context_schemafor heavy logic (e.g.UserModelService.update()/.query()). - For LLM-maintained profiles, consider a structured profile document updated incrementally: see memory profiles.
Doc Reference:
- LangGraph persistence & Store
- Add memory (Python)
- Runtime / context injection
- Deep Agents user-scoped memory
I hope this helps you out in understanding Langgraph and how you could use it in potentially modelling Complex User models using the framework.