Phase 13: Tools & Protocols

توسيع مهام المفوضية: العمل المستدام على أساس بلا جنسية

لا يعني MCP بدون جنسية أن كل عملية يجب أن تنتهي في طلب واحد. تمديد المهام الرسمية يعطي العمل الطويل المشي مسدسة دائمة صريحة. يمكن للخادم إعادة هذا المسدس من tools/call، أي حالة يمكن أن تجيبtasks/getومدخل العميل يصل من خلالtasks/updateبدون إحياء جلسات البروتوكول

Type: Build

Languages: Python

Prerequisites: Phase 13 · 09 (transports), Phase 13 · 11 (stateless MRTR), Phase 13 · 12 (elicitation)

Time: ~90 minutes

أهداف التعلم

  • تمييز النقل البروتوكول بدون ولاية عن حالة مهمة التطبيق الدائمة.
  • التفاوضio.modelcontextprotocol/tasksتوسيع قدرات الطلب وserver/discover. . .
  • أعد إرسال محرك الخادمCreateTaskResultمعresultType: "task"إلا بعد خلق دائم
  • استطلاع معtasks/get، اجتياز مدخل المهمة مع tasks/update، وطلب إلغاء التعاون مع tasks/cancel. . .
  • إزالة الأكبر سنا tasks/status،tasks/resultوtasks/listالافتراضات
  • الاشتراك في إشعارات المهام الاختيارية عبر subscriptions/listenعلى سلسلة SSE الإجابة POST.
  • انتهاء صلاحية المهام النموذجية، وإعادة تشغيل الاسترداد، وتقليل النسخة في مفتاح المدخل، وأخطاء التنفيذ بشكل صحيح.

لماذا المهام هي امتداد

ظهرت المهام لأول مرة كجزء تجريبي أساسي في 2025-11-25.io.modelcontextprotocol/tasksالتوسع حتى يتمكن العملاء والسيرفر من اختيار دورة حياة إضافية دون توسيع بروتوكول الأساس للجميع.

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

استخدم المهمة عندما يكون للعملية واحدة أو أكثر من هذه الخصائص:

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

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

أساسية بدون جنسية، تطبيق دولي

إزالة MCP 2026-07-28 initialize،notifications/initialized، جلسات البروتوكول، وMcp-Session-Idهذا لا يحظر المنتجات الحكومية

تُعد هوية المهمة حالة تطبيق صريحة:

  • الخادم يصرّ عليه قبل إعادتها
  • العميل يمكنه تخزينها وتجربة مرة أخرى بعد إعادة تشغيلها
  • يمكن أن يُوجّه الهوية إلى أي نسخة مدعومة من نفس المتجر الدائم.
  • يتم التحقق من الائتمان على كل طريقة المهمة.
  • يتم تعريف انتهاء الصلاحية والحذف من خلال حقل المهام، وليس مدة حياة النقل.

هذا مختلف عن الحالة الخفية المرتبطة بالاتصال.

أبقوا أربع حياة منفصلة

StateLifetimeWhere it belongs
Protocol metadataOne requestparams._meta, validated again on every call
Transport workOne stdio request or HTTP responseIn-flight coordinator with a bounded deadline
MRTR continuationOne retry sequenceIntegrity-protected requestState, plus replay controls when needed
Durable taskAcross requests, replicas, restarts, and reconnectsShared application store keyed by an authorized taskId

نقل سجل المهام إلى ذاكرة العملية لا يجعل MCP حالة. يجعل التطبيق غير موثوق به. البروتوكول يبقى بلا حالة، ولكن في وقت لاحق tasks/getلا يمكن استرداد السجل. استمر قبل إعادة المقبض، ثم جعل كل طريقة المهمة لحل نفس السجل المشترك تحت الفائز والفحص الرئيسي.

التفاوض حول القدرة

يعلن العميل عن الدعم على كل طلب مؤهل:

json{
  "_meta": {
    "io.modelcontextprotocol/protocolVersion": "2026-07-28",
    "io.modelcontextprotocol/clientCapabilities": {
      "extensions": {
        "io.modelcontextprotocol/tasks": {}
      }
    },
    "io.modelcontextprotocol/clientInfo": {
      "name": "lesson-client",
      "version": "1.0.0"
    }
  }
}

الخادم يعود بالضبطsupportedVersions، القدرات ،ttlMsوcacheScopeمنserver/discoverحيث أنها تعلن عن الأدوات، فإنها تنفيذ أيضا إلزاميةtools/listهذا النتيجة تعود إلى تحديدgenerate_reportوصف، كائن صالح inputSchema،resultType: "complete"، بيانات الهوية الخادم، وتلميحات التخزين العام.

طريقة مهمة من عميل لم يعلن عن إرجاع التوسع -32021, عدم وجود القدرة المطلوبة للعميل ، معdata.requiredCapabilitiesالمحددة إلى{"extensions":{"io.modelcontextprotocol/tasks":{}}}. تُعيد سلسلة بروتوكول غير مدعومة-32022مع دقةsupportedوrequestedالبيانات ؛ إعادة نسخة مفقودة أو غير سلسلة -32602. . .

غلاف بدون JSON-RPC idهو إشعار. قد يعالج المستلمها ، لكنه لا ينبعث عن نتيجة JSON-RPC أو خطأ. يعود مكيّف HTTP قابل للتدفق 202 Acceptedبدون هيئة للإخطار المقبول.

في الوقت الحالي فقطtools/callيدعم تنفيذ مهام معززة. تصميم التجريد الداخلي الخاص بك بحيث أن أنواع الطلبات المستقبلية لا تتطلب إعادة كتابة التخزين.

إنشاء المهام الموجهة إلى الخادم

العلم القديم للعميلparams._meta.task.requiredيُعلن العميل دعم التوسع، ثم يقرر الخادم ما إذا كان هناكtools/callيصبح مهمة

الطلب:

json{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "generate_report",
    "arguments": {"size": "large"},
    "_meta": {
      "io.modelcontextprotocol/protocolVersion": "2026-07-28",
      "io.modelcontextprotocol/clientCapabilities": {
        "extensions": {
          "io.modelcontextprotocol/tasks": {}
        }
      }
    }
  }
}

رد:

json{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "resultType": "task",
    "taskId": "tsk_786512e29e0d",
    "status": "working",
    "statusMessage": "Preparing report outline.",
    "createdAt": "2026-08-21T10:30:00Z",
    "lastUpdatedAt": "2026-08-21T10:30:00Z",
    "ttlMs": 900000,
    "pollIntervalMs": 1000
  }
}

يجب أن لا يعيد الخادم هذه المقبضة حتىtasks/getفي متجر متسق في نهاية المطاف، انتظر رؤية القراءة قبل الإجابة. خلاف ذلك يمكن للعميل الحصول على هوية صالحة تبدو و تحصل على "لا يمكن العثور على" على الفور.

لا يتم طلب استجابة للمهمة بمعنى أن العميل لا يطلب وضع المهمة. لا يتم التفاوض عليه: لا يزال على الطلب الحالي إعلان التوسع.

شكل المهمة

كل مهمة تحمل:

  • taskId: معرف مستقر منخفض الخادم
  • status: working،input_required،completed،cancelledأوfailed(إنه)
  • createdAtوlastUpdatedAt: طوابع زمنية ISO 8601
  • ttlMs: مدة انتهاء الصلاحية من الابتكار، أو nullبدون حد إعلاني
  • اختياريةpollIntervalMs: الحد الأدنى المفترض للحصول على الانتخابات من الخادم
  • اختياريةstatusMessage: سياق يستهدف المستخدم أو النموذج.

تظهر الحقول الخاصة بالحالة فقط عندما تكون ذات صلة:

  • input_requiredيشمل inputRequests. . .
  • completedيتضمن طلب الأصلي resultالشكل
  • failedيتضمن JSON-RPC error-أجسام

يجب على العميل أن يحترمpollIntervalMsقد يحدد الخادم المعدلات التي تستهدف استطلاعات أكثر عدوانية ويمكن أن يغير الفاصل على مدى عمر المهمة.

