كيفية استخدام استدعاء الدوال مع DeepSeek V4 Pro API

دليل عملي لاستدعاء وظائف DeepSeek V4 Pro: مخططات الأدوات، حلقة وكيل بايثون الكاملة، استدعاءات الأدوات المتوازية، وضع التفكير، معالجة الأخطاء، تكاليف التخزين المؤقت، واختبار استدعاءات الأدوات في Apidog.

INEZA Felin-Michel

INEZA Felin-Michel

13 أغسطس 2026

كيفية استخدام استدعاء الدوال مع DeepSeek V4 Pro API

Apidog للمؤسسات

النشر على الخوادم المحلية

SSO و RBAC

متوافق مع SOC 2

استكشف Apidog للمؤسسات

أخرجت DeepSeek الإصدار V4 Pro من مرحلة المعاينة في 12 أغسطس 2026، وتتصدر تغطية الإطلاق سير العمل التفاعلي (agentic workflows): مثل البرمجة، واستخدام الأدوات، والمهام طويلة المدى التي تربط عشرات الخطوات دون فقدان تسلسل العمل. هذا التموضع يجعل ميزة واحدة في واجهة برمجة التطبيقات (API) أهم من أي ميزة أخرى، وهي استدعاء الدالة (function calling)، وهي الميزة الوحيدة التي لم تتطرق إليها أدلة الأسبوع الأول من الإطلاق. تتوقف كل البرامج التعليمية حتى الآن عند إكمال الدردشة.

هذا الدليل يذهب أبعد من ذلك: قم بتعريف مخطط أداة، وقم بأول استدعاء لأداة باستخدام حزمة SDK القياسية `openai` في بايثون، وقم ببناء حلقة الوكيل الكاملة، ثم اختبر كل ذلك في Apidog قبل إطلاق وكيلك. إذا لم يكن لديك مفتاح DeepSeek API بعد، فقم بإعداده باستخدام دليلنا حول كيفية استخدام DeepSeek V4 API، ثم عد إلى هنا.

button

TL;DR

لماذا يعتبر استدعاء الأدوات حالة الاستخدام الرئيسية لـ V4 Pro

صممت DeepSeek الإصدار V4 Pro للوكلاء، وتبدو ورقة المواصفات وكأنها قائمة تحقق لوقت تشغيل الوكيل (agent-runtime):

المواصفات DeepSeek V4 Pro
البنية Sparse MoE: 1.6 تريليون معلمة إجمالية، 49 مليار معلمة نشطة لكل توكن
نافذة السياق 1 مليون توكن
الحد الأقصى للمخرجات 384 ألف توكن
سعر الإدخال 0.435 دولار/مليون توكن (في حالة عدم وجود ذاكرة مؤقتة)، 0.003625 دولار/مليون (في حالة وجود ذاكرة مؤقتة)
سعر المخرجات 0.87 دولار/مليون توكن
استدعاء الدالة مصفوفة `tools` المتوافقة مع OpenAI واستجابات `tool_calls`
واجهات أخرى تنسيق رسائل Anthropic، وواجهة برمجة تطبيقات استجابات DeepSeek

يرتبط كل سطر بمشكلة وكيل: نافذة السياق بحجم 1 مليون توكن تحمل سجل نتائج الأداة الكامل للوكيل الطويل الأمد، وسقف الإخراج البالغ 384 ألف توكن يترك مجالًا للأحمال الكبيرة المنظمة، والتخزين المؤقت للمقدمة يجعل اقتصاديات الحلقة تعمل. النموذج مدرج على OpenRouter باسم deepseek-v4-pro-0813 للمقارنات بين الموفرين.

تنبيه واحد قبل الكود. في مناقشة إطلاق Hacker News، أفاد المطورون أن أداء استدعاء الأدوات حساس للغاية للبيئة المحيطة: نفس النموذج سجل أداءً أفضل أو أسوأ اعتمادًا على الإطار، وهيكل التعليمات (prompt scaffolding)، ونمط المخطط. لن تخبرك المعايير القياسية كيف يتعامل النموذج مع مخططات أدواتك. اختبر بتعريفاتك الحقيقية.

كيف يعمل استدعاء الدوال في DeepSeek

