استدعاء الأدوات
استدعاء الأدوات (function calling) يتيح للنموذج طلب تنفيذ دوالكم الخاصة : استشارة قاعدة بيانات، استدعاء واجهة API، إطلاق إجراء. لا ينفّذها النموذج بنفسه أبدًا : بل يخبركم بما يجب استدعاؤه، وبأي معاملات.
الدورة الكاملة#
1. Vous envoyez : messages + description des outils
2. Le modèle répond : finish_reason = "tool_calls" + arguments JSON
3. VOUS exécutez la fonction dans votre code
4. Vous renvoyez : messages + tool_calls + résultat (role: "tool")
5. Le modèle répond en langage naturel
مثال كامل ببيانات افتراضية#
import json
from openai import OpenAI
client = OpenAI(api_key="zir_ai_...", base_url="https://api.cloudzir.com/v1")
# 1. وصف الأدوات المتاحة
outils = [
{
"type": "function",
"function": {
"name": "stock_produit",
"description": "Retourne le stock disponible d'un produit dans un entrepôt.",
"parameters": {
"type": "object",
"properties": {
"reference": {"type": "string", "description": "مرجع المنتج، مثل DEMO-001"},
"entrepot": {"type": "string", "enum": ["alger", "oran", "constantine"]},
},
"required": ["reference"],
},
},
}
]
# 2. مثال محلي ببيانات افتراضية
def stock_produit(reference: str, entrepot: str = "alger") -> dict:
return {"reference": reference, "entrepot": entrepot, "disponible": 42}
messages = [{"role": "user", "content": "كم تبقى من DEMO-001 في وهران؟"}]
reponse = client.chat.completions.create(
model="mina-full", messages=messages, tools=outils
)
message = reponse.choices[0].message
# 3. تنفيذ ما يطلبه النموذج
if message.tool_calls:
messages.append(message) # garder la demande dans l'historique
for appel in message.tool_calls:
arguments = json.loads(appel.function.arguments)
resultat = stock_produit(**arguments)
messages.append({
"role": "tool",
"tool_call_id": appel.id,
"content": json.dumps(resultat, ensure_ascii=False),
})
# 4. طلب الإجابة النهائية
finale = client.chat.completions.create(
model="mina-full", messages=messages, tools=outils
)
print(finale.choices[0].message.content)
# → « بقيت 42 وحدة من DEMO-001 في مستودع وهران. »import OpenAI from "openai";
const client = new OpenAI({
apiKey: process.env.CLOUDZIR_API_KEY,
baseURL: "https://api.cloudzir.com/v1",
});
const outils = [{
type: "function",
function: {
name: "stock_produit",
description: "Retourne le stock disponible d'un produit dans un entrepôt.",
parameters: {
type: "object",
properties: {
reference: { type: "string" },
entrepot: { type: "string", enum: ["alger", "oran", "constantine"] },
},
required: ["reference"],
},
},
}];
const implementations = {
stock_produit: ({ reference, entrepot = "alger" }) => ({ reference, entrepot, disponible: 42 }),
};
const messages = [{ role: "user", content: "كم تبقى من DEMO-001 في وهران؟" }];
let r = await client.chat.completions.create({ model: "mina-full", messages, tools: outils });
const msg = r.choices[0].message;
if (msg.tool_calls?.length) {
messages.push(msg);
for (const appel of msg.tool_calls) {
const args = JSON.parse(appel.function.arguments);
const resultat = implementations[appel.function.name](args);
messages.push({
role: "tool",
tool_call_id: appel.id,
content: JSON.stringify(resultat),
});
}
r = await client.chat.completions.create({ model: "mina-full", messages, tools: outils });
console.log(r.choices[0].message.content);
}استجابة النموذج عند استدعاء أداة#
{
"choices": [{
"index": 0,
"message": {
"role": "assistant",
"content": null,
"tool_calls": [{
"id": "call_a1b2c3",
"type": "function",
"function": {
"name": "stock_produit",
"arguments": "{\"reference\":\"DEMO-001\",\"entrepot\":\"oran\"}"
}
}]
},
"finish_reason": "tool_calls"
}]
}
arguments هي سلسلة نصية JSON، وليست كائنًا : يجب تحليلها (parse).
التحكم في التفعيل#
tool_choice | السلوك |
|---|---|
"auto" (افتراضي) | النموذج يقرر : أداة أو نص. |
"none" | يمنع الأدوات لهذا الاستدعاء. |
"required" | يفرض استخدام أداة (باختيار النموذج). |
{"type":"function","function":{"name":"x"}} | يفرض هذه الأداة بالذات. |
كتابة أوصاف جيدة#
تعتمد جودة الاستدعاءات كليًا تقريبًا على أوصافكم :
- وصف الدالة : قولوا متى تُستخدَم، لا فقط ما تفعله. «استخدم عند طلب المستخدم توفر منتج» أفضل من «يُعيد المخزون».
- كل معامل يستحق
descriptionخاصًا به، وإن أمكنenum؛ هذا يلغي القيم المُختلَقة. - ضعوا علامة
requiredعلى ما هو ضروري فعلًا : وإلا سيحذف النموذج حقولًا. - أدوات قليلة في المرة الواحدة : بعد نحو عشرة، تنخفض الدقة ويصبح الإدخال مكلفًا (التعريفات تُفوتَر في كل استدعاء).
الأمان#
النموذج ليس تفويضًا
استدعاء الأداة اقتراح. تحققوا دائمًا، في شيفرتكم، من : هوية
المستخدم، صلاحياته، وصحة المعاملات. لا تربطوا أبدًا tool_call
مباشرة بإجراء مدمّر (حذف، دفع، إرسال) دون تأكيد صريح.
- تحققوا من المعاملات مقابل مخطط قبل التنفيذ : قد ينتج النموذج قيمًا خارج النطاق.
- حدّدوا عدد الجولات (مثلًا 5 كحد أقصى) لتجنب الحلقات.
- أعيدوا رسائل خطأ الأداة بوضوح : غالبًا ما يعرف النموذج تصحيح استدعائه في الجولة التالية.
النماذج الموصى بها#
| النموذج | استدعاء الأدوات |
|---|---|
mina-full | موصى به : سلاسل معقدة، عدة أدوات. |
mina-low | جيد لـ1 إلى 3 أدوات بسيطة. |
mina-flash | ممكن على أداة واحدة موصوفة جيدًا. |
صيغة Anthropic#
على /anthropic، تمر نفس القدرات عبر tools مع
input_schema، وكتل tool_use وtool_result.
انظروا استخدام API الخاصة بـAnthropic.