مستوى المقال: متوسط — تحتاج معرفة بـ Python واستدعاء HTTP API بسيط، ويفترض إنك سبق وكلّمت Claude أو ChatGPT من كود مرة على الأقل. زمن القراءة المتوقع: 9 دقائق.
Tool Use في Claude: ازاي تخلّي النموذج يستدعي كودك بدل ما يهلوس
لو سألت Claude "كام الساعة في طوكيو دلوقتي؟" هيرد عليك جواب اخترعه من دماغه. السبب مش غباء — الـ LLM ما عندوش وصول للوقت الحقيقي. Tool Use هو الجسر اللي بيخلّي النموذج يقول لكودك "أنا محتاج أنادي function اسمها get_time" بدل ما يخمّن. النتيجة: شات بوت بيرد على أسئلة عن المخزون والأسعار والـ APIs الداخلية بدقة بتطلع من 64% لـ 91% على شات بوت دعم فني بـ 2,400 محادثة يومياً.
المشكلة باختصار
الـ LLM model عنده وزن (weights) مدرّب على بيانات لحد تاريخ معيّن. بالظبط زي محاسب حافظ كتاب من سنة 2024: يعرف كل اللي فيه، لكن مش هيعرف سعر الدولار النهارده. لو سألته، هيخمّن. والتخمين ده اسمه hallucination.
طبّق ده على شات بوت لشركة بتبيع منتجات. الزبون سأل: "هل عندكم اللاب توب موديل X في المخزن؟". النموذج لوحده مش هيعرف. هيخترع جواب لأن weights الـ training ما فيهاش inventory الشركة بتاعتك. الحل مش fine-tuning، الحل إن النموذج يكلّم قاعدة بياناتك في اللحظة ويرجع بالرقم الحقيقي.
مثال للمبتدئ: السكرتير والمراجع
تخيّل سكرتير ذكي بيرد على مكالمات الشركة. حد اتصل وسأل "كام رصيد فاتورتي؟" — السكرتير معندوش الرقم في دماغه، لكنه عارف يقول للزبون "ثانية واحدة"، يفتح برنامج المحاسبة، يدوّر باسم الزبون، ياخد الرقم، يقفل البرنامج، يرجع للزبون يقوله الجواب.
السكرتير ده Claude. برنامج المحاسبة ده الـ tool. اللحظة اللي بيقول فيها "ثانية واحدة" هي الـ tool_use response. والرقم اللي بيرجع هو الـ tool_result. النموذج لا بيخترع رقم ولا بيقول "معرفش". بيقول "أنا محتاج أكلّم نظام تاني".
التعريف العلمي
Tool Use (والمسمّى الأكاديمي Function Calling) هو بروتوكول بين الـ LLM وكودك بيشتغل في 4 خطوات محدّدة:
- إنت بتبعت request للنموذج فيه: السؤال + قائمة tools متاحة. كل tool له اسم، وصف، و JSON Schema لمدخلاته.
- لو النموذج قرّر إنه محتاج tool، بيرد بـ
stop_reason = "tool_use"ومعاه اسم الـ tool والـ inputs اللي يطابقوا الـ schema. - كودك بينفّذ الـ tool فعلياً (DB query، API call، حسبة، write على ملف) ويرجّع النتيجة كـ
tool_result. - بتبعت النتيجة تاني للنموذج، وهو بيكوّن الإجابة النهائية بلغة طبيعية للمستخدم.
الطريقة دي مبنية على فكرة ReAct (Reasoning + Acting) من ورقة Yao et al. 2022، اللي بتسمح للنموذج إنه يفكّر مرحلياً، يستدعي tool، يقرأ النتيجة، يفكّر تاني، ويستدعي tool ثاني لو محتاج. الـ loop ده بيستمر لحد ما النموذج يقرّر إنه عنده كفاية معلومات يرد بيها.
كود شغّال على Claude Sonnet 4.6
المثال ده شات بوت بسيط بيرد على سؤال "كام درجة الحرارة في القاهرة؟" بدل ما يخمّن، بيستدعي tool حقيقي:
import anthropic
client = anthropic.Anthropic()
tools = [{
"name": "get_weather",
"description": "ترجع درجة الحرارة الحالية لمدينة بالسيلسيوس + الرطوبة.",
"input_schema": {
"type": "object",
"properties": {
"city": {"type": "string", "description": "اسم المدينة بالعربي أو الإنجليزي"}
},
"required": ["city"]
}
}]
def execute_tool(name, params):
if name == "get_weather":
# هنا بتكلّم API حقيقي زي OpenWeather
return {"city": params["city"], "temp_c": 32, "humidity": 58}
raise ValueError(f"Unknown tool: {name}")
messages = [{"role": "user", "content": "كام درجة الحرارة في القاهرة دلوقتي؟"}]
while True:
resp = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=1024,
tools=tools,
messages=messages,
)
messages.append({"role": "assistant", "content": resp.content})
if resp.stop_reason != "tool_use":
print(resp.content[-1].text)
break
tool_results = []
for block in resp.content:
if block.type == "tool_use":
result = execute_tool(block.name, block.input)
tool_results.append({
"type": "tool_result",
"tool_use_id": block.id,
"content": str(result),
})
messages.append({"role": "user", "content": tool_results})
الـ loop ده مهم: النموذج ممكن يستدعي 1 أو 5 tools على التوالي قبل ما يكتفي. وقتها stop_reason بيتغيّر من "tool_use" لـ "end_turn". لو حذفت الـ loop وكتفيت بـ if واحد، شات البوت هيقطع في نص الـ reasoning لو النموذج محتاج tool ثاني.
أرقام من Berkeley Function Calling Leaderboard
BFCL هو المرجع الفعلي لقياس دقة استدعاء الـ tools في 2026. القياس بيتم على Abstract Syntax Tree بيقارن استدعاء النموذج بالاستدعاء الصحيح. على نسخة V3:
- GLM 4.5 في الصدارة بـ 76.7%.
- Qwen3 32B بـ 75.7%.
- على V4 الأحدث (multi-turn و agentic)، Llama 3.1 405B Instruct بـ 88.5%.
على شات بوت دعم فني تجاري عربي بمعدل 2,400 محادثة يومياً، قياس داخلي لفريق Optimizing بالعربي رصد إن تطبيق Tool Use بيرفع الدقة من 64% (تخمين النموذج وحده) لـ 91% (مع DB query حقيقي على المخزون). الـ trade-off: متوسط الـ latency يزيد من 1.1 ثانية لـ 2.4 ثانية بسبب الـ round trip الإضافي.
Trade-offs خفية لازم تعرفها
- Latency بيتضاعف: كل tool call = round trip إضافي للنموذج. لو فيه 3 tools متتالية، الـ response هيتأخر 3 أضعاف. الحل: تشغيل الـ tools على التوازي لما النموذج يطلب أكتر من tool في نفس الرد (parallel tool use مدعوم في Claude 4 family).
- التكلفة بتزيد قبل ما تكسب: الـ tools description بتتحط في كل request كـ system prompt. لو عندك 20 tool وكل واحد متوسطه 200 token، إنت بتدفع 4,000 token زيادة في كل استدعاء. استخدم Prompt Caching علشان تنزّل التكلفة دي 90%.
- تصميم الـ schema حرج: لو الـ description بتاع الـ tool ضعيف، النموذج هيستدعيه في الوقت الغلط أو يبعت inputs غلط. اكتب description مفصّل لكل field. مثلاً بدل "city: string" اكتب "city: اسم المدينة بالعربي أو الإنجليزي، مثلاً 'القاهرة' أو 'Tokyo'".
- error handling مسؤوليتك: الـ tool ممكن يفشل (API down، DB lock، rate limit). لازم ترجّع error واضح للنموذج بدل ما تطلع exception. الـ best practice: ابعت
{"error": "rate_limited", "retry_after": 30}وخلّي النموذج يقرّر يحاول تاني ولا يعتذر للمستخدم.
متى لا تستخدم Tool Use
الافتراض الأساسي إن النموذج لوحده مش عارف الإجابة. خالف الافتراض ده وTool Use بيبقى ضرر. حالات بعينها:
- مهام لغوية بحتة: تلخيص، ترجمة، إعادة صياغة، تصحيح إملائي. النموذج عارف يعملها وحده. إضافة tools هتزوّد latency وtokens بدون فايدة.
- workflow ثابت ومعروف الخطوات سلفاً: لو الـ pipeline هو fetch → transform → save في كل مرة بدون قرار، اعمل function calls عادية من الكود ومتخليش النموذج يقرّر. هتوفر round trip كامل.
- عمليات حساسة جداً: تحويلات مالية، حذف سجلات. خلي النموذج يرجّع الـ intent بس، وكودك يطلب confirmation يدوية قبل التنفيذ. سيب الـ Tool ينفّذ بنفسه بس في الحاجات اللي reversible.
الخطوة التالية
افتح Anthropic Console، اعمل tool واحد بسيط (مثلاً get_current_time اللي بيرجع datetime.now())، وجرّب الـ loop اللي فوق. لو الـ stop_reason رجع "end_turn" من أول استدعاء بدون ما النموذج يطلب الـ tool، ده معناه إن وصف الـ tool مش واضح لـ Claude. حسّن الـ description و استلم. ولو لقيت إن الـ tools description بتاكل tokens كتير، اقرأ مقال Prompt Caching للمتوسط على نفس الموقع وطبّق الـ cache_control على array الـ tools.
مصادر
- توثيق Claude Tool Use الرسمي: platform.claude.com/docs/en/agents-and-tools/tool-use/overview
- Advanced Tool Use announcement من Anthropic Engineering: anthropic.com/engineering/advanced-tool-use
- Berkeley Function Calling Leaderboard V4: gorilla.cs.berkeley.edu/leaderboard.html
- ورقة ReAct: Reasoning and Acting in Language Models — Yao et al. 2022: arxiv.org/abs/2210.03629
- ورقة BFCL: From Tool Use to Agentic Evaluation — Patil et al. 2025 (ICML): proceedings.mlr.press/v267/patil25a.html