استطلاع معtasks/get

العميل يطلب صورة حالية:

httpPOST /mcp HTTP/1.1
Content-Type: application/json
MCP-Protocol-Version: 2026-07-28
Mcp-Method: tasks/get
Mcp-Name: tsk_786512e29e0d
json{
  "jsonrpc": "2.0",
  "id": 2,
  "method": "tasks/get",
  "params": {
    "taskId": "tsk_786512e29e0d",
    "_meta": {
      "io.modelcontextprotocol/protocolVersion": "2026-07-28",
      "io.modelcontextprotocol/clientCapabilities": {
        "extensions": {
          "io.modelcontextprotocol/tasks": {}
        }
      }
    }
  }
}

tasks/getنفسها قد اكتملت، لذلك نتيجة لها دائماresultType: "complete"المهمة المُعقدة لا تزال قد تكونstatus: "working"أوstatus: "input_required". . .

هذا التمييز يمنع حدوث خطأ عام في المصفح:

textresult.resultType = complete    means the tasks/get RPC finished
result.status = working        means the represented job is still running

لا يوجدtasks/resultعندما تنتهي المهمة، القادمtasks/getرد يطابق الأصلي CallToolResultتحتresult:

json{
  "resultType": "complete",
  "taskId": "tsk_786512e29e0d",
  "status": "completed",
  "createdAt": "2026-08-21T10:30:00Z",
  "lastUpdatedAt": "2026-08-21T10:34:12Z",
  "ttlMs": 900000,
  "result": {
    "resultType": "complete",
    "content": [
      {"type": "text", "text": "Generated large report with approved outline."}
    ],
    "structuredContent": {"size": "large", "approved": true},
    "isError": false,
    "_meta": {
      "io.modelcontextprotocol/serverInfo": {
        "name": "tasks-demo",
        "version": "1.0.0"
      }
    }
  },
  "_meta": {
    "io.modelcontextprotocol/serverInfo": {
      "name": "tasks-demo",
      "version": "1.0.0"
    }
  }
}

الخارجيresultTypeيقولtasks/getتم إكمال عملية التجربةresult.resultTypeيقول أن الاتصال الأصلي للدوائر قد تم، ويتطلب ذلك التمييز المتعثر.CallToolResultيجب أن تحمل أيضاًio.modelcontextprotocol/serverInfoهذا الدروس يتضمنها بدلا من تخزين حمولة مفيدة غير محددة.

لا يوجدtasks/list. لا يمكن لخادمات غير الجلسة استنتاج الآمن عن المهام التي تنتمي إلى قائمة محددة عن الاتصال. يجب على التطبيقات التي تحتاج إلى تاريخ الكشف عن أداة نطاق مصرح بها مع مرشحات صريحة وقواعد الملكية.

إدخال أثناء تنفيذ المهمة

إن إدخال المهمة و MRTR الأساسية تبدو متشابهة ولكنها تستخدم مواصلات مختلفة.

الإدخال المطلوب قبل إنشاء المهمة

النواة العائدةresultType: "input_required"من الأصليtools/callالعميل يقوم بذلك ويحاول مرة أخرى الاتصال الأصلي فقط إخلال المهمة بعد انتهاء تلك الجولات المزامنة

الإدخال المطلوب بعد إنشاء المهمة

حدد المهمةinput_required. .tasks/getيُكشف عن المميزاتinputRequestsو يقوم العميل بإرسال الردود من خلالtasks/updateالعميل لا يحاول إعادة التطبيق الأصليtools/call. . .

صورة سريعة:

json{
  "resultType": "complete",
  "taskId": "tsk_786512e29e0d",
  "status": "input_required",
  "createdAt": "2026-08-21T10:30:00Z",
  "lastUpdatedAt": "2026-08-21T10:31:00Z",
  "ttlMs": 900000,
  "inputRequests": {
    "approve_outline": {
      "method": "elicitation/create",
      "params": {
        "mode": "form",
        "message": "Approve the generated report outline?",
        "requestedSchema": {
          "type": "object",
          "properties": {"approved": {"type": "boolean"}},
          "required": ["approved"]
        }
      }
    }
  }
}

