Sari la conținut
Apelare funcții

Apelare funcții

Descrie-ți funcțiile în cerere, iar modelul răspunde cu apelurile pe care vrea să le facă. Codul tău le rulează și trimite rezultatele înapoi: API-ul returnează apeluri de instrumente și nu rulează el însuși un instrument.

POST https://api.shannon-ai.com/v1/chat/completions

Exemplele de pe această pagină folosesc /v1/chat/completions. Aceeași buclă rulează pe /v1/responses și /v1/messages; unde un format scrie ceva diferit, secțiunile de mai jos le arată pe toate trei.

import json
from openai import OpenAI

client = OpenAI(api_key="YOUR_API_KEY", base_url="https://api.shannon-ai.com/v1")

tools = [{
    "type": "function",
    "function": {
        "name": "get_weather",
        "description": "Get the current weather for a city.",
        "parameters": {
            "type": "object",
            "properties": {
                "city": {"type": "string", "description": "City name, for example Paris"},
                "unit": {"type": "string", "enum": ["celsius", "fahrenheit"]},
            },
            "required": ["city"],
        },
    },
}]

def get_weather(city, unit="celsius"):
    # Your code: ask a weather service here.
    return {"city": city, "temperature": 18, "unit": unit, "conditions": "cloudy"}

messages = [{"role": "user", "content": "What is the weather in Paris right now?"}]
answer = None

for _ in range(5):  # the API sets no limit on rounds: set your own
    response = client.chat.completions.create(
        model="Kimi-K3-3BIT-REAP",
        messages=messages,
        tools=tools,
    )
    choice = response.choices[0]
    if choice.finish_reason != "tool_calls":
        answer = choice.message.content
        break

    messages.append(choice.message)  # the assistant turn with its tool_calls
    for call in choice.message.tool_calls:
        args = json.loads(call.function.arguments)  # arguments is a JSON string
        result = get_weather(**args)
        messages.append({
            "role": "tool",
            "tool_call_id": call.id,
            "content": json.dumps(result),
        })

print(answer)

Primul răspuns nu răspunde la întrebare. Cere un apel:

200 JSON
{
  "id": "chatcmpl-5b0c1d8e7f6a4b3c9d2e1f0a8b7c6d5e",
  "object": "chat.completion",
  "created": 1791590400,
  "model": "Kimi-K3-3BIT-REAP",
  "choices": [
    {
      "index": 0,
      "message": {
        "role": "assistant",
        "content": null,
        "reasoning_content": "The user asks for the current weather in Paris. I should call get_weather.",
        "tool_calls": [
          {
            "id": "call_9f1c2ab34d5e4f60a7b8c9d0e1f2a3b4",
            "type": "function",
            "function": {
              "name": "get_weather",
              "arguments": "{\"city\":\"Paris\"}"
            }
          }
        ]
      },
      "finish_reason": "tool_calls"
    }
  ],
  "usage": {
    "prompt_tokens": 312,
    "completion_tokens": 58,
    "total_tokens": 370,
    "prompt_tokens_details": {"cached_tokens": 0},
    "completion_tokens_details": {"reasoning_tokens": 31}
  }
}

După ce trimiți rezultatul, următorul răspuns este un răspuns obișnuit: message.content conține textul, iar finish_reason este stop.

Bucla, pas cu pas

Pas Cine Ce se întâmplă
1 Tu Trimite messages împreună cu tools, lista funcțiilor pe care modelul le poate cere.
2 Model Răspunsul poartă tool_calls și finish_reason: "tool_calls". Fiecare apel numește o funcție și îi dă argumentele.
3 Tu Parsează arguments ale fiecărui apel și rulează funcția ta.
4 Tu Adaugă în messages mesajul asistentului și câte un mesaj tool pentru fiecare apel, apoi trimite din nou cererea cu aceleași tools.
5 Model Modelul răspunde în text cu finish_reason: "stop" sau cere alte apeluri. În acest caz, întoarce-te la pasul 3.

O cerere este o rundă a modelului. API-ul nu păstrează nicio conversație între cereri și nu stabilește un număr de runde: codul tău ține messages și decide când se oprește.

Definirea instrumentelor

tools este o matrice cu câte o intrare pentru fiecare funcție. Fiecare model din catalog o acceptă; GET /v1/models raportează capabilities.tools: true pentru fiecare id.

Câmp Tip Descriere
type string Întotdeauna function.
function.name string Numele pe care îl folosește modelul când cere această funcție. Obligatoriu.
function.description string Ce face funcția, în limbaj simplu.
function.parameters object Argumentele ca JSON Schema, cu type: "object" la nivelul de sus. Vezi Cuvinte-cheie de schemă mai jos.

Fiecare endpoint are propria scriere a unui instrument. Trimite-o pe cea care aparține endpoint-ului pe care îl apelezi:

