Durable LangGraph workflows with Oracle AI Database


Key Takeaways

  • Oracle AI Database can be used as a persistence layer for LangGraph using langchain-oracle libraries. This persistence layer powers agent workflows with retries, audit trails, and repeatability.
  • OracleSaver preserves (checkpoints) graph state at a point in time. This state may be resumed, inspected, or replayed using a the run’s uniquethread_id.
  • OracleStore persists long-term, cross-thread memory, including user preferences, facts, and shared knowledge.

A human-in-the-loop graph is easy to demonstrate when the entire workflow stays in memory. The more realistic challenge starts when the graph pauses for a reviewer, waits for a business decision, and later resumes with the same state intact.

The langgraph_persistence sample shows how to build that pattern with LangGraph and Oracle AI Database. It evaluates a travel request, uses OCI Generative AI to draft a concise reviewer brief, checkpoints the graph state with langgraph-oracledb, interrupts for approval, resumes the same thread_id with the reviewer’s decision, and stores the approved record separately with OracleStore.

This sample keeps the workflow intentionally small so the persistence pattern is easy to follow: graph state is durable, human approval happens outside the running process, and the final approved request is stored as application data.

Diagram showing a LangGraph application connected to a human review workflow and Oracle AI Database persistence. The application runs a StateGraph approval flow and runtime context. A draft summary pauses for human approval before resuming execution. OracleSaver stores resumable graph checkpoints and thread state, while OracleStore persists approved records and durable application data.
LangGraph persistence architecture using Oracle AI Database for checkpoints and durable application state.

Sample Description

This sample demonstrates a LangGraph travel approval workflow that persists graph state in Oracle AI Database using langgraph-oracledb.

The workflow evaluates a travel request, generates a reviewer brief with OCI Generative AI, and then pauses for human approval. While the graph is interrupted, LangGraph checkpoints the current state in Oracle AI Database. After a reviewer provides a decision, the workflow resumes using the same thread_id and continues from the saved state.

Diagram showing a policy-driven approval workflow. A travel request enters a policy evaluation stage and is routed either to a fast path or a human review path. Requests within policy are finalized automatically. Requests needing approval generate an LLM draft brief, pause with an interrupt payload, and resume after approval. OracleSaver stores paused workflow state, while OracleStore records approved outcomes.
LangGraph approval workflow with human review, checkpointing, and Oracle AI Database persistence.

When a request is approved, the sample also writes a separate approved record through OracleStore, including the original request, approval decision, policy reason, and generated brief.

The accompanying diagrams show how the Python sample, LangGraph, OracleSaver, OracleStore, Testcontainers, OCI Generative AI, and Oracle AI Database fit together.


Prerequisites

  • Python 3.13+
  • Poetry
  • Docker compatible environment to run Oracle AI Database Free
  • Local OCI configuration for OCI Generative AI on-demand chat

Install dependencies from the python-oracle/ directory:

poetry install

Set the OCI compartment before running the command-line sample:

export OCI_COMPARTMENT_ID=<your-compartment-ocid>

The sample assumes an OCI Generative AI on-demand model and defaults to the model alias cohere.command-latest. It builds the regional service endpoint from the region in your DEFAULT OCI config profile, so no dedicated AI cluster endpoint is required.


Run the Sample

Diagram showing a policy-driven approval workflow. A travel request enters a policy evaluation stage and is routed either to a fast path or a human review path. Requests within policy are finalized automatically. Requests needing approval generate an LLM draft brief, pause with an interrupt payload, and resume after approval. OracleSaver stores paused workflow state, while OracleStore records approved outcomes.
LangGraph approval workflow with automated routing, human review, and Oracle AI Database persistence.

From the python-oracle/ directory:

poetry run python src/python_oracle/langgraph_persistence/travel_approval_graph.py

The script starts Oracle AI Database Free with Testcontainers, creates the LangGraph checkpoint and store tables, runs the request, and prints the final outcome. For the default over-limit request, it also drafts an OCI-generated approval brief, pauses with interrupt() (which pauses graph execution), prints a checkpoint summary from OracleSaver, resumes with Command(resume=...), and reads the approved business record back from OracleStore.

To run the rejection branch:

poetry run python src/python_oracle/langgraph_persistence/travel_approval_graph.py --reject

LangGraph bits

  • thread_id identifies the LangGraph run, used for the checkpoint summary, and the resume command.
  • OracleSaver is the persistence checkpointer. It persists graph state so the human approval interrupt can survive outside the process.
  • OracleStore is the persistence store. The last graph node writes approved business records and the CLI reads the record back with store.get(...).
  • Runtime[ApprovalContext] carries the live ChatOCIGenAI model into the graph. The model is runtime context, not checkpointed graph state — it can be easily reconstructed on a new run.
  • OCI Generative AI drafts reviewer context only after policy says approval is required. Auto-approved requests skip the model call and go straight to finalization.

Building the graph with OracleStore and OracleSaver

The OracleStore and OracleSaver objects are easily constructed with a database connection string:

with (
    OracleSaver.from_conn_string(conn_string) as checkpointer,
    OracleStore.from_conn_string(conn_string) as store,
):
    checkpointer.setup()
    store.setup()

Then, the store and checkpointer can be used to build our graph:

def build_graph(checkpointer: OracleSaver, store: OracleStore):
    builder = StateGraph(ApprovalState, context_schema=ApprovalContext)
    builder.add_node("evaluate_policy", evaluate_policy)
    builder.add_node("draft_approval_brief", draft_approval_brief)
    builder.add_node("request_approval", request_approval)
    builder.add_node("finalize_request", finalize_request)
    builder.add_edge(START, "evaluate_policy")
    builder.add_conditional_edges(
        "evaluate_policy",
        route_after_policy,
        {"approval": "draft_approval_brief", "finalize": "finalize_request"},
    )
    builder.add_edge("draft_approval_brief", "request_approval")
    builder.add_edge("request_approval", "finalize_request")
    builder.add_edge("finalize_request", END)
    return builder.compile(
        checkpointer=checkpointer,
        store=store,
    )

FAQ

  1. Why use OracleSaver? OracleSaver is used as the LangGraph checkpointer. It persists graph state under a thread_id so the workflow can survive a pause and resume later.
  2. Why use OracleStore? OracleStore stores the final approved business record. This is separate from checkpointing because application records and graph execution state have different purposes.
  3. What is stored as the approved record? The approved record includes the travel request, approval decision, final status, policy reason, and generated approval brief.
  4. What’s the difference between OracleSaver and OracleStore? The Saver (Checkpointer) is for checkpoints of in-progress work, and the Store (Durable memory) is for workflow history.
  5. What data is checkpointed? Checkpointers like OracleSaver save a snapshot of the graph state at each step, organized by thread_id. Checkpoints enable human-in-the-loop workflows, time travel debugging, fault-tolerant execution, and conversational memory.
  6. Why does thread_id matter? The thread_id corresponds to a specific checkpoints in graph state. The state can be inspected, replayed, and more from a given thread_id .
  7. Why use Oracle AI Database persistence? Use persistence when you want to keep information beyond a single graph run. Persistence helps when you want to continue a conversation, resume after an interruption, recover from a failure, or remember information across interactions.

References