new·The score now tells you which way it movedA brain's exam only ever grows: its own material writes questions, and so does every question a real caller asked and did not get answered. The score is a percentage over that growing set, so a brain that learned more could post a smaller number — and this week three did. One of them answered two MORE questions than the week before and showed eighteen points less. Printed as a single percentage, that reads as decline to a reader and as punishment to anyone who contributes material.all news →
mozg.beta
Sign in

LangChain · Deep Agents · all subjects

deep agents/fault-tolerance

20 notes, read out of this brain and free to use. Each one was extracted from a source and is re-checked against its exam.

Error handling strategies for deep agents

Different error types require different handling strategies: Transient errors (network issues, rate limits) should be retried automatically with exponential backoff using ModelRetryMiddleware or ToolRetryMiddleware. LLM-recoverable errors (tool failures, parsing issues) should be converted to error ToolMessages so the model can adjust. User-fixable errors (missing information, unclear instructions) should pause with interrupt(). Provider outages should fall back to an alternative model using ModelFallbackMiddleware. Excessive calls (runaway loops) should be capped using ModelCallLimitMiddleware and ToolCallLimitMiddleware. Unexpected errors should be allowed to bubble up for debugging.

ModelRetryMiddleware configuration

ModelRetryMiddleware retries model calls on rate limits, timeouts, and 5xx errors. Parameters: max_retries (maximum number of retry attempts), backoff_factor (multiplier for delay between retries, e.g., 2.0), initial_delay (starting delay in seconds before first retry, e.g., 1.0). Example: ModelRetryMiddleware(max_retries=3, backoff_factor=2.0, initial_delay=1.0).

ToolRetryMiddleware configuration

ToolRetryMiddleware retries specific tool calls that fail with transient errors. Parameters: max_retries (maximum retry attempts), tools (list of specific tool names to retry, e.g., ['search', 'fetch_url']), retry_on (tuple of exception types to retry on, e.g., (TimeoutError, ConnectionError)). Should be scoped to specific tools rather than retrying all tools, as not all tool failures benefit from retry (e.g., filesystem read_file failures).

ToolErrorMiddleware converts tool exceptions to recoverable errors

ToolErrorMiddleware catches tool exceptions and converts them into error ToolMessages so the LLM can see what went wrong and retry with adjusted inputs. Requires langchain>=1.3.14. Takes an on_error handler function that accepts exception and ToolCallRequest, returns a string message for recoverable errors or None to propagate unexpected errors. Example: if isinstance(exc, ValueError), return error message; otherwise return None to propagate.

ModelFallbackMiddleware for provider outages

ModelFallbackMiddleware automatically switches to an alternative model if the primary model provider goes down entirely. Takes the fallback model identifier as a string parameter. Example: ModelFallbackMiddleware('gpt-5.5').

ModelCallLimitMiddleware and ToolCallLimitMiddleware

ModelCallLimitMiddleware caps the number of model calls per run to prevent runaway loops burning through API budgets. ToolCallLimitMiddleware caps the number of tool executions per run. Both accept run_limit parameter to cap calls within a single invocation (resets each turn), and thread_limit parameter to cap calls across an entire conversation (requires a checkpointer). Example: ModelCallLimitMiddleware(run_limit=50), ToolCallLimitMiddleware(run_limit=200).

InMemoryRateLimiter for provider rate limiting

InMemoryRateLimiter controls the rate at which requests are sent to model providers. Parameters: requests_per_second (e.g., 0.1 for 1 request every 10 seconds), check_every_n_seconds (how often to check if allowed to make a request, e.g., 0.1 for every 100ms), max_bucket_size (maximum burst size allowed). Initialize the model with rate_limiter parameter: init_chat_model(model='...', rate_limiter=rate_limiter).

Middleware composition for fault tolerance

Multiple middleware can be composed together in the middleware list to handle different fault tolerance strategies simultaneously. Example: create_deep_agent(model='...', middleware=[ModelRetryMiddleware(...), ToolErrorMiddleware(...), ModelCallLimitMiddleware(...)]).

Python retry middleware example with search and fetch tools

This example shows creating a deep agent with both ModelRetryMiddleware and ToolRetryMiddleware: from deepagents import create_deep_agent from langchain.agents.middleware import ModelRetryMiddleware, ToolRetryMiddleware agent = create_deep_agent( model="google_genai:gemini-3.6-flash", middleware=[ ModelRetryMiddleware(max_retries=3, backoff_factor=2.0, initial_delay=1.0), ToolRetryMiddleware( max_retries=2, tools=["search", "fetch_url"], retry_on=(TimeoutError, ConnectionError), ), ], )

JavaScript retry middleware example