تحديث:

httpPOST /mcp HTTP/1.1
Content-Type: application/json
MCP-Protocol-Version: 2026-07-28
Mcp-Method: tasks/update
Mcp-Name: tsk_786512e29e0d
json{
  "jsonrpc": "2.0",
  "id": 4,
  "method": "tasks/update",
  "params": {
    "taskId": "tsk_786512e29e0d",
    "inputResponses": {
      "approve_outline": {
        "action": "accept",
        "content": {"approved": true}
      }
    },
    "_meta": {
      "io.modelcontextprotocol/protocolVersion": "2026-07-28",
      "io.modelcontextprotocol/clientCapabilities": {
        "extensions": {
          "io.modelcontextprotocol/tasks": {}
        }
      }
    }
  }
}

رد النجاح هو اعتراف فارغ بالإضافةresultType: "complete"قد يكون التغيير في الدولة متسقًا في النهاية، لذا يواصل العميل إجراء الاستطلاع أو الاستماع.

كل واحدinputRequestsيجب أن تكون مفتاحها فريدة طوال عمر المهمة.tasks/getقد تظهر اللقطات الفورية نفس المفتاح المتبقي؛ العملاء يقللون من واجهة المستخدم ويتجاهلون الخوادم الاستجابات لمفاتيح غير معروفة أو استبدلت أو تمت بالفعل.input_requiredحتى يتم الإجابة على جميع المفاتيح المطلوبة

الإلغاء هو تعاون

tasks/cancelإشارات النية وتعطي إقرارًا فارغًا كاملًا. هذا الإقرار لا يضمن توقف العامل. قد ينتهي العمل أولاً، أو يتجاهل الإلغاء أو الانتقال في وقت لاحق.

httpPOST /mcp HTTP/1.1
Content-Type: application/json
MCP-Protocol-Version: 2026-07-28
Mcp-Method: tasks/cancel
Mcp-Name: tsk_786512e29e0d
json{
  "jsonrpc": "2.0",
  "id": 5,
  "method": "tasks/cancel",
  "params": {
    "taskId": "tsk_786512e29e0d",
    "_meta": {
      "io.modelcontextprotocol/protocolVersion": "2026-07-28",
      "io.modelcontextprotocol/clientCapabilities": {
        "extensions": {
          "io.modelcontextprotocol/tasks": {}
        }
      }
    }
  }
}

لكل أساليب المهمة الثلاثةMcp-Nameالمرآةparams.taskId. لا تكرر اسم طريقة JSON-RPC. code/main.pyيمركز هذا القاعدة في make_http_request. . .

يقوم العامل في الدروس بتشرف الإلغاء على الفور، ويعمل على المكالمات المتكررة غير قابلة. لا يزال على عميل الإنتاج أن يعامل الإلغاء كمتعاون بدلاً من استنتاج حالة المهمة النهائية من التأكيد.

لا تستخدمnotifications/cancelledلتحل مهمة، هذا الإخطار ينتمي إلى طلب إلغاء، وليس مهمات دائمة.

الاختلاف مهم في حدود التوجيه. استبعد الطلب يستهدف عملية JSON-RPC واحدة في الطيران أو استجابة HTTP المحددة لطلبها. إذا tools/callلقد عاد بالفعلresultType: "task"، أن الطلب كامل وإغلاق النقل لا يمكن أن يذكر أو توقف العمل الدائم. tasks/cancelهو مركز جديد مصرح به.params.taskId، مرآة تلك الهوية فيMcp-Name، يحل الخلفية المملكة للمهمة، ويُسجل نية إلغاء التعاون، ويُعيد تأكيدًا دون أن يدعي العامل أنه توقف.

