API และ SDKคู่มือ
Function calling ใน Python ด้วย API ที่เข้ากันได้กับ OpenAI
ส่ง tools อ่าน tool_calls และคืนผลลัพธ์ด้วย role tool: ลูป function calling สองขั้นตอนใน Python ด้วย MiniMax-M2.7

ในหน้านี้
Function calling (tool calling) ช่วยให้โมเดลขอให้โค้ดของคุณรันฟังก์ชันได้ คุณส่งรายการ tools ไปพร้อมกับคำขอ โมเดลจะตอบกลับด้วย tool_calls แทนข้อความ คุณรันฟังก์ชันเอง แล้วส่งผลลัพธ์กลับไปในข้อความที่มี role: tool จากนั้นโมเดลจะเขียนคำตอบสุดท้าย คู่มือนี้แสดงลูปทั้งหมดใน Python กับ endpoint ที่เข้ากันได้กับ OpenAI https:/ ด้วย MiniMax-M2.7 (id MiniMaxAI/, context 180K, เอาต์พุตสูงสุด 8,192 โทเคนต่อคำตอบ)
Tool calling ระบุว่ารองรับสำหรับทุกโมเดลในแคตตาล็อก (CheapTokens docs, ตรวจสอบเมื่อ 22 ตุลาคม 2026) คุณต้องมี API key; หากยังไม่เคยส่งคำขอ ให้เริ่มที่ คำขอ API แรกของคุณ
หลักการทำงานของ function calling#
โมเดลไม่เคยรันอะไรเลย มันเพียงสร้างคำขอแบบมีโครงสร้าง: "เรียก get_weather ด้วย {\"city\": \"Paris\"}" โปรแกรมของคุณทำงานจริงและรายงานกลับมา นั่นทำให้เกิดลูปของคำขอสองครั้ง:
- คำขอที่ 1 คุณส่งข้อความของผู้ใช้พร้อมรายการ
toolsโมเดลจะตอบเป็นข้อความหรือคืนtool_callsหนึ่งรายการหรือมากกว่า - โค้ดของคุณ คุณแยกวิเคราะห์แต่ละ call รันฟังก์ชันที่ตรงกัน และรวบรวมผลลัพธ์
- คำขอที่ 2 คุณส่งบทสนทนาทั้งหมดอีกครั้ง: ข้อความเดิม ข้อความของ assistant ที่มี
tool_callsและข้อความrole: toolหนึ่งรายการต่อ call หนึ่งครั้ง โมเดลใช้ผลลัพธ์เพื่อเขียนคำตอบสุดท้าย
ทุกคำขอส่งประวัติทั้งหมดซ้ำ ดังนั้นลูปเครื่องมือจึงใช้โทเคนอินพุตมากกว่าคำถามเดียว หากคุณเพิ่งเริ่มรู้จักเรื่องนี้ อ่าน โทเคนคืออะไร
ตั้งค่าไคลเอนต์#
ติดตั้ง OpenAI SDK (pip install openai) และใส่คีย์ของคุณในตัวแปรสภาพแวดล้อมแทนที่จะใส่ในซอร์สโค้ด:
export CHEAPTOKENS_API_KEY="your-key-here"Base URL คือ https:/ ใช้ model id จากเอกสาร CheapTokens: ผู้ให้บริการแต่ละรายตั้งชื่อโมเดลเดียวกันต่างกัน คู่มือนี้ใช้ MiniMaxAI/
ประกาศฟังก์ชันและส่งคำขอแรก#
ฟังก์ชันอธิบายไว้ในอาร์เรย์ tools แต่ละรายการมี type: function และออบเจกต์ function ที่มี name, description และ parameters เขียนเป็น JSON Schema คำอธิบายคือสิ่งที่โมเดลอ่านเพื่อตัดสินใจว่าจะเรียกฟังก์ชันเมื่อใด ดังนั้นเขียนเป็นประโยคสั้นและชัดเจน
ด้านล่างคือสคริปต์ที่สมบูรณ์ ฟังก์ชันสภาพอากาศเป็น stub ที่มีข้อมูลปลอม ตัวอย่างจึงไม่ต้องใช้บริการเพิ่มเติม:
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)รายละเอียดสามอย่างตัดสินว่าลูปจะทำงานได้หรือไม่:
call.เป็น สตริง JSON ไม่ใช่ดิกชันนารี แยกวิเคราะห์ด้วยfunction. arguments json.loads- ข้อความ
role: toolแต่ละรายการต้องมีtool_call_idของ call ที่มันตอบ ซึ่งก็คือcall.id contentของข้อความเครื่องมือเป็นสตริง ใช้json.dumpsสำหรับผลลัพธ์แบบมีโครงสร้าง
สิ่งที่คุณควรเห็น#
หากคุณพิมพ์ฟิลด์หลังคำขอแรก จะมีลักษณะเช่นนี้ (call id ต่างกันในทุกครั้งที่รัน):
finish_reason: tool_calls
call.id: call_abc123
call.function.name: get_weather
call.function.arguments: {"city": "Paris"}จากนั้นสคริปต์จะพิมพ์คำตอบสุดท้าย เป็นประโยคธรรมดาประมาณว่า "It is currently 14 °C in Paris." ถ้อยคำเปลี่ยนไปในแต่ละครั้งที่รัน ตัวเลขมาจากฟังก์ชันของคุณ
หลาย call และลูปที่ยาวขึ้น#
โมเดลสามารถคืน call มากกว่าหนึ่งรายการในคำตอบเดียว เช่น เมื่อคุณถามสภาพอากาศในสองเมือง นั่นคือเหตุผลที่ตัวอย่างวนลูปผ่าน message. และตอบแต่ละ call ด้วย id ของมันเอง คู่มือ function calling ของ OpenAI อธิบายพฤติกรรมเดียวกัน: ด้วยค่าเริ่มต้น tool_choice เป็น auto โมเดลอาจเรียกศูนย์ หนึ่ง หรือหลายฟังก์ชัน (OpenAI docs, ตรวจสอบเมื่อ 22 ตุลาคม 2026; หน้าเว็บไม่มีวันที่อัปเดตล่าสุดและอธิบายรูปแบบ Responses API ที่ใหม่กว่า ขณะที่คู่มือนี้ใช้รูปแบบ Chat Completions ของ endpoint /)
เอเจนต์ทำสองขั้นตอนซ้ำจนกว่าโมเดลจะหยุดขอเครื่องมือ ครอบคำขอด้วยลูปและกำหนดขีดจำกัดจำนวนขั้นเสมอ:
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)})หากคุณต้องการให้คำตอบปรากฏทีละโทเคน ให้รวมกับ streaming ใน Python
ทำไม MiniMax-M2.7 จึงเหมาะกับลูปเครื่องมือ#
ลูปเครื่องมือส่งคำขอจำนวนมากพร้อมประวัติที่เพิ่มขึ้น สำหรับรูปแบบนั้น CheapTokens เสนอ MiniMax-M2.7: context 180K, เอาต์พุตสูงสุด 8,192 โทเคนต่อคำตอบ, ราคาเดียวตลอดเวลาของวันโดยไม่มีช่วงพีค และยอดคงเหลือเดียวสำหรับทุกโมเดล เมื่อนับอินพุตและเอาต์พุตรวมกัน ถูกกว่าราคาอ้างอิงของ OpenRouter (การเปรียบเทียบราคา CheapTokens, ตรวจสอบ 31 ตุลาคม 2026)
ราคาปัจจุบันต่อ 1M โทเคน: อินพุต $0.05, เอาต์พุต $0.15 ตัวอย่างภาระงาน (ไม่ใช่การวัดจริง) การไปกลับสองคำขอข้างต้นที่มีอินพุตประมาณ 2,700 และเอาต์พุต 350 โทเคนรวมกันมีค่าใช้จ่าย $0.00019 รายการราคาทั้งหมดอยู่ที่ หน้าราคา
หากต้องการลองโมเดลอื่น เปลี่ยนเฉพาะ id; รายการ id อยู่ที่ หน้ารุ่นโมเดล
หากใช้งานไม่ได้#
message.เป็นtool_ calls Noneโมเดลตอบเป็นข้อความ ทำให้คำอธิบายฟังก์ชันdescriptionเจาะจงมากขึ้น และตรวจสอบว่าคำถามจำเป็นต้องใช้ฟังก์ชันจริง ๆjson.ที่JSONDecodeError argumentsโมเดลสร้าง JSON ที่ไม่ถูกต้อง ครอบjson.loadsด้วยtry/exceptและส่งข้อความข้อผิดพลาดกลับเป็นผลลัพธ์เครื่องมือ เพื่อให้โมเดลลองใหม่ด้วยอาร์กิวเมนต์ที่แก้ไขแล้ว- คำขอที่สองล้มเหลวหรือโมเดลเพิกเฉยต่อผลลัพธ์ ตรวจสอบว่าแต่ละ call มีข้อความ
role: toolหนึ่งรายการพอดีที่มีtool_call_idตรงกัน และข้อความของ assistant ที่มีtool_callsอยู่ในประวัติก่อนหน้านั้น KeyErrorในFUNCTIONS[...]โมเดลระบุชื่อฟังก์ชันที่คุณไม่ได้ลงทะเบียน คืนสตริงข้อผิดพลาดสั้น ๆ เป็นผลลัพธ์เครื่องมือแทนที่จะทำให้โปรแกรมพัง- คำตอบถูกตัด ตรวจสอบ
finish_reason: ค่าlengthหมายถึงถึงขีดจำกัดโทเคนเอาต์พุตแล้ว ดู ทำไมคำตอบ AI จึงหยุดกลางประโยค - 401 หรือข้อผิดพลาดการยืนยันตัวตน ตรวจสอบว่าคีย์อยู่ใน
CHEAPTOKENS_และ base URL ลงท้ายด้วยAPI_ KEY /v1
ขั้นตอนถัดไป#
แทนที่ stub ด้วยฟังก์ชันจริง: การคิวรีฐานข้อมูล การเรียกค้นหา หรือเครื่องคิดเลข เพิ่มรายการใน tools และ FUNCTIONS และเก็บผลลัพธ์ของทุกฟังก์ชันให้สั้น เพราะมันจะกลับเข้าสู่ประวัติในทุกคำขอถัดไป หากต้องการรับคีย์และส่งคำขอแรก เปิด เอกสาร CheapTokens



