Designing Simple Tool Interfaces: A Complete Guide to Connecting AI Agents with External Functions
Back to Writing

Designing Simple Tool Interfaces: A Complete Guide to Connecting AI Agents with External Functions

Michael BrenndoerferNovember 9, 202511 min read1,812 wordsInteractive

Learn how to design effective tool interfaces for AI agents, from basic function definitions to multi-tool orchestration. Covers tool descriptions, parameter extraction, workflow implementation, and best practices for agent-friendly APIs.

AI Agent Handbook Cover
Part of AI Agent Handbook

This article is part of the free-to-read AI Agent Handbook

View full handbook

Designing Simple Tool Interfaces

You know why agents need tools. Now let's talk about how to actually connect them. How does an agent know what tools are available? How does it decide which one to use? And once it decides, how does it actually call the tool and use the result?

These questions might sound complicated, but the answers are surprisingly straightforward. At its core, a tool is just a function the agent can call. The trick is making sure the agent understands what the function does, what inputs it needs, and what output to expect.

In this chapter, we'll design a simple, practical framework for connecting tools to your agent. We'll stay library-agnostic and focus on the concepts, so you can apply these ideas regardless of which specific framework you eventually use.

What Makes a Good Tool Interface?

Before we dive into implementation details, let's think about what makes a tool easy for an agent to use. A good tool interface has three essential characteristics:

Clear purpose: The agent needs to understand what the tool does. Is it for calculations? Weather lookups? Database queries? The more specific and focused a tool is, the easier it is for the agent to decide when to use it.

Simple inputs: The tool should require only the information the agent can reasonably extract from a user's question. If you ask "What's the weather in Tokyo?", the agent should be able to extract "Tokyo" as the location parameter. If the tool requires complex nested data structures or obscure parameters, the agent will struggle to use it correctly.

Predictable outputs: The tool should return information in a format the agent can understand and incorporate into its response. A weather tool that returns {"temp": 72, "conditions": "sunny"} is easier to work with than one that returns a binary blob or a complex nested structure.

Think of it like designing an API for another developer. You want clear documentation, sensible parameters, and predictable responses. The same principles apply when designing tools for agents.

The Anatomy of a Tool

Let's break down what a tool actually consists of. We'll use a simple weather tool as our example:

The Tool Function

At its most basic, a tool is just a Python function:

1def get_weather(city: str) -> dict:
2    """Get current weather for a city."""
3    # In reality, this would call a weather API
4    # For now, we'll return mock data
5    return {
6        "city": city,
7        "temperature": 72,
8        "conditions": "partly cloudy",
9        "humidity": 65
10    }

This function takes a city name and returns weather information. Simple enough. But how does the agent know this function exists? How does it know what parameter to pass? That's where tool descriptions come in.

The Tool Description

The agent needs metadata about the tool. Think of this as the function's documentation, but in a format the agent can understand:

1weather_tool = {
2    "name": "get_weather",
3    "description": "Get current weather conditions for a specified city",
4    "parameters": {
5        "city": {
6            "type": "string",
7            "description": "The name of the city (e.g., 'Tokyo', 'New York', 'London')"
8        }
9    }
10}

This description tells the agent:

  • What the tool does: "Get current weather conditions"
  • What it's called: get_weather
  • What inputs it needs: A city name (string)
  • What the parameter means: Examples help the agent understand the format

With this information, the agent can decide whether this tool is appropriate for a given question and extract the necessary parameters.

The Tool Registry

If you have multiple tools, you need a way to organize them. A simple registry is just a dictionary mapping tool names to their functions:

1tool_registry = {
2    "get_weather": get_weather,
3    "calculate": calculate,
4    "search_web": search_web
5}

When the agent decides to use a tool, it looks up the function in this registry and calls it with the appropriate parameters.

The Tool Use Workflow

Now let's walk through the complete workflow of how an agent uses a tool. We'll break it down into clear steps:

Step 1: Receive User Input

The user asks a question:

1User: What's the weather like in Tokyo right now?

Step 2: Decide Whether to Use a Tool

The agent analyzes the question and determines whether it needs a tool. This is where the agent's reasoning comes in. It might think:

1This question asks about current weather in Tokyo. I don't have access to 
2real-time weather data, but I have a get_weather tool that can retrieve 
3this information. I should use that tool.

How does the agent make this decision? We can prompt it to consider whether it needs external information:

1system_prompt = """
2You are a helpful assistant with access to tools.
3
4When a user asks a question, first determine if you need to use a tool:
5- If the question requires current information (weather, news, stock prices), use a tool
6- If the question requires precise calculations, use a tool
7- If the question requires taking an action (sending email, updating records), use a tool
8- If you can answer from your general knowledge, respond directly
9
10Available tools:
11{tool_descriptions}
12"""

