Tool calling și Structured Outputs pe Groq: tools, tool_choice și json_schema în Groq: LPU și GroqCloud API

Funcții și JSON GroqCloud API (octombrie 2026)

Pe Groq, modelul poate cere apelarea funcțiilor tale (tool calling) și poate răspunde într-o schemă JSON garantată prin json_schema cu strict: true, pe modelele care acceptă decodare constrânsă.

Sintaxă & invocare
tools=[{"type": "function", "function": {...}}], tool_choice="auto"
response_format={"type": "json_schema", "json_schema": {"name": ..., "strict": True, "schema": {...}}}

Groq acceptă trei moduri de folosire a uneltelor: unelte built-in executate de Groq, servere MCP la distanță (vezi Responses API și MCP) și tool calling local. La cel local, trimiți definițiile în tools (nume, descriere, parametri ca JSON Schema), modelul întoarce tool_calls cu id, function.name și function.arguments (un șir JSON pe care îl parsezi), codul tău execută funcția și trimite rezultatul ca mesaj cu role: "tool" și același tool_call_id. Bucla continuă până când modelul nu mai cere unelte.

Toate modelele găzduite acceptă tool use, dar apelurile paralele (mai multe tool_calls într-un răspuns) nu sunt acceptate de GPT-OSS 20B, GPT-OSS 120B și GPT-OSS-Safeguard 20B; le acceptă, de exemplu, qwen/qwen3.8-27b. tool_choice poate fi auto (implicit), required, none sau o funcție anume. Dacă modelul nu respectă alegerea sau generează un apel invalid, API-ul întoarce 400, cu textul generat în failed_generation; documentația recomandă reîncercarea cu temperatură mai mică.

Structured Outputs (response_format cu type: "json_schema") are două moduri. Cu strict: true, decodarea constrânsă garantează că răspunsul respectă schema; este disponibil pe openai/gpt-oss-20b, openai/gpt-oss-120b, qwen/qwen3.8-27b și meta-models/muse-spark-open și cere ca toate câmpurile să fie în required, iar fiecare obiect să aibă additionalProperties: false (câmpurile opționale se scriu ca uniune cu null). Cu strict: false (implicit), schema este respectată de obicei, dar pot apărea erori 400. Streaming-ul și tool use nu sunt acceptate împreună cu Structured Outputs. JSON Object Mode ({"type": "json_object"}) dă doar JSON valid sintactic, fără schemă, și cere instrucțiuni explicite de JSON în prompt.

Concepte cheie și caracteristici

Concept / Parametru Descriere practică
tools Lista funcțiilor: type: "function", name, description, parameters (JSON Schema).
tool_choice="auto" Implicit; modelul decide dacă apelează o unealtă.
tool_choice="required" Cel puțin un apel; altfel 400.
tool_choice="none" Fără apeluri; unele modele pot încerca totuși, caz în care primești 400.
tool_choice={"type": "function", "function": {"name": ...}} Obligă apelul unei funcții anume.
parallel_tool_calls Implicit true; are efect doar pe modelele care acceptă apeluri paralele.
role: "tool", tool_call_id Mesajul cu rezultatul funcției, legat de id-ul apelului.
response_format json_schema, strict: true Schemă garantată prin decodare constrânsă (GPT-OSS 20B / 120B, Qwen 3.8 27B, Muse Spark Open).
response_format json_schema, strict: false Best-effort; poate întoarce 400 „Generated JSON does not match the expected schema”.
response_format json_object JSON valid, fără schemă; promptul trebuie să ceară JSON.
failed_generation Câmpul din eroarea 400 cu apelul invalid generat de model.

Exemple practice și scenarii reale

Exemplul 1: Bucla completă de tool calling local

import json
from groq import Groq

client = Groq()
MODEL = "openai/gpt-oss-120b"

def verifica_stoc(cod_sku, cantitate=1):
    stoc = {"PROD-8899": 3}                      # în realitate: interogare în baza de date
    disponibil = stoc.get(cod_sku, 0)
    return {"cod_sku": cod_sku, "disponibil": disponibil, "suficient": disponibil >= cantitate}

unelte = [{
    "type": "function",
    "function": {
        "name": "verifica_stoc",
        "description": "Verifică stocul unui produs după codul SKU.",
        "parameters": {
            "type": "object",
            "properties": {
                "cod_sku": {"type": "string", "description": "Codul produsului, de exemplu PROD-8899"},
                "cantitate": {"type": "integer", "description": "Bucăți cerute"},
            },
            "required": ["cod_sku"],
        },
    },
}]
functii = {"verifica_stoc": verifica_stoc}
mesaje = [{"role": "user", "content": "Mai avem 5 bucăți din PROD-8899?"}]

for _ in range(5):                                   # limită de iterații
    r = client.chat.completions.create(model=MODEL, messages=mesaje, tools=unelte, tool_choice="auto")
    msg = r.choices[0].message
    if not msg.tool_calls:
        print(msg.content)
        break
    mesaje.append(msg)
    for apel in msg.tool_calls:
        argumente = json.loads(apel.function.arguments)
        rezultat = functii[apel.function.name](**argumente)
        mesaje.append({"role": "tool", "tool_call_id": apel.id, "content": json.dumps(rezultat)})

Exemplul 2: Schemă JSON garantată (strict: true)

r = client.chat.completions.create(
    model="openai/gpt-oss-20b",
    messages=[
        {"role": "system", "content": "Extrage datele recenziei."},
        {"role": "user", "content": "Am cumpărat căștile X200. Bateria ține o zi, sunetul e clar. Nota mea: 4 din 5."},
    ],
    response_format={
        "type": "json_schema",
        "json_schema": {
            "name": "recenzie",
            "strict": True,
            "schema": {
                "type": "object",
                "properties": {
                    "produs": {"type": "string"},
                    "nota": {"type": "number"},
                    "pret": {"type": ["number", "null"]},
                },
                "required": ["produs", "nota", "pret"],
                "additionalProperties": False,
            },
        },
    },
)
date = json.loads(r.choices[0].message.content)

Exemplul 3: JSON Object Mode, fără schemă

r = client.chat.completions.create(
    model="openai/gpt-oss-20b",
    messages=[
        {"role": "system", "content": "Răspunzi doar cu un obiect JSON cu cheile sentiment și scor."},
        {"role": "user", "content": "Livrarea a întârziat trei zile."},
    ],
    response_format={"type": "json_object"},
)

Greșeli frecvente și capcane

  • Aștepți mai multe tool_calls într-un singur răspuns de la GPT-OSS. Aceste modele nu acceptă apeluri paralele; modelul cere unealta de mai multe ori, în pași succesivi.
  • Folosești strict: true cu o schemă care are câmpuri opționale sau fără additionalProperties: false. Cererea este respinsă; scrie câmpurile opționale ca uniune cu null.
  • Combini response_format json_schema cu stream=True sau cu tools. Combinația nu este acceptată.
  • Execuți argumentele primite de la model fără validare. Verifică tipurile și valorile înainte de a atinge baza de date sau un API extern.

Noțiuni și module înrudite