Panoramica del function calling e la necessità di quattro adattatori

Il function calling consente a un modello di linguaggio di richiedere l’esecuzione di un tool, leggere il risultato e continuare l’elaborazione. Tutti i principali fornitori offrono questa funzionalità, ma i formati delle richieste differiscono nei dettagli che spesso rompono il codice.

Il 27 ottobre 2026 i quattro modelli più recenti che è probabile tu voglia integrare sono GPT‑6.1 Sol (API Responses), Claude Sonnet 5.5 (API Messages di Anthropic), Gemini 4 Argon (Google generate_content) e DeepSeek deepseek‑flash (endpoint stile chat‑completions). Questa tutorial costruisce un unico strato Python, chiamato toolbridge, che dichiara ogni tool una sola volta e comunica con tutti e quattro.

Indice dei contenuti

Come funziona il function calling e perché servono quattro adattatori

Ogni scambio di function calling segue cinque fasi:

    • Invii al modello un prompt più una lista di dichiarazioni di tool (nome, descrizione, JSON Schema).
    • Il modello risponde con testo, una o più chiamate a tool, oppure entrambi.
    • Il tuo codice valida gli argomenti e avvia il tool.
    • Il risultato viene restituito al modello, associato alla chiamata originale.
    • Il modello legge il risultato e decide se richiedere un altro tool o produrre la risposta finale. Il loop termina quando la risposta non contiene più chiamate a tool.

Questo ciclo è alla base di tutti gli “agent” AI moderni. Il Stack Overflow Developer Survey 2025 indica che il 31 % degli intervistati usa già agenti AI al lavoro, e il 69 % di questi ha registrato un aumento di produttività. Anche se i dati sono del 2025, mostrano la rilevanza del pattern.

I fornitori differiscono nella struttura del payload. Nessuno standard universale è stato adottato per questi quattro modelli (al 27 ottobre 2026), e nessuna documentazione ufficiale afferma che accettano lo stesso payload senza modifiche. La tabella seguente riassume le differenze chiave, basata sulle forme SDK usate dagli adattatori della guida.

ProviderStile endpointDichiarazione toolChiamata ricevuta comeRisultato restituito come
OpenAI (GPT‑6.1 Sol)responses.createOggetto flat: type, name, parametersfunctioncall con stringa JSON arguments, callidfunctioncalloutput item
Anthropic (Sonnet 5.5)messages.createname, description, inputschemaBlocco tooluse con dizionario inputBlocco tool_result all’interno di un messaggio utente
Google (Gemini 4 Argon)models.generatecontentFunctionDeclaration con parametersjsonschemaParte functioncall, dizionario args, ID può mancareParte function_response che corrisponde alla chiamata
DeepSeek (Flash)Chat‑completions styleStruttura function simile a OpenAI ma con campi parameters nidificatiElemento functioncall con arguments stringaElemento functionoutput con content

I quattro modelli al 27 ottobre 2026

1. GPT‑6.1 Sol – ultima iterazione della famiglia GPT di OpenAI, disponibile tramite l’API Responses.

2. Claude Sonnet 5.5 – modello di Anthropic con capacità di ragionamento avanzato, accessibile tramite l’API Messages.

3. Gemini 4 Argon – modello di Google lanciato a prezzo introduttivo di 2 $ per milione di token in ingresso e 10 $ per milione di token in uscita, valido fino al 30 novembre 2026; da dicembre il prezzo raddoppia a 4 $ e 20 $ rispettivamente.

4. DeepSeek Flash – modello cinese di nuova generazione, offerto con endpoint simile a chat‑completions.

Prerequisiti e versioni

Assicurati di avere:

    • Python 3.12.3 o superiore.
    • Virtualenv o venv attivo.
    • Le SDK ufficiali più recenti:
      • openai ≥ 1.2.0
      • anthropic ≥ 0.5.0
      • google‑generativeai ≥ 0.4.0
      • deepseek-sdk ≥ 0.1.3
    • Un file .env con le chiavi API per tutti i provider.

Step 1‑2: Creare il progetto e i tipi neutri

Step 1: Scaffold della cartella e ambiente virtuale

Crea una directory toolbridge e al suo interno un virtual environment:

mkdir toolbridge && cd toolbridge

python -m venv venv

source venv/bin/activate

pip install -r requirements.txt

Il file requirements.txt includerà tutte le SDK sopra elencate più pydantic per la validazione.

Step 2: Definire i tipi di messaggio neutri

Usa pydantic.BaseModel per creare classi comuni che rappresentano:

    • Message (role, content)
    • ToolDeclaration (name, description, json_schema)
    • ToolCall (id, name, arguments)
    • ToolResult (callid, result, iserror)

Questi tipi saranno condivisi da tutti gli adattatori, evitando duplicazioni.

Step 3‑4: Dichiarare gli strumenti una sola volta con validazione

Step 3: Costruire il registro che valida e esegue gli strumenti