Step 3: Select the Appropriate Tool

If the agent decides it needs a tool, it must choose which one. With our weather example, this is straightforward since we only have one relevant tool. But imagine the agent has access to:

  • get_weather(city): Get current weather
  • get_forecast(city, days): Get weather forecast
  • calculate(expression): Perform calculations
  • search_web(query): Search the internet

The agent needs to match the user's intent to the right tool. For "What's the weather like in Tokyo right now?", it should choose get_weather, not get_forecast.

Step 4: Extract Parameters

Once the agent has selected a tool, it needs to extract the required parameters from the user's question. For our weather example:

  • Question: "What's the weather like in Tokyo right now?"
  • Tool: get_weather
  • Required parameter: city
  • Extracted value: "Tokyo"

The agent uses its language understanding to identify that "Tokyo" is the city the user is asking about.

Step 5: Call the Tool

Now the agent calls the tool with the extracted parameters:

1result = tool_registry["get_weather"](city="Tokyo")
2## Returns: {"city": "Tokyo", "temperature": 72, "conditions": "partly cloudy", "humidity": 65}

Step 6: Interpret the Result

The agent receives the tool's output and needs to incorporate it into a natural response:

1Tool output: {"city": "Tokyo", "temperature": 72, "conditions": "partly cloudy", "humidity": 65}
2
3Agent response: "In Tokyo right now, it's 72°F and partly cloudy with 65% humidity."

The agent translates the structured data into natural language that answers the user's question.

Implementing the Framework

Let's put this all together into a simple implementation. We'll build a basic framework that handles the entire tool use workflow:

1import anthropic
2
3## Using Claude Sonnet 4.5 for its superior agent reasoning and tool use capabilities
4client = anthropic.Anthropic(api_key="YOUR_API_KEY")
5
6## Define our tools
7def get_weather(city: str) -> dict:
8    """Get current weather for a city."""
9    # Mock implementation
10    return {
11        "city": city,
12        "temperature": 72,
13        "conditions": "partly cloudy"
14    }
15
16## Tool descriptions for the agent
17tools = [
18    {
19        "name": "get_weather",
20        "description": "Get current weather conditions for a specified city",
21        "input_schema": {
22            "type": "object",
23            "properties": {
24                "city": {
25                    "type": "string",
26                    "description": "City name (e.g., 'Tokyo', 'New York')"
27                }
28            },
29            "required": ["city"]
30        }
31    }
32]
33
34## Tool registry
35tool_registry = {
36    "get_weather": get_weather
37}
38
39def run_agent(user_message: str) -> str:
40    """Run the agent with tool support."""
41    messages = [{"role": "user", "content": user_message}]
42    
43    # Initial agent call
44    response = client.messages.create(
45        model="claude-sonnet-4.5",
46        max_tokens=1024,
47        tools=tools,
48        messages=messages
49    )
50    
51    # Check if agent wants to use a tool
52    if response.stop_reason == "tool_use":
53        tool_use = response.content[-1]
54        tool_name = tool_use.name
55        tool_input = tool_use.input
56        
57        # Call the tool
58        tool_result = tool_registry[tool_name](**tool_input)
59        
60        # Send result back to agent
61        messages.append({"role": "assistant", "content": response.content})
62        messages.append({
63            "role": "user",
64            "content": [{
65                "type": "tool_result",
66                "tool_use_id": tool_use.id,
67                "content": str(tool_result)
68            }]
69        })
70        
71        # Get final response
72        final_response = client.messages.create(
73            model="claude-sonnet-4.5",
74            max_tokens=1024,
75            tools=tools,
76            messages=messages
77        )
78        
79        return final_response.content[0].text
80    
81    # No tool needed, return direct response
82    return response.content[0].text

This implementation handles the complete workflow:

  1. Sends the user's message to the agent
  2. Checks if the agent wants to use a tool
  3. If yes, calls the tool and sends the result back
  4. Gets the agent's final response incorporating the tool result

Let's see it in action:

1response = run_agent("What's the weather in Tokyo?")
2print(response)
1In Tokyo right now, it's 72°F and partly cloudy.

The agent recognized it needed weather information, called the get_weather tool with "Tokyo" as the parameter, received the result, and formulated a natural response.

Key Design Principles

As you design tool interfaces for your agents, keep these principles in mind:

Make Tools Focused

Each tool should do one thing well. Instead of a giant do_everything function, create specific tools:

  • ✅ Good: get_weather(city), get_forecast(city, days), get_air_quality(city)
  • ❌ Bad: get_weather_data(city, type, days, include_air_quality, include_pollen)

