LangGraph vs Google ADK 2.0 vs LlamaIndex: Deep Dive into State Management

This article compares LangGraph, Google ADK 2.0, and LlamaIndex on how they model, scope, update, persist, interrupt, and concurrently control state in agent workflows, providing concrete code snippets, tables, and practical guidance for selecting the right framework.

AI Engineer Programming
AI Engineer Programming
AI Engineer Programming
LangGraph vs Google ADK 2.0 vs LlamaIndex: Deep Dive into State Management

1. State Model Comparison

LangGraph uses a graph‑state machine where all nodes share a global TypedDict / Pydantic object. Nodes return a delta that the framework merges via a StateGraph + Reducer (Channel). This design fits long‑running, auditable workflows that may be paused and resumed.

Google ADK 2.0 treats state as a session draft: a key‑value store that is incrementally updated by Event objects through SessionService. The core abstractions are session.state, Event, and SessionService, targeting conversational agents and multi‑agent collaboration within the Google ecosystem.

LlamaIndex adopts a lightweight, transient approach. The Context (holding a Context + Workflow) must be passed explicitly to each step; there is no built‑in persistent user‑ or app‑level state, so developers implement their own serialization.

LangGraph – Graph state machine – StateGraph + Reducer – Ideal for long‑cycle, auditable workflows.

Google ADK 2.0 – Session draft – session.state + Event + SessionService – Suited for dialogic agents and Google Cloud integration.

LlamaIndex – Temporary carrier – Context + Event + Workflow – Best for data‑intensive RAG and lightweight multi‑step orchestration.

2. Scope of Data (Ownership)

Google ADK 2.0 prefixes keys to separate scopes: no prefix: current session (e.g., current_intent, booking_step) user:: cross‑session user level (persisted in a database or VertexAI) app:: application‑wide level (also persisted externally) temp:: invocation‑only, discarded after the call ends

LlamaIndex only provides a temp scope by default; any longer‑lived scope must be built manually.

3. State Update Mechanisms

LangGraph returns a delta from each node; the framework merges deltas at the end of a super‑step and creates a checkpoint.

def my_node(state: AgentState) -> dict:
    return {"messages": [new_message]}  # framework merges via reducer

Google ADK forbids direct mutation of session.state. Updates must be expressed as EventActions.state_delta or via CallbackContext.state, which the runner captures and writes as a state_delta.

# Incorrect: direct mutation
session.state['key'] = 'value'

# Correct: through Context
context.state['key'] = 'value'

# Correct: via EventActions
system_event = Event(actions=EventActions(state_delta={"key": "value"}))
await session_service.append_event(session, system_event)

LlamaIndex uses ctx.store for explicit reads/writes. The older ctx.set/get API is deprecated.

@step
async def my_step(self, ctx: Context, ev: MyEvent) -> NextEvent:
    await ctx.store.set("my_key", "my_value")
    value = await ctx.store.get("my_key")
    return NextEvent(data=value)

When multiple parallel steps modify the same key, LlamaIndex requires the atomic async with ctx.store.edit_state() block.

4. Persistence and Crash Recovery

LangGraph provides automatic checkpoints at each super‑step. A PostgresSaver (or Redis via community integration) stores checkpoint tables; MemorySaver / InMemorySaver are for local testing only.

from langgraph.checkpoint.postgres import PostgresSaver
checkpointer = PostgresSaver.from_conn_string(DB_URI)
checkpointer.setup()
graph = builder.compile(checkpointer=checkpointer)

Google ADK uses append_event to persist state_delta and last_update_time. Developers choose an in‑memory InMemorySessionService for development or a DatabaseSessionService for production.

session_service = InMemorySessionService()  # dev
# or
session_service = DatabaseSessionService(db_url=...)

LlamaIndex requires manual serialization. After a run, the context can be saved with to_dict() and later restored with Context.from_dict().

handler = w.run()
await handler
db.save("my-run", json.dumps(handler.ctx.to_dict()))
ctx = Context.from_dict(w, json.loads(db.load("my-run")))
result = await w.run(ctx=ctx)

5. Interrupts and Human‑in‑the‑Loop (HITL)

LangGraph supports compile‑time and runtime interrupts via interrupt_before, interrupt_after, and the interrupt() command. The interrupted node is re‑executed on resume, so side‑effects must be idempotent.

graph = builder.compile(
    checkpointer=checkpointer,
    interrupt_before=["review_node"],
    interrupt_after=["tool_node"]
)

Google ADK 2.0 offers collaboration modes ( chat, task, single_turn) and a built‑in confirmation mechanism ( require_confirmation) that can be extended with a SecurityPlugin and custom policy engine.

class CustomPolicyEngine implements BasePolicyEngine {
    async evaluate(_context) {
        return {outcome: PolicyOutcome.CONFIRM, reason: "Needs confirmation for tool call"};
    }
}
const runner = new InMemoryRunner({
    agent: rootAgent,
    plugins: [new SecurityPlugin({policyEngine: new CustomPolicyEngine()})]
});

LlamaIndex provides a native HITL workflow via HumanResponseEvent and InputRequiredEvent. The context snapshot must be persisted manually before awaiting human input.

6. Concurrency Control

LangGraph isolates steps by super‑step checkpoints; concurrent writes are merged deterministically by the reducer, but the order cannot be forced. If a reducer is not commutative, the state design must avoid ordering assumptions.

Google ADK serializes state updates through the event queue; parallel single_turn agents run in isolated branches and are merged by the parent agent after all branches finish.

LlamaIndex relies on a store lock. Parallel steps must use async with ctx.store.edit_state() to guarantee atomic updates; there is no built‑in reducer.

7. Selection Guidance

When you need checkpoint‑based time travel, strong auditability, or long‑running workflows, LangGraph (often combined with Temporal) is the most complete choice.

For conversational agents that require tight Google Cloud integration, multi‑agent collaboration, and built‑in confirmation policies, Google ADK 2.0 is preferable.

If the primary workload is data‑intensive Retrieval‑Augmented Generation (RAG) or you want a lightweight API for rapid prototyping, LlamaIndex shines.

In practice, production systems rarely lock into a single framework; they compose layers—e.g., LangGraph for orchestration, ADK for session handling, and LlamaIndex for RAG—according to the specific requirements.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

state managementworkflowagent frameworksLangGraphLlamaIndexGoogle ADK
AI Engineer Programming
Written by

AI Engineer Programming

In the AI era, defining problems is often more important than solving them; here we explore AI's contradictions, boundaries, and possibilities.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.