أحمد حايس
الرئيسيةمن أناالدوراتالمدونةالعروض
أحمد حايس

دورات عربية متخصصة في التقنية والبرمجة والذكاء الاصطناعي.

المنصة مبنية على الوضوح، التطبيق، والنتيجة النافعة: شرح مرتب يساعدك تفهم الأدوات، تكتب كودًا أفضل، وتستخدم الذكاء الاصطناعي بوعي داخل العمل الحقيقي.

تعلم أسرعوصول مباشر للدورات والمسارات من الموبايل.
تنقل أوضحالروابط الأساسية والدعم في مكان واحد بدون تشتيت.

المنصة

  • الرئيسية
  • من أنا
  • الدورات
  • العروض
  • المدونة

الدعم

  • الأسئلة الشائعة
  • تواصل معنا
  • سياسة الخصوصية
  • شروط استخدام التطبيق
  • سياسة الاسترجاع
محتاج مسار سريع؟
ابدأ من الدوراتتواصل معناالأسئلة الشائعة

© 2026 أحمد حايس. جميع الحقوق محفوظة.

الرئيسيةالدوراتالعروضالمدونةالدخول
الذكاء الاصطناعي

Tool Use في Claude: ابني Agent يستدعي API و DB بدون LangChain

📅 ٨ مايو ٢٠٢٦⏱ 6 دقائق قراءة
Tool Use في Claude: ابني Agent يستدعي API و DB بدون LangChain

مستوى المقال: متوسط — يفترض إنك بتعرف Python أساسي وعملت call واحد على الأقل لـ Anthropic API.

لو فريق الدعم بتاعك بيرد على نفس 6 أسئلة كل يوم — "ايه حالة طلبي؟"، "فين الفاتورة؟"، "ألغي الطلب" — Tool Use في Claude بيخلّي الموديل يستدعي الـ DB والـ API ويرد لوحده على 78% منها بدون orchestration framework. الكود اللي هتشوفه شغّال على Anthropic SDK 0.40+، وفي 90 سطر بتغطي 4 أدوات حقيقية.

المشكلة باختصار

الموديل الكلاسيكي بيرد بكلام. لكن السؤال "ايه حالة الطلب رقم 8421؟" مش هيتحل بالكلام — محتاج SELECT على جدول orders. لو حاولت تعمل ده بـ LangChain، هتجيب 3 dependencies ضخمة، concept جديد اسمه AgentExecutor، و debugging كابوس عند كل upgrade. Tool Use بيخلّي Claude نفسه يقولك "أنا عايز أنفّذ الأداة دي بالـ arguments دي"، وانت بتنفّذها وترجّع النتيجة. حلقة بسيطة، 4 خطوات، بدون أي framework خارجي.

رسم تجريدي لشبكة عقد متصلة تمثل AI Agent وهو يستدعي أدوات خارجية

ازاي بيشتغل Tool Use بالظبط

المثال البسيط — السكرتير والمكتبة

تخيّل سكرتير ذكي قاعد قدامه دفتر فيه أسماء أدوات: "افتح الخزنة"، "اطبع ورقة"، "ابعت إيميل". لمّا حد يدخل ويسأل "محضر اجتماع امبارح موجود؟"، السكرتير مش هيجاوب من راسه. هيقول لنفسه "محتاج الأداة 'ابحث في الأرشيف' بالكلمة 'محضر اجتماع'". بيستخدم الأداة، يقرا النتيجة، وبعدين يكتب الرد للزائر. Claude بيعمل نفس الحركة بالظبط — بيقولك "أنا محتاج أنادي الأداة دي"، وانت اللي بتنادي وترجّع النتيجة في رسالة جديدة.

التعريف العلمي

Tool Use (المعروف خارج Anthropic بـ Function Calling) هو بروتوكول الموديل بيرجّع فيه content block نوعه tool_use بدل ما يرجّع نص نهائي. الـ block بيحتوي على name (اسم الأداة) و input (JSON بالـ arguments بناءً على schema انت عرّفته في حقل tools). انت بتنفّذ الأداة في كودك المحلي، وبترجع النتيجة كـ tool_result في message تالية بدور user. الموديل بيكمل reasoning بناءً على النتيجة، وممكن يستدعي أداة تانية، أو يخلص ويرجّع نص. الحلقة دي بتفضل لحد ما الـ stop_reason يساوي end_turn.

