Building Your First AI Agent With Function Calling: A Beginner's Guide
An AI agent is just a loop plus a few tools. Here's how to build the simplest possible version yourself, and what to understand before reaching for a framework.
AI & Tech Insights Team
October 7, 2026 · 4 min read
Building your first AI agent from scratch, without a framework, is one of the better ways to actually understand how agents work, rather than starting with a framework that hides the loop behind abstractions you don't yet have a mental model for. This tutorial walks through the core pattern using a simple example: an agent that can answer questions by calling a basic calculator function when math is involved.
Exact API syntax varies between providers and changes as APIs evolve, so treat the code below as illustrating the pattern rather than copy-paste-exact for whichever provider and SDK version you're using. Check your provider's current documentation for the precise function-calling syntax.
Step 1: Define a tool the model can call
Before anything else, you need at least one function the agent can actually invoke, along with a clear description of what it does and what input it expects. This description is what the model uses to decide when to call it, so it needs to be specific.
def calculate(expression: str) -> str:
"""Evaluates a basic math expression and returns the result."""
try:
result = eval(expression, {"__builtins__": {}})
return str(result)
except Exception as e:
return f"Error: {e}"
tool_definition = {
"name": "calculate",
"description": "Evaluates a basic math expression like '12 * 7' and returns the numeric result.",
"parameters": {
"type": "object",
"properties": {
"expression": {"type": "string", "description": "A math expression to evaluate."}
},
"required": ["expression"]
}
}
Note that eval here is simplified for illustration. In real code, use a safe expression parser rather than raw eval, since evaluating arbitrary strings is a genuine security risk.
Step 2: Send the user's request along with the available tools
When you call the model, you pass both the user's message and the list of tools it's allowed to use. The model itself decides whether answering requires calling a tool or whether it can respond directly.
response = client.messages.create(
model="your-chosen-model",
messages=[{"role": "user", "content": "What is 847 times 12?"}],
tools=[tool_definition]
)
Step 3: Check if the model wants to call a tool
If the model decides it needs the calculator, its response will indicate a tool call rather than a direct text answer, including which tool and what input to use.
if response.stop_reason == "tool_use":
tool_call = response.tool_use
tool_name = tool_call.name
tool_input = tool_call.input
Step 4: Actually execute the tool and get the result
This is the step that makes it an agent rather than just a model generating text: your code runs the actual function with the input the model specified.
if tool_name == "calculate":
result = calculate(tool_input["expression"])
Step 5: Send the result back to the model
The tool's result gets added back into the conversation, and you call the model again so it can generate a final answer using that result.
messages.append({"role": "assistant", "content": response.content})
messages.append({
"role": "user",
"content": [{"type": "tool_result", "tool_use_id": tool_call.id, "content": result}]
})
final_response = client.messages.create(
model="your-chosen-model",
messages=messages,
tools=[tool_definition]
)
The model now has the calculated result and can respond to the original question using it, for example: "847 times 12 is 10,164."
What you just built
This is the complete agent loop in its simplest form: the model decides an action is needed, your code executes it, the result feeds back in, and the model produces a final answer using that result. Every more elaborate agent framework is built on some version of this same underlying pattern, just with more tools available, more sophisticated handling of multi-step tasks, and more infrastructure around error handling and retries.
When to move to a framework
Once you're comfortable with this basic loop, a framework becomes useful when you need to manage several tools, multi-step planning across several actions before reaching a final answer, or coordination between multiple specialized agents working on different parts of a task. Building the simple version first gives you a real mental model for what a framework is actually doing underneath its abstractions, which makes debugging a framework-based agent far easier than starting with the framework and treating the loop as a black box.
Final thoughts
An AI agent is fundamentally a loop: the model decides on an action, your code executes it, and the result feeds back for the model to use. Building this from scratch with one simple tool, before reaching for a framework, is worth the hour it takes, since it turns "agent" from an abstract buzzword into a pattern you actually understand and can debug when something goes wrong later in a more complex system.
© 2026 AI & Tech Insights. All rights reserved. This article may not be reproduced without permission. See our disclaimer.
← Previous
How Restaurants Are Using AI for Scheduling and Orders
Next →
How to Debug AI-Generated Code Safely
Related articles
Using AI to Write Unit Tests Faster
AI can generate a test suite in seconds. The catch is that high coverage and good tests aren't the same thing, and it's easy to mistake one for the other.
Oct 8 · 4 min read
Understanding API Rate Limits When Building With AI Models
A 429 error in production usually means your rate limit handling wasn't ready for real traffic. Here's what these limits actually measure and how to handle them properly.
Oct 8 · 4 min read
AI Tools for Writing and Maintaining Documentation
Writing documentation once is the easy part. Keeping it accurate as code changes is where most documentation actually fails, and where AI tools help the most.
Oct 8 · 4 min read
Get new guides by email
Useful AI and tech guides, occasionally. No unnecessary emails.