This example shows creating an agent with retry middleware in JavaScript: import { createAgent, modelRetryMiddleware, toolRetryMiddleware, } from "langchain"; const agent = createAgent({ model: "google_genai:gemini-3.6-flash", middleware: [ modelRetryMiddleware({ maxRetries: 3, backoffFactor: 2.0, initialDelayMs: 1000 }), toolRetryMiddleware({ maxRetries: 2, tools: ["search", "fetch_url"], retryOn: [TimeoutError, TypeError], }), ], });

Python ToolErrorMiddleware example

This example shows using ToolErrorMiddleware to catch ValueError exceptions: from deepagents import create_deep_agent from langchain.agents.middleware import ToolErrorMiddleware def on_error(exc: Exception, request: ToolCallRequest) -> str | None: if isinstance(exc, ValueError): return f"`{request.tool_call['name']}` failed with {type(exc).__name__}." # propagate everything else agent = create_deep_agent( model="google_genai:gemini-3.6-flash", middleware=[ToolErrorMiddleware(on_error)], )

Python ModelFallbackMiddleware example

This example shows configuring a fallback model: from deepagents import create_deep_agent from langchain.agents.middleware import ModelFallbackMiddleware agent = create_deep_agent( model="google_genai:gemini-3.6-flash", middleware=[ ModelFallbackMiddleware("gpt-5.5"), ], )

Python ModelCallLimitMiddleware and ToolCallLimitMiddleware example

This example shows capping model and tool calls per run: from deepagents import create_deep_agent from langchain.agents.middleware import ModelCallLimitMiddleware, ToolCallLimitMiddleware agent = create_deep_agent( model="google_genai:gemini-3.6-flash", middleware=[ ModelCallLimitMiddleware(run_limit=50), ToolCallLimitMiddleware(run_limit=200), ], )

Python InMemoryRateLimiter example

This example shows initializing a model with rate limiting: from langchain.rate_limiters import InMemoryRateLimiter from langchain.chat_models import init_chat_model from deepagents import create_deep_agent rate_limiter = InMemoryRateLimiter( requests_per_second=0.1, check_every_n_seconds=0.1, max_bucket_size=10, ) model = init_chat_model( model="google_genai:gemini-3.6-flash", rate_limiter=rate_limiter, ) agent = create_deep_agent(model=model, tools=[search_tool])

JavaScript ModelFallbackMiddleware example

This example shows configuring a fallback model in JavaScript: import { createAgent, modelFallbackMiddleware, } from "langchain"; const agent = createAgent({ model: "google_genai:gemini-3.6-flash", middleware: [ modelFallbackMiddleware("gpt-5.5"), ], });

JavaScript ModelCallLimitMiddleware and ToolCallLimitMiddleware example

This example shows capping model and tool calls per run in JavaScript: import { createAgent, modelCallLimitMiddleware, toolCallLimitMiddleware } from "langchain"; const agent = createAgent({ model: "google_genai:gemini-3.6-flash", middleware: [ modelCallLimitMiddleware({ runLimit: 50 }), toolCallLimitMiddleware({ runLimit: 200 }), ], });

Pitfall: Not scoping ToolRetryMiddleware to specific tools

Do not retry all tools indiscriminately. Scope ToolRetryMiddleware to specific tools that hit external APIs. A filesystem read_file that fails will not benefit from a retry, but a web search that times out probably will. Specify tools=['search', 'fetch_url'] rather than retrying every tool.

Pitfall: Runaway loops burning API budget without call limits

Without call limits, a confused agent can burn through LLM API budget in minutes by looping on the same tool call or making hundreds of model calls. Always set ModelCallLimitMiddleware and ToolCallLimitMiddleware caps, especially run_limit to cap calls within a single invocation.

Durable execution with checkpoints in LangGraph

Deep Agents run on LangGraph which provides durable execution out of the box. The persistence layer checkpoints state at each step, so a run interrupted by failure, timeout, or human-in-the-loop pause resumes from its last recorded state without reprocessing previous steps. For long-running deep agents that spawn many subagents, mid-run failure doesn't lose completed work. Checkpointing enables indefinite interrupts (human-in-the-loop workflows can pause for minutes or days and resume exactly where they left off), time travel (every checkpointed step is a snapshot you can rewind to for replay if something goes wrong), and safe handling of sensitive operations (workflows involving payments or irreversible actions get audit trails and recovery points).

Avoid passing secrets to sandboxes via environment variables or file uploads

Avoid passing secrets into sandboxes via environment variables or file uploads. Agents can read any accessible file or environment variable inside the sandbox, including credentials. The sandbox auth proxy keeps secrets out of the sandbox entirely.

Give your agent this brain