# from crewai import Agent, Task # import os # import json # from modules import llm_4m # from schemas import BookOutlineOutput # # --------------------------------- # # 2) Book Structure Agent # # --------------------------------- # def book_structure_agent(): # model = llm_4m() # return Agent( # name="SubsectionStructureAgent", # role="منظّم محاور فرعية داخل هيكل كتاب جاهز", # goal=( # "تنظيم وبناء المحاور الفرعية (Subsections) فقط داخل الهيكل المُعطى للكتاب، " # "مع الحفاظ التام على أسماء وترتيب الفصول والأقسام كما وردت، " # "ودون إنشاء أو إعادة تسمية أي وحدات عليا (Chapters/Sections)، " # "ودون كتابة محتوى فعلي. " # "المطلوب: محاور فرعية بعناوين جذابة وواضحة وغير تقليدية، تُسهل رحلة القارئ." # ), # backstory=( # "أنت محرر كتب محترف متخصص في تصميم هياكل الكتب بمختلف أنواعها " # "(تعليمية، معرفية، تطوير ذات، أعمال، أو غير خيالية). " # "تجيد العمل داخل هياكل كتب جاهزة دون تعديلها، " # "وتلتزم التزامًا صارمًا بالحفاظ على أسماء الفصول والأقسام وترتيبها كما هي. " # "ويقتصر دورك على بناء المحاور الفرعية (Subsections) وتنظيمها منطقيًا داخل كل قسم.\n\n" # "تميزك الأساسي: صياغة عناوين محاور فرعية قوية غير جامدة ولا أكاديمية ثقيلة. " # "تتجنب التكرار اللفظي، وتبتعد عن الافتتاحيات التقليدية، " # "وتقسم الأفكار الكبيرة إلى محاور صغيرة واضحة (فكرة واحدة لكل محور)." # ), # llm=model, # verbose=False, # memory=False, # allow_delegation=False, # ) # # --------------------------------- # # 3) Task: Generate Book Outline JSON (STRICT) # # --------------------------------- # def generate_book_outline_task(structure_agent): # return Task( # name="Generate book outline (NO content writing)", # description=( # """أنت تبني هيكل كتاب فقط (Outline) من بيانات الإدخال، # بما يتناسب مع نوع الكتاب (تعليمي، معرفي، تطوير ذات، أعمال، أو غير خيالي)، # مع مراعاة الجمهور المستهدف وطبيعة التجربة القرائية. # """ # """تنبيه صارم: # - لا تقم بإنشاء فصول (Chapters) جديدة. # - لا تقم بإنشاء أقسام (Sections) جديدة. # - لا تغيّر أسماء Chapters أو Sections الواردة في raw_units حرفيًا. # - لا تعيد ترتيب الفصول أو الأقسام. # - دورك يقتصر حصريًا على: # • تنظيم وبناء Subsections داخل كل Section موجود. # """ # "==============================\n" # "قواعد إلزامية (معايير إعداد الكتب)\n" # "==============================\n" # "1) ممنوع كتابة محتوى الكتاب/شرح مطول/أمثلة تفصيلية. أنت تنتج هيكل فقط.\n" # "2) الوضوح والبساطة في العناوين واللغة.\n" # """3) عدد Subsections يجب أن يكون مرنًا حسب حجم الفكرة داخل Section. # - الحد الأدنى: 2 # - الحد الأقصى: 6 # لكن لا تختَر دائمًا الحد الأدنى. # قاعدة الاختيار: # - إذا كان القسم بسيط → 2–3 محاور # - إذا كان القسم متوسط → 3–4 محاور # - إذا كان القسم غني بالمفاهيم → 4–6 محاور # اختر العدد الذي يخدم الفكرة وليس الحد الأدنى دائمًا.""" # "5) منع التكرار: لا تكرر نفس الفكرة بين محاور متجاورة، ولا تكرر نفس الصياغة الافتتاحية.\n" # """6) التدرج: # - الكتب التعليمية: من الأساسيات إلى التطبيق/التحليل # - الكتب غير التعليمية: من التمهيد إلى التعمق ثم الخلاصة/التحول # - يجب أن يعكس الترتيب رحلة القارئ الطبيعية # """ # "7) ترابط منطقي بين الأقسام والمحاور (بدون قفزات مفاهيمية).\n\n" # "==============================\n" # "قواعد إلزامية لصياغة عناوين Subsections (مهم جدًا)\n" # "==============================\n" # "A) عناوين المحاور الفرعية لازم تكون:\n" # " - قصيرة وواضحة (يفضل 2–6 كلمات).\n" # " - غير تقليدية/غير جامدة، وتشد القارئ.\n" # " - لغة بسيطة مناسبة للجمهور (ابتعد عن الأسلوب الأكاديمي الثقيل).\n" # " - فكرة واحدة لكل عنوان.\n" # "B) ممنوع تكرار بدايات العناوين أو الحشو اللفظي.\n" # " - لا تبدأ عدة محاور بنفس الصيغة مثل: (في ظل...)، (يبرز...)، (من المعروف...)، (يتناول هذا القسم...).\n" # "C) تجنب العناوين المركّبة التي تجمع محورين مختلفين في عنوان واحد.\n" # " - مثال ممنوع: (تعريف الصمود النفسي وأهميته)\n" # " - الصحيح: محور لتعريف المفهوم + محور مستقل للأهمية/الفوائد.\n" # "D) تجنب كلمات فضفاضة أو غير دقيقة في العناوين مثل:\n" # " - (الرئيسية/الأساسية) إذا كانت لا تضيف معنى.\n" # "E) لا تستخدم عناوين تشبه عناوين الأبحاث (توثيق/اقتباسات/أسماء باحثين/سنوات) داخل العناوين.\n" # "F) يجوز استخدام أساليب عنوان جذابة حسب نوع القسم:\n" # " - سؤال تحفيزي، عبارة قصيرة، أو صياغة عملية (لكن بدون كتابة محتوى).\n\n" # """ # ============================== # تقسيم المحاور بطريقة جذابة للقارئ # ============================== # لا تقسّم المحاور بطريقة ميكانيكية. # بدلًا من تقسيم عشوائي، استخدم أحد أنماط التقسيم التالية حسب طبيعة الموضوع: # - المشكلة → الفهم → الحل # - المفهوم → المكونات → التطبيق # - الفكرة → التحديات → الاستراتيجيات # - الأساسيات → الأدوات → الاستخدام # - الأخطاء → التصحيح → التحسين # الهدف: # أن يشعر القارئ أن كل Section يمثل رحلة فكرية وليس مجرد عناوين متفرقة. # """ # """ # ============================== # توزيع الصفحات (مهم جدًا) # ============================== # إذا تم تمرير target_total_pages: # 1) احسب متوسط صفحات الفصل: # avg_chapter_pages = target_total_pages ÷ عدد الفصول # مثال: # كتاب 100 صفحة # 4 فصول # → متوسط الفصل ≈ 25 صفحة # 2) وزّع الصفحات على الفصول بشكل قريب من المتوسط # لكن يمكن أن يختلف ±20% حسب عمق الفصل. # 3) داخل كل فصل: # قسّم الصفحات على Sections بشكل منطقي. # 4) داخل كل Section: # قسّم الصفحات على Subsections بحيث: # - المحور القصير: 1–2 صفحات # - المحور المتوسط: 2–3 صفحات # - المحور المتعمق: 3–5 صفحات # 5) تحقق إلزامي: # مجموع est_pages لكل Subsections # = target_total_pages بالضبط # إذا لم يساوِ: # قم بتعديل التوزيع حتى يتطابق المجموع. # """ # """ # ============================== # مراعاة حجم الكتاب # ============================== # لا تقرر عدد المحاور أولًا. # ابدأ بتقدير حجم الكتاب: # - كتاب 60–100 صفحة → محاور أقل وشرح مركز # - كتاب 100–180 صفحة → توازن بين عدد المحاور وعمق الشرح # - كتاب 180+ صفحة → محاور أكثر وتفصيل أكبر # القاعدة الأساسية: # عدد الصفحات هو الذي يحدد عدد المحاور # وليس العكس. # """ # "==============================\n" # "الحفاظ على الأسماء\n" # "==============================\n" # """- استخدم عناوين Chapters وSections كما هي حرفيًا من raw_units. # - يُمنع إعادة الصياغة أو التحسين اللغوي لعناوين Chapters/Sections. # - التعديل/التحسين مسموح فقط داخل Subsections التي تنشئها. # """ # "==============================\n" # "المدخلات\n" # "==============================\n" # "- book_title: {book_title}\n" # "- target_audience: {target_audience}\n" # "- book_description: {book_description}\n" # "- learning_outcomes: {learning_outcomes}\n" # "- raw_units: {raw_units}\n" # "- target_total_pages (optional): {target_total_pages}\n" # "- example_reference (optional): {example_reference}\n\n" # """ملاحظة مهمة: # raw_units تمثل الهيكل النهائي للفصول والأقسام. # يُمنع تعديل أو إعادة تسمية أي Unit أو Topic. # Subsections فقط هي التي يتم إنشاؤها وتنظيمها. # """ # "==============================\n" # "مطلوب الإخراج (JSON صارم)\n" # "==============================\n" # "أخرج JSON فقط مطابق لـ BookOutlineOutput وبنفس أسماء الحقول:\n" # "{\n" # ' "book_title": "...",\n' # ' "target_audience": "...",\n' # ' "book_description": "...",\n' # ' "chapters": [\n' # " {\n" # ' "chapter_title": "...",\n' # ' "outcome": "...",\n' # ' "sections": [\n' # " {\n" # ' "title": "...",\n' # ' "overview": "...",\n' # ' "subsections": [\n' # " {\n" # ' "title": "...",\n' # ' "purpose": "...",\n' # ' "suggested_queries": ["..."],\n' # ' "difficulty": "basic|intermediate|advanced",\n' # ' "est_pages": 1\n' # " }\n" # " ]\n" # " }\n" # " ]\n" # " }\n" # " ],\n" # ' "outline_notes": "..."\n' # ' "total_pages": 50\n' # "}\n" # "==============================\n" # "تحقق إلزامي قبل الإخراج\n" # "==============================\n" # """ # قبل إخراج الـ JSON النهائي، راجع ما يلي بدقة: # - كل Chapter يحتوي 2–6 Sections # - كل Section يحتوي على 2–6 Subsections (لا أقل من 2 نهائيًا) # - إذا وجدت Section تحتوي فكرة واحدة فقط: # → قم بتقسيمها إلى محورين منطقيين مختلفين # - راجع عناوين Subsections: # → لا تكرار في بدايات العناوين # → لا عناوين جامدة/تقليدية # → لا دمج (تعريف + أهمية) في عنوان واحد # 1) اجمع جميع est_pages في Subsections. # 2) تحقق أن المجموع = target_total_pages. # إذا لم يتطابق: # قم بإعادة توزيع est_pages حتى يصبح المجموع مطابقًا تمامًا. # - لا تخرج JSON حتى تتأكد أن جميع القيود محققة # - أي مخالفة ستُعد إخراجًا غير صالح # """ # ), # expected_output="Strict JSON matching BookOutlineOutput schema (NO extra keys).", # output_json=BookOutlineOutput, # agent=structure_agent, # async_execution=False, # ) from crewai import Agent, Task from modules import llm_open_4m from schemas import BookOutlineOutput # --------------------------------------------------- # Agent: Book Structure Designer # --------------------------------------------------- def book_structure_agent(): model = llm_open_4m() return Agent( name="BookStructureDesigner", role="مصمم هياكل كتب احترافية", goal=( "تصميم محاور فرعية جذابة داخل الهيكل المعطى للكتاب " "مع الحفاظ الكامل على أسماء الفصول والأقسام كما هي " "ودون تعديلها أو إعادة ترتيبها." ), backstory=( "أنت محرر كتب محترف تعمل مع دور نشر كبيرة. " "مهمتك تصميم المحاور الفرعية (Subsections) التي تجعل القارئ " "يتنقل داخل القسم بسهولة وبفضول معرفي.\n\n" "لا تكتب محتوى الكتاب. دورك هو تصميم الهيكل فقط.\n\n" "تميزك الأساسي:\n" "- صياغة عناوين جذابة وليست أكاديمية ثقيلة\n" "- تقسيم الفكرة الكبيرة إلى محاور واضحة\n" "- كل عنوان يمثل فكرة واحدة فقط\n" "- تجنب التكرار والجمود في العناوين\n" ), llm=model, verbose=False, memory=False, allow_delegation=False, ) # --------------------------------------------------- # Task: Generate Book Outline # --------------------------------------------------- def generate_book_outline_task(structure_agent): return Task( name="Generate book outline", description=( "مهمتك بناء هيكل كتاب (Book Outline) فقط.\n" "لا تكتب محتوى فعلي للكتاب.\n\n" "=========================\n" "القواعد الأساسية\n" "=========================\n" "1) لا تقم بإنشاء Chapters جديدة\n" "2) لا تقم بإنشاء Sections جديدة\n" "3) لا تغيّر أسماء Chapters أو Sections\n" "4) لا تعيد ترتيب الهيكل\n" "5) دورك فقط إنشاء Subsections داخل كل Section\n\n" "=========================\n" "قواعد إنشاء Subsections\n" "=========================\n" "- كل Section يجب أن يحتوي 2 إلى 6 Subsections\n" "- كل Subsection يمثل فكرة واحدة واضحة\n" "- رتب المحاور بشكل منطقي بحيث تشكل رحلة للقارئ\n" "أنماط تقسيم مناسبة:\n" "- المفهوم → الفهم → التطبيق\n" "- المشكلة → التحليل → الحل\n" "- الفكرة → التحديات → الاستراتيجيات\n" "- الأساسيات → الأدوات → الاستخدام\n\n" "=========================\n" "قواعد صياغة العناوين\n" "=========================\n" "العناوين يجب أن تكون:\n" "- قصيرة (2 إلى 6 كلمات)\n" "- جذابة وسهلة القراءة\n" "- غير أكاديمية ثقيلة\n" "- فكرة واحدة لكل عنوان\n" "تجنب:\n" "- تعريف + أهمية في نفس العنوان\n" "- تكرار نفس بداية العنوان\n" "- العناوين الجامدة\n\n" "أمثلة لعناوين جيدة:\n" "- لماذا تفشل الخطط؟\n" "- لحظة اكتشاف المشكلة\n" "- الفكرة التي تغير كل شيء\n" "- عندما يتحول الضغط إلى فرصة\n\n" "=========================\n" "المدخلات\n" "=========================\n" "book_title: {book_title}\n" "target_audience: {target_audience}\n" "book_description: {book_description}\n" "learning_outcomes: {learning_outcomes}\n" "raw_units: {raw_units}\n" "target_total_pages: {target_total_pages}\n\n" "example_reference (استلهم منه أسلوب العناوين فقط):\n" "{example_reference}\n\n" "raw_units تمثل الهيكل النهائي للفصول والأقسام.\n" "يُمنع تعديلها.\n" "قم فقط بإضافة Subsections داخل كل Section.\n\n" "=========================\n" "توزيع الصفحات\n" "=========================\n" "إذا تم تمرير target_total_pages:\n" "- وزع الصفحات على Subsections\n" "- المحور القصير: 1-2 صفحات\n" "- المحور المتوسط: 2-3 صفحات\n" "- المحور العميق: 3-5 صفحات\n" "مجموع الصفحات يجب أن يساوي target_total_pages.\n\n" "=========================\n" "الإخراج المطلوب\n" "=========================\n" "أخرج JSON فقط مطابق لـ BookOutlineOutput.\n" "{\n" ' "book_title": "...",\n' ' "target_audience": "...",\n' ' "book_description": "...",\n' ' "chapters": [\n' " {\n" ' "chapter_title": "...",\n' ' "outcome": "...",\n' ' "sections": [\n' " {\n" ' "title": "...",\n' ' "overview": "...",\n' ' "subsections": [\n' " {\n" ' "title": "...",\n' ' "purpose": "...",\n' ' "suggested_queries": ["..."],\n' ' "difficulty": "basic|intermediate|advanced",\n' ' "est_pages": 1\n' " }\n" " ]\n" " }\n" " ]\n" " }\n" " ],\n" ' "outline_notes": "...",\n' ' "total_pages": 50\n' "}\n\n" "لا تضف أي نص خارج JSON." ), expected_output="Strict JSON matching BookOutlineOutput schema", output_json=BookOutlineOutput, agent=structure_agent, async_execution=False, )