# التحويل لموظف والأمان

> قائمة «لا تتعامل معها بنفسك»، والرد الحرفي عند التصعيد، والتحويل الصادق، وانتهاء مدة التحويل، وقاعدة «لا صمت أبدًا» — ضمانات مفروضة في الكود لا آمال معلّقة على التعليمات.

الوكيل الذي يحادث عملاءك سيواجه أسئلة لا يجوز له أن يجيب عنها: ادعاء ضرر، أو تهديد قانوني، أو مبلغ استرداد. يتعامل K-Agent مع هذه الحالات بوصفها **ضمانات في المنتج مفروضة في الكود**، فتصمد مهما كان سلوك النموذج في يوم بعينه.

## قائمة «لا تتعامل معها بنفسك»

يسرد `guardrails.never_handle` الحالات التي يجب ألا يتعامل معها الوكيل بنفسه أبدًا. القائمة **مفعّلة افتراضيًا** وتأتي بقيم افتراضية مترجمة:

1. ادعاءات الأضرار أو الإصابات أو الحوادث؛
2. التهديدات القانونية، أو ذكر المحامين أو الشرطة أو الجهات الرسمية؛
3. مبالغ الاسترداد أو التعويض؛
4. الشكاوى التي تذكر موظفًا بعينه؛
5. طلبات بيانات عميل آخر.

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

ما يفعله الوكيل بعد ذلك يعتمد على الأدوات المتاحة فعلًا. مع `transfer_to_human` يحوّل المحادثة إلى فريقك. ومن دونها يخبر العميل بوضوح أن هذا لا يمكن التعامل معه هنا وأن عليه التواصل معكم مباشرة — ولا يعد أبدًا بمتابعة لن يقوم بها أحد.

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

## الرد الحرفي عند التصعيد

`guardrails.escalation_reply` هو الرد الذي يتلقاه العميل بالضبط حين يحوّل الوكيل حالة ذات **مسؤولية قانونية** (`reason_type: "liability"`). اكتبه مرة واحدة بالعربية والإنجليزية، واعتمده، وسيُستخدم حرفيًا:

```json
{
  "guardrails": {
    "escalation_reply": {
      "ar": "شكرًا لتواصلك. حوّلنا طلبك إلى المسؤول المختص وسيتواصل معك قريبًا.",
      "en": "Thank you for telling us. We've passed this to the responsible manager, who will contact you shortly."
    }
  }
}
```

حين ينجح `transfer_to_human` مع `reason_type: "liability"` وفي الإعدادات رد مكتوب:

- لا تُنفَّذ استدعاءات الأدوات المعلّقة في تلك الجولة؛
- **لا يُستدعى النموذج مرة أخرى**؛
- ينتهي التشغيل بالنتيجة `handed_off` برسالة مساعد أخيرة واحدة نصّها **هو** ردك، بلغة العميل، مع `metadata.replaced: true`؛
- لا تُحفظ صياغة النموذج إلا في خطوات التشغيل، للمراجعة.

النص المرسل في جولات سابقة يبقى رسالة مستقلة. ومع `conversation.stream_mode: "auto"` (الافتراضي) تُجمَّع الردود جولةً جولة متى كان رد التصعيد مُعدًّا، فلا يمكن أن يناقض نصٌّ مبثوث الاستبدال. وفي الوضع `live` يحمل `message.completed` الحقل `replaced: true` وهو النص الذي يجب عرضه.

والأمر نفسه في طلبات السؤال الواحد `ask`: يعيد التشغيل الرد ومعه `handoff`، ويُطلق الويب هوك `handoff.requested` مع `run_id`.

## لا تقل إلا ما قيل لك

