惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

aimingoo的专栏
aimingoo的专栏
Y
Y Combinator Blog
云风的 BLOG
云风的 BLOG
Microsoft Azure Blog
Microsoft Azure Blog
腾讯CDC
T
The Blog of Author Tim Ferriss
P
Proofpoint News Feed
Hugging Face - Blog
Hugging Face - Blog
博客园_首页
小众软件
小众软件
美团技术团队
Martin Fowler
Martin Fowler
爱范儿
爱范儿
有赞技术团队
有赞技术团队
博客园 - 【当耐特】
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Microsoft Security Blog
Microsoft Security Blog
宝玉的分享
宝玉的分享
J
Java Code Geeks
B
Blog
V
V2EX
Stack Overflow Blog
Stack Overflow Blog
B
Blog RSS Feed
博客园 - Franky

LangChain Forum - Topics tagged python-help

Llama-server process has terminated: invalid argument --load-mode with Ollama client 0.32.6 and langchain-ollama 1.1.0 Langchain Certified Agent Engineer Exam - Exam link not received and no response Null-drift: A bare-metal O(1) Memory Store for continuous LangGraph agents Clarification needed: Assistant config vs context and graph initialization Proposal: a small local helper for readable run traces via PR Proxy Authentication Required 407 What is the right way to dynamically create and run a graph? Re-Implement claude code's dynamic workflow using langchian & deepagents How to define a correct state for multi-agent system Response Format Groq Model Pydantic I hope to get some recommendations for practical skills Interrupt does not work correctly in LangGraph The Qwen3.6b model in fireworks through initchatmodel reporting hugely inflated tokens For parallel execution in Node, should i use the functional API? Potential Enhancement: Django-Managed PostgresSaver Pre-interrupt() code re-runs on resume — anti-pattern, or is there a sanctioned way to detect resume? Interrupt parallel branch execution Best practices for self-hosting LangGraph Server OSS without LangGraph keys Dynamically Enabling/Disabling Graphs in a LangGraph Server at Runtime LangGraph thread copy can take 12+ minutes: recommended production pattern? Will DeltaChannel be the default for AgentState.messages, or expected to stay opt-in? Proposal: additional docs for implementing custom DB checkpointers or a guide on generic base checkpointer Prompt_cache_retention: '24h' supported in langchain agents and where to provide it, inside invoke or while creating client? Could RAG pipelines realistically cause deployment timeouts, is Render suitable for first-time RAG deployments? How do I use langchain_postgres' init_vectorstore_table correctly? Proposal: Graph-wide default error handler for StateGraph (fallback for nodes without error_handler) Support timedelta for CachePolicy.ttl, consistent with TimeoutPolicy Anyone confirms this issue that deepagent ui streaming is disturb by update in deepagent or bug issue Best Stack for Building AI Applications Seeking help regarding the connection between Websocket and tool calls
Parallel Nodes: how to manage failures or exceptions
2026-03-20 · via LangChain Forum - Topics tagged python-help

hi @carmine-sacco

LangGraph actually has built-in machinery for handling failures in parallel nodes, plus several strategies you can layer on top.

1. LangGraph already cancels sibling nodes on failure (default behavior)

When nodes run in parallel (same superstep), the runner uses concurent.features.wait() (sync) or asyncio.wait() (async) with return_when=FIRST_COMPLETED.
After each task completes, it calls an internal function _should_stop_others() that checks if any completed task raised a non-interrupt exception. If so, it breaks out of the execution loop immediately.

Then _panic_or_proceed() kicks in:

  • it iterates over all futures
  • if it finds an exception, it cancels all still-inflight tasks
  • it re-raises the first exception

Here’s the relevant logic from the LangGraph source code

Therefore, is a node A and node B run in parallel and a node A throws an exception, LangGrpah will cancel node B and re-raise node A’s exception.

important nuance: GraphInterrupt (used for human-in-the-loop) is not treated as a failure. Only real exceptions trigger cancellation. Source: _runner.py

2. RetryPolicy to make nodes resilient before failing

Before a node failure propagates and cancels siblings, you can add retry policies to give transient errors a chance to recover. This is configured per-node via add_node().

from langgraph.graph import StateGraph
from langgraph.types import RetryPolicy

builder = StateGraph(MyState)

