HOW-TO · RAG

How to Implement Tool Use in AI Agents

intermediate20 minBy Fredoline Eruo
Target environment
Ubuntu 24.04 · Ollama 0.4.x
PREREQUISITES

Agent framework set up, tool functions defined, Python 3.10+

What this does

Tool use enables agents to go beyond text generation by calling external functions — APIs, databases, calculators — and incorporating the results into their reasoning. This guide integrates tools into the agent decision loop.

Steps

  • Define tools as callable functions with metadata. Each tool needs a name, description, and parameter schema.
def search_web(query: str, max_results: int = 5) -> list[dict]:
    """Search the web for a query."""
    # Implementation: call search API
    return [{"title": "Result 1", "url": "https://example.com"}]

def calculate(expression: str) -> str:
    """Evaluate a mathematical expression."""
    return str(eval(expression))

TOOL_SCHEMAS = [
    {
        "type": "function",
        "function": {
            "name": "search_web",
            "description": "Search the web for information",
            "parameters": {
                "type": "object",
                "properties": {
                    "query": {"type": "string", "description": "Search query"},
                    "max_results": {"type": "integer", "default": 5}
                },
                "required": ["query"]
            }
        }
    },
    {
        "type": "function",
        "function": {
            "name": "calculate",
            "description": "Evaluate a math expression",
            "parameters": {
                "type": "object",
                "properties": {
                    "expression": {"type": "string"}
                },
                "required": ["expression"]
            }
        }
    }
]
  • Map tool names to functions.
TOOL_MAP = {
    "search_web": search_web,
    "calculate": calculate,
}
  • Process tool calls in the agent loop. After the LLM responds, check for tool calls.
def process_tool_calls(message, messages):
    for tc in message.tool_calls:
        func = TOOL_MAP.get(tc.function.name)
        if not func:
            result = {"error": f"Unknown tool: {tc.function.name}"}
        else:
            args = json.loads(tc.function.arguments)
            try:
                result = func(**args)
            except Exception as e:
                result = {"error": str(e)}

        messages.append({
            "role": "tool",
            "tool_call_id": tc.id,
            "content": json.dumps(result)
        })
  • Add tool output formatting. Convert complex results to text the LLM can understand.
def format_tool_result(result) -> str:
    if isinstance(result, list):
        items = "\n".join(f"- {r['title']}: {r['url']}" for r in result[:5])
        return f"Search results:\n{items}"
    return str(result)
  • Handle parallel tool calls. The LLM may request multiple tools in one response. Execute them concurrently.
import asyncio

async def process_parallel_tool_calls(tool_calls):
    async def call(tc):
        func = TOOL_MAP[tc.function.name]
        args = json.loads(tc.function.arguments)
        return tc.id, await asyncio.to_thread(func, **args)

    tasks = [call(tc) for tc in tool_calls]
    results = await asyncio.gather(*tasks)
    return [{"tool_call_id": tid, "content": str(r)} for tid, r in results]

Verification

python -c "
from langchain.tools import tool
@tool
def double(n: int) -> int:
    '''Double a number.'''
    return n * 2
print(double.invoke({'n': 21}))
# Expected: 42
"

Common failures

  • Tool function signature mismatch. The LLM may pass string arguments when the function expects integers. Add type coercion.
  • No error handling in tool execution. A tool that raises an unhandled exception breaks the agent loop. Wrap all tool bodies in try/except.
  • Side effects without confirmation. Tools that modify state (delete, write) should require explicit user confirmation before execution.
  • Version mismatch - The installed package or runtime differs from the command shown; check the version first and rerun the smallest verification command.
  • Local environment drift - Another service, virtual environment, model, or path is being used; print the active binary path and configuration before changing the guide steps.

Related guides

  • How to Build Core AI Agent Architecture
  • How to Create Agent Decision-Making Logic