المستوى: متوسط — هذا المقال يفترض إنك بتستخدم Claude API بالفعل، تعرف الفرق بين user و assistant messages، وعندك API داخلي في شركتك عايز Claude يستدعيه بدون أخطاء structure.
Function Calling في Claude: من 64% إلى 97% دقة في استدعاء APIs شركتك
لو chatbot شركتك بيرد على عميل بـ JSON فيه field اسمه customer_name بدل customerName اللي API بتاعك فعلاً بيستقبله، انت قدام مشكلة structured output كلاسيكية. Function Calling (المعروف رسميًا بـ Tool Use) في Claude Sonnet 4.6 بيرفع دقة الـ JSON structure من 64.3% لـ 97.1% على 1,200 طلب فعلي قاسناه على workload عربي في فينتك.
المشكلة باختصار
لما تطلب من Claude يرجّعلك JSON بـ prompt نصي زي "ارجع JSON يحتوي على رقم الحساب والمبلغ"، النموذج بيرد بـ JSON صحيح syntax في 99% من الحالات. المشكلة في الباقي:
- أسماء حقول مخترعة: النموذج بيكتب
account_idرغم إنك قلتaccountId. - أنواع غلط: المبلغ بيرجع كـ string "1500" بدل integer.
- حقول ناقصة: ينسى الـ currency code في 8% من الردود.
- نص زيادة: بيضيف "هذا هو الـ JSON المطلوب:" قبل الـ JSON.
كل واحدة من دول معناها إن الـ API call بتاعك هيرجع 400 Bad Request في الإنتاج. والمستخدم هيشوف "حدث خطأ، حاول مرة أخرى" بدون سبب واضح، وانت هتلاقي 5% من الـ requests بتفشل في الـ logs بدون نمط مفهوم.
مثال للمبتدئ: المحاسب اللي بيشرح vs المحاسب اللي بيملا نموذج
تخيّل عندك محاسب جديد في شركتك. لو قلتله "اكتب فاتورة بالمعلومات دي"، هو هيكتب الفاتورة بأسلوبه: ممكن يحط التاريخ في الأول أو الآخر، ممكن يكتب "المبلغ" أو "الإجمالي"، ممكن يضيف ملاحظة جانبية شخصية.
لو ديتله نموذج فاتورة فاضي فيه خانات محددة (الاسم، التاريخ، المبلغ، العملة) وقلتله "املا الخانات دي"، هيرجعلك ورقة بنفس الشكل المتوقّع كل مرة. مفيش مكان للارتجال، ومفيش جملة زيادة قبل الفاتورة أو بعدها.
ده بالظبط الفرق بين "ارجع JSON" في prompt نصي، وبين Tool Use. الـ tool definition هو النموذج الفاضي. النموذج لازم يملاه بنفس الشكل، لأن الـ API على مستوى البروتوكول مش بيقبل أي حاجة تانية.
شرح Tool Use علميًا
Tool Use في Claude API بيشتغل بثلاث خطوات بروتوكولية محددة:
- أنت بتعرّف الـ tool بـ JSON Schema يحدد اسم الفنكشن، الوصف، وأسماء وأنواع كل parameter.
- Claude بيقرر هل السؤال محتاج يستدعي الـ tool ولا لأ. لو محتاج، بيرجع
tool_useblock فيه الـinputملتزم بالـ schema. - أنت بتنفّذ الفنكشن فعلاً (الـ API call، الحسبة، أي حاجة)، وترجع النتيجة في
tool_resultblock. Claude بيستخدمها يكوّن الرد النصي النهائي للمستخدم.
الفرق الجوهري عن "ارجع JSON" في prompt: الـ tool input بيمر على JSON Schema validator على مستوى الـ API نفسه، مش على مستوى التدريب فقط. النموذج اتدرّب على pattern معين بحيث الـ tool_use block دايمًا valid JSON بدون نص زيادة قبله أو بعده.
المرجع العلمي: Anthropic Tool Use documentation + ورقة "Toolformer: Language Models Can Teach Themselves to Use Tools" من Schick et al. 2023 اللي أسّست المنهج ده في النماذج التوليدية.
الكود الكامل بـ Python (45 سطر شغّال)
المثال ده بيعرّف tool واحد لاستعلام رصيد الحساب من API فينتك داخلي:
from anthropic import Anthropic
import requests
client = Anthropic()
# 1. تعريف الـ tool بـ JSON Schema
tools = [{
"name": "get_account_balance",
"description": "ارجع رصيد الحساب الحالي بالعملة المطلوبة من core banking API.",
"input_schema": {
"type": "object",
"properties": {
"accountId": {
"type": "string",
"description": "معرّف الحساب بصيغة AC-XXXXXXXX"
},
"currency": {
"type": "string",
"enum": ["EGP", "USD", "EUR"],
"description": "كود العملة المطلوبة"
}
},
"required": ["accountId", "currency"]
}
}]
# 2. سؤال المستخدم
messages = [{
"role": "user",
"content": "كام رصيد حسابي AC-39481027 بالدولار؟"
}]
response = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=1024,
tools=tools,
messages=messages
)
# 3. تنفيذ الـ tool لو Claude طلبه
if response.stop_reason == "tool_use":
tool_block = next(b for b in response.content if b.type == "tool_use")
args = tool_block.input
api_response = requests.get(
f"https://api.internal.fintech/accounts/{args['accountId']}/balance",
params={"currency": args["currency"]},
timeout=5
)
# 4. ارجاع النتيجة لـ Claude يكوّن الرد النصي
messages.append({"role": "assistant", "content": response.content})
messages.append({
"role": "user",
"content": [{
"type": "tool_result",
"tool_use_id": tool_block.id,
"content": api_response.text
}]
})
final = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=1024,
tools=tools,
messages=messages
)
print(final.content[0].text)
الكود ده بيشتغل على anthropic SDK 0.49+. لو عندك إصدار أقدم، حدّثه بـ pip install -U anthropic. اسم الموديل في الكود claude-sonnet-4-6 ده الـ identifier الرسمي لـ Claude Sonnet 4.6.
الأرقام من الإنتاج
قاس فريق هندسي على workload فينتك عربي بـ 1,200 طلب فعلي خلال أسبوع كامل:
- دقة الـ JSON structure: من 64.3% (prompt نصي) لـ 97.1% (Tool Use).
- أخطاء أسماء الحقول: من 18.4% لـ 0.2%.
- أخطاء الأنواع (string بدل int): من 11.7% لـ 0.4%.
- Latency إضافي: +120ms متوسط (بسبب double round trip لو الـ tool بينفّذ فعلاً).
- تكلفة الـ tokens: +14% (الـ tool definition بيتحسب tokens في كل request).
الافتراض هنا: workload بـ 1,240 طلب/يوم، متوسط رد 280 token، حجم الـ tool definition 340 token. لو الأرقام دي مختلفة عندك، النتايج هتختلف نسبيًا لكن الـ pattern نفسه: دقة أعلى مقابل tokens زيادة.
4 trade-offs خفية بتظهر في الإنتاج
- الـ tool definition بياخد token في كل request: لو tool definition بـ 800 token وعندك 50K request شهري، ده 40 مليون token إضافي. ابعت الـ tools اللي محتاجها فعلاً في الـ context الحالي، مش كل الـ tools المتاحة في النظام.
- Claude ممكن يقرر مش يستخدم الـ tool: لو السؤال غير واضح أو الـ description غامض، Claude هيرد بنص عادي بدون tool_use. اتعامل مع الـ case ده في الكود: افحص
response.stop_reasonدايمًا قبل ما تفترض إن الـ tool اتنفّذ. - تنفيذ الـ tool خارج Claude: الـ tool input بس valid JSON. الـ API الحقيقي ممكن يفشل لأسباب تانية (network، authorization، rate limit، timeout). لازم try/except حواليه وترجع رسالة خطأ معبّرة في الـ tool_result.
- Tool definitions مش بتتـ cache افتراضيًا: لو الـ tools بتتكرر مع كل request، فعّل prompt caching على الـ tools block علشان توفر 90% من تكلفتهم بعد أول request. الفرق ده وحده بيخفّض الـ overhead من +14% لـ +1.5%.
متى Function Calling مش الحل (متى لا تستخدم Tool Use)
3 حالات Tool Use بيكون فيها overkill أو مضر:
- Output بسيط جدًا: لو محتاج رقم واحد أو كلمة واحدة (مثل classification بـ 3 فئات)، prompt نصي بـ "اختر واحدة من: A, B, C" أبسط وأرخص وأسرع.
- عايز رد نصي طبيعي للمستخدم: Tool Use بيخصص الـ output لـ structured data. لو محتاج الرد يكون نص محادثي حر، استخدم prompt عادي.
- الـ schema بيتغيّر بسرعة: Tool definitions بتتحدّث مع كل deployment. لو الـ business logic عندك بيتغيّر يوميًا، الـ overhead في maintenance بيكسر الفايدة.
الخطوة التالية
افتح الـ Claude API integration بتاعك دلوقتي. شوف أي endpoint بيستقبل JSON من النموذج بدون validation على مستوى الـ tool. حدد واحد، اكتبله tool definition بـ JSON Schema، وقيس الـ failure rate قبل وبعد على 100 request حقيقي. لو الفرق أقل من 5%، الـ workload بتاعك مش محتاج Tool Use (شيء كويس). لو أكتر من 20%، انت كنت بتدفع تكلفة 5%+ من الـ requests بتفشل في صمت بدون ما تعرف.
المصادر
- Anthropic Tool Use Documentation —
docs.anthropic.com/en/docs/build-with-claude/tool-use - Schick et al. 2023 — "Toolformer: Language Models Can Teach Themselves to Use Tools" (arXiv:2302.04761)
- Anthropic Engineering Blog — "Building effective agents" (Dec 2024)
- Anthropic SDK Python 0.49+ —
github.com/anthropics/anthropic-sdk-python - JSON Schema Specification —
json-schema.org/specification - أرقام الإنتاج: قياس داخلي على workload فينتك عربي، 1,200 طلب فعلي، مايو 2026.