استدعاء الدالة لا يعني أن النموذج ينفذ أي شيء. إنه يستجيب بطلب منظم، "استدعاء `get_order` مع `{"order_id": "ORD-10442"}`"، بدلاً من النص النثري. يقوم الكود الخاص بك بتشغيل الدالة، ويعيد النتيجة، ويستمر النموذج في العمل بالبيانات الحقيقية. الدورة هي:

  1. ترسل `messages` بالإضافة إلى مصفوفة `tools` تصف كل دالة في مخطط JSON.
  2. يقرر النموذج أن هناك حاجة لأداة ويستجيب بـ `tool_calls` و `finish_reason: "tool_calls"`.
  3. يقوم الكود الخاص بك بتحليل الوسائط وتشغيل الدالة الفعلية.
  4. تقوم بإلحاق النتيجة كرسالة `role: "tool"` مرتبطة بمعرف الاستدعاء.
  5. يطلب النموذج أداة أخرى أو ينتج إجابته النهائية.

إذا كنت قد عملت مع استدعاء الدوال في OpenAI، فهذا هو نفس تنسيق الاتصال؛ يتم نقل معظم أكواد الوكلاء عن طريق تغيير عنوان URL الأساسي واسم النموذج. تغطي وثائق DeepSeek الرسمية أيضًا نقطة نهاية للرسائل متوافقة مع Anthropic وواجهة برمجة تطبيقات للاستجابات (Responses API)، ولكن هذا الدليل يلتزم بالواجهة المتوافقة مع OpenAI.

الخطوة 1: إعداد العميل

قم بتثبيت حزمة SDK ووجّهها إلى DeepSeek:

pip install openai
export DEEPSEEK_API_KEY="sk-..."
import os
from openai import OpenAI

client = OpenAI(
    api_key=os.environ["DEEPSEEK_API_KEY"],
    base_url="https://api.deepseek.com",
)

هذا هو الإعداد بالكامل. يستخدم كل مثال `model="deepseek-v4-pro"`، والذي يشير إلى إصدار GA DeepSeek-V4-Pro-0813.

الخطوة 2: تحديد مخطط أداة

سنقوم ببناء وكيل دعم لمتجر عبر الإنترنت. تقوم أول أداة لديه بالبحث عن الطلبات. يحتوي تعريف الأداة على ثلاثة أجزاء: اسم، وصف، ومخطط JSON للمعاملات.

tools = [
    {
        "type": "function",
        "function": {
            "name": "get_order",
            "description": (
                "Look up a customer order by its ID. Returns the order status, "
                "carrier, tracking number, and estimated delivery date. Use this "
                "whenever the user asks where an order is or what state it's in."
            ),
            "parameters": {
                "type": "object",
                "properties": {
                    "order_id": {
                        "type": "string",
                        "description": "The order ID, formatted like 'ORD-10442'.",
                    }
                },
                "required": ["order_id"],
            },
        },
    }
]

الوصف ليس مجرد زينة: يقرر النموذج متى يستدعي أداة من خلال قراءته. الأوصاف الغامضة هي السبب الرئيسي وراء تجاهل النموذج لأداة أو اختيار أداة خاطئة.

الدالة المحلية التي يصفها المخطط، وهي بديل لخدمة طلبات حقيقية:

def get_order(order_id: str) -> dict:
    """Stub for your real order service."""
    fake_db = {
        "ORD-10442": {
            "status": "shipped",
            "carrier": "DHL",
            "tracking_number": "4281337005",
            "estimated_delivery": "2026-08-15",
        },
        "ORD-10587": {
            "status": "processing",
            "estimated_ship_date": "2026-08-14",
        },
    }
    return fake_db.get(order_id, {"error": f"Unknown order ID: {order_id}"})

الخطوة 3: إجراء أول استدعاء لأداة

أرسل سؤالًا لا يمكن للنموذج الإجابة عليه بدون الأداة:

messages = [
    {"role": "system", "content": "You are a support agent for an online store."},
    {"role": "user", "content": "Where is my order ORD-10442?"},
]

response = client.chat.completions.create(
    model="deepseek-v4-pro",
    messages=messages,
    tools=tools,
)

message = response.choices[0].message
print(message.tool_calls[0].function.name) # get_order
print(message.tool_calls[0].function.arguments) # {"order_id": "ORD-10442"}