Focused tools are easier for the agent to understand and use correctly.

Use Clear, Descriptive Names

Tool names should clearly indicate what they do:

  • ✅ Good: send_email, search_documents, calculate_mortgage
  • ❌ Bad: do_thing, helper, process

The agent uses tool names as part of its decision-making process. Clear names help it choose the right tool.

Provide Examples in Descriptions

When describing parameters, include examples:

1"city": {
2    "type": "string",
3    "description": "City name (e.g., 'Tokyo', 'New York', 'London')"
4}

Examples help the agent understand the expected format and extract the right information from user queries.

Return Structured Data

Tools should return data in a consistent, structured format:

1## Good: Structured dictionary
2return {
3    "temperature": 72,
4    "conditions": "partly cloudy",
5    "humidity": 65
6}
7
8## Bad: Unstructured string
9return "It's 72 degrees and partly cloudy with humidity at 65%"

Structured data gives the agent flexibility in how it presents the information. It can emphasize different aspects based on what the user asked.

Handle Errors Gracefully

Tools should return meaningful error information when something goes wrong:

1def get_weather(city: str) -> dict:
2    """Get current weather for a city."""
3    try:
4        # Call weather API
5        result = weather_api.get(city)
6        return {
7            "success": True,
8            "data": result
9        }
10    except CityNotFound:
11        return {
12            "success": False,
13            "error": f"City '{city}' not found"
14        }
15    except APIError as e:
16        return {
17            "success": False,
18            "error": "Weather service temporarily unavailable"
19        }

This allows the agent to provide helpful error messages to the user instead of crashing or giving confusing responses.

Multiple Tools: Decision Making

When your agent has access to multiple tools, it needs to choose the right one for each situation. Let's see how this works with a more complex example:

1tools = [
2    {
3        "name": "get_weather",
4        "description": "Get current weather conditions for a city",
5        "input_schema": {
6            "type": "object",
7            "properties": {
8                "city": {"type": "string", "description": "City name"}
9            },
10            "required": ["city"]
11        }
12    },
13    {
14        "name": "calculate",
15        "description": "Perform mathematical calculations",
16        "input_schema": {
17            "type": "object",
18            "properties": {
19                "expression": {
20                    "type": "string",
21                    "description": "Math expression to evaluate (e.g., '1234 * 5678')"
22                }
23            },
24            "required": ["expression"]
25        }
26    },
27    {
28        "name": "search_web",
29        "description": "Search the internet for current information",
30        "input_schema": {
31            "type": "object",
32            "properties": {
33                "query": {
34                    "type": "string",
35                    "description": "Search query"
36                }
37            },
38            "required": ["query"]
39        }
40    }
41]

Now when a user asks a question, the agent analyzes it and chooses the appropriate tool:

  • "What's the weather in Paris?" → get_weather(city="Paris")
  • "What's 1234 times 5678?" → calculate(expression="1234 * 5678")
  • "What are the latest developments in quantum computing?" → search_web(query="latest quantum computing developments")

The agent's language understanding allows it to map user intent to the right tool. This is where the quality of your tool descriptions matters. Clear, specific descriptions help the agent make the right choice.

Chaining Tools

Sometimes answering a question requires using multiple tools in sequence. Consider this request:

1User: What should I wear for my meeting tomorrow in Chicago?

To answer this, the agent needs to:

  1. Check the calendar to find when the meeting is
  2. Get the weather forecast for Chicago at that time
  3. Reason about appropriate attire based on the weather and meeting type

This is called tool chaining. The output of one tool becomes input to the next:

1Step 1: check_calendar(date="tomorrow")
2→ Result: Meeting at 2 PM, type: "client presentation"
3
4Step 2: get_forecast(city="Chicago", date="tomorrow", time="2 PM")
5→ Result: 45°F, rainy
6
7Step 3: Agent reasons about the results
8→ Response: "Your client presentation in Chicago tomorrow is at 2 PM. 
9   It will be 45°F and rainy, so I'd recommend business attire with 
10   a coat and umbrella."

The agent orchestrates this sequence, using the output from each tool to inform what to do next. This is where the agent's reasoning capabilities (from Chapter 4) combine with its tool use abilities to handle complex, multi-step tasks.

When Not to Use a Tool

An important part of tool design is knowing when the agent shouldn't use a tool. Not every question requires external information:

1User: What's the capital of France?

The agent can answer this from its general knowledge. It doesn't need to search the web or call an API. Using a tool here would be slower and waste resources.

Good tool use involves:

  • Using tools when needed: For current information, precise calculations, or actions
  • Not using tools when not needed: For general knowledge questions the agent can answer directly
  • Failing gracefully: If a tool isn't available or returns an error, the agent should explain the limitation