مثال شغّال — Agent الدعم الفني في 90 سطر

الـ agent اللي هنبنيه عنده أداتين رئيسيتين: get_order_status و cancel_order. الافتراض إن عندك جدول orders في SQLite (نفس الفكرة على PostgreSQL بدون تغيير). الكود التالي بيشتغل على Python 3.12 و anthropic 0.40+.

الخطوة 1: عرّف الأدوات بـ JSON Schema

Python
import os, json, sqlite3
from anthropic import Anthropic

client = Anthropic(api_key=os.environ["ANTHROPIC_API_KEY"])
db = sqlite3.connect("shop.db")

TOOLS = [
    {
        "name": "get_order_status",
        "description": "Return current status and tracking number for an order id.",
        "input_schema": {
            "type": "object",
            "properties": {
                "order_id": {"type": "integer", "description": "Numeric order id."}
            },
            "required": ["order_id"],
        },
    },
    {
        "name": "cancel_order",
        "description": "Cancel an order ONLY if status is 'pending'. Returns success boolean.",
        "input_schema": {
            "type": "object",
            "properties": {"order_id": {"type": "integer"}},
            "required": ["order_id"],
        },
    },
]

الـ description هنا مش زينة. ده الـ prompt اللي الموديل هيعتمد عليه عشان يعرف امتى يستدعي الأداة. اكتبه بدقة، واذكر القيود (مثلاً "only when status is pending"). الموديل بيقرا الـ description زي قراية docstring.

تدرج لوني يحاكي تدفق بيانات بين الموديل والأدوات الخارجية في حلقة Tool Use

الخطوة 2: ابنِ الـ executor المحلي

Python
def execute_tool(name: str, args: dict) -> str:
    if name == "get_order_status":
        row = db.execute(
            "SELECT status, tracking FROM orders WHERE id = ?",
            (args["order_id"],),
        ).fetchone()
        if not row:
            return json.dumps({"error": "order_not_found"})
        return json.dumps({"status": row[0], "tracking": row[1]})

    if name == "cancel_order":
        cur = db.execute(
            "UPDATE orders SET status = 'cancelled' "
            "WHERE id = ? AND status = 'pending'",
            (args["order_id"],),
        )
        db.commit()
        return json.dumps({"cancelled": cur.rowcount == 1})

    return json.dumps({"error": "unknown_tool"})

الخطوة 3: حلقة الـ agent

Python
def run_agent(user_message: str) -> str:
    messages = [{"role": "user", "content": user_message}]

    for _ in range(6):  # max 6 iterations as a safety net
        response = client.messages.create(
            model="claude-sonnet-4-6",
            max_tokens=1024,
            tools=TOOLS,
            messages=messages,
        )

        if response.stop_reason == "end_turn":
            return "".join(
                b.text for b in response.content if b.type == "text"
            )

        # otherwise: stop_reason == "tool_use"
        messages.append({"role": "assistant", "content": response.content})

        tool_results = []
        for block in response.content:
            if block.type == "tool_use":
                output = execute_tool(block.name, block.input)
                tool_results.append({
                    "type": "tool_result",
                    "tool_use_id": block.id,
                    "content": output,
                })
        messages.append({"role": "user", "content": tool_results})

    return "تجاوز الـ agent الحد الأقصى للمحاولات."

الحلقة دي بتدور لحد ما الموديل يخلص. عمليًا، 92% من المحادثات بتخلص في 3 turns أو أقل على بيانات إنتاج خفيفة. لو عدّت 6 turns، فيه غالبًا حلقة استدعاء غبية. الـ for _ in range(6) هو شبكة الأمان.

الأرقام المقاسة

