ScavioScavio
ProductPricingDocs
Sign InGet Started
Blog
pythonagentsminimal

Plain Python Agent with Tool Dispatch 2026

Skip LangChain and CrewAI for simple agents. Plain Python with a tool registry and LLM function calling. 50 lines, no framework lock-in.

May 20, 2026
8 min

Most AI agent projects do not need LangGraph, CrewAI, or any framework. A plain Python loop with explicit tool dispatch handles 80% of use cases: call the LLM with function definitions, check which tool it selected, execute it, append the result, repeat. When it breaks, you see exactly where.

The explicit dispatch pattern

Python
import os, json, requests
from anthropic import Anthropic

client = Anthropic()
SCAVIO_H = {"x-api-key": os.environ["SCAVIO_API_KEY"],
            "Content-Type": "application/json"}

def web_search(query: str) -> list:
    resp = requests.post(
        "https://api.scavio.dev/api/v1/search",
        headers=SCAVIO_H,
        json={"query": query, "country_code": "us"},
    )
    return resp.json().get("organic_results", [])[:5]

TOOLS = {"web_search": web_search}
TOOL_DEFS = [{
    "name": "web_search",
    "description": "Search the web for current information.",
    "input_schema": {
        "type": "object",
        "properties": {"query": {"type": "string"}},
        "required": ["query"],
    },
}]

def agent(task: str, max_steps: int = 8):
    messages = [{"role": "user", "content": task}]
    for step in range(max_steps):
        resp = client.messages.create(
            model="claude-sonnet-4-6",
            max_tokens=1024,
            tools=TOOL_DEFS,
            messages=messages,
        )
        # Check if the model wants to use a tool
        tool_use = next(
            (b for b in resp.content if b.type == "tool_use"), None)
        if not tool_use:
            return next(
                b.text for b in resp.content if b.type == "text")
        # Execute the tool
        result = TOOLS[tool_use.name](**tool_use.input)
        messages.append({"role": "assistant", "content": resp.content})
        messages.append({
            "role": "user",
            "content": [{"type": "tool_result",
                         "tool_use_id": tool_use.id,
                         "content": json.dumps(result)}],
        })
    return "Max steps reached"

print(agent("What are the latest AI search API pricing changes?"))

Why this beats a framework for simple agents

  • Debugging is a stack trace, not a graph traversal
  • Adding a new tool is one function + one schema dict
  • No dependency on framework release cycles or breaking changes
  • Error handling is explicit: try/except around each tool call
  • Testing is straightforward: mock the LLM response, check the tool was called correctly

Adding error handling

Python
import time

def safe_tool_call(name: str, args: dict, retries: int = 2):
    for attempt in range(retries + 1):
        try:
            result = TOOLS[name](**args)
            return {"success": True, "data": result}
        except requests.exceptions.Timeout:
            if attempt < retries:
                time.sleep(2 ** attempt)
                continue
            return {"success": False, "error": "Tool timed out after retries"}
        except Exception as e:
            return {"success": False, "error": str(e)}

When to graduate to LangGraph

Move to LangGraph when you need: parallel tool execution with fan-out/fan-in, persistent state across sessions (checkpointing), branching logic where different tool results trigger different paths, or built-in human-in-the-loop patterns. For a single agent doing sequential tool calls, plain Python is cleaner.

Continue reading

aeod2c

AEO Tracking for D2C Ecommerce Brands in 2026

6 min read
ai-agentscost-optimization

Agent Discovery vs Extraction: Why Cost Split Matters

6 min read
ScavioScavio

Real-time search API for AI agents. Search every platform, not just Google.

Product

  • Features
  • Pricing
  • Dashboard
  • Affiliates

Developers

  • Documentation
  • API Reference
  • Quickstart
  • MCP Integration
  • Python SDK

Alternatives

  • Tavily Alternative
  • SerpAPI Alternative
  • Firecrawl Alternative
  • Exa Alternative

Tools

  • JSON Formatter
  • cURL to Code
  • Token Counter
  • All Tools

© 2026 Scavio. All rights reserved.

Featured on TAAFT
Terms of ServicePrivacy Policy