| # 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, | |
| ) | |