المستوى المطلوب: متوسط — تحتاج تكون عامل request لـ LLM API قبل كده، وتعرف JSON أساسي. مش لازم خبرة سابقة في الـ agents.
Function Calling: خلّي الـ LLM ينفّذ بدل ما يخمّن
لو ربطت شات بوت بموقعك ولقيته بيرد على العميل برقم طلب أو سعر أو حالة شحن مخترعة، ركّز: ده مش bug في النموذج. ده بالظبط اللي بيحصل لمّا تطلب من LLM بيانات حيّة وانت مديتهوش طريقة يجيبها. الحل اسمه Function Calling، وفي المقال ده هتطلع عارف تطبّقه بكود شغّال في أقل من 20 سطر.
المشكلة باختصار
الـ LLM بيتنبّأ بالكلمة اللي بعدها بناءً على الاحتمالات. هو مايعرفش حالة طلب رقمه ORD-10293، فبيولّد جملة تبان صح: "طلبك في الطريق، هيوصل بكرة". الجملة سليمة لغويًا، لكنها اختراع كامل. لو عندك متجر بـ 50 ألف زائر/يوم وشات بوت بيرد على استفسارات الطلبات، كل رد مخترع ده تذكرة دعم زيادة وعميل مكسور الثقة.
الفكرة بمثال: الموظف الجديد
تخيّل موظف استقبال جديد في شركة. عميل اتصل وسأل: "وصل طلبي ولا لسه؟". في إيد الموظف طريقين. الأول إنه يرد من دماغه علشان ميبانش جاهل: "آه وصل، متقلقش". ده بالظبط اللي الـ LLM بيعمله من غير tools — بيجاوب بثقة من بيانات مش موجودة عنده. الطريق التاني إنه يقول "ثانية واحدة"، يرفع سماعة المخزن، يسأل، وبعدين يرد بالإجابة الحقيقية.
Function Calling بيدّي الـ LLM السماعة دي. بدل ما يخمّن، بيقولك: "أنا محتاج أنادي دالة get_order_status وأديها الرقم ده". انت بتنفّذ الدالة وترجّعله النتيجة، وهو يصيغ الرد النهائي على البيانات الصح.
التعريف العلمي
Function Calling (واسمه التاني Tool Use، والمصطلحين مترادفين) هو عقد بين تطبيقك والنموذج. انت بتعرّف للنموذج مجموعة أدوات، كل أداة ليها اسم، وصف بلغة طبيعية، وJSON Schema بيحدد شكل المدخلات. النموذج بيقرر إمتى وبأي وسائط يستدعي الأداة، لكنه مابينفّذش حاجة بنفسه. هو بس بيصدر طلب منظّم (block اسمه tool_use)، كودك ينفّذ العملية، والنتيجة ترجع للمحادثة في block اسمه tool_result. الحلقة دي بتتكرر لحد ما النموذج يبقى عنده كل اللي محتاجه علشان يرد. (المصدر: توثيق Anthropic عن Tool Use).
الكود: tool use على Claude API
هنعرّف أداة واحدة بترجّع حالة طلب. لاحظ إن الدالة الحقيقية get_order_status هي كودك انت — query على الداتابيز أو call على microservice داخلي.
import anthropic
client = anthropic.Anthropic()
tools = [{
"name": "get_order_status",
"description": "يرجّع حالة الطلب الحالية من قاعدة بيانات الطلبات. استخدمه لما العميل يسأل عن طلب برقمه.",
"input_schema": {
"type": "object",
"properties": {
"order_id": {"type": "string", "description": "رقم الطلب، مثال: ORD-10293"}
},
"required": ["order_id"]
}
}]
def get_order_status(order_id: str) -> dict:
# ده كودك الفعلي — استعلام على الداتابيز بتاعتك
return {"order_id": order_id, "status": "تم الشحن", "eta": "2026-06-20"}
messages = [{"role": "user", "content": "فين طلبي رقم ORD-10293؟"}]
resp = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=1024,
tools=tools,
messages=messages,
)
# بدل ما يخترع الإجابة، Claude رجّع stop_reason == "tool_use"
if resp.stop_reason == "tool_use":
call = next(b for b in resp.content if b.type == "tool_use")
result = get_order_status(**call.input) # نفّذ الدالة بالوسائط اللي طلبها
messages.append({"role": "assistant", "content": resp.content})
messages.append({"role": "user", "content": [{
"type": "tool_result",
"tool_use_id": call.id,
"content": str(result),
}]})
final = client.messages.create(
model="claude-sonnet-4-6", max_tokens=1024,
tools=tools, messages=messages,
)
print(final.content[0].text)
# -> "طلبك ORD-10293 اتشحن ومتوقع يوصلك يوم 20 يونيو."