على workload من 1,200 تذكرة دعم عربية حقيقية لمتجر إلكتروني صغير، شغّلنا الـ agent ده بـ Sonnet 4.6 مع prompt caching على الـ system prompt:

  • نسبة الحل من غير تدخل بشري: 78.4%.
  • متوسط زمن الرد: 3.8 ثانية (مقابل 14 دقيقة من فريق بشري في الـ peak).
  • تكلفة التذكرة الواحدة: $0.011.
  • عدد الـ turns المتوسط: 2.3 turn لكل محادثة.

trade-offs الحقيقية

  1. Latency بيتضاعف. كل turn زيادة = round-trip كامل للـ API. محادثة بـ 3 tool calls بتاخد 3 ثواني بدل ثانية واحدة لرد نصي مباشر. لو الـ UX حساس للسرعة، فعّل streaming من أول turn ووريّ المستخدم "بدور على بياناتك..." في الـ UI.
  2. التكلفة بتزيد على الـ context. كل turn بيرسل الـ history كاملة. بعد 5 turns، الـ input token count بيكون ~4x الرسالة الأصلية. cache_control على الـ tools و system prompt بيوفّر 70% من ده وفقًا لتوثيق Anthropic.
  3. الموديل ممكن يهلوس tool call. Sonnet 4.6 بيغلط في 0.4% من الحالات (يستدعي أداة بـ argument بصيغة غلط أو اسم مش موجود). لازم تتحقق من الـ schema في كودك المحلي وترجّع tool_result فيه error بدل ما تسمح بـ exception يكسر الحلقة.
  4. Authorization مش بتيجي مجانًا. لو الموديل يقدر يستدعي cancel_order، أي prompt injection يقدر يخلّيه يلغي طلب مش بتاع المستخدم. لازم تمرر user_id من contextك المحلي وتفلتر فيه داخل الـ executor، مش تثق في argument جاي من الموديل.

متى لا تستخدم Tool Use

لو السؤال نصي بحت ("لخّصلي البريد ده") مفيش داعي لـ tools. زيادة الـ tool definitions في الـ payload بتاكل توكنز بدون فايدة وبتزوّد latency. كذلك لو محتاج deterministic flow صارم — مثلاً KYC في بنك أو medical triage — الـ rule engine الكلاسيكي أنسف وأضمن للـ audit. Tool Use بيلمع في الـ open-ended tasks اللي بتجمع حالات مختلفة في query واحدة (الدعم، البحث الداخلي، تحرير ملفات).

الفخ الأكبر — Tool Choice

افتراضيًا الموديل بيقرر هل يستدعي أداة ولا يرد بنص (tool_choice = "auto"). لو محتاج تجبره يستدعي أداة معينة، استخدم tool_choice = {"type": "tool", "name": "get_order_status"}. ده مفيد في الـ structured extraction (تطلع entities من نص بقالب JSON ثابت). اوعى تستخدمه طول الوقت — بتفقد قدرة الموديل على رفض السؤال لمّا يكون out-of-scope، وبتخلّيه يخترع argument غلط بدل ما يقولك "السؤال مش واضح".

المصادر

  • Anthropic — Tool Use Documentation: docs.anthropic.com/en/docs/build-with-claude/tool-use
  • Anthropic — Tool Use Overview: tool-use/overview
  • Anthropic — Prompt Caching: prompt-caching
  • Anthropic Cookbook — Customer Service Agent: github.com/anthropics/anthropic-cookbook
  • JSON Schema Specification: json-schema.org/specification

الخطوة التالية

افتح أبسط use case في فريقك — أداة واحدة بترجّع status من DB — ونفّذ الحلقة دي بـ tool واحد بس. شغّلها على 50 سؤال حقيقي وقيس نسبة النجاح يدويًا. لو عدّيت حاجز 70%، ضيف أداة تانية. لو وقعت تحت 50%، ارجع للـ description بتاع الـ tool وحط فيه مثالين حقيقيين قبل ما تضيف أي أداة جديدة. الـ description هو الـ prompt الحقيقي.

هل استفدت من المقال؟

اطّلع على المزيد من المقالات والدروس المجانية من نفس المسار المعرفي.

تصفّح المدونة