# Step 3: Call the model
completion = client.chat.completions.create(
    model="gpt-4o",
    messages=[
        {"role": "user", "content": prompt}
    ],
)
```

This works, but only on a small scale. The model has to interpret the meaning of the data from plain text, which bloats token usage and loses structure.

To minimize token use and loss of structure, native toolchains emerged. Using toolchains such as OpenAI function calling, Anthropic tools, and Mistral functions, you can define structured input and output schemas, register tools, and let the model **call** them in a controlled way.

```python
from openai import OpenAI

client = OpenAI()

tools = [{
    "type": "function",
    "function": {
        "name": "query_user_count",
        "description": "Query the database to get the total number of users.",
        "parameters": {
            "type": "object",
            "properties": {
                "table": {
                    "type": "string",
                    "description": "Name of the table to query, e.g. 'users'"
                }
            },
            "required": ["table"],
            "additionalProperties": False
        }
    }
}]

response = client.chat.completions.create(
    model="gpt-4o",
    messages=[
        {
            "role": "user",
            "content": "How many users are currently in the system?"
        }
    ],
    tools=tools,
    tool_choice="auto"
)