Function calling (जिसे tool calling या tool use भी कहा जाता है) वह तरीका है जिससे आप किसी model को अपने code का access देते हैं। आप "look up an order" या "quote shipping" जैसे functions का विवरण देते हैं। Model तय करता है कि किस function को किस arguments के साथ call करना है; आपका code उसे चलाता है और result वापस भेजता है। Store support bot से लेकर Claude Code तक, हर agent इसी loop पर बना है।
GetVibe API पर function calling, OpenAI format में standard /v1/chat/completions endpoint और Anthropic format में /v1/messages के ज़रिए काम करता है। नीचे एक पूरा loop दिया गया है, जिसे हमने तीन अलग-अलग makers के तीन models पर चलाया।
Loop कैसे काम करता है
- आप messages के साथ
toolsकी एक list भेजते हैं। हर tool में एक name, description और उसके parameters के लिए JSON Schema होता है। - Text के बजाय model
tool_callsलौटाता है: किस function को call करना है और किन arguments के साथ।finish_reasontool_callsहोता है। - आपका code functions चलाता है और हर call के लिए role
toolवाला एक message जोड़ता है, जिसमें वहीtool_call_idहोता है। - आप history फिर से भेजते हैं। Model या तो और calls मांगता है या user को text में जवाब देता है।
Model खुद कभी कुछ नहीं चलाता। वह केवल call के लिए request करता है। वास्तव में क्या चलेगा और किन permissions के साथ चलेगा, यह आपका code तय करता है।
एक पूरा उदाहरण: store support assistant
दो functions: order status और shipping quote। User एक साथ दोनों के बारे में पूछता है और model एक ही turn में दोनों functions call करता है।
import json
import os
from openai import OpenAI
client = OpenAI(base_url="https://getvibeapi.com/v1", api_key=os.environ["GETVIBE_API_KEY"])
MODEL = "gpt-6-luna"
def get_order_status(order_id: str) -> dict:
# आपका database या CRM lookup यहां होगा
return {"order_id": order_id, "status": "out for delivery", "eta": "2026-10-24"}
def get_shipping_quote(zip_code: str) -> dict:
return {"zip_code": zip_code, "price_usd": 7.5, "days": 2}
TOOLS = [
{"type": "function", "function": {
"name": "get_order_status",
"description": "Look up an order by its ID",
"parameters": {"type": "object",
"properties": {"order_id": {"type": "string", "description": "Order ID, e.g. A-1042"}},
"required": ["order_id"]}}},
{"type": "function", "function": {
"name": "get_shipping_quote",
"description": "Courier shipping price and delivery time to a US ZIP code",
"parameters": {"type": "object",
"properties": {"zip_code": {"type": "string"}},
"required": ["zip_code"]}}},
]
FUNCTIONS = {"get_order_status": get_order_status, "get_shipping_quote": get_shipping_quote}
messages = [
{"role": "system", "content": "आप एक store support assistant हैं। संक्षिप्त रहें।"},
{"role": "user", "content": "मेरा order A-1042 कहां है? और 94110 पर shipping कितनी है?"},
]
for _ in range(5): # rounds की संख्या सीमित करें
resp = client.chat.completions.create(model=MODEL, messages=messages, tools=TOOLS)
msg = resp.choices[0].message
if not msg.tool_calls:
print(msg.content)
break
messages.append(msg.model_dump(exclude_none=True))
for call in msg.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)})
हमने इस code को gpt-6-luna, deepseek-v4.1-flash और claude-haiku-5.5 पर बिना कोई बदलाव किए चलाया और केवल MODEL बदला। पहले round में तीनों ने दोनों functions call किए: get_order_status को A-1042 के साथ और get_shipping_quote को 94110 के साथ। दूसरे round में तीनों ने text में delivery status, ETA, 7.50 की price और two-day delivery time के साथ जवाब दिया।
इस code में क्या महत्वपूर्ण है
- Model का पूरा tool-call message history में जोड़ें। इसके बिना आपका
toolmessage ऐसे call का जवाब देता है जिसे model देख नहीं सकता, और कई models बस वही function फिर से call करते हैं, जिससे loop चक्कर काटता रहता है। - हर call के लिए matching
tool_call_idवाला एकtoolmessage रखें। जैसा यहां हुआ, model एक साथ कई calls मांग सकता है। - Arguments एक string के रूप में आते हैं।
argumentsएक string के अंदर JSON होता है। उसे parse और validate करें, क्योंकि model कोई value गलत दे सकता है। - Rounds की सीमा तय करें। Limit के बिना किसी function का bug loop को endless बना सकता है और token bill भी लगातार बढ़ा सकता है।
tool_choice: जब call अनिवार्य हो
डिफ़ॉल्ट रूप से model तय करता है कि tool call करना है या text में जवाब देना है ("auto")। tool_choice इसे बदलता है:
"none"— tools को कभी call न करें;"required"— कम से कम एक tool call करें;{"type": "function", "function": {"name": "..."}}— इस specific function को call करें।
आखिरी form data extraction के लिए उपयोगी है। Function का parameter schema answer का shape बन जाता है:
curl https://getvibeapi.com/v1/chat/completions \
-H "Authorization: Bearer $GETVIBE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "deepseek-v4.1-flash",
"messages": [{"role": "user", "content": "Jane Doe, [email protected], गुरुवार को demo चाहती हैं"}],
"tools": [{
"type": "function",
"function": {
"name": "save_lead",
"description": "Save a sales lead to the CRM",
"parameters": {
"type": "object",
"properties": {"name": {"type": "string"}, "email": {"type": "string"}, "request": {"type": "string"}},
"required": ["name", "email", "request"]
}
}
}],
"tool_choice": {"type": "function", "function": {"name": "save_lead"}}
}'
Response में save_lead call था, जिसमें name "Jane Doe", email "[email protected]" और request "गुरुवार को demo चाहती हैं" था।
एक caveat: कुछ Claude models, जिनमें Claude Sonnet 5.5 और Claude Opus 5.5 शामिल हैं, forced tool choice स्वीकार नहीं करते। GetVibe ऐसी request को उन्हीं tools के साथ auto में बदल देता है, इसलिए आपको error के बजाय answer मिलता है, लेकिन फिर model खुद तय करता है कि call करना है या नहीं। इन models से strict JSON के लिए structured outputs का इस्तेमाल करें।
Anthropic format: /v1/messages
Anthropic SDK के साथ tools थोड़े अलग दिखते हैं: parameter schema input_schema में जाता है और call tool_use content block के रूप में वापस आता है।
curl https://getvibeapi.com/v1/messages \
-H "x-api-key: $GETVIBE_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-H "Content-Type: application/json" \
-d '{
"model": "claude-haiku-5.5",
"max_tokens": 512,
"tools": [{
"name": "get_order_status",
"description": "Look up an order by its ID",
"input_schema": {"type": "object", "properties": {"order_id": {"type": "string"}}, "required": ["order_id"]}
}],
"messages": [{"role": "user", "content": "Order A-1042 कहां है?"}]
}'
Response में stop_reason tool_use था और एक tool_use block था, जो order_id A-1042 के साथ get_order_status को call कर रहा था। आप अगली user message में tool_result block के रूप में result वापस भेजते हैं और उसमें वही tool_use_id रखते हैं।
Tools के लिए कौन-सा model इस्तेमाल करें
- High-volume bots और simple tools — DeepSeek V4.1 Flash ($0.0112 इनपुट · $0.0445 आउटपुट प्रति 10 लाख टोकन) या Claude Haiku 5.5 ($0.0267 इनपुट · $0.1334 आउटपुट प्रति 10 लाख टोकन)।
- कई tools और लंबे plans वाले agents — GPT-6 Luna ($0.0055 इनपुट · $0.0274 आउटपुट प्रति 10 लाख टोकन) या Claude Sonnet 5.5।
Agent loops हर round में वही लंबा prefix फिर से भेजते हैं, इसलिए यहां prompt caching बहुत महत्वपूर्ण है। Request fields की अधिक जानकारी tool calling docs में है।
