Bumalik sa blog

API at SDKGabay

Function calling sa Python gamit ang OpenAI-compatible na API

Magpadala ng tools, basahin ang tool_calls at ibalik ang resulta gamit ang role tool: isang two-step na function calling loop sa Python gamit ang MiniMax-M2.7.

Ni CheapTokens TeamNai-publish noong Na-update noong 6 min na pagbabasa

Diagram ng two-step na tool call loop: magpadala ng tools, basahin ang tool_calls, ibalik ang resulta bilang tool message
Sa pahinang ito
  1. Paano gumagana ang function calling
  2. I-set up ang client
  3. Magdeklara ng function at ipadala ang unang request
  4. Ano ang dapat mong makita
  5. Maraming call at mas mahabang loop
  6. Bakit bagay ang MiniMax-M2.7 sa mga tool loop
  7. Kung hindi ito gumana
  8. Mga susunod na hakbang

Ang function calling (tool calling) ay nagpapahintulot sa isang modelo na hilingin sa iyong code na magpatakbo ng isang function. Nagpapadala ka ng listahan ng tools kasama ng request, sumasagot ang modelo ng tool_calls sa halip na teksto, ikaw mismo ang nagpapatakbo ng function, at ipinapadala mo pabalik ang resulta nito sa isang mensaheng may role: tool. Pagkatapos, isusulat ng modelo ang huling sagot. Ipinapakita ng gabay na ito ang buong loop sa Python laban sa OpenAI-compatible na endpoint na https://api.cheaptokens.dev/v1/chat/completions gamit ang MiniMax-M2.7 (id MiniMaxAI/MiniMax-M2.7, 180K context, hanggang 8,192 output tokens bawat sagot).

Nakalista ang tool calling bilang sinusuportahan para sa bawat modelo sa catalog (CheapTokens docs, sinuri noong 22 Oktubre 2026). Kailangan mo ng API key; kung wala ka pang nagawang request, magsimula sa iyong unang API request.

Paano gumagana ang function calling#

Hindi kailanman nagpapatakbo ng kahit ano ang modelo. Gumagawa lamang ito ng structured na request: "tawagin ang get_weather gamit ang {\"city\": \"Paris\"}". Ang iyong programa ang gumagawa ng totoong trabaho at nag-uulat pabalik. Kaya nagiging loop ito ng dalawang request:

  1. Request 1. Ipinapadala mo ang mensahe ng user kasama ang listahan ng tools. Sumasagot ang modelo sa teksto o nagbabalik ng isa o higit pang tool_calls.
  2. Ang iyong code. Pinaparse mo ang bawat call, pinapatakbo ang tugmang function at kinokolekta ang resulta.
  3. Request 2. Ipinapadala mong muli ang buong usapan: ang orihinal na mga mensahe, ang mensahe ng assistant na may tool_calls, at isang mensaheng role: tool bawat call. Ginagamit ng modelo ang mga resulta para isulat ang huling sagot.

Ipinapadala muli ng bawat request ang buong history, kaya mas maraming input token ang ginagamit ng mga tool loop kaysa sa isang tanong lang. Kung bago ito sa iyo, basahin ang ano ang token.

I-set up ang client#

I-install ang OpenAI SDK (pip install openai) at ilagay ang iyong key sa isang environment variable sa halip na sa source code:

bash
export CHEAPTOKENS_API_KEY="your-key-here"

Ang base URL ay https://api.cheaptokens.dev/v1. Kunin ang model id mula sa dokumentasyon ng CheapTokens: magkaiba ang pangalan ng parehong modelo sa iba't ibang provider. Ginagamit ng gabay na ito ang MiniMaxAI/MiniMax-M2.7.

Magdeklara ng function at ipadala ang unang request#

Inilalarawan ang isang function sa array na tools. Bawat entry ay may type: function at isang object na function na may name, isang description at parameters na nakasulat bilang JSON Schema. Ang description ang binabasa ng modelo para magpasya kung kailan tatawagin ang function, kaya isulat ito bilang maikli at konkretong pangungusap.

Nasa ibaba ang kumpletong script. Ang weather function ay isang stub na may pekeng data, kaya hindi kailangan ng karagdagang serbisyo ang halimbawa:

python
import json
import os

from openai import OpenAI

client = OpenAI(
    base_url='https://api.cheaptokens.dev/v1',
    api_key=os.environ['CHEAPTOKENS_API_KEY'],
)
MODEL = 'MiniMaxAI/MiniMax-M2.7'


def get_weather(city: str) -> dict:
    # Stub with fake data: replace with a real lookup
    fake = {'Paris': 14, 'Tokyo': 19}
    return {'city': city, 'temp_c': fake.get(city, 10)}


FUNCTIONS = {'get_weather': get_weather}

tools = [
    {
        'type': 'function',
        'function': {
            'name': 'get_weather',
            'description': 'Get the current temperature in Celsius for a city.',
            'parameters': {
                'type': 'object',
                'properties': {
                    'city': {'type': 'string', 'description': 'City name, for example Paris'},
                },
                'required': ['city'],
            },
        },
    }
]

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

# Step 1: the model decides whether to call a function
first = client.chat.completions.create(model=MODEL, messages=messages, tools=tools)
message = first.choices[0].message

if not message.tool_calls:
    print(message.content)
    raise SystemExit

# Step 2: run every requested call and send the results back
messages.append(message)
for call in message.tool_calls:
    args = json.loads(call.function.arguments)
    result = FUNCTIONS[call.function.name](**args)
    messages.append({
        'role': 'tool',
        'tool_call_id': call.id,
        'content': json.dumps(result),
    })