بدلاً من الإجابة، يطلب منك النموذج تشغيل `get_order`. تبدو حمولة الاستجابة الخام هكذا:

{
  "id": "chatcmpl-8f3a1c",
  "object": "chat.completion",
  "model": "deepseek-v4-pro",
  "choices": [
    {
      "index": 0,
      "message": {
        "role": "assistant",
        "content": "",
        "tool_calls": [
          {
            "id": "call_0_f1c29a44",
            "type": "function",
            "function": {
              "name": "get_order",
              "arguments": "{\"order_id\": \"ORD-10442\"}"
            }
          }
        ]
      },
      "finish_reason": "tool_calls"
    }
  ],
  "usage": {
    "prompt_tokens": 312,
    "completion_tokens": 24,
    "total_tokens": 336,
    "prompt_cache_hit_tokens": 0,
    "prompt_cache_miss_tokens": 312
  }
}

ثلاثة تفاصيل مهمة. `finish_reason` هو `"tool_calls"`، والذي يخبر حلقتك أن النموذج يريد التنفيذ. يحمل كل استدعاء `id` يجب عليك إرجاعه مع النتيجة. و `arguments` هو *سلسلة نصية* JSON تقوم بتحليلها بنفسك، لذا توقع أن تكون أحيانًا خاطئة التكوين.

الخطوة 4: تنفيذ الدالة وإرجاع النتيجة

قم بتشغيل الدالة، ثم ألحق رسالتين: دور المساعد الذي يحتوي على `tool_calls`، ورسالة `tool` التي تحمل نتيجتك.

import json

tool_call = message.tool_calls[0]
args = json.loads(tool_call.function.arguments)
result = get_order(args)

messages.append(message) # the assistant turn containing tool_calls
messages.append({
    "role": "tool",
    "tool_call_id": tool_call.id, # must match the id from the response
    "content": json.dumps(result),
})

final = client.chat.completions.create(
    model="deepseek-v4-pro",
    messages=messages,
    tools=tools,
)
print(final.choices[0].message.content)
# Your order ORD-10442 shipped with DHL and is estimated to arrive
# by August 15, 2026. Tracking number: 4281337005.

الرابط `tool_call_id` صارم: كل إدخال `tool_calls` يحتاج إلى رسالة `tool` مطابقة قبل دور النموذج التالي، وإلا سيفشل الطلب.

الخطوة 5: حلقة الوكيل الكاملة

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

TOOLS_BY_NAME = {"get_order": get_order}

def run_agent(client, messages, tools, max_rounds=10):
    """Run the model until it produces a final answer or hits the cap."""
    for _ in range(max_rounds):
        response = client.chat.completions.create(
            model="deepseek-v4-pro",
            messages=messages,
            tools=tools,
        )
        message = response.choices[0].message
        messages.append(message)

        if not message.tool_calls: # no tool requests: we're done
            return message.content

        for tool_call in message.tool_calls:
            fn = TOOLS_BY_NAME.get(tool_call.function.name)
            try:
                if fn is None:
                    raise ValueError(f"Unknown tool: {tool_call.function.name}")
                args = json.loads(tool_call.function.arguments)
                result = fn(args)
            except Exception as exc:
                result = {"error": str(exc)} # feed failures back to the model
            messages.append({
                "role": "tool",
                "tool_call_id": tool_call.id,
                "content": json.dumps(result),
            })

    raise RuntimeError(f"Agent did not finish within {max_rounds} rounds")

تعتبر الأطر وحزم SDK للوكلاء تفصيلات لهذه الحلقة. يحول حد `max_rounds` النموذج العالق في إعادة استدعاء أداة فاشلة إلى فشل نظيف بدلاً من فاتورة مفتوحة.

استدعاءات الأدوات المتوازية

اطلب بحثين، "قارن حالة ORD-10442 و ORD-10587"، وغالبًا ما يجمع V4 Pro كلاهما في دور واحد:

"tool_calls": [
  {
    "id": "call_0_a7d1",
    "type": "function",
    "function": { "name": "get_order", "arguments": "{\"order_id\": \"ORD-10442\"}" }
  },
  {
    "id": "call_1_b3e9",
    "type": "function",
    "function": { "name": "get_order", "arguments": "{\"order_id\": \"ORD-10587\"}" }
  }
]

