الانتقال إلى المحتوى الرئيسي

نظرة عامة

تعامل التطبيقات المحادثية مع كل سطر من المستخدم كـ تشغيل flow جديد بنفس معرّف الجلسة. توفر CrewAI مساعدات لسجل الرسائل وتصنيف النية الاختياري وتأجيل التتبع وجسور الواجهة، إضافة إلى REPL محلي flow.chat() للتدفقات المحادثية.

واجهات الجولات

استخدم flow.handle_turn(message, session_id=...) لكل رسالة مستخدم من REST أو WebSocket أو الاختبارات أو الواجهات المخصصة. استخدم flow.chat() عندما تريد حلقة دردشة محلية في الطرفية لـ Flow محادثي. لا يقبل Flow.kickoff() الوسيطين user_message= أو session_id=. في التدفقات المحادثية، يخزن handle_turn() الرسالة المعلقة ويستدعي داخلياً kickoff(inputs={"id": session_id}).

بداية سريعة

دورة حياة الجولة

كل handle_turn يشغّل:
  1. _configure_conversational_kickoff — دمج session_id / user_message في inputs وتطبيق ConversationalConfig.
  2. استعادة الحالة — عند وجود inputs["id"] و@persist.
  3. FlowStarted — في أول جولة للجلسة المؤجلة فقط.
  4. prepare_conversational_turn — إضافة رسالة المستخدم وlast_user_message وتصنيف اختياري.
  5. تنفيذ الرسم@start@router → معالجات @listen.
  6. نهاية التشغيل — يُتخطى flow_finished والتتبع لكل جولة عند التأجيل؛ Agent.kickoff() / crews لا تغلق دفعة الأب.
استدعِ append_assistant_message(reply) في المعالجات. سطر المستخدم محفوظ عبر handle_turn — لا تُضفه مرة أخرى.

ConversationalConfig (افتراضيات على مستوى الصنف)

عيّن على صنف Flow كـ conversational_config: ClassVar[ConversationalConfig | None]. يمكن التجاوز لكل kickoff عبر intents= وintent_llm=.

ChatState (شكل الحالة الموصى به للحفظ)

ConversationalInputs هو TypedDict لـ kickoff(inputs={...}): id, user_message, last_intent.

API المحادثة على Flow

معاملات kickoff / kickoff_async

سمات المثيل

طرق وخصائص

مساعدات الوحدة (crewai.flow.conversation)

أنماط توجيه النية

أ. تصنيف مسبق عبر ConversationalConfig (الأبسط)

عيّن default_intents وintent_llm. كل kickoff يصنّف قبل @router؛ اقرأ self.state.last_intent في route().

ب. تصنيف داخل @router (مطالبات أغنى)

عيّن default_intents=None ليضيف kickoff الرسالة فقط. في route() استدعِ classify_intent:
للبحث على الويب أو أدوات متعددة الخطوات استخدم @listen("RESEARCH") مع Agent.kickoff() وأدوات — وليس LLM.call() فقط.

عندما ينتهي الـ flow ويستمر المستخدم

FlowFinished يعني أن تنفيذ الرسم هذا اكتمل. تستمر المحادثة بـ kickoff آخر ونفس session_id. @persist يستعيد messages والأعلام والسياق. نمط الحفظ: يُفضّل @persist على خطوة نهائية واحدة (مثل finalize) وليس على صنف Flow بالكامل. الحفظ على مستوى الصنف بعد كل method قد يفقد تحديثات المعالجات في نفس الجولة. لا تستخدم @human_feedback لأسطر المتابعة في الدردشة إلا عند الحاجة لموافقة بشرية على مخرجات خطوة محددة.

Flow المحادثاتي (تجريبي)

ميزة تجريبية. سطح Flow المحادثاتي (conversational = True، handle_turn، ConversationConfig، RouterConfig، ConversationState، الرسم البياني المدمج والمساعدات) يقع تحت crewai.experimental وقد يتغير شكله قبل التخرج. ثبّت إصدار CrewAI إذا كنت تعتمد على سلوك محدد، وراقب changelog للتحديثات الكاسرة. الملاحظات والمشاكل مرحب بها.
فعّل الرسم المحادثاتي بتعيين conversational = True على صنف فرعي من Flow. عندئذٍ يُظهر Flow الأساسي رسم @start / @router / converse_turn / end_conversation مدمجاً، ويدير state.messages، ويُشغّل LLM التوجيه، ويبقي دفعة trace مفتوحة عبر الجولات. أنت تكتب المسارات المخصصة فقط؛ والإطار يتولى الباقي. استخدمه عندما تريد دردشة متعددة الجولات مع موجّه قائم على LLM ومعالجات لكل مسار دون توصيل دورة الحياة يدوياً. استخدم Flow[ChatState] (النمط الأدنى مستوى في الأعلى) عندما تحتاج تحكماً كاملاً.

مثال سريع

للدردشة المحلية في الطرفية، استخدم chat():
يلف chat() استدعاءات handle_turn() داخل REPL، ويخرج عند exit / quit، ويتجاهل الأسطر الفارغة افتراضياً، ويستدعي finalize_session_traces() عند انتهاء الجلسة.

ConversationConfig

مزخرف صنف يُلحق افتراضيات الدردشة على مستوى الصنف.

RouterConfig وفهرس المسارات المُولَّد تلقائياً

