PRACTICAL AI & AUTOMATION
LangGraph for Practical Workflows: State, Approval and Recovery
Build a runnable LangGraph workflow in Python with explicit state, human approval, conditional routing and verification, then plan durable recovery.

Build a runnable LangGraph workflow in Python with explicit state, human approval, conditional routing and verification, then plan durable recovery.
Step 1: Decide whether your task needs a graph
A single script is often enough for a linear task. LangGraph becomes useful when work has explicit state, branches, pauses and resumable steps. Think of a file report that must be prepared, reviewed, written and checked: the route matters as much as the model’s answer.
We will build that flow without an LLM first. This makes the control behavior easy to inspect and costs no model API calls. Later you can replace the preparation node with an Ollama or Codex-backed adapter while preserving the same review and verification boundaries.
The Graph API overview explains state, nodes and edges. A node performs one step; an edge chooses what follows; state contains the information passed between them.
Step 2: Create an isolated Python environment
On Ubuntu install python3-venv if needed, create a fresh lab directory and activate a virtual environment. Install LangGraph there and check its installed version. Save the resulting dependencies when you have a working example so another machine can reproduce the same package set.
The official quickstart shows the core graph construction. This article’s file-report example is deliberately small and does not require LangSmith or a model-provider key.
Open the complete copyable example — example-01.txt
# Open full code above.Step 3: Define the state and approval boundary
Our state contains the input note, proposed report, approval decision and verification flag. The flow is START → prepare → approve → write → verify → END. Rejection goes from approve directly to END and never reaches the writer.
The approval node calls interrupt, which pauses the graph. Resume it with Command(resume=...) using the same thread_id. Keep file writes after the approval node: an interrupted node can run again when resumed. See interrupts and resuming for these semantics.
The report output is a fixed lab path. It replaces an earlier lab report when approved. Run the example in its dedicated directory, rather than placing an existing important report at that path.
Step 4: Run a complete review-and-write flow
Save this code as flow.py. Run python flow.py and first answer n. Run it again and answer y. The first run stops without writing; the second writes output/report.txt and verifies its exact contents.
The in-memory checkpointer supports this pause and resume within one running process. It does not survive process exit. This is a complete local teaching example, not a production persistence configuration.
Open the complete copyable example — flow.py
# Open full code above.Step 5: Verify both branches and add a model carefully
Test rejection in a fresh directory and confirm no output file appears. Test approval and compare the file with the displayed proposal. Test an empty input note and expect failure before approval. If a previous report exists, rejection should leave it unchanged; checking only for file existence would be the wrong test.
When adding an LLM, make prepare return a proposed report in the same state field. Validate its type, size and allowed content before approval. Treat retrieved documents as data and leave the writer deterministic. A generated claim that a write succeeded cannot replace the verify node’s file read.
For the KVM project, the graph can organize observe → propose one action → approve → operate → observe again. That requires your own tested bridge adapter. LangGraph does not supply a GL-RM10 driver or make coordinates reliable. Limit the action count and route unexpected screens to a stop state.
Step 6: Add durable recovery and bounded retries
For a service, replace InMemorySaver with a supported durable checkpointer and use a unique thread ID per job. Protect stored state and define retention. State checkpoints preserve workflow progress; they do not guarantee that external side effects happened exactly once. See the persistence guide.
Retry transient reads with a small attempt limit and delay. Before retrying a write or remote action, check whether the prior attempt already happened and use an idempotency key where possible. A recursive loop without a stop condition can repeat clicks, duplicate messages or overwrite files.
Keep a simple run record: job ID, input source, approved proposal, executed step, verification and error. Prefer inspecting those facts over trusting a fluent final summary. The right starting flow is one you can explain, reject and recover—not the largest graph you can draw.
Japanese practice: the marked verb is ‘approve’. Read the sentence alongside the approval node and notice how を marks the action being approved.
Continue the series
LangGraphで実用フロー:状態、承認、回復
手順1:グラフが必要か判断する
直線的な作業にはスクリプトで十分な場合があります。LangGraphは状態、分岐、一時停止、再開が必要な処理に役立ちます。レポートの準備、確認、保存、検証では、回答だけでなく経路が重要です。
まずLLMなしで作り、API費用をかけず制御を確認します。後で準備ノードをOllamaやCodexのアダプターへ置き換え、確認と検証の境界を維持できます。
Graph API概要では、状態、ノード、エッジを説明しています。ノードは処理、エッジは次の経路、状態は共有する情報です。
手順2:専用Python環境を作る
必要ならpython3-venvを入れ、新しいラボで仮想環境を作ります。LangGraphを導入して版を確認し、動作後に依存関係を保存します。
基本構成は公式クイックスタートを参照します。この例はLangSmithやモデル用APIキーを必要としません。
コピー可能な完全なコードを開く — example-01.txt
# Open full code above.手順3:状態と承認境界を決める
状態には入力メモ、提案レポート、承認、検証フラグを入れます。経路はSTART → prepare → approve → write → verify → ENDです。拒否は保存ノードへ行かずENDへ進みます。
interruptで停止し、同じthread_idのCommand(resume=...)で再開します。停止したノードは再開時に再実行される場合があるため、保存は承認後に置きます。中断と再開の仕様を確認してください。
出力先は固定のラボ用パスで、承認すると以前のレポートを置き換えます。大切なファイルがない専用フォルダーで試します。
手順4:確認と保存のフローを実行する
flow.pyとして保存し、python flow.pyを実行します。最初はn、次の実行ではyと答えます。拒否では保存せず、承認ではoutput/report.txtへ保存して内容を照合します。
メモリー内チェックポイントは同一プロセスでの停止と再開に使えます。終了後は残りません。これはローカル学習用の実装です。
# Open full code above.手順5:分岐を検証してモデルを追加する
新しいフォルダーで拒否時に出力がないこと、承認時に提案と一致すること、空メモが承認前に失敗することを確認します。既存レポートがある場合、拒否は変更しません。存在だけを検査するのは不十分です。
LLMを加えるならprepareから同じ状態フィールドへ提案を返し、型、長さ、内容を検査します。資料はデータとして扱い、保存は決定的な処理にします。モデルの成功宣言で検証ノードの読み取りを置き換えません。
KVMでは観察 → 1操作提案 → 承認 → 操作 → 再観察を構成できます。独自の検証済みブリッジが必要です。LangGraphはGL-RM10ドライバーを提供せず、座標の信頼性も保証しません。操作数を制限し、予期しない画面では停止します。
手順6:永続的な回復と上限付き再試行を加える
サービス化ではInMemorySaverを対応する永続ストアへ置き換え、作業ごとに固有thread IDを使います。状態を保護し保持期間を決めます。チェックポイントだけで外部操作の一度限り実行は保証できません。永続化ガイドを参照します。
一時的な読み取り失敗は回数と待ち時間を制限して再試行します。書き込みや操作の再試行前に、前回が実行済みか確認し、可能なら冪等性キーを使います。停止条件のないループはクリックや送信を重複させます。
作業ID、入力出典、承認提案、実行、検証、エラーを記録します。流暢な最終要約より事実を確認します。説明、拒否、回復ができる小さなフローから始めましょう。
利用者が操作を承認します。をは承認される操作を示します。
技術資料の確認日:2026年10月9日。コマンドとAPIは更新されることがあります。実行時に公式資料と利用中のバージョンを確認してください。
