الانتقال إلى المحتوى الرئيسي
فعّلت قاعدة سطح استجابةdeny أو sanitize على استدعاءات الأدوات التي يصدرها نموذجك — ويستدعي وكيلك البوابة بـ "stream": true. السؤال الذي يهم فعلاً: هل يمكن لاستجابة مبثوثة أن تسرّب استدعاء أداة محجوباً قبل أن يقرّر جدار الحماية؟ لا يمكنها، وتشرح هذه الصفحة الآلية الوحيدة التي تجعل ذلك صحيحاً فيمكنك التفكير في زمن الاستجابة والأجزاء التي يتلقّاها عميلك. هذه نظرة مركّزة على سلوك SSE. للأحكام نفسها انظر الأحكام؛ ولقواعد القاعدة انظر مرجع القواعد.

1. مشكلة sse للبث في جدار الحماية

استجابة غير مبثوثة هي جسم JSON واحد — يرى جدار الحماية الكل، يقيّم tool_calls، ويعيد النتيجة المنظَّفة. البث مختلف: يصدر نموذج استدعاء أداة كعشرات فروقات tool_call عبر إطارات SSE كثيرة، وبمجرد تمرير إطار، يملكه وكيلك بالفعل — لا تراجع عن رمز أرسلته. قيّم مبكراً جداً ولا تملك الاستدعاء الكامل (الاسم + الوسائط الكاملة) لتحكم؛ ومرّر أثناء التقدّم ويكون deny قد فات أوانه. تحل البوابة هذا بعقد بسيط قابل للملاحظة:

المحتوى يُبَث حياً

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

إطارات استدعاء الأداة تُحتجَز

أي إطار يحمل فرق tool_call (أو function_call القديم) يُحجَب من البث الحي حتى يكتمل الاستدعاء ويُقيَّم.
جدار الحماية بوابة أمنية، فهو يحلّل كل إطار. لا يخمّن أن إطاراً محتوى فقط من البايتات الخام — عضو tool_calls مهرَّب بـ JSON لا سلسلة فرعية حرفية له ليطابق عليها، فاختصار سلسلة فرعية سيمرّر استدعاء أداة غير مُقيَّم. إطارات SSE صغيرة؛ البوابة تحلّل كل واحد.

2. تسلسل الاحتجاز-التجميع-التقييم

لاستجابة chat-completions مبثوثة بسياسة سطح استجابة نشطة، كل إطار يصدره الأعلى يأخذ أحد مسارين:
يُبَث إلى عميلك فوراً، بايت ببايت. هذه لا تحمل أبداً استدعاء أداة، فلا شيء لجدار الحماية ليقرّره.
يُخزَّن خارج البث الحي. إطار finish_reason الختامي لدور أداة يُحتجَز معه، لأن إصداره مبكراً سيخبر عميلك أن الدور انتهى قبل أن يحكم جدار الحماية.
عند نهاية البث، تجمّع البوابة الإطارات المُحتجَزة إلى استدعاءات أدوات كاملة (تضمّ شظايا arguments المبثوثة لكل استدعاء)، تقيّم كل واحد مقابل سياستك على سطح responseنفس دلالات الحكم والقاعدة كمسار غير البث — وتصدر الناجين فقط:
حكم الاستدعاء المُحتجَزماذا يتلقّى عميلك
allow / auditالإطارات المُحتجَزة الأصلية، دون تغيير — تمرير مؤجَّل، وليس جزءاً مُعاد تجميعه.
sanitizeالاستدعاء بوسائطه مُعاد كتابتها (الأسرار/PII المطابقة مُستبدلة برمز مكتوب)، مُعاد إصداره.
denyيُسقَط الاستدعاء. إذا كان استدعاء الدور الوحيد، يُغلَق الدور بـ finish_reason: "stop" — يبدو البث كأن النموذج لم يقم بأي استدعاء أداة.
إذا لم يطابق شيء، تدفع فقط تأخير التخزين على إطارات استدعاء الأداة — المحتوى بُثّ حياً بالفعل. يعيد جدار الحماية بناء الإطارات فقط عندما يتصرّف فعلاً (deny أو sanitize)؛ allow نظيف يمرّر بايتات الأعلى بالضبط.

3. مثال ملموس واحد

سياسة استجابة بقاعدة deny على *.delete (ألّفها في محرر القواعد بوحدة التحكم) وطلب مبثوث يقرّر نموذجه استدعاء كلٍّ من db.query وdb.delete:
SSE timeline (what your agent receives)
───────────────────────────────────────
data: {"choices":[{"delta":{"content":"Looking that up…"}}]}   ← live
data: {"choices":[{"delta":{"content":" one moment."}}]}        ← live
                                                                ← db.query + db.delete
                                                                  tool_call frames HELD
─── end of stream ───
data: {"choices":[{"delta":{"role":"assistant",
        "tool_calls":[{"index":0,"function":{"name":"db.query",…}}]}}]}