final = client.chat.completions.create(model=MODEL, messages=messages, tools=tools)
print(final.choices[0].message.content)

Tatlong detalye ang nagpapasya kung gumagana ang loop:

  • Ang call.function.arguments ay isang JSON string, hindi dictionary. I-parse ito gamit ang json.loads.
  • Bawat mensaheng role: tool ay dapat may dalang tool_call_id ng call na sinasagot nito, na call.id.
  • Ang content ng isang tool message ay string. Gamitin ang json.dumps para sa structured na resulta.

Ano ang dapat mong makita#

Kung ipi-print mo ang mga field pagkatapos ng unang request, ganito ang hitsura nila (iba-iba ang call id sa bawat run):

text
finish_reason: tool_calls
call.id: call_abc123
call.function.name: get_weather
call.function.arguments: {"city": "Paris"}

Pagkatapos, ipi-print ng script ang huling sagot, isang simpleng pangungusap tulad ng "It is currently 14 °C in Paris." Nagbabago ang pananalita sa bawat run; ang numero ay galing sa iyong function.

Maraming call at mas mahabang loop#

Maaaring magbalik ang modelo ng higit sa isang call sa isang sagot, halimbawa kapag nagtanong ka tungkol sa panahon sa dalawang lungsod. Kaya naglo-loop ang halimbawa sa message.tool_calls at sinasagot ang bawat call ayon sa sarili nitong id. Inilalarawan ng function calling guide ng OpenAI ang parehong pag-uugali: sa default na tool_choice na auto, maaaring tumawag ang modelo ng zero, isa o maraming function (OpenAI docs, sinuri noong 22 Oktubre 2026; walang petsa ng huling update ang pahina at inilalarawan nito ang mas bagong hugis ng Responses API, habang ginagamit ng gabay na ito ang hugis ng Chat Completions ng endpoint na /v1/chat/completions).

Inuulit ng mga agent ang dalawang hakbang hanggang tumigil ang modelo sa paghingi ng mga tool. Balutin ang mga request sa isang loop at laging magtakda ng limitasyon sa hakbang:

python
for _ in range(5):  # safety limit against endless loops
    response = client.chat.completions.create(model=MODEL, messages=messages, tools=tools)
    message = response.choices[0].message
    if not message.tool_calls:
        print(message.content)
        break
    messages.append(message)
    for call in message.tool_calls:
        args = json.loads(call.function.arguments)
        result = FUNCTIONS[call.function.name](**args)
        messages.append({'role': 'tool', 'tool_call_id': call.id, 'content': json.dumps(result)})

Kung gusto mong lumabas ang sagot nang token by token, pagsamahin ito sa streaming sa Python.

Bakit bagay ang MiniMax-M2.7 sa mga tool loop#

Maraming request ang ipinapadala ng isang tool loop na may lumalaking history. Para sa pattern na iyon, inaalok ng CheapTokens ang MiniMax-M2.7: 180K context, hanggang 8,192 output tokens bawat sagot, isang presyo sa anumang oras ng araw na walang peak hours, at isang balanse para sa lahat ng modelo. Kung pagsasamahin ang input at output, mas mura ito kaysa sa reference price ng OpenRouter (paghahambing ng presyo ng CheapTokens, sinuri noong 31 Oktubre 2026).

Kasalukuyang presyo bawat 1M tokens: input $0.05, output $0.15. Bilang halimbawang workload (hindi pagsukat), ang two-request round trip sa itaas na may kabuuang humigit-kumulang 2,700 input at 350 output tokens ay nagkakahalaga ng $0.00019. Nasa pricing page ang buong listahan ng presyo.

Para subukan ang ibang modelo, id lang ang palitan; nasa models page ang listahan ng mga id.

Kung hindi ito gumana#

  • Ang message.tool_calls ay None. Sumagot ang modelo sa teksto. Gawing mas tiyak ang description ng function, at tiyaking talagang kailangan ng tanong ang function.
  • json.JSONDecodeError sa arguments. Gumawa ang modelo ng invalid na JSON. Balutin ang json.loads sa try/except at ipadala pabalik ang teksto ng error bilang resulta ng tool, para makapag-retry ang modelo gamit ang itinamang arguments.
  • Nabigo ang ikalawang request o hindi pinansin ng modelo ang resulta. Tiyakin na ang bawat call ay may eksaktong isang mensaheng role: tool na may tugmang tool_call_id, at nasa history bago ang mga ito ang mensahe ng assistant na may tool_calls.
  • KeyError sa FUNCTIONS[...]. Pinangalanan ng modelo ang isang function na hindi mo nirehistro. Ibalik ang maikling error string bilang resulta ng tool sa halip na mag-crash.
  • Naputol ang sagot. Tingnan ang finish_reason: ang value na length ay nangangahulugang naabot ang limitasyon ng output token. Tingnan ang bakit napuputol sa gitna ng pangungusap ang sagot ng AI.
  • 401 o mga error sa authentication. Tiyakin na nasa CHEAPTOKENS_API_KEY ang key at nagtatapos sa /v1 ang base URL.

Mga susunod na hakbang#

Palitan ang stub ng totoong function: isang database query, isang search call o isang calculator. Magdagdag ng mas maraming entry sa tools at sa FUNCTIONS, at panatilihing maikli ang bawat resulta ng function, dahil bumabalik ito sa history sa bawat sumunod na request. Para makakuha ng key at makagawa ng unang call, buksan ang CheapTokens docs.