Skip to content
Fondazione ITS INCOM

Examples · Programming

Let the model call your functions

Give Qwen3.6 two Python functions with the school timetable. The model decides which ones to call and with what arguments, your code runs them, and the model writes the answer.

Advanced · 45 min

The idea

A model knows nothing about your timetable, your database or the weather today. But you can give it tools: you describe your functions, the model answers “call this one, with these arguments”, your program runs it and gives back the result. This is how assistants book rooms, read calendars and open tickets.

The model

Qwen3.6 35B (qwen3.6-35b). Tools work also with gemma-4-26b, ministral-3-14b and qwen3-coder-30b.

What you need

A key and the openai library, as in Your first API call in Python.

The program

import json
import os

from openai import OpenAI

client = OpenAI(
    base_url="https://api.ai.itsincom.org/v1",
    api_key=os.environ["API_KEY"],
)

TIMETABLE = {
    ("Cloud & Cybersecurity", "monday"): [("09:00", "Networks", "Lab 2"), ("14:00", "Linux", "Room 5")],
    ("Cloud & Cybersecurity", "tuesday"): [("09:00", "Security", "Lab 2")],
    ("Programming", "monday"): [("09:00", "Python", "Lab 1"), ("14:00", "Databases", "Lab 1")],
    ("Programming", "tuesday"): [("10:00", "Web", "Lab 1")],
}
TEACHERS = {"Networks": "Prof. Rossi", "Linux": "Prof. Bianchi", "Security": "Prof. Verdi",
            "Python": "Prof. Neri", "Databases": "Prof. Neri", "Web": "Prof. Gallo"}


def get_timetable(course, day):
    lessons = TIMETABLE.get((course, day), [])
    return [{"time": t, "subject": s, "room": r} for t, s, r in lessons]


def get_teacher(subject):
    return {"subject": subject, "teacher": TEACHERS.get(subject, "unknown")}


FUNCTIONS = {"get_timetable": get_timetable, "get_teacher": get_teacher}

tools = [
    {"type": "function", "function": {
        "name": "get_timetable",
        "description": "The lessons of a course on a day of the week: time, subject and room.",
        "parameters": {
            "type": "object",
            "properties": {
                "course": {"type": "string", "enum": ["Cloud & Cybersecurity", "Programming"]},
                "day": {"type": "string", "enum": ["monday", "tuesday", "wednesday", "thursday", "friday"]},
            },
            "required": ["course", "day"],
        },
    }},
    {"type": "function", "function": {
        "name": "get_teacher",
        "description": "The teacher of a subject.",
        "parameters": {
            "type": "object",
            "properties": {"subject": {"type": "string"}},
            "required": ["subject"],
        },
    }},
]

messages = [{"role": "user", "content": "I'm in Cloud & Cybersecurity. What do I have on Monday, "
                                        "where, and who teaches the first lesson?"}]

for _ in range(5):
    answer = client.chat.completions.create(model="qwen3.6-35b", messages=messages, tools=tools)
    message = answer.choices[0].message
    if not message.tool_calls:
        print(message.content)
        break
    messages.append(message.model_dump(exclude_none=True))
    for call in message.tool_calls:
        args = json.loads(call.function.arguments)
        print(f"  the model calls {call.function.name}({args})")
        result = FUNCTIONS[call.function.name](**args)
        messages.append({"role": "tool", "tool_call_id": call.id, "content": json.dumps(result)})

What you should see

  the model calls get_timetable({'course': 'Cloud & Cybersecurity', 'day': 'monday'})
  the model calls get_teacher({'subject': 'Networks'})
On Monday you have Networks at 09:00 in Lab 2, with Prof. Rossi, and Linux at 14:00 in Room 5.

The model never runs anything: it only asks. Your code decides whether to run the function. Never let a model call a function that deletes, pays or sends without a check by a person.

Exercise

All examples