وبالتالي يجب على البوابة أن تحتفظ بمنسقات الطلبات وطرق المهام في جداول مختلفة. يمكن أن تختفي جدول الطلبات عند انتهاء الاستجابة. يجب أن تبقى مسار المهام حتى تنتهي الحالة النهائية والاحتفاظ بها. Lesson 29: MCP Reliability, Cancellation, and Flow Controlيُبني السباق، وقتاً وقفياً، وفرصاً، و ضغوطاً، و إعادة محاولة القواعد لكلا الطرق.

الإخطارات الاختيارية

الاستطلاع هو الخط الأساسي العميل الذي يريد تحديثات دفع يرسلهاsubscriptions/listenمع أرقام المهام. بالنسبة إلى HTTP المباشر ، هذه هي POST التي تكون استجابةها تدفق SSE المطلوب. لا يوجد تدفق حدث GET مستقل ولا جلسة بروتوكول للحفاظ على الحياة.

الجهاز يقر بأسم الشخصية المقبولة مع notifications/subscriptions/acknowledgedويمكن بعد ذلك إرسال اللقطات الفورية الكاملة من خلال notifications/tasks. الإقرار وكل إشعار مهمة يحملio.modelcontextprotocol/subscriptionIdفي_meta, يساوي subscriptions/listenكل إشعار مهمة يعادل ما هو عليهtasks/getسيعود في تلك اللحظة

يجب على العملاء أن يعلنوا على طول المهام. يجب أن يعيدوا الاتصال واستئناف من أوراق تعريف المهام الدائمة بدلاً من الاعتماد على إعادة عرض الأحداث أو Last-Event-ID. . .

النقص في النطقية

استخدم طبقتين الخطأ بشكل صحيح.

خطأ بروتوكول

عدة معايير غير صالحة للطريقة أو اسم مهم مجهول يعيد خطأ JSON-RPC، عادة -32602. غياب بيانات دعم التمديد-32021مع جسم القدرة المطلوب.

نتائج تنفيذ المهمة

  • نتيجة أداة طبيعية معisError: trueما زالcompletedالمهمة لأن دعوة الأداة قدمت نتيجة محددة.
  • خطأ JSON-RPC أثناء التنفيذ المؤجل يجعل المهمة failedوتخزن خطأ JSON-RPC تحت error. . .
  • الرفض المستخدم يمكن أن يؤدي إلىcancelledنتيجة رفض كاملة أو نتيجة آمنة أخرى محددة للمجال.

استمرارية، انتهاء صلاحية، وملكية

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

يجب أن يحتوي مفتاح التخزين على مستأجر ومدير مصرح أو يحل ذلك. لا يجب أن يمنح معرفة هوية المهمة الوصول. تحقق من ملكية كل tasks/get،tasks/update،tasks/cancel، والإشتراك

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

استخدام الكتب الذرية أو المعاملات. الدرس يكتب ملفًا مؤقتًا ويُعيد تسميته بشكل ذري. يجب أن تستخدم خدمة متعددة النسخة متجرًا دائمًا مشتركًا وترخيص عامل أو تحكم متزامن معادلة.

بناءها

code/main.pyتنفيذ خدمة مهمة تحديدية:

  • server/discoverالعائداتsupportedVersions، إشارات التخزين، ومدّة المهام
  • tools/listيعود تحديد، قابلة للتخفيض generate_reportوصف مع مخطط إدخال صالح.
  • tools/callيخلق و يواصل المهمة قبل العودةresultType: "task". . .
  • مثال خدمة جديد يُعيد تحميل نفس المهمة، يُظهر إعادة تشغيل التعافي.
  • tasks/getيعيد صور اللقطات الكاملة للمهمة.
  • العامل ينتقل منworkingإلىinput_required. . .
  • tasks/updateيقبل استجابة من النموذج ويرد إقرارًا كاملًا فارغًا.
  • العامل يحتفظ بمثابة عُشCallToolResultمع أفرادهاresultTypeو هويت الخادم ، ثم الانتقال إلى completed. . .
  • tasks/cancelلا يُمكن أن يكون ذلك ممكناً في هذا التنفيذ.
  • أجهزة بناء HTTPMcp-Nameإلىparams.taskIdلـtasks/get،tasks/updateوtasks/cancel. . .
  • المساعدون في الإخطار يستخدمون notifications/subscriptions/acknowledgedوnotifications/tasks، كلاهما مع علامة اسم طلب الاستماع.
  • الإخطارات بدون ID لا تنتج استجابة JSON-RPC.

