LangChain/Tools
Intermediate12 min

Dynamic Tools

Static tool registries break in multi-tenant agents — an admin tool visible to a free user is an auth bug. Learn when dynamic filtering is worth the middleware complexity, which of the four strategies to pick, and how LangChain's built-in LLMToolSelectorMiddleware handles the hardest case automatically.

Quick Reference

  • Dynamic tools = intercept request.tools inside @wrap_model_call before the LLM call fires
  • All tools must be registered at create_agent() time — middleware only filters, not adds (for most cases)
  • Four strategies: by State (session auth), by Store (persistent user flags), by Context (request-time role), by Stage (message count)
  • LLMToolSelectorMiddleware: LangChain's built-in — runs a fast LLM to pick semantically relevant tools
  • Runtime registration (DynamicToolMiddleware) requires BOTH wrap_model_call (inject) + wrap_tool_call (execute)
  • Filtering to zero tools causes an infinite loop — always guarantee at least one tool survives
  • Each tool schema costs ~50 tokens; filtering 15→5 saves ~500 tokens/call = $15/day at 10K calls

When NOT to Use Dynamic Tools

Dynamic tool filtering adds a middleware layer that runs on every LLM call. Before building it, verify you have an actual problem.

SituationDo you need dynamic filtering?
Fewer than 10 tools totalNo — the model handles this fine statically
All users have the same permissionsNo — one tool set, no filtering needed
Tools differ by feature (not auth)Maybe — only if tool count causes errors or cost spikes
Different roles have genuinely different tool accessYes — auth filtering prevents privilege escalation
20+ tools and only 5 are relevant per callYes — token cost and error rate will be measurable
Tools loaded from MCP or a remote registry at runtimeYes — requires DynamicToolMiddleware, the advanced pattern
Middleware has a maintenance cost

Every filtering rule is a piece of auth logic that can go wrong silently. A bug that hides a tool from users who should have it will look like a product bug, not a code bug. Build filtering only when the absence of it causes a concrete problem — auth exposure, error rate increase, or token cost spike you can measure.