{
  "type": "function",
  "function": {
    "name": "get_weather",
    "description": "Get the current weather for a city.",
    "parameters": {
      "type": "object",
      "properties": {
        "city": {
          "type": "string",
          "description": "City name, for example Paris"
        },
        "unit": {"type": "string", "enum": ["celsius", "fahrenheit"]}
      },
      "required": ["city"]
    }
  }
}

tool_choice

tool_choice spune dacă modelul poate sau trebuie să apeleze un instrument. Este citit doar împreună cu tools.

Valoare Descriere Aplicat de
"auto" Modelul decide dacă răspunde în text sau apelează un instrument. Aceasta este valoarea implicită. Toate modelele
"required" Răspunsul apelează cel puțin un instrument. Modele open-weight găzduite
{"type": "function", "function": {"name": "get_weather"}} Răspunsul apelează această funcție. Numele trebuie să fie al uneia dintre funcțiile din tools. Apelurile către alte funcții sunt omise din răspuns. Modele open-weight găzduite

Modelele Shannon (shannon-*) decid la fiecare cerere, ca la auto.

Cu required sau cu o funcție numită, citește finish_reason înainte de tool_calls. Când modelul nu produce niciun apel, răspunsul este un răspuns text cu finish_reason: "stop".

Semnificație /v1/chat/completions /v1/responses /v1/messages
Modelul decide "auto" "auto" {"type": "auto"}
Apelează cel puțin un instrument "required" "required" {"type": "any"}
Apelează o funcție numită {"type": "function", "function": {"name": "get_weather"}} {"type": "function", "name": "get_weather"} {"type": "tool", "name": "get_weather"}

Acceptate pentru compatibilitate: tool_choice: "none" și parallel_tool_calls. Pentru o rundă fără apeluri de instrumente, trimite cererea fără tools.

Apeluri de instrumente în răspuns

Câmp Tip Descriere
finish_reason string tool_calls când răspunsul conține cel puțin un apel.
message.tool_calls array O intrare pentru fiecare apel. Câmpul este prezent doar când modelul a cerut un apel.
tool_calls[].id string call_ urmat de 32 de caractere hexazecimale. Trimite-l înapoi ca tool_call_id împreună cu rezultatul.
tool_calls[].type string Întotdeauna function.
tool_calls[].function.name string Funcția de rulat.
tool_calls[].function.arguments string Argumentele ca șir JSON, "{}" când nu există. Parsează-l înainte de utilizare.
message.content string | null null când răspunsul conține doar apeluri. Modelele open-weight găzduite pot returna text alături de apeluri; modelele Shannon returnează null.

Același apel în fiecare format. Pe /v1/responses este un element function_call din output, cu arguments ca șir JSON. Pe /v1/messages este un bloc de conținut tool_use al cărui input este un obiect JSON, id începe cu toolu_, iar stop_reason este tool_use.

{
  "finish_reason": "tool_calls",
  "message": {
    "role": "assistant",
    "content": null,
    "tool_calls": [
      {
        "id": "call_9f1c2ab34d5e4f60a7b8c9d0e1f2a3b4",
        "type": "function",
        "function": {
          "name": "get_weather",
          "arguments": "{\"city\":\"Paris\"}"
        }
      }
    ]
  }
}

Mai multe apeluri într-o rundă

Un răspuns poate purta mai multe apeluri. Rulează-le pe toate și trimite câte un rezultat pentru fiecare apel, fiecare cu propriul tool_call_id, în cererea următoare.

Modelele open-weight găzduite returnează fiecare apel distinct o singură dată: două apeluri cu același nume și aceleași argumente sosesc ca unul.

Apeluri de instrumente în streaming

Cu stream: true, un apel sosește dintr-o bucată: chunk-ul conține șirul arguments complet, deci nu există fragmente de unit. index numără apelurile rundei începând de la 0.

data: un chunk, formatat
{
  "id": "chatcmpl-5b0c1d8e7f6a4b3c9d2e1f0a8b7c6d5e",
  "object": "chat.completion.chunk",
  "created": 1791590400,
  "model": "Kimi-K3-3BIT-REAP",
  "choices": [
    {
      "index": 0,
      "delta": {
        "tool_calls": [
          {
            "index": 0,
            "id": "call_9f1c2ab34d5e4f60a7b8c9d0e1f2a3b4",
            "type": "function",
            "function": {
              "name": "get_weather",
              "arguments": "{\"city\":\"Paris\"}"
            }
          }
        ]
      },
      "finish_reason": null
    }
  ]
}
Endpoint Ce sosește
/v1/chat/completions Un chat.completion.chunk pentru fiecare apel, cu apelul în delta.tool_calls[0]. Ultimul chunk are finish_reason: "tool_calls" și usage.
/v1/responses Pentru fiecare apel: response.output_item.added (un element function_call cu arguments goale), response.function_call_arguments.delta (întregul șir), response.function_call_arguments.done, response.output_item.done.
/v1/messages Pentru fiecare apel: content_block_start (un bloc tool_use cu input gol), un content_block_delta al cărui input_json_delta.partial_json este întregul text al argumentelor, content_block_stop. message_delta poartă apoi stop_reason: "tool_use".