يلتزم كل وكيل بقاعدة التأسيس على المعلومات (تظهر في «أشعة إكس» باسم `grounding@1`): الأسعار، والمواعيد، والعناوين، وما تشمله الخدمة — ما لم يكن في التعليمات أو المعرفة فالوكيل لا يعرفه. وبدل التخمين أو الوعد بـ«أتأكد وأرجع لك» (وهو ما لن يفعله أحد)، يحوّل السؤال إلى شخص. وحين لا تتوفر أداة تحويل يقول بوضوح إن على العميل التواصل معكم مباشرة.

## التحويل لموظف

**التحويل لموظف** (`ho_…`) ينقل المحادثة إلى فريقك. ويمكن أن يطلبه:

| `requested_by` | كيف |
|---|---|
| `agent` | يستدعي النموذج `transfer_to_human`. |
| `api` | يستدعي الكود الخاص بك `POST /v1/sessions/{session}/handoff` مع `{reason_type, summary}`، أو يطلب العميل ذلك من الودجت. |
| `policy` | K-Agent نفسه — مثل تكرار فشل المزوّد، أو نفاد حصة الخطة المجانية. |
| `human` | يستلم أحد أعضاء فريقك محادثة جارية (`POST /v1/sessions/{session}/takeover`)، أو يرد فيها مباشرة. |

لكل تحويل `reason_type` — ‏`customer_requested` أو `out_of_scope` أو `complaint` أو `liability` أو `technical` — و`summary` قصير يسجّل الموضوع لا الاتهام. وتحويلات المسؤولية القانونية تأخذ `priority: "high"` وتتصدّر مكتب التحويل.

### نتائج أدوات صادقة

يبلغ `transfer_to_human` بما حدث بالضبط، ولا يجوز للوكيل أن يقول للعميل إلا ما تدعمه النتيجة. لا يقول «حوّلتك» أبدًا ما لم يُسجَّل التحويل.

| `status` | المعنى |
|---|---|
| `queued` | أُنشئ التحويل. سيستلمه فريقك، ويصمت الذكاء الاصطناعي في هذه الجلسة. |
| `recorded` | طلب سؤال واحد: سُجّل التحويل لفريقك (لا توجد جلسة لإيقافها). |
| `recorded_closed` | سُجّل خارج ساعات العمل. تتضمن النتيجة `next_open_local`، مثل `Sunday 09:00 (Asia/Riyadh)`، ويخبر الوكيل العميل متى سيرد عليه شخص — لا «قريبًا» أبدًا. |
| `already` | يوجد تحويل مفتوح لهذه المحادثة بالفعل. |
| `failed` | تعذّر التسجيل. لا يجوز للوكيل ادعاء التحويل. |

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

### وضع الموظف

ما دام تحويل طلبه الوكيل أو الواجهة البرمجية أو أحد الموظفين مفتوحًا، تكون الجلسة في **وضع الموظف** (`session.mode: "human"`):

- تُحفظ الرسائل الجديدة وتظهر لفريقك، لكن **لا يعمل الذكاء الاصطناعي**؛
- يعيد `POST …/messages` الحالة `200` مع `run: null`؛
- يرد فريقك بالدور `role: "human_agent"`، ويصل الرد فورًا إلى الودجت وإلى بث جلستك.

**التحويلات التقنية لا تُصمِت الجلسة.** التحويل الناتج عن فشل المزوّد أو انقطاع التشغيل أو نفاد الحصة يُسجَّل (سجل، وويب هوك `handoff.requested`، ونتيجة `handed_off`، وإشعار للعميل) لكن الجلسة تبقى في الوضع `agent`، فيُجاب عن الرسالة التالية كالمعتاد. وللجلسة تحويل تقني مفتوح واحد كحد أقصى.

### انتهاء المدة

التحويل الذي لا يغلقه أحد يجب ألا يُصمت المحادثة إلى الأبد:

- `handoff.ttl_hours` (من 1 إلى 720، الافتراضي **24**) يحدد المدة؛ و`handoff.never_expire: true` يلغي انتهاء المدة عن قصد.
- المدة **منزلقة**: استلام التحويل، أو أي رسالة من فريقك (ردًا عامًا أو ملاحظة داخلية)، يمدّ `expires_at` إلى «الآن + المدة» على الأقل.
- عند انتهاء المدة يصبح التحويل `expired`، وتعود الجلسة إلى الوضع `agent`، وتُنشر رسالتك `handoff.expire_message` إشعارَ نظام عامًا. لا يبدأ رد ذكاء اصطناعي من تلقاء نفسه؛ ويجيب الوكيل عن رسالة العميل التالية.
- مع `handoff.on_expire: "close"` تُغلق الجلسة بدلًا من ذلك؛ ورسالة جديدة من العميل تعيد فتحها.

### الإنهاء

ينهي `POST /v1/handoffs/{handoff}/resolve` مع `{"action": "release" | "close", "note": "…"}` التحويل. عند الإعادة (release) يتولى الوكيل المحادثة من جديد: تصبح ردود فريقك العامة جزءًا من سجله، وتُعطى له الملاحظة الاختيارية **مرة واحدة** ملاحظةً داخلية لا يجوز له اقتباسها للعميل.

## ساعات العمل

مع `business_hours.enabled` يعرف الوكيل هل فريقك متصل، بحسب المنطقة الزمنية للوكيل (`locale.timezone`):

- `handoff.outside_hours: "record"` (الافتراضي) يواصل تسجيل التحويلات خارج الساعات بصياغة `recorded_closed` الصادقة. و`"withhold"` يزيل `transfer_to_human` ما دمتم مغلقين.
- `business_hours.outside_hours_ai: "answer"` (الافتراضي) يُبقي الوكيل يجيب خارج الساعات؛ و`"message_only"` يرسل `out_of_hours_message` حرفيًا دون أي استدعاء للذكاء الاصطناعي.
- يمكن أن تمتد الفترات بعد منتصف الليل (`"open": "20:00", "close": "02:00"`)، والأيام غير المدرجة مغلقة، والجدول الافتراضي من الأحد إلى الخميس، 09:00–17:00.

## لا صمت أبدًا

ينتهي كل تشغيل بنتيجة نهائية واحدة بالضبط. حين يفشل المزوّد يعيد K-Agent المحاولة بفواصل متزايدة، ثم يجرّب نماذجك البديلة `fallback_models`، ثم يرسل `fallback.message` ويحوّل الجلسة إلى فريقك (`fallback.handoff_on_failure`، مفعّل افتراضيًا). وإذا نفدت المحادثات الذكية في الخطة المجانية تتلقى الجلسات إشعارًا قصيرًا وتحويلًا تقنيًا — لا يرى العميل خطأ فوترة أبدًا.

## الأحداث

| الحدث | متى |
|---|---|
| `handoff.requested` | سُجّل تحويل (من أي مصدر). |
| `handoff.assigned` | استلمه أحد أعضاء فريقك. |
| `handoff.unclaimed` | ما زال دون استلام بعد `handoff.notify.unclaimed_reminder_minutes` (الافتراضي 10). |
| `handoff.resolved` | أُعيد إلى الوكيل أو أُغلق. |
| `handoff.expired` | انتهت المدة. |
| `session.updated` | تغيّر `mode` أو `status` في الجلسة. |
| `message.created` | رسالة جديدة، بما فيها ردود فريقك العامة (مع `role` و`author`). |

تصل عبر [الويب هوك](/docs/guides/webhooks/) وعبر بث أحداث الجلسة. أما التحويلات من لوحة التجربة في لوحة التحكم فمعزولة: لا تصل أبدًا إلى مكتب التحويل ولا إلى الويب هوك ولا إلى التنبيهات.

## اقرأ المزيد

- اعمل على قائمة الانتظار في [دليل مكتب التحويل](/docs/guides/handoff-desk/).
- اطّلع على كل الإعدادات المتعلقة في [مرجع الإعدادات](/docs/concepts/settings/#الضوابط-guardrails).
