Przejdź do treści
Wywołanie funkcji

Wywołanie funkcji

Opisz swoje funkcje w zapytaniu, a model odpowie wywołaniami, które chce wykonać. Twój kod je uruchamia i odsyła wyniki: API zwraca wywołania narzędzi i samo nie uruchamia żadnego narzędzia.

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

Przykłady na tej stronie używają /v1/chat/completions. Ta sama pętla działa w /v1/responses i /v1/messages; tam, gdzie format zapisuje coś inaczej, sekcje poniżej pokazują wszystkie trzy.

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)

Pierwsza odpowiedź nie odpowiada na pytanie. Prosi o wywołanie:

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}
  }
}

Po wysłaniu wyniku następna odpowiedź jest zwykłą odpowiedzią: message.content zawiera tekst, a finish_reason to stop.

Pętla krok po kroku

Krok Kto Co się dzieje
1 Ty Wyślij messages razem z tools, czyli listą funkcji, o które model może poprosić.
2 Model Odpowiedź niesie tool_calls i finish_reason: "tool_calls". Każde wywołanie podaje nazwę funkcji i jej argumenty.
3 Ty Sparsuj arguments każdego wywołania i uruchom swoją funkcję.
4 Ty Dopisz do messages wiadomość asystenta i po jednej wiadomości tool na wywołanie, a potem wyślij zapytanie ponownie z tymi samymi tools.
5 Model Model odpowiada tekstem z finish_reason: "stop" albo prosi o kolejne wywołania. W takim razie wróć do kroku 3.

Jedno zapytanie to jedna tura modelu. API nie przechowuje rozmowy między zapytaniami i nie ustala liczby rund: to Twój kod trzyma messages i decyduje, kiedy skończyć.

Definiowanie narzędzi

tools to tablica z jedną pozycją na funkcję. Przyjmuje ją każdy model katalogu; GET /v1/models raportuje capabilities.tools: true dla każdego id.

Pole Typ Opis
type string Zawsze function.
function.name string Nazwa, której model używa, prosząc o tę funkcję. Wymagana.
function.description string Co robi funkcja, prostym językiem.
function.parameters object Argumenty jako JSON Schema z type: "object" na górze. Zobacz niżej Słowa kluczowe schematu.

Każdy endpoint ma własny zapis narzędzia. Wyślij ten, który należy do wywoływanego endpointu:

{
  "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 mówi, czy model może, czy musi wywołać narzędzie. Jest odczytywane tylko razem z tools.

Wartość Opis Stosowane przez
"auto" Model decyduje, czy odpowiedzieć tekstem, czy wywołać narzędzie. To ustawienie domyślne. Wszystkie modele
"required" Odpowiedź wywołuje co najmniej jedno narzędzie. Hostowane modele open-weight
{"type": "function", "function": {"name": "get_weather"}} Odpowiedź wywołuje tę funkcję. Nazwa musi być jedną z funkcji w tools. Wywołania innych funkcji są pomijane w odpowiedzi. Hostowane modele open-weight

Modele Shannon (shannon-*) decydują w każdym zapytaniu, jak przy auto.

Przy required lub nazwanej funkcji odczytaj finish_reason, zanim odczytasz tool_calls. Gdy model nie utworzy wywołania, odpowiedzią jest tekst z finish_reason: "stop".

Znaczenie /v1/chat/completions /v1/responses /v1/messages
Model decyduje "auto" "auto" {"type": "auto"}
Wywołaj co najmniej jedno narzędzie "required" "required" {"type": "any"}
Wywołaj jedną nazwaną funkcję {"type": "function", "function": {"name": "get_weather"}} {"type": "function", "name": "get_weather"} {"type": "tool", "name": "get_weather"}

Akceptowane dla zgodności: tool_choice: "none" i parallel_tool_calls. Dla tury bez wywołań narzędzi wyślij zapytanie bez tools.

Wywołania narzędzi w odpowiedzi

Pole Typ Opis
finish_reason string tool_calls, gdy odpowiedź niesie co najmniej jedno wywołanie.
message.tool_calls array Jedna pozycja na wywołanie. Pole jest obecne tylko wtedy, gdy model poprosił o wywołanie.
tool_calls[].id string call_ i 32 znaki szesnastkowe. Odeślij go jako tool_call_id razem z wynikiem.
tool_calls[].type string Zawsze function.
tool_calls[].function.name string Funkcja do uruchomienia.
tool_calls[].function.arguments string Argumenty jako ciąg JSON, "{}", gdy ich nie ma. Sparsuj go przed użyciem.
message.content string | null null, gdy odpowiedź zawiera tylko wywołania. Hostowane modele open-weight mogą zwrócić tekst obok wywołań; modele Shannon zwracają null.

To samo wywołanie w każdym formacie. W /v1/responses jest to element function_call w output, z arguments jako ciągiem JSON. W /v1/messages jest to blok treści tool_use, którego input jest obiektem JSON, jego id zaczyna się od toolu_, a stop_reason to 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\"}"
        }
      }
    ]
  }
}

Kilka wywołań w jednej turze