تتعامل حلقة `run_agent` مع هذا بالفعل: حلقة `for` الداخلية تجيب على كل استدعاء بمعرف `tool_call_id` الخاص به (كل استدعاء يحتاج إلى نتيجة مطابقة قبل الدور التالي)، وأنت حر في تنفيذ الدفعة بشكل متزامن. إنها فلسفة مختلفة عن استدعاء الأدوات البرمجي في GPT-5.6، حيث يكتب النموذج كود التنسيق في بيئة معزولة (sandbox)؛ بينما تحتفظ DeepSeek بالتنفيذ، وحدود الثقة، في بيئة التشغيل الخاصة بك.

وضع التفكير بالإضافة إلى الأدوات

يأتي V4 Pro بثلاثة أوضاع للتفكير، حتى تتمكن من زيادة جهد التفكير لخطط صعبة وتجاوزه لعمليات البحث الروتينية (راجع الوثائق الرسمية لأسماء الأوضاع والإعدادات الافتراضية). مع تمكين التفكير، تُعيد واجهة برمجة التطبيقات (API) تتبع النموذج كـ `reasoning_content` جنبًا إلى جنب مع أي استدعاءات للأدوات:

response = client.chat.completions.create(
    model="deepseek-v4-pro",
    messages=messages,
    tools=tools,
    extra_body={"thinking": {"type": "enabled"}},
)

message = response.choices[0].message
print(message.reasoning_content) # the planning trace
print(message.tool_calls) # the calls it settled on

يعرض التتبع سبب اختيار النموذج لأداة ما، وهو عادةً ما يتجلى فيه المخطط السيئ. قم بإزالة `reasoning_content` قبل إلحاق دور المساعد بالسجل، واحتفظ بالتفكير للأدوار التي تتطلب تخطيطًا مكثفًا، حيث يتم محاسبة التفكير كمخرجات بسعر 0.87 دولار/مليون.

معالجة الأخطاء: عندما يخطئ النموذج في استدعاء

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

from jsonschema import ValidationError, validate

schema = tools[0]["function"]["parameters"]

try:
    args = json.loads(tool_call.function.arguments)
    validate(instance=args, schema=schema)
    result = get_order(**args)
except (json.JSONDecodeError, ValidationError) as exc:
    result = {
        "error": f"Invalid arguments: {exc}",
        "hint": "Call get_order again with an order_id string like 'ORD-10442'.",
    }

حقل `hint` مهم: تصحيح سطر واحد عادة ما ينتج عنه إعادة محاولة ثابتة في الجولة التالية. تعامل مع أخطاء الوكيل كأحداث أمنية أيضًا. النموذج الذي تم إقناعه باستدعاء `delete_order` باستخدام وسائط قدمها مهاجم لا يمثل خطورة إلا بقدر المفتاح الذي يقف وراءه، وهي حالة لمفاتيح API بأقل امتياز (least-privilege) لوكلاء الذكاء الاصطناعي. حدد نطاق بيانات الاعتماد بحيث لا يمكن أن يتحول الاستدعاء الخاطئ إلى حادث.

اختبار وتصحيح استدعاءات الأدوات باستخدام Apidog قبل الإطلاق

كل أداة هي غلاف رفيع حول واجهة برمجة تطبيقات (API)، والنموذج الآن هو مستهلك لتلك الواجهة. إذا كانت نقطة النهاية الخلفية غامضة أو غير مستقرة، فإن النموذج يرث كل ذلك. وهنا يكتسب Apidog مكانه في الحلقة:

  1. صمم واجهة برمجة التطبيقات الخلفية أولاً. عرّف `GET /orders/{order_id}` كمواصفة في مصمم Apidog المرئي؛ مخطط JSON الخاص بأداتك ينبثق مباشرة من المواصفة، لذلك لا يمكن أن ينجرف الاثنان بصمت.
  2. قم بمحاكاتها قبل وجود الواجهة الخلفية. تقدم المحاكاة الذكية في Apidog استجابات واقعية من المخطط، لذلك تعمل حلقة الوكيل مقابل `get_order` بينما لا تزال الخدمة الحقيقية قيد الإنشاء.
  3. افحص الحمولة الخام. أرسل نفس جسم `messages` + `tools` إلى `https://api.deepseek.com` من Apidog واقرأ `tool_calls` JSON الخام مباشرةً، لتظهر `properties` المدمجة بشكل خاطئ أو الوسائط المشفرة مرتين في فحص واحد.
  4. حول المحادثات إلى سيناريوهات اختبار. تحقق من `finish_reason` وأشكال الوسائط، وقم بتشغيل المجموعة في كل تغيير للمخطط؛ بالنظر إلى حساسية البيئة المبلغ عنها على Hacker News، فإن مجموعة اختبار الانحدار على مخططاتك الحقيقية هي المعيار الذي يتنبأ بالإنتاج. راجع ربط وكيل الذكاء الاصطناعي بنظام اختبار Apidog للحصول على نمط أعمق.

