نظرة عامة
تعامل التطبيقات المحادثية مع كل سطر من المستخدم كـ تشغيل 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 يشغّل:
_configure_conversational_kickoff— دمجsession_id/user_messageفيinputsوتطبيقConversationalConfig.- استعادة الحالة — عند وجود
inputs["id"]و@persist. FlowStarted— في أول جولة للجلسة المؤجلة فقط.prepare_conversational_turn— إضافة رسالة المستخدم وlast_user_messageوتصنيف اختياري.- تنفيذ الرسم —
@start→@router→ معالجات@listen. - نهاية التشغيل — يُتخطى
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 المحادثاتي (تجريبي)
فعّل الرسم المحادثاتي بتعيين 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 وفهرس المسارات المُولَّد تلقائياً
RouterConfig.route_descriptions[label]— تجاوز صريح.Flow.builtin_route_descriptions[label]— نص جاهز من الإطار لـconverseوendوanswer_from_history(مصاغ لـ LLM التوجيه).- أول سطر غير فارغ من docstring معالج
@listen(label). - فارغ (المسار يظهر في الفهرس بلا وصف).
@listen("X") + docstring من سطر واحد:
RouterConfig.prompt مخصص لـ تأطير النطاق (شخصية المساعد، قواعد العمل، النبرة). فهرس المسارات يُبنى تلقائياً — لا تُدرج المسارات في prompt؛ سيختل التزامن لحظة إضافة معالج جديد.
المسارات المدمجة
يمكنك تجاوز أي من هذه بتعريف معالج بنفس الاسم في الصنف الفرعي.
دلالات handle_turn()
flow.handle_turn(message) يُشغّل جولة واحدة:
- يعيد ضبط تعقّب التنفيذ لكل جولة (
_completed_methods,_method_outputs) ليُعاد تشغيل الرسم — بدون ذلك، استدعاءاتkickoffالمتكررة على نفس النسخة ستُحدث دائرة قصر من الجولة الثانية لأنFlow.kickoff_asyncيعتبرinputs={"id": ...}استعادة من نقطة تفتيش. - يُلحق رسالة المستخدم بـ
state.messagesويضبطcurrent_user_message/last_user_message. يُحافَظ علىlast_intentمن الجولة السابقة كي يستخدمها LLM التوجيه كإشارة. - يُشغّل
conversation_start→route_conversation→ معالج@listenالمختار. - يخزّن الموجّه قراره في
state.last_intent(يكون مرئياً لسياق التوجيه في الجولة التالية). - إذا أعاد معالجك سلسلة نصية ولم يستدعِ
append_assistant_message، فإنhandle_turnيُلحقها نيابةً عنك.
handle_turn() لرسائل الدردشة. استدعاء kickoff(inputs={"id": ...}) مباشرةً يشغل الرسم بدون غلاف الجولة المحادثية.
chat() للـ REPL المحلي
flow.chat() هو غلاف الطرفية الجاهز فوق handle_turn():
- يطلب رسالة من المستخدم.
- يتوقف عند
exit/quitأوEOFErrorأوKeyboardInterrupt. - يستدعي
handle_turn(message, session_id=...). - يطبع نتيجة المساعد.
- ينهي traces الجلسة المؤجلة داخل كتلة
finally.
handle_turn() مباشرةً.
سلوك موجّه مخصص
لتشغيل آثار جانبية (إعداد ناقل أحداث، قياس عن بُعد) في كل قرار توجيه، تجاوزroute_turn:
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 (وما يرتبط بها) عبر ناقل الأحداث القياسي.
الاستيراد
مراجع
- إتقان إدارة حالة Flow
- أنشئ أول Flow
- Demo:
lib/crewai/runner_conversational_flow_simple.py— REPL بسيط معRESEARCHووكيل Exa
