LangGraph Agents

Course Content

LangGraph Agents

7 sections · 49 lessons

How do you constrain tool usage (allowlist, rate limits, max tool calls, safe tools only)?


What you need to know

ControlHowWhat it stops
Allowlistllm.bind_tools(read_only_tools) per nodeCalls to tools the role should never use
Call budgetToolCallLimitMiddleware(tool_name="web_search", run_limit=5)Loops of repeated searches
Argument checksPydantic Field(le=...) plus a policy nodeOut-of-range or dangerous arguments
Approvalinterrupt() or HumanInTheLoopMiddlewareIrreversible actions without a human
Rate limitClient-side limiter, max_concurrencyProvider 429s, runaway cost
Least privilegeUser token from runtime contextActing beyond the user's own rights

Tool-call limits in create_agent

Python
from langchain.agents.middleware import ToolCallLimitMiddlewaremiddleware = [    ToolCallLimitMiddleware(run_limit=10, exit_behavior="end"),          # all tools    ToolCallLimitMiddleware(tool_name="web_search", run_limit=4),         # one tool]

exit_behavior="continue" (the default) blocks further calls with an error message the model sees; "end" stops the run; "error" raises. thread_limit counts across the whole thread.

Tool count and accuracy

Tool selection gets worse as the list grows, because descriptions start to overlap. Keep each agent's list small, and give tools clear, distinct descriptions. If you need many tools, select a subset per request (for example LLMToolSelectorMiddleware) or split into specialised agents.

A real-life example

An e-commerce operations agent has 22 tools, including cancel_order and bulk_update_prices. A red-team prompt, "clear out the old stock prices to zero", made it call bulk_update_prices on 3,000 products in a staging run. The team restructured: the customer-facing agent gets 6 read-only tools plus issue_refund behind approval; bulk_update_prices exists only in an internal agent that requires an employee token from the runtime context and an interrupt() showing the product count. Wrong-tool calls in evals dropped from 9% to 2%, and the dangerous path now needs two independent checks.

Follow-up questions to expect

  • "Why not just tell the model not to use a tool?" — Instructions are advice. Under prompt injection or confusion, the model may call it anyway. A tool that is not bound cannot be called.
  • "Where do you count tool calls if you build the graph yourself?" — In a state key incremented by the tool node, checked by the routing edge.
  • "How do you rate-limit across many runs?" — A shared limiter (for example Redis-backed) in the tool's client, because per-run counters do not see other users.