ReAct & Tool Use

LLMs are powerful reasoners, but they can't take actions on their own. Tool use gives LLMs the ability to call functions — search the web, run code, query databases — and then reason about the results. This turns a chatbot into an agent.

📖 Covers: ReAct Pattern · Function Calling · Tool Definitions · Agent Loops · LangChain Agents

What is an Agent?

A traditional LLM responds to a prompt with text. An agent:

🤖 LLM (stateless)
  • Receives prompt
  • Generates text response
  • Done
🦾 Agent (agentic)
  • Receives goal
  • Reasons about what to do
  • Calls a tool (web search, code, API)
  • Observes result
  • Repeats until goal is achieved

The ReAct Pattern

ReAct (Reasoning + Acting) is the foundational pattern for LLM agents. The model iterates through: Thought → Action → Observation until it has enough information to give a final answer.

💭 Thought

I need to find the current weather in Tokyo. I'll use the weather tool.

↓
⚡ Action

get_weather(location="Tokyo, Japan")

↓
👁️ Observation

"Tokyo: 22°C, partly cloudy, humidity 65%"

↓
💭 Thought

I have the weather. I can now answer the user's question.

↓
✅ Final Answer

The current weather in Tokyo is 22°C and partly cloudy.

Function Calling and Tool Use

Modern LLM APIs support "function calling" — you define tools in JSON schema format, and the model decides when and how to call them.

Python · Anthropic Tool Use (Claude)
import anthropic

client = anthropic.Anthropic()

# Define tools
tools = [
    {
        "name": "get_weather",
        "description": "Get current weather for a city",
        "input_schema": {
            "type": "object",
            "properties": {
                "location": {"type": "string", "description": "City name, e.g. 'Tokyo, Japan'"}
            },
            "required": ["location"]
        }
    },
    {
        "name": "run_python",
        "description": "Execute Python code and return the output",
        "input_schema": {
            "type": "object",
            "properties": {
                "code": {"type": "string", "description": "Python code to execute"}
            },
            "required": ["code"]
        }
    }
]

response = client.messages.create(
    model="claude-sonnet-4-6",
    max_tokens=1024,
    tools=tools,
    messages=[{"role": "user", "content": "What's 2^50 + the current year?"}]
)

# Check if model wants to call a tool
if response.stop_reason == "tool_use":
    tool_call = next(b for b in response.content if b.type == "tool_use")
    print(f"Model wants to call: {tool_call.name}")
    print(f"With inputs: {tool_call.input}")

Building a Complete Agent Loop

Python · Simple Agent Loop
import anthropic
import subprocess

client = anthropic.Anthropic()

def run_python(code: str) -> str:
    result = subprocess.run(['python', '-c', code], capture_output=True, text=True, timeout=10)
    return result.stdout or result.stderr

def agent_loop(user_message: str, max_iterations: int = 10) -> str:
    messages = [{"role": "user", "content": user_message}]

    for _ in range(max_iterations):
        response = client.messages.create(
            model="claude-sonnet-4-6",
            max_tokens=2048,
            tools=[{
                "name": "run_python",
                "description": "Run Python code",
                "input_schema": {"type": "object", "properties": {"code": {"type": "string"}}, "required": ["code"]}
            }],
            messages=messages
        )

        # If done, return the text response
        if response.stop_reason == "end_turn":
            return response.content[0].text

        # Otherwise, execute the tool and continue
        tool_use = next(b for b in response.content if b.type == "tool_use")
        result = run_python(tool_use.input['code'])

        messages.append({"role": "assistant", "content": response.content})
        messages.append({
            "role": "user",
            "content": [{"type": "tool_result", "tool_use_id": tool_use.id, "content": result}]
        })

    return "Max iterations reached"

print(agent_loop("What is the sum of all prime numbers under 100?"))

Common Agent Tools

🔍Web Search

Tavily, Serper, Google Search API. Get real-time information the model wasn't trained on.

💻Code Execution

Python REPL, Jupyter kernel. Let the model calculate, analyse data, create charts.

📂File Operations

Read/write files, search directories. Build file management agents.

🌐HTTP/API calls

Call any REST API. Weather, CRM, databases, internal services.

🗄️Database Queries

Natural language to SQL. The model writes queries and interprets results.

📧Communications

Send emails, Slack messages, create calendar events via tool calls.

Frequently Asked Questions

How do I prevent agents from taking harmful actions?

Always implement a "human-in-the-loop" for irreversible actions (sending emails, deleting files, making purchases). Use tool descriptions to constrain scope. Add a confirmation step before executing high-risk actions. Run tools in sandboxed environments (Docker containers) to prevent system access.

What is the difference between ReAct and chain-of-thought?

Chain-of-thought (CoT) is pure reasoning — the model thinks step by step but doesn't take external actions. ReAct extends CoT with action steps: the model can call real tools and incorporate the results into its reasoning. ReAct agents can access information beyond their training data.