0Pricing
AI Agents · Lesson

How Function Calling Works

Understand the full round-trip: model picks a tool, your code runs it, you send the result back, and the model continues.

How Function Calling Works is a free AI Agents lesson on CoddyKit — lesson 1 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the AI Agents learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.

Function Calling: The Core Pattern

Function calling is the protocol that turns an LLM into an agent. The model picks a function from a list you provide, fills in the arguments, and you run it.

This pattern is supported by OpenAI, Anthropic, Google, Cohere, Mistral, and most major OSS models with the right fine-tunes.

The Five-Step Round-Trip

  1. You send messages + tool definitions
  2. Model returns either a final answer OR a tool_call
  3. You execute the tool with the model's arguments
  4. You append the result as a tool message
  5. You call the model again with the updated history

Repeat 2-5 until the model returns a final answer.

Step 1: Define Tools

Tool definitions are JSON schemas describing each function:

tools = [{
    'type': 'function',
    'function': {
        'name': 'get_weather',
        'description': 'Current weather for a city',
        'parameters': {
            'type': 'object',
            'properties': {
                'city': {'type': 'string'}
            },
            'required': ['city']
        }
    }
}]
import json
print(json.dumps(tools, indent=2))

Step 2: First Model Call

Send messages and tools:

response = client.chat.completions.create(
    model='gpt-4o-mini',
    messages=[{'role': 'user', 'content': 'Weather in Paris?'}],
    tools=tools,
)
message = response.choices[0].message
print(message.tool_calls)
# [ToolCall(name='get_weather', arguments='{"city": "Paris"}')]

Step 3: Execute the Tool

Dispatch to your Python function:

import json

def get_weather(city: str) -> dict:
    # ...call your weather API...
    return {'city': city, 'temp_c': 18, 'condition': 'cloudy'}

tool_call = message.tool_calls[0]
args = json.loads(tool_call.function.arguments)
result = get_weather(**args)

Step 4: Append the Tool Result

Add a tool message with the matching ID:

messages.append(message)  # the assistant message with tool_calls
messages.append({
    'role': 'tool',
    'tool_call_id': tool_call.id,
    'content': json.dumps(result)
})

Step 5: Second Model Call

Call the model again — now it has the tool result and produces a user-facing answer:

final = client.chat.completions.create(
    model='gpt-4o-mini',
    messages=messages,
    tools=tools,
)
print(final.choices[0].message.content)
# 'It is currently 18 degrees and cloudy in Paris.'

The Agent Loop

Wrap this in a while loop — the model may call several tools in sequence:

while True:
    response = client.chat.completions.create(model=MODEL, messages=messages, tools=tools)
    msg = response.choices[0].message
    messages.append(msg)
    if not msg.tool_calls:
        return msg.content  # final answer
    for tc in msg.tool_calls:
        result = dispatch(tc)
        messages.append({'role': 'tool', 'tool_call_id': tc.id, 'content': json.dumps(result)})

Parallel Tool Calls

Modern models return multiple tool_calls in one response. Run them in parallel where safe:

import asyncio

async def run_tools(tool_calls):
    coros = [dispatch_async(tc) for tc in tool_calls]
    return await asyncio.gather(*coros)

finish_reason: tool_calls

You can also check finish_reason instead of looking at tool_calls:

if response.choices[0].finish_reason == 'tool_calls':
    # the model wants to call tools
    ...
elif response.choices[0].finish_reason == 'stop':
    # done
    ...

Common Mistakes

  • Forgetting to append the assistant message before the tool result
  • Using the wrong tool_call_id
  • Sending tool results as user messages
  • Letting the loop run unbounded — set MAX_STEPS

Loop Termination

How do you know when the agent is done?

Recap

Function calling is the most important pattern in this entire course. Master it before moving on.

Frequently asked questions

Is the “How Function Calling Works” lesson free?

Yes — the full text of “How Function Calling Works” is free to read here on the web, and the AI Agents course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the AI Agents course, upgrade to CoddyKit PRO.

What will I learn in “How Function Calling Works”?

Understand the full round-trip: model picks a tool, your code runs it, you send the result back, and the model continues. You practise AI Agents with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.

Do I need any experience to start AI Agents?

No prior experience is required. AI Agents on CoddyKit is structured for beginners through advanced learners; this is — lesson 1 of 4, so you can start here or from the beginning and move at your own pace.

How long does the “How Function Calling Works” lesson take?

Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.

Can I write and run code in this AI Agents lesson?

Yes. Every AI Agents lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.

All lessons in this course

  1. How Function Calling Works
  2. Defining Tool Schemas (JSON Schema)
  3. Choosing Tools at Runtime
  4. Returning Results to the Model
← Back to AI Agents