تخطَّ إلى المحتوى

مستويات المخاطر في نموذج HITL في NextPDF Connect

تُعلن كل أداة عن مستوى واحد من مستويات المخاطر الأربعة. أما المستوى الأعلى، الذي يتطلب موافقة، فلا يُنفَّذ في الاستدعاء الأول. بدلًا من ذلك، تُعيد ⁨ConfirmationGate⁩ رمز تحدٍّ يُستخدم لمرة واحدة. اجعل الوكيل يمرّر ذلك الرمز إلى إنسان ليأذن بإعادة الاستدعاء.

Terminal window
composer require nextpdf/server

يضم نموذج المخاطر أربعة مستويات مرتَّبة ترتيبًا محددًا:

المستوىالقيمةالمعنىالأثر
⁨safe⁩0للقراءة فقط، دون آثار جانبيةتنفيذ تلقائي
⁨caution⁩1يُنشئ أو يُعدّل حالة في الذاكرةتنفيذ تلقائي، مع تسجيل في سجل التدقيق
⁨review⁩2يُنتج مخرجات قد يُساء استخدامهاتنفيذ تلقائي، مع تسجيل في سجل التدقيق
⁨approval_required⁩3إجراء تدميري أو قانوني أو حسّاس للخصوصيةيتطلب تأكيدًا بشريًا

ينشأ مستوى مخاطر الأداة من مصدرين اثنين فقط: إعلان الأداة نفسها، وتجاوز اختياري في إعداد المُشغِّل. لا يوجد مصدر ثالث. يحمل النموذج رقم إصدار. تكشف استجابة initialize في ⁨MCP⁩ عن ذلك الرقم كي يتمكن العميل من اكتشاف أي تغيير غير متوافق. يبدأ التسجيل في سجل التدقيق من مستوى ⁨caution⁩ وما فوقه.

عند إيقاف إجراء آلي ريثما يأذن به إنسان، يكون التحكم في الموضع نفسه الذي تُدخِل فيه الأتمتة المخاطر. ويصف ⁨IEC 31010⁩ هذا الموضع بأنه موضع التحكم في المخاطر المُدخَلة عبر الفعل البشري، عند نقطة الإدخال أو بالقرب منها (⁨IEC 31010⁩:2019).

عند استدعاء أداة من نوع approval_required دون رمز صالح، تُصدر البوابة تحدّيًا. تُعيد عملية الفحص أحد شكلين.

{ "allowed": true }

أو

{ "allowed": false, "challenge": "<human-readable text>", "token": "confirm_<nonce>" }

يذكر نص التحدّي العملية ووصفها. كما يُحذِّر إذا كان الاستدعاء سيكتب فوق ملف هدف. ويوجّه المُستدعِي إلى إعادة استدعاء الأداة نفسها مع ضبط مُعامِل _confirmation_token على الرمز الصادر. تنتهي صلاحية الرمز خلال 300 ثانية.

ربط الرمز بهذا الشكل مقصود: يربط الرمز اسم الأداة، وقيمة عشوائية لمرة واحدة (⁨nonce⁩)، ومدة الصلاحية (⁨TTL⁩) — وليس الوسائط. عند إعادة المحاولة، قد يُعيد عملاء ⁨MCP⁩ تسلسل الوسائط بترتيب مختلف للمفاتيح أو بتطبيع مختلف، لذا فإن تجزئة الوسائط قد تُعطِّل التأكيدات المشروعة. يُستخدم الرمز لمرة واحدة. واستهلاكه عند إعادة الاستدعاء يسمح بالاستدعاء مرة واحدة بالضبط.

تُطبَّق البوابة على كل وسيلة نقل تُشغِّل الأدوات:

  • ⁨MCP⁩: يُعاد التحدّي داخل القناة نفسها على هيئة استجابة ⁨JSON-RPC⁩ ناجحة، ويكون نص التحدّي محتواها. يُعيد المُستدعِي استدعاء tools/call مع arguments._confirmation_token.
  • ⁨REST⁩ و⁨gRPC⁩: تعمل البوابة نفسها في مُنفِّذ الأدوات المشترك قبل أي عملية من نوع approval_required. يظهر التحدّي في استجابة العملية. يُكرّر المُستدعِي العملية مع الرمز.

حماية مدمجة من خفض المستوى

قسم بعنوان «حماية مدمجة من خفض المستوى»

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

أطلِق تحدّيًا بكتابة ملف باستخدام output_pdf:

