Langsung ke konten
Pemanggilan fungsi

Pemanggilan fungsi

Deskripsikan fungsi Anda dalam permintaan dan model membalas dengan panggilan yang diinginkannya. Kode Anda menjalankannya dan mengirim hasilnya kembali: API mengembalikan panggilan tool dan tidak menjalankan tool itu sendiri.

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

Contoh di halaman ini memakai /v1/chat/completions. Loop yang sama berjalan di /v1/responses dan /v1/messages; ketika sebuah format menuliskan sesuatu secara berbeda, bagian di bawah menunjukkan ketiganya.

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)

Balasan pertama tidak menjawab pertanyaan. Balasan itu meminta sebuah panggilan:

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

Setelah Anda mengirim hasilnya, balasan berikutnya adalah jawaban biasa: message.content berisi teks dan finish_reason bernilai stop.

Loop, langkah demi langkah

Langkah Siapa Yang terjadi
1 Anda Kirim messages bersama tools, daftar fungsi yang boleh diminta model.
2 Model Balasan membawa tool_calls dan finish_reason: "tool_calls". Setiap panggilan menyebutkan fungsi dan memberikan argumennya.
3 Anda Parse arguments dari setiap panggilan dan jalankan fungsi Anda.
4 Anda Tambahkan pesan assistant dan satu pesan tool per panggilan ke messages, lalu kirim permintaan sekali lagi dengan tools yang sama.
5 Model Model menjawab dengan teks dan finish_reason: "stop", atau meminta panggilan lagi. Dalam hal itu kembali ke langkah 3.

Satu permintaan adalah satu giliran model. API tidak menyimpan percakapan antarpermintaan dan tidak menetapkan jumlah putaran: kode Anda yang memegang messages dan memutuskan kapan berhenti.

Mendefinisikan tool

tools adalah array dengan satu entri per fungsi. Setiap model dalam katalog menerimanya; GET /v1/models melaporkan capabilities.tools: true untuk setiap id.

Field Tipe Deskripsi
type string Selalu function.
function.name string Nama yang dipakai model ketika meminta fungsi ini. Wajib.
function.description string Apa yang dilakukan fungsi, dalam bahasa sederhana.
function.parameters object Argumen sebagai JSON Schema dengan type: "object" di level atas. Lihat Keyword schema di bawah.

Setiap endpoint punya penulisan tool-nya sendiri. Kirim yang sesuai dengan endpoint yang Anda panggil:

{
  "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 menyatakan apakah model boleh, atau harus, memanggil tool. Ia hanya dibaca bersama tools.

Nilai Deskripsi Diterapkan oleh
"auto" Model memutuskan apakah menjawab dengan teks atau memanggil tool. Ini default-nya. Semua model
"required" Balasan memanggil setidaknya satu tool. Model open-weight hosted
{"type": "function", "function": {"name": "get_weather"}} Balasan memanggil fungsi ini. Namanya harus salah satu fungsi di tools. Panggilan ke fungsi lain dihilangkan dari balasan. Model open-weight hosted

Model Shannon (shannon-*) memutuskan di setiap permintaan, seperti pada auto.

Dengan required atau fungsi bernama, baca finish_reason sebelum membaca tool_calls. Ketika model tidak menghasilkan panggilan, balasannya adalah jawaban teks dengan finish_reason: "stop".

Arti /v1/chat/completions /v1/responses /v1/messages
Model memutuskan "auto" "auto" {"type": "auto"}
Panggil setidaknya satu tool "required" "required" {"type": "any"}
Panggil satu fungsi bernama {"type": "function", "function": {"name": "get_weather"}} {"type": "function", "name": "get_weather"} {"type": "tool", "name": "get_weather"}

Diterima demi kompatibilitas: tool_choice: "none" dan parallel_tool_calls. Untuk giliran tanpa panggilan tool, kirim permintaan tanpa tools.

Panggilan tool dalam balasan

Field Tipe Deskripsi
finish_reason string tool_calls ketika balasan membawa setidaknya satu panggilan.
message.tool_calls array Satu entri per panggilan. Field ini hanya ada ketika model meminta panggilan.
tool_calls[].id string call_ diikuti 32 karakter heksadesimal. Kirim kembali sebagai tool_call_id bersama hasilnya.
tool_calls[].type string Selalu function.
tool_calls[].function.name string Fungsi yang dijalankan.
tool_calls[].function.arguments string Argumen sebagai string JSON, "{}" jika tidak ada. Parse sebelum dipakai.
message.content string | null null ketika balasan hanya berisi panggilan. Model open-weight hosted dapat mengembalikan teks di samping panggilan; model Shannon mengembalikan null.

Panggilan yang sama di setiap format. Di /v1/responses berupa item function_call dari output, dengan arguments sebagai string JSON. Di /v1/messages berupa blok konten tool_use yang input-nya adalah objek JSON, id-nya diawali toolu_, dan stop_reason bernilai 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\"}"
        }
      }
    ]
  }
}

Beberapa panggilan dalam satu giliran

