CloudCodeTree LogoCloudCodeTree
AI NewsTutorialsAbout
CloudCodeTree Logo
CloudCodeTree
  • AI News
  • Tutorials
  • About
← Back to AI News
Kill the 40-Line Agentic Loop: The Claude SDK tool_runner Handles Multi-Turn Tool Calls For You

Kill the 40-Line Agentic Loop: The Claude SDK tool_runner Handles Multi-Turn Tool Calls For You

Chris Harper

2 min read

Aug 1, 2026 · 04:15 UTC

AI
Workflow
Agents
Best Practices

The standard agentic loop — check stop_reason, dispatch tool calls, append results, repeat — is 30+ boilerplate lines. The Claude SDK's tool_runner collapses it to an iterable.

Every multi-turn tool-using agent follows the same cycle: call the API, check if stop_reason == "tool_use", run each tool_use block, append tool_result messages, call the API again. The client.beta.messages.tool_runner (beta, available in Python, TypeScript, Go, C#, Java, Ruby, PHP) handles all of that internally.

Minimal working example

pip install anthropic
from anthropic import Anthropic, beta_tool
import json

client = Anthropic()

@beta_tool
def get_price(ticker: str) -> str:
    """Fetch current stock price.
    Args: ticker: Stock symbol, e.g. AAPL.
    Returns: JSON with price and daily change.
    """
    return json.dumps({"ticker": ticker, "price": 182.50, "change": "+1.2%"})

@beta_tool
def search_news(query: str, limit: int = 3) -> str:
    """Search recent news headlines.
    Args: query: Search topic. limit: Max number of results (default 3).
    Returns: JSON list of headline strings.
    """
    return json.dumps([f"Headline about {query} #{i}" for i in range(limit)])

runner = client.beta.messages.tool_runner(
    model="claude-sonnet-5",
    max_tokens=2048,
    tools=[get_price, search_news],
    messages=[{"role": "user", "content": "Research AAPL: get the price and two recent headlines."}],
)

for msg in runner:
    pass  # runner iterates through every tool-call/result cycle

print(runner.get_final_message().content[0].text)

Three things the runner does for you:

  1. @beta_tool generates the schema. The decorator reads your function signature and docstring and builds the full JSON schema — no manual input_schema dict.
  2. Parallel dispatch by default. When Claude requests multiple tools in one turn, the runner fans them all out before the next iteration.
  3. Error wrapping. If your tool throws, the runner returns the exception message as an is_error: true tool result — Claude sees the error and can adapt, rather than your process crashing.

The 5-ring official tutorial walks through writing the manual loop first (rings 1–4), then collapsing it with tool_runner (ring 5) — worth reading to understand what happens under the hood.

Sources: Tool Runner (SDK) — Claude Platform Docs · Tutorial: Build a tool-using agent — Claude Platform Docs · Agent SDK overview — Claude API Docs