data: {"choices":[{"finish_reason":"tool_calls"}]}
يقرأ وكيلك نص المساعد في الزمن الحقيقي، ثم يتلقّى db.query فقطdb.delete جُمِّع، قُيِّم، رُفِض، ولم يُصدَر أبداً. الاستدعاء الناجي مُعاد فهرسته من 0، وحدث جدار الحماية للاستدعاء المرفوض يهبط في سجل الأحداث مع القاعدة التي أُطلقت.
اطرح سياسة استجابة مبثوثة تحت وضع الظل أولاً. في وضع الظل يُخفَّض كل حكم فارض إلى audit (سبب مسبوق بـ [shadow] would …) وكل إطارات استدعاء الأداة تمرّ — فيمكنك تأكيد أن السياسة تطابق ما تتوقعه على حركة المرور المبثوثة الحقيقية قبل أن تبدأ إسقاط الاستدعاءات.

4. حجوبات inbound تختصر قبل بدء البث

رقصة الإطار المُحتجَز للسطح response فقط — الاستدعاءات التي يصدرها النموذج. deny على inbound (أداة يعلن عنها وكيل) يُطلق قبل استدعاء النموذج الأعلى، فطلب مبثوث يتعثّر بقاعدة inbound لا يفتح بث SSE أبداً: يعيد HTTP 400 عادياً برمز خطأ firewall_blocked، معلّماً بـ skip-retry. لا إطارات، لا نافذة احتجاز — يهبط الحجب كأي خطأ غير مبثوث.

5. حواجز الحماية على نفس البث

استجابة مبثوثة يمكن أن تحمل سياسة مخرجات حاجز حماية و سياسة استجابة جدار حماية دفعةً واحدة. تتصرفان على أشياء مختلفة — حواجز الحماية تفحص النص الذي يبثّه النموذج؛ وجدار الحماية يحكم استدعاءات الأدوات — وتتركّبان:
  • حجب حاجز مخرجات (بث): فاحص المخرجات يقطع البث لحظة تعثّر قاعدة، يمرّر جزء استبدال عاماً واحداً — [Response blocked by content policy.] بـ finish_reason: "content_filter" — ويتوقف. الرسالة عامة عمداً (لا فئة قاعدة) فلا يمكن لمستكشف تعداد سياستك. احتجاز جدار حماية أثناء الطيران عند حدوث هذا يُلغى، فاستدعاء أداة محجوب لا يمكنه التسلل بعد الحجب.
  • إخفاء حاجز مخرجات (بث): إخفاء الطلب قبل أن يصبح النموذج حياً؛ الإخفاء المضمّن الحي لـ المخرجات المبثوثة على خارطة الطريق. على بث، قاعدة إخفاء تسجّل المطابقة لكنها حالياً تمرّر الجزء الأصلي — ألّفها عالماً أن التنقيح لم يُعَد كتابته على السلك بعد. حجب المخرجات مفروض بالكامل على البث.
تصف هذه الصفحة شكل SSE لـ chat-completions في OpenAI. نفس عقد الاحتجاز-التقييم-الإصدار مربوط لكل صيغة — Anthropic Messages الأصلي، وGemini، وxAI، وبث OpenAI Responses كل منها يحمله في شكل حدثه الخاص — فالسلوك الملاحظ من قبل العميل متطابق بغض النظر عن أي مزود خدم الطلب.

6. ماذا يعني هذا لعميلك

بضع عواقب عملية لنموذج الإطار المُحتجَز:
دور كان استدعاء أداته الوحيد مرفوضاً يُغلَق بـ finish_reason: "stop" بدلاً من "tool_calls" — لوكيلك يُقرأ كـ “اختار النموذج عدم استدعاء أداة.” دور نجا فيه بعض الاستدعاءات يُغلَق بـ "tool_calls"، حاملاً الناجين فقط.
عندما يحزم أعلى رموز usage على نفس الجزء النهائي الذي احتجزه جدار الحماية، تعيد البوابة إرفاقه بالإطار النهائي المُعاد بناؤه — عميل طلب استخدام البث لا يزال يحصل عليه.
إذا أصدر النموذج محتوى و استدعاء أداة في نفس الإطار، يُستعاد المحتوى ويُعاد إصداره حتى عندما يُجرَّد استدعاء الأداة — حجب استدعاء واحد لا يُسقط أبداً نص مساعدك.
لا تختار إدخال بث في أي من هذا. اربط سياسة بالمفتاح (أو اضبط افتراضي مساحة عمل) وابقَ تبث تماماً كما من قبل — الفرض في البوابة.

أين تذهب بعد ذلك

المراحل والأسطح

inbound، response، mcp، egress — أين يُقيَّم كل قاعدة.

الأحكام

allow، audit، deny، sanitize، pending_approval، cap_cost.

تطهير الوسائط

نقّح الأسرار من وسائط استدعاء أداة — مستوى الوسيطة فقط.

وضع الظل

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