Best Practices for Dynamic User Modeling with LangGraph

Hello @AdamSobieski welcome to the langchain community.

I would suggest using a layered approach: not one of the five options alone:

  1. Session / dialogue context uses Graph state + checkpointer as its mechanism, and is used for messages, current turn, and working hypotheses within a thread.
  2. Persistent user model uses Store (long-term memory) as its mechanism, and is used for profiles, preferences, and facts that survive across threads.
  3. Runtime dependencies uses Runtime / context_schema as its mechanism, and is used for user_id, DB clients, and user-model service handles.
  4. Avoid global singletons, as they break concurrency, testing, and deployment.

How to evaluate the five approaches

  1. Global object: Avoid. Not thread-safe, hard to test, doesn’t work with parallel invocations or LangGraph Server.

  2. 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.

  3. Configuration / context: Good for injecting identity and services (user_id, a UserModelService, DB connection), not for storing the evolving model itself. Pass user_id via context; read/write the model via runtime.store or an injected service.

  4. 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 via runtime.store.search() / runtime.store.put().

  5. New dedicated parameter: You don’t need one; Runtime already exposes context, 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_schema for heavy logic (e.g. UserModelService.update() / .query()).
  • For LLM-maintained profiles, consider a structured profile document updated incrementally: see memory profiles.

Doc Reference:

I hope this helps you out in understanding Langgraph and how you could use it in potentially modelling Complex User models using the framework.