تُبنى رسالة الموجّه إلى LLM تلقائياً. لكل مسار يختار الإطار وصفاً بهذا الترتيب من الأولوية:
  1. RouterConfig.route_descriptions[label] — تجاوز صريح.
  2. Flow.builtin_route_descriptions[label] — نص جاهز من الإطار لـ converse وend وanswer_from_history (مصاغ لـ LLM التوجيه).
  3. أول سطر غير فارغ من docstring معالج @listen(label).
  4. فارغ (المسار يظهر في الفهرس بلا وصف).
عملياً، إضافة مسار جديد = @listen("X") + docstring من سطر واحد:
…وسيرى LLM التوجيه:
RouterConfig.prompt مخصص لـ تأطير النطاق (شخصية المساعد، قواعد العمل، النبرة). فهرس المسارات يُبنى تلقائياً — لا تُدرج المسارات في prompt؛ سيختل التزامن لحظة إضافة معالج جديد.

المسارات المدمجة

يمكنك تجاوز أي من هذه بتعريف معالج بنفس الاسم في الصنف الفرعي.

دلالات handle_turn()

flow.handle_turn(message) يُشغّل جولة واحدة:
  1. يعيد ضبط تعقّب التنفيذ لكل جولة (_completed_methods, _method_outputs) ليُعاد تشغيل الرسم — بدون ذلك، استدعاءات kickoff المتكررة على نفس النسخة ستُحدث دائرة قصر من الجولة الثانية لأن Flow.kickoff_async يعتبر inputs={"id": ...} استعادة من نقطة تفتيش.
  2. يُلحق رسالة المستخدم بـ state.messages ويضبط current_user_message / last_user_message. يُحافَظ على last_intent من الجولة السابقة كي يستخدمها LLM التوجيه كإشارة.
  3. يُشغّل conversation_startroute_conversation → معالج @listen المختار.
  4. يخزّن الموجّه قراره في state.last_intent (يكون مرئياً لسياق التوجيه في الجولة التالية).
  5. إذا أعاد معالجك سلسلة نصية ولم يستدعِ append_assistant_message، فإن handle_turn يُلحقها نيابةً عنك.
استدعِ handle_turn() لرسائل الدردشة. استدعاء kickoff(inputs={"id": ...}) مباشرةً يشغل الرسم بدون غلاف الجولة المحادثية.

chat() للـ REPL المحلي

flow.chat() هو غلاف الطرفية الجاهز فوق handle_turn():
يتولى الحلقة المحلية الشائعة:
  1. يطلب رسالة من المستخدم.
  2. يتوقف عند exit / quit أو EOFError أو KeyboardInterrupt.
  3. يستدعي handle_turn(message, session_id=...).
  4. يطبع نتيجة المساعد.
  5. ينهي traces الجلسة المؤجلة داخل كتلة finally.
خصص سلوك الطرفية عبر I/O قابل للحقن:
لتطبيقات الويب والـ workers الخلفية والاختبارات ووسائط النقل المخصصة، استمر في استخدام handle_turn() مباشرةً.

سلوك موجّه مخصص

لتشغيل آثار جانبية (إعداد ناقل أحداث، قياس عن بُعد) في كل قرار توجيه، تجاوز route_turn:
لتجاوز موجّه LLM واختيار مسار برمجياً، أعد سلسلة نصية من route_turn؛ إعادة None تسقط إلى _route_with_config(...).

append_assistant_message وappend_agent_result

داخل معالج @listen(label)، اختر:
  • self.append_assistant_message(text) — يضيف جولة مساعد مرئية للمستخدم إلى state.messages. سيراها converse_turn في الجولة التالية.
  • self.append_agent_result(agent_name, result, visibility="private") — يسجّل حدثاً منظماً في state.events وموضوعاً في state.agent_threads[agent_name]. الرؤية العامة تستدعي append_assistant_message أيضاً. استخدم النتائج الخاصة للعمل الجانبي الذي يجب ألا يلوث التاريخ القانوني.
يمكن لـ ConversationConfig.visible_agent_outputs رفع النتائج الخاصة لـ agents محددين إلى عامة عالمياً ("all" أو قائمة بالأسماء).

التتبع عبر الجولات

مع defer_trace_finalization=True (افتراضي في ConversationalConfig):
  • دفعة trace واحدة لجلسة الدردشة.
  • flow_started في الجولة الأولى فقط؛ flow_finished مرة في finalize_session_traces().
  • kickoff لكل جولة لا يطبع “Trace batch finalized”.
  • العمل المتداخل (Agent.kickoff(), crews, Exa) يُلحق بدفعة الأب؛ flow داخلي من AgentExecutor لا يغلق دفعة الجلسة مبكراً.
flow.chat() يستدعي finalize_session_traces() نيابةً عنك. عندما تملك الحلقة عبر handle_turn() أو kickoff(...)، استدعِ finalize_session_traces() عند انتهاء الجلسة. suppress_flow_events=True يخفي لوحات Rich فقط؛ أحداث trace والـ methods تُصدر.

دورة حياة trace لـ Flow المحادثاتي

يستخدم Flow المحادثاتي التجريبي نفس دورة حياة tracing: defer_trace_finalization افتراضياً True، فيبقي كل handle_turn() أثر الجلسة مفتوحاً. أنهِ دوماً عند نهاية الجلسة — لُف حلقتك بـ try/finally واستدعِ flow.finalize_session_traces() عند الخروج. بدون ذلك، تبقى الدفعة مفتوحة وقد لا تُصدَّر آخر محادثة أبداً.

البث

اضبط stream = True على صنف Flow. عندئذٍ يُصدر kickoff(...) أحداث assistant_delta (وما يرتبط بها) عبر ناقل الأحداث القياسي.

الاستيراد

مراجع