# Default retry: 3 attempts, exponential backoff, jitter
builder.add_node(my_flaky_node, retry_policy=RetryPolicy())

# Custom retry: 5 attempts, only on specific exceptions
builder.add_node(
    my_api_node,
    retry_policy=RetryPolicy(
        max_attempts=5,
        initial_interval=1.0,
        backoff_factor=2.0,
        max_interval=30.0,
        jitter=True,
        retry_on=[ConnectionError, TimeoutError],
    ),
)

RetryPolicy fields:

Parameter Default Description
initial_interval 0.5 Seconds before first retry
backoff_factor 2.0 Multiplier for each subsequent retry
max_interval 128.0 Maximum seconds between retries
max_attempts 3 Total attempts (including the first)
jitter True Add random jitter to avoid thundering herd
retry_on default_retry_on Exception class(es) or a callable returning bool

Source: RetryPolicy in langgraph.types and _retry.py

3. catch exceptions inside the node (graceful degradation)

If you want a parallel branch to fail gracefully instead of crashing the entire graph, wrap the node logic in a try/except and write a fallback result to the state:

from typing import Annotated, TypedDict
from langgraph.graph import StateGraph, START, END
import operator


class MyState(TypedDict):
    query: str
    results: Annotated[list[dict], operator.add]
    errors: Annotated[list[str], operator.add]


def node_a(state: MyState) -> dict:
    try:
        result = call_external_api_a(state["query"])
        return {"results": [{"source": "A", "data": result}]}
    except Exception as e:
        # Graceful degradation: record the error, don't crash
        return {
            "results": [],
            "errors": [f"Node A failed: {e}"],
        }


def node_b(state: MyState) -> dict:
    try:
        result = call_external_api_b(state["query"])
        return {"results": [{"source": "B", "data": result}]}
    except Exception as e:
        return {
            "results": [],
            "errors": [f"Node B failed: {e}"],
        }


def aggregate(state: MyState) -> dict:
    if not state["results"] and state.get("errors"):
        # All branches failed
        raise RuntimeError(f"All parallel nodes failed: {state['errors']}")
    # Process whatever results we got
    return {"results": state["results"]}


builder = StateGraph(MyState)
builder.add_node(node_a)
builder.add_node(node_b)
builder.add_node(aggregate)

# Fan-out: START -> node_a, node_b (parallel)
builder.add_edge(START, "node_a")
builder.add_edge(START, "node_b")

# Fan-in: node_a, node_b -> aggregate
builder.add_edge("node_a", "aggregate")
builder.add_edge("node_b", "aggregate")
builder.add_edge("aggregate", END)

graph = builder.compile()

This pattern gives you partial results even when some branches fail. The aggregate node can then decide what to do (proceed with partial data, raise an error if all failed, etc.).

Note: the Annotated[list[...], operator.add] reducer is critical here - it merges lists from all parallel branches into a single list in the state.

4. Dynamic fan-out with send + error handling

For map-reduce workflows where you dynamically spawn parallel tasks using Send, the same patterns apply:

from langgraph.types import Send


class OverallState(TypedDict):
    subjects: list[str]
    jokes: Annotated[list[str], operator.add]
    errors: Annotated[list[str], operator.add]


def continue_to_jokes(state: OverallState):
    return [Send("generate_joke", {"subject": s}) for s in state["subjects"]]


def generate_joke(state: dict) -> dict:
    try:
        joke = call_llm(f"Tell me a joke about {state['subject']}")
        return {"jokes": [joke]}
    except Exception as e:
        return {"jokes": [], "errors": [f"Failed for {state['subject']}: {e}"]}


builder = StateGraph(OverallState)
builder.add_node(
    generate_joke,
    retry_policy=RetryPolicy(max_attempts=2), 
)
builder.add_conditional_edges(START, continue_to_jokes)
builder.add_edge("generate_joke", END)

graph = builder.compile()

Source: Send class in langgraph.types

5. Summary

Strategy When to Use Behavior
Default (do nothing) You want fail-fast One node fails → siblings cancelled → exception raised
RetryPolicy Transient errors (APIs, network) Retry N times with backoff before failing
Try/except in node Partial results are acceptable Node catches its own error, writes fallback to state
Combine retry + try/except Maximum resilience Retry first, then graceful fallback if all retries exhausted