يعمل العامل بشكل صريح بدلاً من النوم في خيط خلفي، مما يجعل كل انتقال حالة محدداً ويحافظ على مثال البروتوكول منفصل عن ميكانيكا الصف.

استخدمها

من جذور المخبأ:

bashcd phases/13-tools-and-protocols/13-mcp-async-tasks/code
python3 main.py
python3 -m unittest discover tests -v

تسلسل النتائج المتوقع:

textid=0 resultType=complete status=ack
id=1 resultType=task status=working
id=2 resultType=complete status=working
id=3 resultType=complete status=input_required
id=4 resultType=complete status=ack
id=5 resultType=complete status=completed

أيضاً تأكد من ذلكtasks/status،tasks/resultوtasks/listطريقة العودة لا توجد في الخدمة الحديثة.

تأكد من ذلكtools/listهو تحديدية وكل طريقة مهمة HTTP الحالية تعكس اسم المهمة من خلال Mcp-Name. . .

أرسله

outputs/skill-task-store-designer.mdالآن تنتج تصميمًا واعًا للتوسع: تفاوض القدرات، إنشاء استمرار قبل العودة، والطرق الحالية، وتدفق تحديث المدخلات، والمالك، والانتهاء من الصلاحية، والإلغاء، والإشتراك، والهجرة من الطرق التجريبية المزودة.

التمارين

  1. إضافة مفتاح إدخال ثانياً لا يزال قائماً. أرسل مفتاح جزئي tasks/updateو إثبات أن المهمة لا تزال قائمةinput_requiredحتى يتم الإجابة على كلتا المفاتيح
  2. إضافة ملكية المستأجر إلى المتجر ورفض هوية مهمة صالحة قدمتها رئيس المصادقة الخطأ.
  3. إضافة عقد تأجير العمال مع انتهاء صلاحيتها. إثبات أن حالات الخدمة لا يمكن أن تقوم بنفس المهمة في وقت واحد.
  4. تنفيذ مُعدل SSE للرد على POSTsubscriptions/listenلا تضيف GETLast-Event-IDأو عنوان جلسة
  5. إضافة تنظيف انتهاء الصلاحية. تمييز مهمة انتهت الصلاحية من هوية مهمة خاطئة دون تسريب وجود المتبادل المستأجر.

الشروط الرئيسية

TermMeaning in the current extension
Tasks extensionOptional io.modelcontextprotocol/tasks capability for durable async work
CreateTaskResultServer-directed resultType: "task" response to an eligible request
tasks/getPoll a full current task snapshot, including terminal result or pending input
tasks/updateSubmit responses to a task's outstanding inputRequests
tasks/cancelAcknowledge cooperative cancellation intent
input_requiredTask status indicating client input is outstanding
pollIntervalMsServer-suggested minimum delay before another poll
ttlMsExpiry duration measured from task creation
Durable-before-returnRule that the task id must resolve before its handle is sent
notifications/tasksOptional full task snapshot delivered on a subscribed SSE response

التوافق مع التراث

السطح التجريبي 2025-11-25 استخدم زيادة المهام التي طلبها العميلtasks/status،tasks/result، و اختياري tasks/list. إبقوا هذه الأسماء فقط داخل مُعدّل إرث مُثبت . العميل الحالي يستخدم إمكانية التوسع ، يقبل المُسَلّطات المُوجّهة إلى الخادم ، استطلاعاتtasks/get، يقدم المدخلات مع tasks/update، ويقرأ النتيجة النهائية من صورة المهام.

المزيد من القراءة

This free lesson is part of the AI Engineering from Scratch curriculum. Read the full explanation, run the lesson code, and verify the result in the interactive reader or from the repository source.

Browse the complete course catalog or open this lesson on GitHub.