Pe shannon-1.6-lite, shannon-1.6-pro, shannon-2-lite, shannon-2-pro și shannon-coder-1, o cerere cu streaming care poartă tools livrează textul răspunsului într-un singur delta content la sfârșitul rundei. Streaming

Trimiterea rezultatelor înapoi

A doua cerere repetă conversația și adaugă două lucruri: runda asistentului care a cerut apelurile și câte un rezultat pentru fiecare apel.

{
  "messages": [
    {"role": "user", "content": "What is the weather in Paris right now?"},
    {
      "role": "assistant",
      "content": null,
      "tool_calls": [
        {
          "id": "call_9f1c2ab34d5e4f60a7b8c9d0e1f2a3b4",
          "type": "function",
          "function": {
            "name": "get_weather",
            "arguments": "{\"city\":\"Paris\"}"
          }
        }
      ]
    },
    {
      "role": "tool",
      "tool_call_id": "call_9f1c2ab34d5e4f60a7b8c9d0e1f2a3b4",
      "content": "{\"city\":\"Paris\",\"temperature\":18,\"unit\":\"celsius\",\"conditions\":\"cloudy\"}"
    }
  ]
}
  • Trimite înapoi runda asistentului așa cum ai primit-o, înaintea rezultatelor. Fiecare rezultat este asociat apelului său prin id: tool_call_id pe /v1/chat/completions, call_id pe /v1/responses, tool_use_id pe /v1/messages.
  • Un rezultat este text. Serializează un obiect într-un șir JSON pentru content (output pe /v1/responses). Pe /v1/messages, content al unui bloc tool_result este un șir de caractere sau o listă de blocuri de text.
  • În runda asistentului, function.arguments rămâne un șir JSON, exact așa cum a sosit.
  • Conversația se poate încheia cu un rezultat de instrument. Nu este nevoie de un mesaj nou al utilizatorului: modelul continuă de la rezultat.
  • Când funcția ta eșuează, trimite eșecul ca text al rezultatului. Modelul îl poate raporta sau poate cere alt apel.

Cuvinte-cheie de schemă

parameters (input_schema pe /v1/messages) este o schemă JSON Schema. Familia Shannon 3 (shannon-3, shannon-3-pro, shannon-3.1, shannon-3.1-pro) și modelele open-weight găzduite o primesc așa cum o trimiți.

shannon-1.6-lite, shannon-1.6-pro, shannon-2-lite, shannon-2-pro și shannon-coder-1 primesc acest subset, pe toate cele trei endpoint-uri:

Tratament Cuvinte-cheie
Citite așa cum sunt trimise Fiecare cuvânt-cheie care nu este numit în rândurile de mai jos, de exemplu type, properties, required, items, enum, description, minimum, maximum, anyOf și allOf, la fiecare nivel al schemei.
format Citit pentru valorile int32, int64, float, double, byte, date, date-time și enum.
oneOf Citit ca anyOf.
Nu fac parte din schema pe care o primesc aceste modele $schema, $id, $ref, $defs, $comment, definitions, additionalProperties, unevaluatedProperties, patternProperties, propertyNames, examples, default, title, const, not, if, then, else, contains, minContains, maxContains, dependentRequired, dependentSchemas, dependencies, readOnly, writeOnly, deprecated, contentEncoding, contentMediaType, contentSchema, multipleOf, uniqueItems; exclusiveMinimum și exclusiveMaximum când sunt numere; alte valori ale format.

Comportament și limite

  • API-ul nu stabilește un număr maxim de instrumente și nici un număr maxim de runde.
  • Corpul unei cereri poate avea până la 32 MiB, iar conversația cu rezultatele ei trebuie să încapă în fereastra de context a modelului.
  • Când o cerere poartă tools, shannon-1.6-lite, shannon-1.6-pro, shannon-2-lite și shannon-2-pro folosesc un temperature implicit de 0.2. Trimite temperature pentru a seta altă valoare.
  • Fiecare rundă este o cerere de sine stătătoare: consumă din soldul tău și se numără la protecția anti-flood ca orice altă cerere. Limite și sold

Erori

Un apel de instrument este un răspuns normal cu starea 200. Aceste erori privesc cererea în sine:

Stare Tip Mesaj Când
400 invalid_request_error unknown model: <id> model nu este un id din lista publicată.
422 invalid_request_error Failed to deserialize the JSON body into the target type: … tools nu este o matrice sau un alt câmp are tipul JSON greșit.
413 invalid_request_error Failed to buffer the request body: … Corpul cererii este mai mare de 32 MiB. Eroarea poartă code: "request_too_large".

Modelul scrie argumentele. Verifică-le în raport cu schema ta înainte să rulezi funcția, așa cum ai verifica orice intrare din exterior.

Erorile de autentificare, de sold și de server sunt aceleași ca pentru orice cerere. Gestionare erori