Odpowiedź może nieść kilka wywołań. Uruchom każde z nich i w następnym zapytaniu odeślij po jednym wyniku na wywołanie, każdy z własnym tool_call_id.

Hostowane modele open-weight zwracają każde odrębne wywołanie raz: dwa wywołania z tą samą nazwą i tymi samymi argumentami przychodzą jako jedno.

Wywołania narzędzi w streamingu

Z stream: true wywołanie przychodzi w jednym kawałku: fragment zawiera kompletny ciąg arguments, więc nie ma fragmentów do łączenia. index liczy wywołania tury od 0.

data: jeden fragment, sformatowany
{
  "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 Co przychodzi
/v1/chat/completions Jeden chat.completion.chunk na wywołanie, z wywołaniem w delta.tool_calls[0]. Ostatni fragment ma finish_reason: "tool_calls" i usage.
/v1/responses Na wywołanie: response.output_item.added (element function_call z pustymi arguments), response.function_call_arguments.delta (cały ciąg), response.function_call_arguments.done, response.output_item.done.
/v1/messages Na wywołanie: content_block_start (blok tool_use z pustym input), jedno content_block_delta, którego input_json_delta.partial_json jest całym tekstem argumentów, content_block_stop. Następnie message_delta niesie stop_reason: "tool_use".

W shannon-1.6-lite, shannon-1.6-pro, shannon-2-lite, shannon-2-pro i shannon-coder-1 zapytanie w streamingu, które niesie tools, dostarcza tekst odpowiedzi w jednej delcie content na końcu tury. Streaming

Odsyłanie wyników

Drugie zapytanie powtarza rozmowę i dodaje dwie rzeczy: turę asystenta, która poprosiła o wywołania, oraz po jednym wyniku na wywołanie.

{
  "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\"}"
    }
  ]
}
  • Odeślij turę asystenta tak, jak ją otrzymałeś, przed wynikami. Każdy wynik jest dopasowywany do swojego wywołania po id: tool_call_id w /v1/chat/completions, call_id w /v1/responses, tool_use_id w /v1/messages.
  • Wynik to tekst. Zserializuj obiekt do ciągu JSON dla content (output w /v1/responses). W /v1/messages content bloku tool_result to ciąg znaków albo lista bloków tekstowych.
  • W turze asystenta function.arguments pozostaje ciągiem JSON, dokładnie takim, jaki przyszedł.
  • Rozmowa może kończyć się wynikiem narzędzia. Nowa wiadomość użytkownika nie jest potrzebna: model kontynuuje od wyniku.
  • Gdy Twoja funkcja zawiedzie, wyślij błąd jako tekst wyniku. Model może wtedy o nim poinformować albo poprosić o kolejne wywołanie.

Słowa kluczowe schematu

parameters (input_schema w /v1/messages) to JSON Schema. Rodzina Shannon 3 (shannon-3, shannon-3-pro, shannon-3.1, shannon-3.1-pro) i hostowane modele open-weight otrzymują go tak, jak go wysyłasz.

shannon-1.6-lite, shannon-1.6-pro, shannon-2-lite, shannon-2-pro i shannon-coder-1 otrzymują ten podzbiór, we wszystkich trzech endpointach:

Traktowanie Słowa kluczowe
Odczytywane tak, jak wysłano Każde słowo kluczowe, którego nie wymieniają wiersze poniżej, na przykład type, properties, required, items, enum, description, minimum, maximum, anyOf i allOf, na każdym poziomie schematu.
format Odczytywane dla wartości int32, int64, float, double, byte, date, date-time i enum.
oneOf Odczytywane jako anyOf.
Nie jest częścią schematu, który te modele otrzymują $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, gdy są liczbami; inne wartości format.

Zachowanie i limity

  • API nie ustala maksymalnej liczby narzędzi ani maksymalnej liczby rund.
  • Treść zapytania może mieć do 32 MiB, a rozmowa wraz z wynikami musi się zmieścić w oknie kontekstu modelu.
  • Gdy zapytanie niesie tools, shannon-1.6-lite, shannon-1.6-pro, shannon-2-lite i shannon-2-pro używają domyślnej temperature 0.2. Wyślij temperature, aby ustawić inną wartość.
  • Każda runda to osobne zapytanie: pobiera z Twojego salda i wlicza się do ochrony przed floodem jak każde inne zapytanie. Limity i saldo

Błędy

Wywołanie narzędzia to zwykła odpowiedź ze statusem 200. Te błędy dotyczą samego zapytania:

Status Typ Komunikat Kiedy
400 invalid_request_error unknown model: <id> model nie jest id z opublikowanej listy.
422 invalid_request_error Failed to deserialize the JSON body into the target type: … tools nie jest tablicą albo inne pole ma zły typ JSON.
413 invalid_request_error Failed to buffer the request body: … Treść zapytania jest większa niż 32 MiB. Błąd niesie code: "request_too_large".

Argumenty pisze model. Sprawdź je ze swoim schematem, zanim uruchomisz funkcję, tak jak sprawdzasz każde dane z zewnątrz.

Błędy uwierzytelniania, salda i serwera są takie same jak przy każdym zapytaniu. Obsługa błędów