Terminal window
./vendor/bin/nextpdf-mcp <<'EOF'
{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"c","version":"1.0.0"}}}
{"jsonrpc":"2.0","method":"notifications/initialized"}
{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"output_pdf","arguments":{"document_id":"<id>","file_path":"/var/lib/nextpdf/tmp/out.pdf"}}}
EOF

ستكون الاستجابة هي التحدّي، وليست الملف. أعِد الاستدعاء باستخدام الرمز الصادر:

{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"output_pdf","arguments":{"document_id":"<id>","file_path":"/var/lib/nextpdf/tmp/out.pdf","_confirmation_token":"confirm_<nonce>"}}}

نموذج برمجي — بيئة الإنتاج

قسم بعنوان «نموذج برمجي — بيئة الإنتاج»

ارفع أداة مستواها عادةً ⁨caution⁩ إلى ⁨approval-required⁩ لأجل نشر مُحصَّن:

/etc/nextpdf/nextpdf-mcp.yaml
nextpdf_mcp:
risk_level_overrides:
add_image: 3 # require human confirmation for image insertion

يُرفض خفض المستوى في وقت التحميل، ولا يبدأ الخادم. على سبيل المثال، ضبط output_pdf دون 3 يُعدّ خفضًا للمستوى.

  • output_pdf في وضع ⁨base64⁩ لا يخضع للبوابة. الكتابة على القرص تتطلب موافقة؛ أما إعادة ملف ⁨PDF⁩ بترميز ⁨base64⁩ (دون file_path) فتُعامَل على أنها أقل خطورة وتُنفَّذ دون تأكيد.

  • الرمز ليس بيانات اعتماد دخول. فهو لا يُصادق على المُستدعِي ولا يحل محل مفتاح ⁨API⁩ على وسائل النقل الشبكية. ولا يفتح إلا استدعاءً محددًا واحدًا خاضعًا للبوابة، ولمرة واحدة فقط، خلال 300 ثانية.

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

  • يُجرى التدقيق بغض النظر عن النتيجة. إصدار تحدٍّ، والتنفيذ الناجح، والتنفيذ الفاشل عند مستوى ⁨caution⁩ وما فوقه، تُسجَّل جميعها في سجل التدقيق مع اسم الأداة ومستوى المخاطر.

تُضيف البوابة عملية بحث في مخزن الرموز، وتوليد رمز عشوائي عند إصدار تحدٍّ. وهذه تكلفة ضئيلة مقارنة بالعملية الخاضعة للبوابة، ولا تنطبق إلا على أدوات approval_required.

البوابة ضابط احتواء، وليست ضابط مصادقة. فهي تضمن أن يأذن إنسان بالإجراءات التدميرية أو القانونية أو الحسّاسة للخصوصية حتى عندما يُشغِّل الأداة وكيل مستقل. في هذه العمليات، لا يدّعي الخادم العمل دون إشراف بشري، ولا يستطيع الإعداد إضعاف البوابة. اجمع بينها وبين نموذج مفتاح ⁨API⁩ على وسائل النقل الشبكية، وحدّد النطاق بأقل الامتيازات عبر enabled_tools. راجع /⁨connect/security-and-operations/.⁩

الادّعاءالمصدرreference_id
التحكم في المخاطر عند نقطة الإدخال (البشري)⁨IEC 31010⁩:2019

تتضمن استجابة initialize في ⁨MCP⁩ إصدار نموذج المخاطر كي يتمكن العملاء من اكتشاف أي تغيير غير متوافق. صيغة النقل موثَّقة في /⁨transports/mcp/.⁩

تُعلن أدوات ⁨Premium⁩ مستوى مخاطرها الخاص باستخدام نموذج المستويات الأربعة نفسه. تستخدم عمليات ⁨Premium⁩ التدميرية، مثل التنقيح، البوابة نفسها تمامًا. البوابة جزء من الخادم، وليست جزءًا من حزمة ⁨Premium.⁩

  • /⁨connect/tool-catalog/⁩ — مستويات المخاطر لكل أداة أساسية مُتحقَّق منها
  • /⁨connect/configuration/⁩ — تجاوزات المخاطر للرفع فقط
  • /⁨connect/security-and-operations/⁩ — كيف تتلاءم البوابة مع نموذج التهديد
  • /⁨transports/mcp/⁩ — صيغة نقل التحدّي داخل القناة
  • /⁨connect/overview/⁩ — أين تقع البوابة في البنية المعمارية