Skip to content
AI Agents Tutorial

Build a Simple AI Agent With Function Calling

An agent is a loop: the model decides, calls a function you gave it, receives the result and decides again. We build that loop with a weather tool.

A Alex Morgan Updated 3 min read

An AI agent is a surprisingly simple loop:

1. The model reads the conversation.
2. It decides: reply, or call a tool you provided?
3. If it calls a tool, your code runs the tool and feeds the result back.
4. Repeat until the model replies.

That loop — model, tools, results, repeat — is what powers every "agent" you have heard about. Once you see it, building your own is straightforward.

Tools are just functions with descriptions

The model cannot run your code. It can only request that a tool be run, using a structured schema. Your job is to expose functions with clear names and descriptions so the model knows when and how to call them.

def get_weather(city: str) -> str:
    """Look up the current weather for a city."""
    return f"It is 18°C and partly cloudy in {city}."

The function description is your prompt to the model. "Look up the current weather for a city" tells it exactly when this tool applies. Vague descriptions mean the model calls the wrong tool.

Function calling in practice

Modern APIs support tool calling natively. You declare the schema, pass it with the conversation, and the API returns either text or a tool call.

messages = [{"role": "user", "content": "What's the weather in Lisbon?"}]
tools = [{
    "type": "function",
    "function": {
        "name": "get_weather",
        "parameters": {
            "type": "object",
            "properties": {"city": {"type": "string"}},
            "required": ["city"]
        }
    }
}]

response = client.chat.completions.create(
    model="...", messages=messages, tools=tools)

# If response.choices[0].message.tool_calls is non-empty,
# execute each call and append the results to messages.

When the model returns a tool call, you execute it, then append both the tool call and its result to the message history, then call again. The model sees the real outcome and continues.

Keep the loop grounded

Two habits separate reliable agents from chaos:

  • Always append tool results. The model only knows what you put back into the conversation. If you omit a result, it will guess.
  • Limit iterations. Put a hard cap on loop count so a confused model cannot spin forever or run your tools dozens of times.

Add a safety layer

Because the model decides when to call tools, you decide whether to allow it. Before executing an action with real effects — sending email, editing files, spending money — add a confirmation step. Production agents should be allowed to read freely but must confirm before they write.

A minimal weather agent

from openai import OpenAI

client = OpenAI()
messages = [{"role": "user", "content": user_question}]

for _ in range(6):  # hard iteration cap
    resp = client.chat.completions.create(
        model=MODEL, messages=messages, tools=[WEATHER_TOOL])
    msg = resp.choices[0].message
    if not msg.tool_calls:
        print(msg.content); break
    messages.append(msg)
    for call in msg.tool_calls:
        result = run_tool(call.function.name, call.function.arguments)
        messages.append({
            "role": "tool",
            "tool_call_id": call.id,
            "content": result,
        })

Swap the weather tool for "search the database", "query the docs" or "calculate this" and you have the skeleton of most agentic products shipping today.

Agents are not magic. They are a decision loop where a model picks the next step and your code does the doing.

A

Written by

Alex Morgan

Alex has spent a decade building software and five years writing about it. At AIComets they focus on prompt engineering, AI agents and honest product testing.

More articles by Alex Morgan →

Frequently asked questions

How long does it take to read this article?

Most readers finish in under ten minutes. Use the table of contents to jump to the section you need.

Do I need previous experience to follow along?

No. We explain every concept as it appears, and the code examples are self-contained.

Comments

Leave a comment

Comments are moderated and will appear once approved.