قم بتنزيل Apidog مجانًا للمتابعة؛ يتضمن المستوى المجاني خادم المحاكاة وسيناريوهات الاختبار.

تكلفة حلقات الوكيل (ولماذا يحدد التخزين المؤقت ذلك)

تعيد حلقات الوكيل قراءة المحادثة بأكملها في كل جولة: بحلول الجولة العاشرة، يتم احتساب رسوم مطالبتك بالنظام ومخططات الأدوات وتسع جولات من النتائج للمرة العاشرة. يكسر التخزين المؤقت التلقائي للمقدمة في V4 Pro هذه القاعدة، حيث يكون مدخل كل جولة هو مدخل الجولة السابقة بالإضافة إلى القليل، لذلك يتم احتساب معظم المقدمة بسعر 0.003625 دولار/مليون بدلاً من 0.435 دولار/مليون. إعادة قراءة محادثة بحجم 100 ألف توكن تكلف حوالي 0.0435 دولار غير مخزنة مؤقتًا ولكن حوالي 0.0004 دولار مخزنة مؤقتًا؛ يوضح `prompt_cache_hit_tokens` في كتلة الاستخدام معدل الإصابة الفعلي لديك.

للحفاظ على هذا المعدل مرتفعًا، لا تقم أبدًا بتعديل الرسائل السابقة، وحافظ على مصفوفة `tools` مستقرة بايتًا عبر الجولات. يغطي دليلنا حول ماهية التخزين المؤقت للموجه (prompt caching) الآليات. وإذا كان `deepseek-v4-flash` بسعر 0.14 دولار / 0.28 دولار يبدو مغريًا: فهو جيد لتوجيه الأدوات الفردية، لكنه يتدهور في الحلقات التي تربط 10+ استدعاءات، لذلك فإن عمليات إعادة المحاولة تستهلك الوفورات، ويعتبر Pro الخيار الافتراضي الأكثر أمانًا للوكلاء.

الأسئلة الشائعة

هل تكلف تعريفات الأدوات توكنات؟

نعم، تكون مصفوفة `tools` مدخلة في كل طلب. حافظ عليها مستقرة وستنضم إلى المقدمة المخزنة مؤقتًا بعد الجولة الأولى، ويتم احتسابها بسعر الاسترجاع من الذاكرة المؤقتة (cache-hit rate) من ذلك الحين فصاعدًا.

هل يمكنني دمج استدعاء الدوال مع المخرجات المنظمة؟

نعم. نمط شائع: تقوم الأدوات بجلب البيانات الوسيطة، ويقوم مخطط إخراج منظم بتنسيق الإجابة النهائية، بحيث لا يقوم الكود اللاحق بتحليل النص النثري أبدًا.

خلاصة

تنفيذ استدعاء الدوال في DeepSeek V4 Pro غير مثير عن قصد: مخططات متوافقة مع OpenAI، مصفوفة `tool_calls`، رسالة `tool` بمعرف. الحلقة في الخطوة 5 هي البنية بأكملها، وتسعير الاسترجاع من الذاكرة المؤقتة يجعلها أرخص مما تتوقعه معظم الفرق. ما لا يمكن أن تخبرك به المعايير القياسية هو كيف يتصرف النموذج مقابل مخططاتك، صمم واجهات برمجة التطبيقات الخلفية بعناية، حاكها مبكرًا، واحتفظ بمجموعة اختبار انحدار لسيناريوهات استدعاء الأدوات في Apidog حتى لا تؤدي تغييرات المخطط إلى تعطيل وكيلك بصمت.

button

ممارسة تصميم API في Apidog

اكتشف طريقة أسهل لبناء واستخدام واجهات برمجة التطبيقات