You can guide this behavior through your system prompt:

1system_prompt = """
2You are a helpful assistant with access to tools.
3
4Use tools when you need:
5- Current, real-time information (weather, news, stock prices)
6- Precise calculations
7- To take actions (send emails, update records)
8
9Do NOT use tools for:
10- General knowledge questions you can answer directly
11- Simple arithmetic you can handle reliably
12- Questions about your own capabilities
13
14If you're unsure whether to use a tool, prefer using it to ensure accuracy.
15"""

Looking Ahead

You now understand how to design tool interfaces that agents can use effectively. We've covered:

  • The three components of a tool: the function, the description, and the registry
  • The six-step workflow for tool use
  • Key design principles for creating agent-friendly tools
  • How agents choose between multiple tools
  • When to use tools and when not to

In the next chapter, we'll take these concepts and build something concrete: we'll add a calculator tool to our personal assistant. You'll see exactly how to implement tool use from scratch, step by step, creating an agent that can perform precise calculations instead of guessing at math problems.

The framework we've designed here is intentionally simple and library-agnostic. Real-world frameworks like LangChain, LlamaIndex, or Anthropic's SDK provide more sophisticated tool handling, but they all follow these same fundamental principles. Understanding the basics gives you the foundation to use any framework effectively.

Glossary

Tool Description: Metadata that explains what a tool does, what parameters it requires, and what output it produces. This information helps the agent decide when and how to use the tool.

Tool Registry: A collection or dictionary that maps tool names to their actual function implementations, allowing the agent to look up and call tools dynamically.

Parameter Extraction: The process by which an agent identifies and extracts the necessary input values from a user's question to pass to a tool function.

Tool Chaining: Using multiple tools in sequence, where the output of one tool informs what tool to use next or provides input for subsequent tools.

Structured Output: Data returned from a tool in a consistent, predictable format (like a dictionary or JSON object) that the agent can easily parse and use.

Tool Use Workflow: The complete sequence of steps an agent follows when using a tool: receiving input, deciding to use a tool, selecting the right tool, extracting parameters, calling the tool, and interpreting the result.

Quiz

Ready to test your understanding? Take this quick quiz to reinforce what you've learned about designing tool interfaces for AI agents.

Loading component...

Reference

BIBTEXAcademic
@misc{designingsimpletoolinterfacesacompleteguidetoconnectingaiagentswithexternalfunctions, author = {Michael Brenndoerfer}, title = {Designing Simple Tool Interfaces: A Complete Guide to Connecting AI Agents with External Functions}, year = {2025}, url = {https://mbrenndoerfer.com/writing/designing-simple-tool-interfaces-ai-agents}, organization = {mbrenndoerfer.com}, note = {Accessed: 2025-11-09} }
APAAcademic
Michael Brenndoerfer (2025). Designing Simple Tool Interfaces: A Complete Guide to Connecting AI Agents with External Functions. Retrieved from https://mbrenndoerfer.com/writing/designing-simple-tool-interfaces-ai-agents
MLAAcademic
Michael Brenndoerfer. "Designing Simple Tool Interfaces: A Complete Guide to Connecting AI Agents with External Functions." 2025. Web. 11/9/2025. <https://mbrenndoerfer.com/writing/designing-simple-tool-interfaces-ai-agents>.
CHICAGOAcademic
Michael Brenndoerfer. "Designing Simple Tool Interfaces: A Complete Guide to Connecting AI Agents with External Functions." Accessed 11/9/2025. https://mbrenndoerfer.com/writing/designing-simple-tool-interfaces-ai-agents.
HARVARDAcademic
Michael Brenndoerfer (2025) 'Designing Simple Tool Interfaces: A Complete Guide to Connecting AI Agents with External Functions'. Available at: https://mbrenndoerfer.com/writing/designing-simple-tool-interfaces-ai-agents (Accessed: 11/9/2025).
SimpleBasic
Michael Brenndoerfer (2025). Designing Simple Tool Interfaces: A Complete Guide to Connecting AI Agents with External Functions. https://mbrenndoerfer.com/writing/designing-simple-tool-interfaces-ai-agents
Michael Brenndoerfer

About the author: Michael Brenndoerfer

All opinions expressed here are my own and do not reflect the views of my employer.

Michael currently works as an Associate Director of Data Science at EQT Partners in Singapore, where he drives AI and data initiatives across private capital investments.

With over a decade of experience spanning private equity, management consulting, and software engineering, he specializes in building and scaling analytics capabilities from the ground up. He has published research in leading AI conferences and holds expertise in machine learning, natural language processing, and value creation through data.

Stay updated

Get notified when I publish new articles on data and AI, private equity, technology, and more.