Implementa una classe ToolRegistry che:

    • Registra funzioni Python come tool, associando nome e schema.
    • Convalida gli argomenti ricevuti usando jsonschema.
    • Esegue la funzione e restituisce il risultato o un errore.

Step 4: Scrivere gli strumenti demo

Per la demo includi tre tool semplici:

    • getcurrenttime – restituisce data e ora ISO.
    • calculate_sum – accetta una lista di numeri e restituisce la somma.
    • fetch_url – effettua una GET HTTP a un URL fornito (con timeout 3 s).

Ciascuno è decorato con @tool_registry.register e ha un JSON Schema corrispondente.

Step 5‑8: Scrivere gli adattatori per i quattro provider

Step 5: Adattatore OpenAI Responses per GPT‑6.1 Sol

L’adattatore converte i Message neutri in openai.responses.create payload, includendo le dichiarazioni di tool nel campo functions. La risposta viene analizzata per estrarre function_call, convertita in ToolCall e inviata al registro.

Step 6: Adattatore Anthropic Messages per Claude Sonnet 5.5

Qui le dichiarazioni di tool vanno nel campo tooldefinitions. Le chiamate arrivano come blocchi tooluse; l’adattatore li trasforma in ToolCall. I risultati sono inseriti in messaggi tool_result all’interno di un nuovo messaggio utente.

Step 7: Adattatore Gemini per Gemini 4 Argon

L’API di Google richiede un oggetto FunctionDeclaration. Le chiamate sono parti functioncall del risultato di generatecontent. L’adattatore gestisce l’eventuale assenza di ID generando un UUID locale.

Step 8: Adattatore DeepSeek e factory dei provider

L’adattatore DeepSeek segue lo schema OpenAI ma con parameters nidificati. Per semplificare l’uso, è stata creata una ProviderFactory che restituisce l’adattatore corretto in base a una stringa (openai, anthropic, google, deepseek).

Step 9‑10: Loop dell’agente e calcolo dei costi

Step 9: Scrivere il loop

Il loop principale:

    • Costruisce il payload con i messaggi correnti e le dichiarazioni di tool.
    • Chiama l’adattatore selezionato.
    • Se la risposta contiene ToolCall, valida, esegue il tool e aggiunge ToolResult ai messaggi.
    • Ripete fino a quando non ci sono più chiamate a tool.

Il loop è implementato in agent_loop.py ed è completamente asincrono per supportare chiamate I/O non bloccanti.

Step 10: Aggiungere il ledger dei costi

Ogni provider restituisce token usage (prompttokens, completiontokens). Il ledger registra:

    • Data e ora della chiamata.
    • Provider usato.
    • Numero di token in ingresso/uscita.
    • Tariffa applicata (considerando la promozione Gemini fino al 30 novembre).
    • Costo totale cumulativo.

Il ledger è salvato in costlog.json e può essere visualizzato con lo script showcosts.py.

Step 11‑12: Test offline

Step 11: Aggiungere un provider simulato

Per i test è stato creato MockProvider che risponde con JSON predefiniti, simulando le quattro API senza effettuare chiamate di rete.

Step 12: Scrivere ed eseguire la suite di test

La suite, basata su pytest, comprende 11 test che coprono:

    • Validazione schema degli strumenti.
    • Parsing corretto delle chiamate per ogni provider.
    • Loop completo con due chiamate a tool consecutive.
    • Calcolo dei costi in scenari di prezzo variabile.

Tutti i test passano in 0,15 secondi su Python 3.12.3.

Step 13: Smoke test live con le tue chiavi

L’ultimo step è eseguire il loop contro i veri endpoint usando le chiavi API presenti in .env. Il comando è:

python run_agent.py --provider openai --model gpt-6.1-sol

Sostituisci openai con anthropic, google o deepseek per testare gli altri provider. Il risultato mostrerà il log dei costi e confermerà che gli adattatori gestiscono correttamente le risposte reali.

Errori comuni che rompono il tool calling cross‑provider

Le differenze più frequenti includono:

    • Nome dei campi: OpenAI usa functioncall, Anthropic tooluse, Google function_call ma senza ID.
    • Formato degli argomenti: alcuni provider inviano una stringa JSON, altri un dizionario nativo.
    • Limiti di lunghezza: Gemini accetta al massimo 8 KB per dichiarazione di tool.
    • Gestione degli errori: DeepSeek restituisce un campo error separato, mentre gli altri includono il messaggio di errore nel risultato del tool.

Nove errori tipici e le loro soluzioni

    • Argument parsing fails (JSONDecodeError) – Usa json.loads con strict=False e valida con jsonschema prima di eseguire.
    • Missing call_id in Gemini response – Genera un UUID locale e memorizzalo nel registro.
  1. Tool schema mismatch – Verifica che il JSON Schema sia compatibile con la versione di
    Lire l'article original →
    ← Retour aux actualités