Satu balasan dapat membawa beberapa panggilan. Jalankan semuanya dan kirim satu hasil per panggilan, masing-masing dengan tool_call_id-nya sendiri, pada permintaan berikutnya.

Model open-weight hosted mengembalikan setiap panggilan yang berbeda satu kali: dua panggilan dengan nama dan argumen yang sama tiba sebagai satu.

Panggilan tool yang di-stream

Dengan stream: true, panggilan tiba utuh: chunk berisi string arguments yang lengkap, jadi tidak ada fragmen yang perlu digabung. index menghitung panggilan dalam satu giliran mulai dari 0.

data: satu chunk, diformat
{
  "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 Yang tiba
/v1/chat/completions Satu chat.completion.chunk per panggilan, dengan panggilan di delta.tool_calls[0]. Chunk terakhir memiliki finish_reason: "tool_calls" dan usage.
/v1/responses Per panggilan: response.output_item.added (item function_call dengan arguments kosong), response.function_call_arguments.delta (seluruh string), response.function_call_arguments.done, response.output_item.done.
/v1/messages Per panggilan: content_block_start (blok tool_use dengan input kosong), satu content_block_delta yang input_json_delta.partial_json-nya adalah seluruh teks argumen, content_block_stop. message_delta kemudian membawa stop_reason: "tool_use".

Pada shannon-1.6-lite, shannon-1.6-pro, shannon-2-lite, shannon-2-pro, dan shannon-coder-1, permintaan streaming yang membawa tools mengirim teks jawabannya dalam satu delta content di akhir giliran. Streaming

Mengirim hasil kembali

Permintaan kedua mengulang percakapan dan menambahkan dua hal: giliran assistant yang meminta panggilan, dan satu hasil per panggilan.

{
  "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\"}"
    }
  ]
}
  • Kirim kembali giliran assistant seperti yang Anda terima, sebelum hasilnya. Setiap hasil dicocokkan dengan panggilannya berdasarkan id: tool_call_id di /v1/chat/completions, call_id di /v1/responses, tool_use_id di /v1/messages.
  • Hasil adalah teks. Serialisasikan objek menjadi string JSON untuk content (output di /v1/responses). Di /v1/messages, content dari blok tool_result berupa string atau daftar blok teks.
  • Pada giliran assistant, function.arguments tetap berupa string JSON, persis seperti saat tiba.
  • Percakapan boleh berakhir dengan hasil tool. Tidak perlu pesan user baru: model melanjutkan dari hasil tersebut.
  • Ketika fungsi Anda gagal, kirim kegagalannya sebagai teks hasil. Model kemudian dapat melaporkannya atau meminta panggilan lain.

Keyword schema

parameters (input_schema di /v1/messages) adalah JSON Schema. Keluarga Shannon 3 (shannon-3, shannon-3-pro, shannon-3.1, shannon-3.1-pro) dan model open-weight hosted menerimanya seperti yang Anda kirim.

shannon-1.6-lite, shannon-1.6-pro, shannon-2-lite, shannon-2-pro, dan shannon-coder-1 menerima subset ini, di ketiga endpoint:

Perlakuan Keyword
Dibaca apa adanya Setiap keyword yang tidak disebut pada baris di bawah, misalnya type, properties, required, items, enum, description, minimum, maximum, anyOf, dan allOf, di setiap tingkat schema.
format Dibaca untuk nilai int32, int64, float, double, byte, date, date-time, dan enum.
oneOf Dibaca sebagai anyOf.
Bukan bagian dari schema yang diterima model-model ini $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 dan exclusiveMaximum ketika berupa angka; nilai format lainnya.

Perilaku dan batas

  • API tidak menetapkan jumlah maksimum tool dan tidak menetapkan jumlah maksimum putaran.
  • Body permintaan dapat berukuran hingga 32 MiB, dan percakapan beserta hasilnya harus muat dalam jendela konteks model.
  • Ketika permintaan membawa tools, shannon-1.6-lite, shannon-1.6-pro, shannon-2-lite, dan shannon-2-pro memakai temperature default 0.2. Kirim temperature untuk mengatur nilai lain.
  • Setiap putaran adalah permintaan tersendiri: ia menarik dari saldo Anda dan dihitung dalam flood protection seperti permintaan lainnya. Batas dan saldo

Error

Panggilan tool adalah balasan normal dengan status 200. Error berikut menyangkut permintaan itu sendiri:

Status Tipe Pesan Kapan
400 invalid_request_error unknown model: <id> model bukan id dalam daftar yang dipublikasikan.
422 invalid_request_error Failed to deserialize the JSON body into the target type: … tools bukan array, atau field lain memiliki tipe JSON yang salah.
413 invalid_request_error Failed to buffer the request body: … Body permintaan lebih besar dari 32 MiB. Error membawa code: "request_too_large".

Model yang menulis argumen. Periksa terhadap schema Anda sebelum menjalankan fungsi, seperti Anda memeriksa input dari luar.

Error autentikasi, saldo, dan server sama seperti pada setiap permintaan. Penanganan kesalahan