Compare commits

..

1 Commits

Author SHA1 Message Date
Vinicius Brasil
b9586874b3 Add lead scoring FlowDefinition example 2026-06-16 10:54:34 -07:00
76 changed files with 3054 additions and 3492 deletions

View File

@@ -70,39 +70,13 @@ mode: "wide"
## إنشاء الوكلاء
هناك طريقتان شائعتان لإنشاء الوكلاء في CrewAI: باستخدام **تهيئة JSONC (الموصى بها للـ crews الجديدة)** أو تعريفهم **مباشرة في الكود**.
هناك طريقتان لإنشاء الوكلاء في CrewAI: باستخدام **تهيئة YAML (موصى بها)** أو تعريفهم **مباشرة في الكود**.
### تهيئة JSONC (موصى بها)
### تهيئة YAML (موصى بها)
المشاريع الجديدة التي تُنشأ عبر `crewai create crew <name>` تستخدم تهيئة JSON-first. يُعرّف كل Agent في `agents/<agent_name>.jsonc`، ويحدد `crew.jsonc` أي Agents تدخل في الـ crew.
توفر تهيئة YAML طريقة أنظف وأكثر قابلية للصيانة لتعريف الوكلاء. نوصي بشدة باستخدام هذا النهج في مشاريع CrewAI.
```jsonc agents/researcher.jsonc
{
"role": "{topic} Senior Data Researcher",
"goal": "Uncover cutting-edge developments in {topic}",
"backstory": "You find the most relevant information and present it clearly.",
"llm": "openai/gpt-4o",
"tools": ["SerperDevTool"],
"settings": {
"verbose": true,
"allow_delegation": false
}
}
```
استخدم `{placeholder}` داخل `role` أو `goal` أو `backstory`. ضع القيم الافتراضية في `inputs` داخل `crew.jsonc`؛ وسيطلب `crewai run` أي قيم ناقصة. يمكن وضع حقول السلوك مثل `verbose` و `allow_delegation` و `max_iter` و `memory` و `cache` و `planning` في المستوى الأعلى أو داخل `settings`.
<Note>
يدعم JSONC التعليقات والفواصل النهائية. إذا وُجد `agents/<name>.jsonc` و `agents/<name>.json` معًا، يستخدم CrewAI ملف JSONC.
</Note>
### تهيئة YAML الكلاسيكية
المشاريع الكلاسيكية التي تُنشأ عبر `crewai create crew <name> --classic` تستخدم `config/agents.yaml` وفئة `@CrewBase` في `crew.py`.
تظل تهيئة YAML مدعومة للمشاريع الحالية المبنية بـ Python/YAML وللفِرق التي تفضل تعريف الوكلاء من خلال فئة `@CrewBase`.
بعد إنشاء مشروع كلاسيكي، انتقل إلى ملف `src/latest_ai_development/config/agents.yaml` وعدّل القالب ليتوافق مع متطلباتك.
بعد إنشاء مشروع CrewAI كما هو موضح في قسم [التثبيت](/ar/installation)، انتقل إلى ملف `src/latest_ai_development/config/agents.yaml` وعدّل القالب ليتوافق مع متطلباتك.
<Note>
ستُستبدل المتغيرات في ملفات YAML (مثل `{topic}`) بقيم من مدخلاتك عند تشغيل الطاقم:

View File

@@ -52,8 +52,6 @@ crewai create crew my_new_crew
crewai create flow my_new_flow
```
افتراضيًا، ينشئ `crewai create crew` مشروعًا JSON-first يحتوي على `crew.jsonc` و `agents/*.jsonc`. استخدم `crewai create crew my_new_crew --classic` فقط إذا أردت البنية القديمة Python/YAML مع `crew.py` و `config/agents.yaml` و `config/tasks.yaml`.
### 2. الإصدار
عرض الإصدار المثبت من CrewAI.
@@ -144,20 +142,7 @@ crewai chat
```
<Note>
مهم: عيّن خاصية `chat_llm` في تعريف الـ crew لتفعيل هذا الأمر.
للـ crews بنمط JSON-first، أضفها إلى `crew.jsonc`:
```jsonc
{
"name": "My Crew",
"agents": ["researcher"],
"tasks": [],
"chat_llm": "openai/gpt-4o"
}
```
للـ crews الكلاسيكية Python/YAML، عيّنها في `crew.py`:
مهم: عيّن خاصية `chat_llm` في ملف `crew.py` لتفعيل هذا الأمر.
```python
@crew

View File

@@ -40,52 +40,11 @@ mode: "wide"
## إنشاء الأطقم
هناك طريقتان رئيسيتان لإنشاء الأطقم في CrewAI: باستخدام **تهيئة JSONC (الموصى بها للـ crews الجديدة)** أو تعريفها **مباشرة في الكود** للمشاريع الكلاسيكية والحالات المتقدمة.
هناك طريقتان لإنشاء الأطقم في CrewAI: باستخدام **تهيئة YAML (موصى بها)** أو تعريفها **مباشرة في الكود**.
### تهيئة JSONC (موصى بها)
### تهيئة YAML (موصى بها)
المشاريع الجديدة التي تُنشأ عبر `crewai create crew <name>` تستخدم `crew.jsonc` لإعدادات الـ crew والمهام، وملفًا منفصلًا لكل Agent داخل `agents/`. يكتشف `crewai run` ملف `crew.jsonc` أو `crew.json`، ويحمّل الـ Agents المشار إليها، ويطلب قيم placeholders الناقصة، ثم يبدأ الـ crew.
```jsonc crew.jsonc
{
"name": "Market Research Crew",
"agents": ["researcher", "analyst"],
"tasks": [
{
"name": "research",
"description": "Research {topic} and collect the most relevant facts.",
"expected_output": "Structured research notes about {topic}.",
"agent": "researcher"
},
{
"name": "analysis",
"description": "Analyze the research and write a concise report.",
"expected_output": "A markdown report with findings and recommendations.",
"agent": "analyst",
"context": ["research"],
"output_file": "output/report.md"
}
],
"process": "sequential",
"verbose": true,
"memory": true,
"inputs": {
"topic": "AI Agents"
}
}
```
كل عنصر في `agents` يُحل أولًا إلى `agents/<name>.jsonc` ثم إلى `agents/<name>.json`. للـ crews الهرمية، استخدم `"process": "hierarchical"` مع `manager_llm` أو `manager_agent`.
<Warning>
شغّل مشاريع JSON crew من مصادر تثق بها فقط. أدوات `custom:<name>` ومراجع `{"python": "module.attribute"}` تنفذ كود Python محليًا عند تحميل الـ crew.
</Warning>
### تهيئة YAML الكلاسيكية
المشاريع الكلاسيكية التي تُنشأ عبر `crewai create crew <name> --classic` تستخدم `crew.py` و `config/agents.yaml` و `config/tasks.yaml` والمزيّنات `@CrewBase` و `@agent` و `@task` و `@crew`.
تظل هذه الطريقة مدعومة للمشاريع الحالية المبنية بـ Python/YAML وللفِرق التي تحتاج تحكمًا صريحًا عبر decorators.
توفر تهيئة YAML طريقة أنظف وأكثر قابلية للصيانة لتعريف الأطقم وتتسق مع كيفية تعريف الوكلاء والمهام في مشاريع CrewAI.
```python code
from crewai import Agent, Crew, Task, Process

View File

@@ -830,7 +830,7 @@ if __name__ == "__main__":
crewai create flow name_of_flow
```
سيولّد هذا الأمر مشروع CrewAI جديد مع هيكل المجلدات اللازم. يتضمن المشروع المولّد فريق Crew مُعد مسبقًا يُسمى `poem_crew` ويعمل بالفعل. يستخدم الـ embedded crew الابتدائي بنية Python/YAML الكلاسيكية؛ أما crews المستقلة الجديدة التي تُنشأ عبر `crewai create crew` فتستخدم بنية JSON-first.
سيولّد هذا الأمر مشروع CrewAI جديد مع هيكل المجلدات اللازم. يتضمن المشروع المولّد فريق Crew مُعد مسبقًا يُسمى `poem_crew` ويعمل بالفعل. يمكنك استخدام هذا الفريق كقالب بنسخه ولصقه وتعديله لإنشاء فرق أخرى.
### هيكل المجلدات
@@ -860,29 +860,7 @@ crewai create flow name_of_flow
- `config/tasks.yaml`: يحدد المهام للفريق.
- `poem_crew.py`: يحتوي على تعريف الفريق، بما في ذلك الـ Agents والمهام والفريق نفسه.
يمكنك نسخ ولصق وتعديل `poem_crew` لإنشاء crews كلاسيكية مضمّنة أخرى.
للـ crews المضمّنة بنمط JSON-first، استخدم مجلدًا يحتوي على `crew.jsonc` و `agents/*.jsonc`:
```text
crews/
└── research_crew/
├── agents/
│ └── researcher.jsonc
└── crew.jsonc
```
ثم حمّلها من خطوة في Flow:
```python
from pathlib import Path
from crewai.project import load_crew
crew, default_inputs = load_crew(
Path(__file__).parent / "crews" / "research_crew" / "crew.jsonc"
)
result = crew.kickoff(inputs={**default_inputs, "topic": "AI Agents"})
```
يمكنك نسخ ولصق وتعديل `poem_crew` لإنشاء فرق أخرى.
### ربط فرق Crew في `main.py`

View File

@@ -73,48 +73,13 @@ crew = Crew(
## إنشاء المهام
هناك طريقتان شائعتان لإنشاء المهام في CrewAI: باستخدام **تهيئة JSONC (الموصى بها للـ crews الجديدة)** أو تعريفها **مباشرة في الكود**.
هناك طريقتان لإنشاء المهام في CrewAI: باستخدام **إعداد YAML (موصى به)** أو تعريفها **مباشرة في الكود**.
### تهيئة JSONC (موصى بها)
### إعداد YAML (موصى به)
المشاريع الجديدة التي تُنشأ عبر `crewai create crew <name>` تعرّف المهام في `crew.jsonc`.
يوفر استخدام إعداد YAML طريقة أنظف وأكثر قابلية للصيانة لتعريف المهام. نوصي بشدة باستخدام هذا النهج لتعريف المهام في مشاريع CrewAI.
````jsonc crew.jsonc
{
"name": "Research Crew",
"agents": ["researcher", "reporting_analyst"],
"tasks": [
{
"name": "research_task",
"description": "Conduct thorough research about {topic}.",
"expected_output": "A list of the most relevant information about {topic}.",
"agent": "researcher"
},
{
"name": "reporting_task",
"description": "Review the research and expand it into a detailed report.",
"expected_output": "A polished markdown report.",
"agent": "reporting_analyst",
"context": ["research_task"],
"markdown": true,
"output_file": "report.md"
}
],
"inputs": {
"topic": "AI Agents"
}
}
````
كل مهمة تحتاج إلى `description` و `expected_output`. يجب أن يطابق `agent` اسم Agent مذكورًا في `agents`. يشير `context` إلى أسماء مهام سابقة فقط؛ وترفض الإشارات إلى مهام لاحقة.
### إعداد YAML الكلاسيكي
المشاريع الكلاسيكية التي تُنشأ عبر `crewai create crew <name> --classic` تستخدم `config/tasks.yaml` وفئة `@CrewBase` في `crew.py`.
يظل إعداد YAML مدعومًا للمشاريع الحالية المبنية بـ Python/YAML وللفِرق التي تفضل تعريف المهام من خلال فئة `@CrewBase`.
بعد إنشاء مشروع كلاسيكي، انتقل إلى ملف `src/latest_ai_development/config/tasks.yaml` وعدّل القالب ليتوافق مع متطلبات مهامك المحددة.
بعد إنشاء مشروع CrewAI كما هو موضح في قسم [التثبيت](/ar/installation)، انتقل إلى ملف `src/latest_ai_development/config/tasks.yaml` وعدّل القالب ليتوافق مع متطلبات مهامك المحددة.
<Note>
المتغيرات في ملفات YAML (مثل `{topic}`) سيتم استبدالها بالقيم من مدخلاتك عند تشغيل الفريق:

View File

@@ -26,10 +26,10 @@ icon: "arrows-rotate"
## الخطوة 1 — هيكلة طاقم التحقق
أنشئ مشروع crew كلاسيكيًا لأن هذا المثال يربط أداة Python عبر `crew.py`:
أنشئ مشروع طاقم جديد. يُهيكل CrewAI CLI البنية:
```bash
crewai create crew rotation_verifier --classic --skip_provider
crewai create crew rotation_verifier --skip_provider
cd rotation_verifier
```

View File

@@ -374,17 +374,17 @@ git push
**الحل**: تحقق من أن مشروعك يتطابق مع البنية المتوقعة:
- **JSON-first Crews**: أبقِ `crew.jsonc` أو `crew.json` و `agents/` في جذر المشروع
- **Crews كلاسيكية**: استخدم `src/project_name/main.py` مع دالة دخول `run()`
- **Flows**: استخدم `src/project_name/main.py` مع دالة دخول `kickoff()`
- **كل من الطواقم والتدفقات**: يجب أن تكون نقطة الدخول في `src/project_name/main.py`
- **الطواقم**: تستخدم دالة `run()` كنقطة دخول
- **التدفقات**: تستخدم دالة `kickoff()` كنقطة دخول
راجع [التحضير للنشر](/ar/enterprise/guides/prepare-for-deployment) لمخططات البنية المفصلة.
#### مُزخرف CrewBase مفقود في crew كلاسيكية
#### مُزخرف CrewBase مفقود
**العرض**: أخطاء "Crew not found" أو "Config not found" أو أخطاء تهيئة الوكيل/المهمة
**الحل**: في crews الكلاسيكية Python/YAML، تأكد من أن جميع فئات الـ crew تستخدم مُزخرف `@CrewBase`. لا تحتاج crews بنمط JSON-first إلى هذا المزخرف.
**الحل**: تأكد من أن **جميع** فئات الطاقم تستخدم مُزخرف `@CrewBase`:
```python
from crewai.project import CrewBase, agent, crew, task
@@ -404,8 +404,8 @@ class YourCrew():
```
<Info>
ينطبق هذا على فئات crew الكلاسيكية المكتوبة في Python، بما في ذلك crews الكلاسيكية المضمنة داخل مشاريع Flow.
يتم التحقق من crews بنمط JSON-first من `crew.jsonc` و `agents/` بدلاً من ذلك.
ينطبق هذا على الطواقم المستقلة والطواقم المضمنة داخل مشاريع التدفق.
كل فئة طاقم تحتاج المُزخرف.
</Info>
#### نوع pyproject.toml غير صحيح
@@ -442,8 +442,8 @@ type = "flow"
**الحل**:
1. تحقق من سجلات التنفيذ في لوحة تحكم AMP (علامة تبويب Traces)
2. تحقق من أن جميع الأدوات لديها مفاتيح API المطلوبة مُهيأة
3. في crews بنمط JSON-first، تحقق من `crew.jsonc` والملفات المشار إليها داخل `agents/`
4. في crews الكلاسيكية، تأكد من صحة `agents.yaml` و `tasks.yaml`
3. تأكد من صحة تهيئات الوكلاء في `agents.yaml`
4. تحقق من تهيئات المهام في `tasks.yaml` بحثاً عن أخطاء الصياغة
<Card title="تحتاج مساعدة؟" icon="headset" href="mailto:support@crewai.com">
تواصل مع فريق الدعم للمساعدة في مشاكل النشر أو أسئلة حول

View File

@@ -23,9 +23,10 @@ company-ai/
`-- crews/
|-- support_agent/
| |-- pyproject.toml
| |-- crew.jsonc
| `-- agents/
| `-- support_agent.jsonc
| `-- src/
| `-- support_agent/
| |-- main.py
| `-- crew.py
`-- research_flow/
|-- pyproject.toml
`-- src/
@@ -46,7 +47,7 @@ crews/support_agent
عند تعيين دليل عمل، يستخدم AMP ذلك المجلد من أجل:
- التحقق من المشروع، بما في ذلك `pyproject.toml` وملفات crew JSON وأي نقطة دخول كلاسيكية لـ Crew أو Flow
- التحقق من المشروع، بما في ذلك `pyproject.toml` و`src/` ونقطة دخول Crew أو Flow
- تثبيت الاعتماديات باستخدام `uv`
- دليل العمل للعملية قيد التشغيل
- متغير البيئة `CREW_ROOT_DIR`

View File

@@ -24,7 +24,7 @@ mode: "wide"
<CardGroup cols={2}>
<Card title="مشاريع الطاقم" icon="users">
فرق وكلاء ذكاء اصطناعي مستقلة. الـ crews الجديدة تستخدم بنية JSON-first مع `crew.jsonc` و `agents/`؛ ويمكن للـ crews الكلاسيكية الاستمرار في استخدام `crew.py`.
فرق وكلاء ذكاء اصطناعي مستقلة مع `crew.py` يحدد الوكلاء والمهام. الأفضل للمهام المركزة والتعاونية.
</Card>
<Card title="مشاريع التدفق" icon="diagram-project">
سير عمل مُنسّق مع طواقم مضمنة في مجلد `crews/`. الأفضل للعمليات المعقدة متعددة المراحل.
@@ -33,19 +33,19 @@ mode: "wide"
| الجانب | الطاقم | التدفق |
|--------|--------|--------|
| **بنية المشروع** | جذر المشروع مع `crew.jsonc` و `agents/` | `src/project_name/` مع مجلد `crews/` |
| **موقع المنطق الرئيسي** | `crew.jsonc` (كلاسيكي: `src/project_name/crew.py`) | `src/project_name/main.py` (فئة Flow) |
| **دالة نقطة الدخول** | تُحمّل من `crew.jsonc` (كلاسيكي: `run()` في `main.py`) | `kickoff()` في `main.py` |
| **بنية المشروع** | `src/project_name/` مع `crew.py` | `src/project_name/` مع مجلد `crews/` |
| **موقع المنطق الرئيسي** | `src/project_name/crew.py` | `src/project_name/main.py` (فئة Flow) |
| **دالة نقطة الدخول** | `run()` في `main.py` | `kickoff()` في `main.py` |
| **نوع pyproject.toml** | `type = "crew"` | `type = "flow"` |
| **أمر CLI للإنشاء** | `crewai create crew name` | `crewai create flow name` |
| **موقع التهيئة** | `crew.jsonc` و `agents/` و `tools/` اختياريًا | `src/project_name/crews/crew_name/config/` أو مجلدات crew JSON مضمنة |
| **موقع التهيئة** | `src/project_name/config/` | `src/project_name/crews/crew_name/config/` |
| **يمكن أن يحتوي طواقم أخرى** | لا | نعم (في مجلد `crews/`) |
## مرجع بنية المشروع
### بنية مشروع الطاقم
عند تشغيل `crewai create crew my_crew`، تحصل على بنية JSON-first:
عند تشغيل `crewai create crew my_crew`، تحصل على هذه البنية:
```
my_crew/
@@ -54,25 +54,24 @@ my_crew/
├── README.md
├── .env
├── uv.lock # REQUIRED for deployment
── crew.jsonc # إعدادات الـ crew والمهام والعملية والمدخلات
├── agents/
└── researcher.jsonc # تعريفات الـ Agents
├── tools/ # أدوات custom:<name> اختيارية
├── knowledge/
└── skills/
── src/
└── my_crew/
├── __init__.py
├── main.py # Entry point with run() function
├── crew.py # Crew class with @CrewBase decorator
├── tools/
│ ├── custom_tool.py
│ └── __init__.py
└── config/
├── agents.yaml # Agent definitions
└── tasks.yaml # Task definitions
```
<Warning>
في crews بنمط JSON-first، أبقِ `crew.jsonc` و `agents/` و `tools/` و `knowledge/` و `skills/`
في جذر المشروع. وضعها داخل `src/` يمنع `crewai run` والتحقق قبل النشر من العثور على تعريف الـ crew.
بنية `src/project_name/` المتداخلة ضرورية للطواقم.
وضع الملفات في المستوى الخاطئ سيسبب فشل النشر.
</Warning>
<Info>
المشاريع الكلاسيكية التي تُنشأ عبر `crewai create crew my_crew --classic` تستخدم البنية القديمة
`src/project_name/crew.py` و `src/project_name/config/agents.yaml` و
`src/project_name/config/tasks.yaml`. تظل هذه البنية مدعومة للـ crews المكتوبة في Python مع decorators.
</Info>
### بنية مشروع التدفق
عند تشغيل `crewai create flow my_flow`، تحصل على هذه البنية:
@@ -101,9 +100,9 @@ my_flow/
```
<Info>
الـ crews المستقلة بنمط JSON-first تستخدم ملفات JSON في جذر المشروع. أما Flows فتظل تستخدم
`src/project_name/` ويمكن أن تحتوي crews مضمنة كلاسيكية أو مجلدات crew JSON يتم تحميلها عبر
`crewai.project.load_crew`.
كلا الطواقم والتدفقات تستخدم بنية `src/project_name/`.
الفرق الرئيسي أن التدفقات لها مجلد `crews/` للطواقم المضمنة،
بينما الطواقم لها `crew.py` مباشرة في مجلد المشروع.
</Info>
## قائمة فحص ما قبل النشر
@@ -155,89 +154,60 @@ git commit -m "Add uv.lock for deployment"
git push
```
### 3. التحقق من تعريف الـ Crew
### 3. التحقق من استخدام مُزخرف CrewBase
<Tabs>
<Tab title="JSON-first Crews">
يجب أن تحتوي crews بنمط JSON-first على `crew.jsonc` أو `crew.json` في جذر المشروع.
يجب أن يشير مصفوفة `agents` إلى ملفات داخل `agents/`، ويجب أن تشير كل task إلى اسم Agent صحيح.
**يجب أن تستخدم كل فئة طاقم مُزخرف `@CrewBase`.** ينطبق هذا على:
```jsonc crew.jsonc
{
"name": "Research Crew",
"agents": ["researcher"],
"tasks": [
{
"name": "research_task",
"description": "Research {topic}.",
"expected_output": "A concise report.",
"agent": "researcher"
}
],
"inputs": {
"topic": "AI Agents"
}
}
```
- مشاريع الطاقم المستقلة
- الطواقم المضمنة داخل مشاريع التدفق
تُشار الأدوات المخصصة بصيغة `"custom:<name>"` ويجب تنفيذها في
`tools/<name>.py` كصنف يرث من `BaseTool`.
</Tab>
<Tab title="Crews كلاسيكية Python/YAML">
يجب أن تستخدم الـ crews الكلاسيكية وPython crews المضمنة داخل Flows مزخرف `@CrewBase`.
```python
from crewai import Agent, Crew, Process, Task
from crewai.project import CrewBase, agent, crew, task
from crewai.agents.agent_builder.base_agent import BaseAgent
from typing import List
```python
from crewai import Agent, Crew, Process, Task
from crewai.project import CrewBase, agent, crew, task
from crewai.agents.agent_builder.base_agent import BaseAgent
from typing import List
@CrewBase # This decorator is REQUIRED
class MyCrew():
"""My crew description"""
@CrewBase
class MyCrew():
"""My crew description"""
agents: List[BaseAgent]
tasks: List[Task]
agents: List[BaseAgent]
tasks: List[Task]
@agent
def my_agent(self) -> Agent:
return Agent(
config=self.agents_config['my_agent'], # type: ignore[index]
verbose=True
)
@agent
def my_agent(self) -> Agent:
return Agent(
config=self.agents_config['my_agent'], # type: ignore[index]
verbose=True
)
@task
def my_task(self) -> Task:
return Task(
config=self.tasks_config['my_task'] # type: ignore[index]
)
@task
def my_task(self) -> Task:
return Task(
config=self.tasks_config['my_task'] # type: ignore[index]
)
@crew
def crew(self) -> Crew:
return Crew(
agents=self.agents,
tasks=self.tasks,
process=Process.sequential,
verbose=True,
)
```
@crew
def crew(self) -> Crew:
return Crew(
agents=self.agents,
tasks=self.tasks,
process=Process.sequential,
verbose=True,
)
```
</Tab>
</Tabs>
<Warning>
إذا نسيت مُزخرف `@CrewBase`، سيفشل النشر بأخطاء حول
تهيئات الوكلاء أو المهام المفقودة.
</Warning>
### 4. التحقق من نقاط دخول المشروع
لا تحتاج crews المستقلة بنمط JSON-first إلى ملف `src/project_name/main.py` مكتوب يدويًا؛
يقوم `crewai run` وتغليف النشر بتحميل `crew.jsonc` مباشرة. تستخدم crews الكلاسيكية وFlows نقاط دخول Python:
كل من الطواقم والتدفقات لها نقطة دخول في `src/project_name/main.py`:
<Tabs>
<Tab title="JSON-first Crews">
شغّل محليًا من جذر المشروع:
```bash
crewai run
```
</Tab>
<Tab title="Crews كلاسيكية">
<Tab title="للطواقم">
تستخدم نقطة الدخول دالة `run()`:
```python
@@ -308,17 +278,16 @@ grep -A2 "\[tool.crewai\]" pyproject.toml
# 2. Verify uv.lock exists
ls -la uv.lock || echo "ERROR: uv.lock missing! Run 'uv lock'"
# 3. For JSON-first crews, verify crew.jsonc and agents/
([ -f crew.jsonc ] || [ -f crew.json ]) || echo "No crew.jsonc or crew.json found"
test -d agents || echo "No agents/ directory found"
# 3. Verify src/ structure exists
ls -la src/*/main.py 2>/dev/null || echo "No main.py found in src/"
# 4. For classic Crews - verify crew.py exists
# 4. For Crews - verify crew.py exists
ls -la src/*/crew.py 2>/dev/null || echo "No crew.py (expected for Crews)"
# 5. For Flows - verify crews/ folder exists
ls -la src/*/crews/ 2>/dev/null || echo "No crews/ folder (expected for Flows)"
# 6. For classic Python crews - check for CrewBase usage
# 6. Check for CrewBase usage
grep -r "@CrewBase" . --include="*.py"
```
@@ -328,9 +297,8 @@ grep -r "@CrewBase" . --include="*.py"
|-------|-------|---------|
| `uv.lock` مفقود | فشل البناء أثناء حل الاعتماديات | شغّل `uv lock` وارفعه |
| `type` خاطئ في pyproject.toml | نجاح البناء لكن فشل وقت التشغيل | غيّر إلى النوع الصحيح |
| `crew.jsonc` أو `agents/` مفقود في crew بنمط JSON-first | لا يمكن العثور على تعريف الـ crew | أبقِ `crew.jsonc` و `agents/` في جذر المشروع |
| مُزخرف `@CrewBase` مفقود في crew كلاسيكية | أخطاء "Config not found" | أضف المُزخرف لجميع فئات الـ crew الكلاسيكية |
| ملفات كلاسيكية في الجذر بدل `src/` | نقطة الدخول غير موجودة | انقل ملفات Python الكلاسيكية إلى `src/project_name/` |
| مُزخرف `@CrewBase` مفقود | أخطاء "Config not found" | أضف المُزخرف لجميع فئات الطاقم |
| ملفات في الجذر بدل `src/` | نقطة الدخول غير موجودة | انقلها إلى `src/project_name/` |
| `run()` أو `kickoff()` مفقودة | لا يمكن بدء الأتمتة | أضف دالة الدخول الصحيحة |
## الخطوات التالية

View File

@@ -43,7 +43,7 @@ CrewAI مُصمَّم أصلاً للعمل مع الذكاء الاصطناعي
| المهارة | متى تُستخدم |
|---------|-------------|
| `getting-started` | مشاريع جديدة، الاختيار بين `LLM.call()` / `Agent` / `Crew` / `Flow`، ربط `crew.jsonc` / `main.py` |
| `getting-started` | مشاريع جديدة، الاختيار بين `LLM.call()` / `Agent` / `Crew` / `Flow`، ربط `crew.py` / `main.py` |
| `design-agent` | ضبط الوكلاء — الدور، الهدف، الخلفية، الأدوات، نماذج اللغة، الذاكرة، الحدود الآمنة |
| `design-task` | وصف المهام، التبعيات، المخرجات المنظمة (`output_pydantic`، `output_json`)، المراجعة البشرية |
| `ask-docs` | الاستعلام من [خادم CrewAI docs MCP](https://docs.crewai.com/mcp) للحصول على تفاصيل واجهة البرمجة الحالية |

View File

@@ -1,140 +1,321 @@
---
title: ابنِ أول Crew
description: دليل خطوة بخطوة لإنشاء فريق AI تعاوني باستخدام تهيئة JSON-first.
title: ابنِ أول Crew لك
description: دليل تفصيلي لإنشاء فريق AI تعاوني يعمل معًا لحل المشكلات المعقدة.
icon: users-gear
mode: "wide"
---
## بناء Crew للبحث
## إطلاق قوة الذكاء الاصطناعي التعاوني
في هذا الدليل ستنشئ crew من Agentين: واحد للبحث وآخر لكتابة تقرير markdown. مشاريع الـ crew الجديدة هي JSON-first: تُعرّف الـ Agents في `agents/*.jsonc`، وتُعرّف المهام وإعدادات الـ crew في `crew.jsonc`، ويحمّل `crewai run` هذا التعريف مباشرة.
تخيل أن لديك فريقًا من Agents الذكاء الاصطناعي المتخصصة تعمل معًا بسلاسة لحل مشكلات معقدة، كل منها يساهم بمهاراته الفريدة لتحقيق هدف مشترك. هذه هي قوة CrewAI - إطار عمل يمكّنك من إنشاء أنظمة ذكاء اصطناعي تعاونية يمكنها إنجاز مهام تفوق بكثير ما يمكن لـ AI واحد تحقيقه بمفرده.
### المتطلبات
في هذا الدليل، سنمشي عبر إنشاء Crew بحث يساعدنا في البحث والتحليل حول موضوع ما، ثم إنشاء تقرير شامل. يوضح هذا المثال العملي كيف يمكن لـ Agents الذكاء الاصطناعي التعاون لإنجاز مهام معقدة، لكنه مجرد البداية لما هو ممكن مع CrewAI.
1. تثبيت CrewAI من [دليل التثبيت](/ar/installation)
2. إعداد مفتاح LLM من [دليل LLMs](/ar/concepts/llms#setting-up-your-llm)
3. مفتاح [Serper.dev](https://serper.dev/) إذا أردت استخدام البحث على الويب
### ما ستبنيه وتتعلمه
## الخطوة 1: إنشاء Crew جديدة
بنهاية هذا الدليل، ستكون قد:
1. **أنشأت فريق بحث AI متخصص** بأدوار ومسؤوليات مميزة
2. **نسّقت التعاون** بين عدة Agents ذكاء اصطناعي
3. **أتممت سير عمل معقد** يتضمن جمع المعلومات والتحليل وإنشاء التقارير
4. **بنيت مهارات أساسية** يمكنك تطبيقها على مشاريع أكثر طموحًا
### المتطلبات المسبقة
قبل البدء، تأكد من:
1. تثبيت CrewAI باتباع [دليل التثبيت](/ar/installation)
2. إعداد مفتاح API لنموذج LLM في بيئتك، باتباع [دليل إعداد LLM](/ar/concepts/llms#setting-up-your-llm)
3. فهم أساسي لـ Python
## الخطوة 1: إنشاء مشروع CrewAI جديد
أولاً، لننشئ مشروع CrewAI جديد باستخدام CLI. سينشئ هذا الأمر هيكل مشروع كامل بجميع الملفات الضرورية.
```bash
crewai create crew research_crew
cd research_crew
```
البنية الناتجة:
سينتج هيكل مشروع بالبنية الأساسية المطلوبة لـ Crew. ينشئ CLI تلقائيًا:
```text
- مجلد مشروع بالملفات اللازمة
- ملفات تهيئة للـ Agents والمهام
- تطبيق Crew أساسي
- سكريبت رئيسي لتشغيل الـ Crew
<Frame caption="نظرة عامة على إطار عمل CrewAI">
<img src="/images/crews.png" alt="نظرة عامة على إطار عمل CrewAI" />
</Frame>
## الخطوة 2: استكشاف هيكل المشروع
لنخصص لحظة لفهم هيكل المشروع الذي أنشأه CLI.
```
research_crew/
├── .gitignore
├── .env
├── agents/
│ └── researcher.jsonc
├── crew.jsonc
├── knowledge/
├── pyproject.toml
├── README.md
├── skills/
└── tools/
├── .env
└── src/
└── research_crew/
├── __init__.py
├── main.py
├── crew.py
├── tools/
│ ├── custom_tool.py
│ └── __init__.py
└── config/
├── agents.yaml
└── tasks.yaml
```
<Tip>
إذا احتجت إلى البنية القديمة التي تحتوي على `crew.py` و `config/agents.yaml` و `config/tasks.yaml`، استخدم `crewai create crew research_crew --classic`.
</Tip>
يتبع هذا الهيكل أفضل الممارسات لمشاريع Python ويسهّل تنظيم الكود. فصل ملفات التهيئة (YAML) عن كود التنفيذ (Python) يسهّل تعديل سلوك Crew دون تغيير الكود الأساسي.
## الخطوة 2: تعريف الـ Agents
## الخطوة 3: تهيئة الـ Agents
استبدل ملف `agents/researcher.jsonc` المُنشأ وأضف `agents/analyst.jsonc`. اسم الملف هو الاسم الذي تشير إليه في `crew.jsonc`.
الآن يأتي الجزء الممتع - تعريف Agents الذكاء الاصطناعي! في CrewAI، الـ Agents هي كيانات متخصصة بأدوار وأهداف وخلفيات محددة تشكّل سلوكها.
```jsonc agents/researcher.jsonc
{
"role": "Senior Research Specialist for {topic}",
"goal": "Find comprehensive and accurate information about {topic}, with a focus on recent developments and key insights.",
"backstory": "You are an experienced research specialist who organizes complex information into clear, useful notes.",
// استبدله بالنموذج الذي تستخدمه، مثل "openai/gpt-4o".
"llm": "provider/model-id",
"tools": ["SerperDevTool"],
"settings": {
"verbose": true,
"allow_delegation": false
}
}
لـ Crew البحث لدينا، سننشئ Agent اثنين:
1. **باحث** يتفوق في إيجاد وتنظيم المعلومات
2. **محلل** يمكنه تفسير نتائج البحث وإنشاء تقارير ثاقبة
لنعدّل ملف `agents.yaml`. تأكد من تعيين `llm` للمزود الذي تستخدمه.
```yaml
# src/research_crew/config/agents.yaml
researcher:
role: >
Senior Research Specialist for {topic}
goal: >
Find comprehensive and accurate information about {topic}
with a focus on recent developments and key insights
backstory: >
You are an experienced research specialist with a talent for
finding relevant information from various sources. You excel at
organizing information in a clear and structured manner, making
complex topics accessible to others.
llm: provider/model-id # e.g. openai/gpt-4o, google/gemini-2.0-flash, anthropic/claude...
analyst:
role: >
Data Analyst and Report Writer for {topic}
goal: >
Analyze research findings and create a comprehensive, well-structured
report that presents insights in a clear and engaging way
backstory: >
You are a skilled analyst with a background in data interpretation
and technical writing. You have a talent for identifying patterns
and extracting meaningful insights from research data, then
communicating those insights effectively through well-crafted reports.
llm: provider/model-id # e.g. openai/gpt-4o, google/gemini-2.0-flash, anthropic/claude...
```
```jsonc agents/analyst.jsonc
{
"role": "Report Analyst for {topic}",
"goal": "Turn research findings into a clear, well-structured report.",
"backstory": "You are a careful analyst with strong technical writing skills and a talent for extracting useful insights.",
// استبدله بالنموذج الذي تستخدمه، مثل "openai/gpt-4o".
"llm": "provider/model-id",
"settings": {
"verbose": true,
"allow_delegation": false
}
}
لاحظ كيف أن لكل Agent دور وهدف وخلفية مميزة. هذه العناصر ليست وصفية فحسب - بل تشكّل بنشاط كيف يتعامل الـ Agent مع مهامه.
## الخطوة 4: تعريف المهام
مع تعريف الـ Agents، نحتاج الآن لمنحهم مهام محددة. لنعدّل ملف `tasks.yaml`:
```yaml
# src/research_crew/config/tasks.yaml
research_task:
description: >
Conduct thorough research on {topic}. Focus on:
1. Key concepts and definitions
2. Historical development and recent trends
3. Major challenges and opportunities
4. Notable applications or case studies
5. Future outlook and potential developments
Make sure to organize your findings in a structured format with clear sections.
expected_output: >
A comprehensive research document with well-organized sections covering
all the requested aspects of {topic}. Include specific facts, figures,
and examples where relevant.
agent: researcher
analysis_task:
description: >
Analyze the research findings and create a comprehensive report on {topic}.
Your report should:
1. Begin with an executive summary
2. Include all key information from the research
3. Provide insightful analysis of trends and patterns
4. Offer recommendations or future considerations
5. Be formatted in a professional, easy-to-read style with clear headings
expected_output: >
A polished, professional report on {topic} that presents the research
findings with added analysis and insights. The report should be well-structured
with an executive summary, main sections, and conclusion.
agent: analyst
context:
- research_task
output_file: output/report.md
```
استبدل `provider/model-id` بالنموذج الذي تستخدمه، مثل `openai/gpt-4o` أو `anthropic/claude-sonnet-4-6` أو `gemini/gemini-2.0-flash-001`.
لاحظ حقل `context` في مهمة التحليل - هذه ميزة قوية تتيح للمحلل الوصول إلى مخرجات مهمة البحث.
## الخطوة 3: تعريف المهام وإعدادات الـ Crew
## الخطوة 5: تهيئة الـ Crew
استبدل `crew.jsonc` بما يلي:
الآن حان الوقت لجمع كل شيء معًا. لنعدّل ملف `crew.py`:
```jsonc crew.jsonc
{
"name": "Research Crew",
"agents": ["researcher", "analyst"],
"tasks": [
{
"name": "research_task",
"description": "Conduct thorough research on {topic}. Focus on key concepts, recent developments, major challenges, notable applications, and future outlook.",
"expected_output": "A comprehensive research document with organized sections, specific facts, and useful examples about {topic}.",
"agent": "researcher"
},
{
"name": "analysis_task",
"description": "Analyze the research findings and create a polished report on {topic}. Include an executive summary, key insights, trend analysis, and recommendations.",
"expected_output": "A professional markdown report with clear headings, a concise summary, main findings, and recommendations.",
"agent": "analyst",
"context": ["research_task"],
"output_file": "output/report.md",
"markdown": true
```python
# src/research_crew/crew.py
from crewai import Agent, Crew, Process, Task
from crewai.project import CrewBase, agent, crew, task
from crewai_tools import SerperDevTool
from crewai.agents.agent_builder.base_agent import BaseAgent
from typing import List
@CrewBase
class ResearchCrew():
"""Research crew for comprehensive topic analysis and reporting"""
agents: List[BaseAgent]
tasks: List[Task]
@agent
def researcher(self) -> Agent:
return Agent(
config=self.agents_config['researcher'], # type: ignore[index]
verbose=True,
tools=[SerperDevTool()]
)
@agent
def analyst(self) -> Agent:
return Agent(
config=self.agents_config['analyst'], # type: ignore[index]
verbose=True
)
@task
def research_task(self) -> Task:
return Task(
config=self.tasks_config['research_task'] # type: ignore[index]
)
@task
def analysis_task(self) -> Task:
return Task(
config=self.tasks_config['analysis_task'], # type: ignore[index]
output_file='output/report.md'
)
@crew
def crew(self) -> Crew:
"""Creates the research crew"""
return Crew(
agents=self.agents,
tasks=self.tasks,
process=Process.sequential,
verbose=True,
)
```
## الخطوة 6: إعداد السكريبت الرئيسي
```python
#!/usr/bin/env python
# src/research_crew/main.py
import os
from research_crew.crew import ResearchCrew
# Create output directory if it doesn't exist
os.makedirs('output', exist_ok=True)
def run():
"""
Run the research crew.
"""
inputs = {
'topic': 'Artificial Intelligence in Healthcare'
}
],
"process": "sequential",
"verbose": true,
"memory": true,
"inputs": {
"topic": "Artificial Intelligence in Healthcare"
}
}
# Create and run the crew
result = ResearchCrew().crew().kickoff(inputs=inputs)
# Print the result
print("\n\n=== FINAL REPORT ===\n\n")
print(result.raw)
print("\n\nReport has been saved to output/report.md")
if __name__ == "__main__":
run()
```
يشير `context` إلى أسماء مهام سابقة، لذلك يحصل analyst على مخرجات مهمة البحث. يوفر `inputs` قيمة افتراضية لـ `{topic}`. إذا حذفت القيمة الافتراضية، سيطلبها `crewai run`.
## الخطوة 7: إعداد متغيرات البيئة
## الخطوة 4: متغيرات البيئة
عدّل `.env`:
أنشئ ملف `.env` في جذر مشروعك بمفاتيح API:
```sh
SERPER_API_KEY=your_serper_api_key
# أضف مفتاح مزود النموذج أيضًا.
# Add your provider's API key here too.
```
## الخطوة 5: التثبيت والتشغيل
راجع [دليل إعداد LLM](/ar/concepts/llms#setting-up-your-llm) لتفاصيل تهيئة المزود المفضل لديك. يمكنك الحصول على مفتاح Serper API من [Serper.dev](https://serper.dev/).
## الخطوة 8: تثبيت التبعيات
```bash
crewai install
```
## الخطوة 9: تشغيل الـ Crew
الآن اللحظة المثيرة - حان وقت تشغيل Crew ومشاهدة التعاون بين الـ AI!
```bash
crewai run
```
بعد انتهاء التشغيل، افتح `output/report.md`.
عند تشغيل هذا الأمر، سترى Crew يعمل. سيجمع الباحث معلومات حول الموضوع المحدد، ثم سينشئ المحلل تقريرًا شاملاً بناءً على ذلك البحث.
<Warning>
شغّل مشاريع JSON crew من مصادر تثق بها فقط. أدوات `custom:<name>` ومراجع `{"python": "module.attribute"}` تنفذ Python محليًا عند تحميل الـ crew.
</Warning>
## الخطوة 10: مراجعة المخرجات
بمجرد إتمام Crew عمله، ستجد التقرير النهائي في ملف `output/report.md`. سيتضمن التقرير:
1. ملخص تنفيذي
2. معلومات مفصلة عن الموضوع
3. تحليل ورؤى
4. توصيات أو اعتبارات مستقبلية
## استكشاف أوامر CLI الأخرى
يوفر CrewAI عدة أوامر CLI مفيدة للعمل مع Crews:
```bash
# View all available commands
crewai --help
# Run the crew
crewai run
# Test the crew
crewai test
# Reset crew memories
crewai reset-memories
# Replay from a specific task
crewai replay -t <task_id>
```
## ما بعد أول Crew: فن الممكن
ما بنيته في هذا الدليل مجرد البداية. يمكنك توسيع Crew البحث الأساسي بإضافة Agents متخصصة أخرى وأدوات وقدرات إضافية وسير عمل أكثر تعقيدًا. يمكن تطبيق نفس الأنماط لإنشاء Crews لإنشاء المحتوى وخدمة العملاء وتطوير المنتجات وتحليل البيانات.
## الخطوات التالية
1. جرّب تهيئات وشخصيات Agent مختلفة
2. جرب هياكل مهام وسير عمل أكثر تعقيدًا
3. طبّق أدوات مخصصة لمنح الـ Agents قدرات جديدة
4. طبّق Crew على مواضيع أو مجالات مشكلات مختلفة
5. استكشف [CrewAI Flows](/ar/guides/flows/first-flow) لسير عمل أكثر تقدمًا مع البرمجة الإجرائية
<Check>
أصبحت لديك crew تعمل بأسلوب JSON-first تبحث في موضوع وتكتب تقريرًا.
تهانينا! لقد بنيت بنجاح أول CrewAI Crew يمكنه البحث والتحليل في أي موضوع تقدمه. هذه التجربة الأساسية أهّلتك بالمهارات لإنشاء أنظمة AI متطورة بشكل متزايد يمكنها معالجة مشكلات معقدة متعددة المراحل من خلال الذكاء التعاوني.
</Check>

View File

@@ -42,8 +42,6 @@ cd guide_creator_flow
## الخطوة 2: فهم هيكل المشروع
يستخدم الـ crew المبدئي المضمّن في مشروع Flow بنية Python/YAML الكلاسيكية. لاستخدام crew بنمط JSON-first داخل Flow، أنشئ `crew.jsonc` و `agents/*.jsonc` داخل مجلد الـ crew وحمّله عبر `crewai.project.load_crew` كما في [Flows](/ar/concepts/flows#building-your-crews).
```
guide_creator_flow/
├── .gitignore
@@ -71,77 +69,139 @@ crewai flow add-crew content-crew
## الخطوة 4: تهيئة Crew كتابة المحتوى
سنهيئ crew كتابة المحتوى باستخدام JSONC. سنعرّف Agent للكتابة وAgent للمراجعة، ثم نحمّل `crew.jsonc` من خطوة Flow.
1. حدّث ملف تهيئة الـ Agents. تذكر تعيين `llm` للمزود الذي تستخدمه.
1. أنشئ `src/guide_creator_flow/crews/content_crew/agents/content_writer.jsonc`:
```yaml
# src/guide_creator_flow/crews/content_crew/config/agents.yaml
content_writer:
role: >
Educational Content Writer
goal: >
Create engaging, informative content that thoroughly explains the assigned topic
and provides valuable insights to the reader
backstory: >
You are a talented educational writer with expertise in creating clear, engaging
content. You have a gift for explaining complex concepts in accessible language
and organizing information in a way that helps readers build their understanding.
llm: provider/model-id
```jsonc
{
"role": "Educational Content Writer",
"goal": "Create engaging, informative content that thoroughly explains the assigned topic and provides valuable insights to the reader.",
"backstory": "You are a talented educational writer who explains complex concepts in accessible language and organizes information clearly.",
"llm": "provider/model-id",
"settings": {
"verbose": true
}
}
content_reviewer:
role: >
Educational Content Reviewer and Editor
goal: >
Ensure content is accurate, comprehensive, well-structured, and maintains
consistency with previously written sections
backstory: >
You are a meticulous editor with years of experience reviewing educational
content. You have an eye for detail, clarity, and coherence.
llm: provider/model-id
```
2. أنشئ `src/guide_creator_flow/crews/content_crew/agents/content_reviewer.jsonc`:
2. حدّث ملف تهيئة المهام:
```jsonc
{
"role": "Educational Content Reviewer and Editor",
"goal": "Ensure content is accurate, comprehensive, well-structured, and consistent with previously written sections.",
"backstory": "You are a meticulous editor with an eye for detail, clarity, and coherence.",
"llm": "provider/model-id",
"settings": {
"verbose": true
}
}
```yaml
# src/guide_creator_flow/crews/content_crew/config/tasks.yaml
write_section_task:
description: >
Write a comprehensive section on the topic: "{section_title}"
Section description: {section_description}
Target audience: {audience_level} level learners
Your content should:
1. Begin with a brief introduction to the section topic
2. Explain all key concepts clearly with examples
3. Include practical applications or exercises where appropriate
4. End with a summary of key points
5. Be approximately 500-800 words in length
Format your content in Markdown with appropriate headings, lists, and emphasis.
Previously written sections:
{previous_sections}
expected_output: >
A well-structured, comprehensive section in Markdown format that thoroughly
explains the topic and is appropriate for the target audience.
agent: content_writer
review_section_task:
description: >
Review and improve the following section on "{section_title}":
{draft_content}
Target audience: {audience_level} level learners
Previously written sections:
{previous_sections}
Your review should:
1. Fix any grammatical or spelling errors
2. Improve clarity and readability
3. Ensure content is comprehensive and accurate
4. Verify consistency with previously written sections
5. Enhance the structure and flow
6. Add any missing key information
expected_output: >
An improved, polished version of the section that maintains the original
structure but enhances clarity, accuracy, and consistency.
agent: content_reviewer
context:
- write_section_task
```
استبدل `provider/model-id` بالنموذج الذي تستخدمه، مثل `openai/gpt-4o` أو `gemini/gemini-2.0-flash-001` أو `anthropic/claude-sonnet-4-6`.
3. أنشئ `src/guide_creator_flow/crews/content_crew/crew.jsonc`:
```jsonc
{
"name": "Content Crew",
"agents": ["content_writer", "content_reviewer"],
"tasks": [
{
"name": "write_section_task",
"description": "Write a comprehensive section on the topic: \"{section_title}\".\n\nSection description: {section_description}\nTarget audience: {audience_level} level learners\n\nYour content should begin with a brief introduction, explain key concepts clearly with examples, include practical applications where appropriate, end with a summary, and be approximately 500-800 words.\n\nPreviously written sections:\n{previous_sections}",
"expected_output": "A well-structured, comprehensive section in Markdown format that thoroughly explains the topic and is appropriate for the target audience.",
"agent": "content_writer",
"markdown": true
},
{
"name": "review_section_task",
"description": "Review and improve this section on \"{section_title}\":\n\n{draft_content}\n\nTarget audience: {audience_level} level learners\nPreviously written sections:\n{previous_sections}\n\nFix errors, improve clarity, verify consistency, enhance structure, and add missing key information.",
"expected_output": "An improved, polished version of the section that maintains the original structure but enhances clarity, accuracy, and consistency.",
"agent": "content_reviewer",
"context": ["write_section_task"],
"markdown": true
}
],
"process": "sequential",
"verbose": true
}
```
4. استبدل `src/guide_creator_flow/crews/content_crew/content_crew.py` بمحمل صغير:
3. حدّث ملف تنفيذ Crew:
```python
from pathlib import Path
# src/guide_creator_flow/crews/content_crew/content_crew.py
from crewai import Agent, Crew, Process, Task
from crewai.project import CrewBase, agent, crew, task
from crewai.agents.agent_builder.base_agent import BaseAgent
from typing import List
from crewai.project import load_crew
@CrewBase
class ContentCrew():
"""Content writing crew"""
agents: List[BaseAgent]
tasks: List[Task]
def kickoff_content_crew(inputs: dict):
crew, default_inputs = load_crew(Path(__file__).with_name("crew.jsonc"))
return crew.kickoff(inputs={**default_inputs, **inputs})
@agent
def content_writer(self) -> Agent:
return Agent(
config=self.agents_config['content_writer'], # type: ignore[index]
verbose=True
)
@agent
def content_reviewer(self) -> Agent:
return Agent(
config=self.agents_config['content_reviewer'], # type: ignore[index]
verbose=True
)
@task
def write_section_task(self) -> Task:
return Task(
config=self.tasks_config['write_section_task'] # type: ignore[index]
)
@task
def review_section_task(self) -> Task:
return Task(
config=self.tasks_config['review_section_task'], # type: ignore[index]
context=[self.write_section_task()]
)
@crew
def crew(self) -> Crew:
"""Creates the content writing crew"""
return Crew(
agents=self.agents,
tasks=self.tasks,
process=Process.sequential,
verbose=True,
)
```
## الخطوة 5: إنشاء Flow

View File

@@ -113,7 +113,7 @@ python3 --version
# إنشاء مشروع CrewAI
يقوم `crewai create crew` الآن بإنشاء مشروع crew بأسلوب JSON-first. توضع الـ Agents في `agents/*.jsonc`، وتوضع المهام وإعدادات الـ crew في `crew.jsonc`، ويحمّل `crewai run` هذا التعريف مباشرة.
نوصي باستخدام قالب `YAML` لنهج منظم في تعريف الـ Agents والمهام. إليك كيفية البدء:
<Steps>
<Step title="إنشاء هيكل المشروع">
@@ -126,20 +126,21 @@ python3 --version
```
my_project/
├── .gitignore
├── .env
├── agents/
│ └── researcher.jsonc
├── crew.jsonc
├── knowledge/
├── pyproject.toml
├── README.md
├── skills/
└── tools/
```
- إذا احتجت إلى البنية القديمة Python/YAML التي تحتوي على `crew.py` و `config/agents.yaml` و `config/tasks.yaml`، شغّل:
```shell
crewai create crew <your_project_name> --classic
├── .env
└── src/
└── my_project/
├── __init__.py
├── main.py
├── crew.py
├── tools/
│ ├── custom_tool.py
│ └── __init__.py
└── config/
├── agents.yaml
└── tasks.yaml
```
</Step>
@@ -148,15 +149,15 @@ python3 --version
- سيحتوي مشروعك على هذه الملفات الأساسية:
| الملف | الغرض |
| --- | --- |
| `crew.jsonc` | إعداد الـ crew وترتيب المهام والعملية وقيم الإدخال الافتراضية |
| `agents/*.jsonc` | تعريف دور كل Agent وهدفه و backstory والـ LLM والأدوات والسلوك |
| `agents.yaml` | تعريف الـ Agents وأدوارهم |
| `tasks.yaml` | إعداد مهام الـ Agents وسير العمل |
| `.env` | تخزين مفاتيح API ومتغيرات البيئة |
| `tools/` | ملفات Python اختيارية لأدوات `custom:<name>` |
| `knowledge/` | ملفات معرفة اختيارية للـ Agents |
| `skills/` | ملفات skills اختيارية تطبق على الـ crew |
| `main.py` | نقطة دخول المشروع وتدفق التنفيذ |
| `crew.py` | تنسيق وإدارة الـ Crew |
| `tools/` | مجلد الأدوات المخصصة |
| `knowledge/` | مجلد قاعدة المعرفة |
- ابدأ بتحرير `crew.jsonc` والملفات داخل `agents/` لتعريف سلوك الـ crew.
- استخدم قيم `{placeholder}` في نصوص الـ Agents والمهام، ثم ضع القيم الافتراضية في `inputs` داخل `crew.jsonc`. عند تشغيل `crewai run` ستطلب CLI أي قيم ناقصة.
- ابدأ بتحرير `agents.yaml` و`tasks.yaml` لتعريف سلوك الـ Crew.
- احتفظ بالمعلومات الحساسة مثل مفاتيح API في `.env`.
</Step>

View File

@@ -5,15 +5,11 @@ icon: "at"
mode: "wide"
---
يشرح هذا الدليل كيفية استخدام التعليقات التوضيحية للإشارة بشكل صحيح إلى **الوكلاء** و**المهام** والمكونات الأخرى في ملف `crew.py` كلاسيكي.
<Note>
المشاريع الجديدة التي تُنشأ عبر `crewai create crew <name>` هي JSON-first وتستخدم `crew.jsonc` مع `agents/*.jsonc`. استخدم هذا الدليل عند العمل في مشروع كلاسيكي أُنشئ عبر `crewai create crew <name> --classic`، أو عند ترحيل مشروع Python/YAML موجود، أو عندما تحتاج تحكمًا عبر decorators في Python.
</Note>
يشرح هذا الدليل كيفية استخدام التعليقات التوضيحية للإشارة بشكل صحيح إلى **الوكلاء** و**المهام** والمكونات الأخرى في ملف `crew.py`.
## مقدمة
تُستخدم التعليقات التوضيحية في إطار عمل CrewAI لتزيين الفئات والطرق، مما يوفر بيانات وصفية ووظائف للمكونات المختلفة في طاقمك. في مشاريع Python/YAML الكلاسيكية، تنظم الكود الذي يحمّل `config/agents.yaml` و `config/tasks.yaml` ويعيد كائن `Crew`.
تُستخدم التعليقات التوضيحية في إطار عمل CrewAI لتزيين الفئات والطرق، مما يوفر بيانات وصفية ووظائف للمكونات المختلفة في طاقمك. تساعد هذه التعليقات التوضيحية في تنظيم وهيكلة الكود الخاص بك، مما يجعله أكثر قابلية للقراءة والصيانة.
## التعليقات التوضيحية المتاحة
@@ -117,9 +113,9 @@ def crew(self) -> Crew:
تُستخدم التعليقة التوضيحية `@crew` لتزيين الطريقة التي تنشئ وتُرجع كائن `Crew`. تجمع هذه الطريقة جميع المكونات (الوكلاء والمهام) في طاقم وظيفي.
## إعداد YAML الكلاسيكي
## إعداد YAML
في المشاريع الكلاسيكية، تُخزن إعدادات الوكلاء عادةً في ملف YAML. إليك مثالاً على كيفية ظهور ملف `agents.yaml` لوكيل الباحث:
تُخزن إعدادات الوكلاء عادةً في ملف YAML. إليك مثالاً على كيفية ظهور ملف `agents.yaml` لوكيل الباحث:
```yaml
researcher:
@@ -150,6 +146,6 @@ researcher:
- **تسمية متسقة**: استخدم اصطلاحات تسمية واضحة ومتسقة لطرقك. على سبيل المثال، يمكن تسمية طرق الوكلاء بأسماء أدوارهم (مثل researcher، reporting_analyst).
- **متغيرات البيئة**: استخدم متغيرات البيئة للمعلومات الحساسة مثل مفاتيح API.
- **المرونة**: صمم طاقمك ليكون مرناً بالسماح بإضافة أو إزالة الوكلاء والمهام بسهولة.
- **توافق YAML-الكود**: في المشاريع الكلاسيكية، تأكد من أن الأسماء والهياكل في ملفات YAML تتوافق بشكل صحيح مع الطرق المزينة في كود Python الخاص بك.
- **توافق YAML-الكود**: تأكد من أن الأسماء والهياكل في ملفات YAML تتوافق بشكل صحيح مع الطرق المزينة في كود Python الخاص بك.
باتباع هذه الإرشادات واستخدام التعليقات التوضيحية بشكل صحيح، يمكنك الحفاظ على أطقم كلاسيكية منظمة وسهلة الصيانة. للـ crews الجديدة، استخدم بنية JSON-first في [Crews](/ar/concepts/crews).
باتباع هذه الإرشادات واستخدام التعليقات التوضيحية بشكل صحيح، يمكنك إنشاء أطقم منظمة جيداً وسهلة الصيانة باستخدام إطار عمل CrewAI.

View File

@@ -39,60 +39,84 @@ mode: "wide"
يُنشئ ذلك تطبيق Flow ضمن `src/latest_ai_flow/`، بما في ذلك طاقمًا أوليًا في `crews/content_crew/` ستستبدله بطاقم بحث **بوكيل واحد** في الخطوات التالية.
</Step>
<Step title="اضبط وكيلًا واحدًا في JSONC">
أنشئ `src/latest_ai_flow/crews/content_crew/agents/researcher.jsonc` (أنشئ مجلد `agents/` إذا لزم). تُملأ المتغيرات مثل `{topic}` من `crew.kickoff(inputs=...)`.
<Step title="اضبط وكيلًا واحدًا في `agents.yaml`">
استبدل محتوى `src/latest_ai_flow/crews/content_crew/config/agents.yaml` بباحث واحد. تُملأ المتغيرات مثل `{topic}` من `crew.kickoff(inputs=...)`.
```jsonc agents/researcher.jsonc
{
"role": "باحث بيانات أول في {topic}",
"goal": "اكتشاف أحدث التطورات في {topic}",
"backstory": "أنت باحث يجد المعلومات الأكثر صلة ويعرضها بوضوح.",
"tools": ["SerperDevTool"],
"settings": {
"verbose": true
}
}
```yaml agents.yaml
# src/latest_ai_flow/crews/content_crew/config/agents.yaml
researcher:
role: >
باحث بيانات أول في {topic}
goal: >
اكتشاف أحدث التطورات في {topic}
backstory: >
أنت باحث مخضرم تكشف أحدث المستجدات في {topic}.
تجد المعلومات الأكثر صلة وتعرضها بوضوح.
```
</Step>
<Step title="اضبط الـ crew في `crew.jsonc`">
أنشئ `src/latest_ai_flow/crews/content_crew/crew.jsonc`:
```jsonc crew.jsonc
{
"name": "Research Crew",
"agents": ["researcher"],
"tasks": [
{
"name": "research_task",
"description": "أجرِ بحثًا معمقًا عن {topic}. استخدم البحث على الويب للعثور على معلومات حديثة وموثوقة. السنة الحالية 2026.",
"expected_output": "تقرير بصيغة Markdown بأقسام واضحة: الاتجاهات الرئيسية، أدوات أو شركات بارزة، والآثار. بين 800 و1200 كلمة تقريبًا. دون إحاطة المستند بأكمله بكتل كود.",
"agent": "researcher",
"output_file": "output/report.md",
"markdown": true
}
],
"process": "sequential",
"verbose": true
}
<Step title="اضبط مهمة واحدة في `tasks.yaml`">
```yaml tasks.yaml
# src/latest_ai_flow/crews/content_crew/config/tasks.yaml
research_task:
description: >
أجرِ بحثًا معمقًا عن {topic}. استخدم البحث على الويب للعثور على معلومات
حديثة وموثوقة. السنة الحالية 2026.
expected_output: >
تقرير بصيغة Markdown بأقسام واضحة: الاتجاهات الرئيسية، أدوات أو شركات بارزة،
والآثار. بين 800 و1200 كلمة تقريبًا. دون إحاطة المستند بأكمله بكتل كود.
agent: researcher
output_file: output/report.md
```
</Step>
<Step title="حمّل crew JSON (`content_crew.py`)">
استبدل `content_crew.py` المُولّد بمحمل صغير يحول `crew.jsonc` إلى `Crew`.
<Step title="اربط صف الطاقم (`content_crew.py`)">
اجعل الطاقم المُولَّد يشير إلى YAML وأرفق `SerperDevTool` بالباحث.
```python content_crew.py
# src/latest_ai_flow/crews/content_crew/content_crew.py
from pathlib import Path
from typing import List
from crewai.project import load_crew
from crewai import Agent, Crew, Process, Task
from crewai.agents.agent_builder.base_agent import BaseAgent
from crewai.project import CrewBase, agent, crew, task
from crewai_tools import SerperDevTool
def kickoff_content_crew(inputs: dict):
crew, default_inputs = load_crew(Path(__file__).with_name("crew.jsonc"))
return crew.kickoff(inputs={**default_inputs, **inputs})
@CrewBase
class ResearchCrew:
"""طاقم بحث بوكيل واحد داخل Flow."""
agents: List[BaseAgent]
tasks: List[Task]
agents_config = "config/agents.yaml"
tasks_config = "config/tasks.yaml"
@agent
def researcher(self) -> Agent:
return Agent(
config=self.agents_config["researcher"], # type: ignore[index]
verbose=True,
tools=[SerperDevTool()],
)
@task
def research_task(self) -> Task:
return Task(
config=self.tasks_config["research_task"], # type: ignore[index]
)
@crew
def crew(self) -> Crew:
return Crew(
agents=self.agents,
tasks=self.tasks,
process=Process.sequential,
verbose=True,
)
```
</Step>
@@ -106,7 +130,7 @@ mode: "wide"
from crewai.flow import Flow, listen, start
from latest_ai_flow.crews.content_crew.content_crew import kickoff_content_crew
from latest_ai_flow.crews.content_crew.content_crew import ResearchCrew
class ResearchFlowState(BaseModel):
@@ -125,7 +149,7 @@ mode: "wide"
@listen(prepare_topic)
def run_research(self):
result = kickoff_content_crew(inputs={"topic": self.state.topic})
result = ResearchCrew().crew().kickoff(inputs={"topic": self.state.topic})
self.state.report = result.raw
print("اكتمل طاقم البحث.")
@@ -147,7 +171,7 @@ mode: "wide"
```
<Tip>
إذا كان اسم الحزمة ليس `latest_ai_flow`، عدّل استيراد `kickoff_content_crew` ليطابق مسار الوحدة في مشروعك.
إذا كان اسم الحزمة ليس `latest_ai_flow`، عدّل استيراد `ResearchCrew` ليطابق مسار الوحدة في مشروعك.
</Tip>
</Step>
@@ -195,7 +219,7 @@ mode: "wide"
## كيف يترابط هذا
1. **Flow** — يشغّل `LatestAiFlow` أولًا `prepare_topic` ثم `run_research` ثم `summarize`. الحالة (`topic`، `report`) على Flow.
2. **الطاقم** — يحمّل `kickoff_content_crew` ملف `crew.jsonc` ويشغّل مهمة واحدة بوكيل واحد: الباحث يستخدم **Serper** للبحث على الويب ثم يكتب التقرير.
2. **الطاقم** — يشغّل `ResearchCrew` مهمة واحدة بوكيل واحد: الباحث يستخدم **Serper** للبحث على الويب ثم يكتب التقرير.
3. **المُخرَج** — يكتب `output_file` للمهمة التقرير في `output/report.md`.
للتعمق في أنماط Flow (التوجيه، الاستمرارية، الإنسان في الحلقة)، راجع [ابنِ أول Flow](/ar/guides/flows/first-flow) و[Flows](/ar/concepts/flows). للطواقم دون Flow، راجع [Crews](/ar/concepts/crews). لوكيل `Agent` واحد و`kickoff()` بلا مهام، راجع [Agents](/ar/concepts/agents#direct-agent-interaction-with-kickoff).
@@ -206,10 +230,7 @@ mode: "wide"
### اتساق التسمية
يجب أن تطابق الأسماء في `crew.jsonc` الملفات والمراجع:
- `agents: ["researcher"]` يحمّل `agents/researcher.jsonc`
- `context: ["research_task"]` يشير إلى مهمة سابقة اسمها `research_task`
يجب أن تطابق مفاتيح YAML (`researcher`، `research_task`) أسماء الدوال في صف `@CrewBase`. راجع [Crews](/ar/concepts/crews) لنمط الديكورات الكامل.
## النشر

View File

@@ -71,65 +71,81 @@ The Visual Agent Builder enables:
## Creating Agents
There are two common ways to create agents in CrewAI: using **JSONC project configuration (recommended for new crews)** or defining them **directly in code**.
There are two ways to create agents in CrewAI: using **YAML configuration (recommended)** or defining them **directly in code**.
### JSONC Configuration (Recommended)
### YAML Configuration (Recommended)
New projects created with `crewai create crew <name>` use JSON-first configuration. Each agent is defined in `agents/<agent_name>.jsonc`, and `crew.jsonc` lists which agents are part of the crew.
Using YAML configuration provides a cleaner, more maintainable way to define agents. We strongly recommend using this approach in your CrewAI projects.
After creating your CrewAI project as outlined in the [Installation](/en/installation) section, edit the generated files in `agents/`.
After creating your CrewAI project as outlined in the [Installation](/en/installation) section, navigate to the `src/latest_ai_development/config/agents.yaml` file and modify the template to match your requirements.
<Note>
Use `{placeholder}` values in `role`, `goal`, or `backstory`. Put defaults in `crew.jsonc` under `inputs`; `crewai run` prompts for any missing values.
Variables in your YAML files (like `{topic}`) will be replaced with values from your inputs when running the crew:
```python Code
crew.kickoff(inputs={'topic': 'AI Agents'})
```
</Note>
Here's an example `agents/researcher.jsonc` file:
Here's an example of how to configure agents using YAML:
```jsonc agents/researcher.jsonc
{
"role": "{topic} Senior Data Researcher",
"goal": "Uncover cutting-edge developments in {topic}",
"backstory": "You find the most relevant information and present it clearly.",
"llm": "openai/gpt-4o",
"tools": ["SerperDevTool"],
"settings": {
"verbose": true,
"allow_delegation": false,
"max_iter": 20
}
}
```yaml agents.yaml
# src/latest_ai_development/config/agents.yaml
researcher:
role: >
{topic} Senior Data Researcher
goal: >
Uncover cutting-edge developments in {topic}
backstory: >
You're a seasoned researcher with a knack for uncovering the latest
developments in {topic}. Known for your ability to find the most relevant
information and present it in a clear and concise manner.
reporting_analyst:
role: >
{topic} Reporting Analyst
goal: >
Create detailed reports based on {topic} data analysis and research findings
backstory: >
You're a meticulous analyst with a keen eye for detail. You're known for
your ability to turn complex data into clear and concise reports, making
it easy for others to understand and act on the information you provide.
```
Then include that agent from `crew.jsonc`:
To use this YAML configuration in your code, create a crew class that inherits from `CrewBase`:
```jsonc crew.jsonc
{
"name": "Research Crew",
"agents": ["researcher"],
"tasks": [
{
"name": "research_task",
"description": "Research {topic}",
"expected_output": "A concise briefing about {topic}",
"agent": "researcher"
}
],
"inputs": {
"topic": "AI Agents"
}
}
```python Code
# src/latest_ai_development/crew.py
from crewai import Agent, Crew, Process
from crewai.project import CrewBase, agent, crew
from crewai_tools import SerperDevTool
@CrewBase
class LatestAiDevelopmentCrew():
"""LatestAiDevelopment crew"""
agents_config = "config/agents.yaml"
@agent
def researcher(self) -> Agent:
return Agent(
config=self.agents_config['researcher'], # type: ignore[index]
verbose=True,
tools=[SerperDevTool()]
)
@agent
def reporting_analyst(self) -> Agent:
return Agent(
config=self.agents_config['reporting_analyst'], # type: ignore[index]
verbose=True
)
```
Agent files support any public `Agent` field. Common fields include `role`, `goal`, `backstory`, `llm`, `tools`, `function_calling_llm`, `guardrail`, `step_callback`, and `settings`. Behavior options such as `verbose`, `allow_delegation`, `max_iter`, `max_rpm`, `memory`, `cache`, `planning`, and `use_system_prompt` can be placed at the top level or under `settings`; values in `settings` take precedence.
<Note>
JSONC supports comments and trailing commas. If both `agents/<name>.jsonc` and `agents/<name>.json` exist, CrewAI uses the JSONC file.
The names you use in your YAML files (`agents.yaml`) should match the method
names in your Python code.
</Note>
### Classic YAML Configuration
Classic projects created with `crewai create crew <name> --classic` use `config/agents.yaml` and a `@CrewBase` class in `crew.py`. This remains supported for teams that want Python decorators or existing YAML projects.
### Direct Code Definition
You can create agents directly in code by instantiating the `Agent` class. Here's a comprehensive example showing all available parameters:

View File

@@ -52,8 +52,6 @@ crewai create crew my_new_crew
crewai create flow my_new_flow
```
By default, `crewai create crew` creates a JSON-first crew project with `crew.jsonc` and `agents/*.jsonc`. Use `crewai create crew my_new_crew --classic` only when you want the older Python/YAML scaffold with `crew.py`, `config/agents.yaml`, and `config/tasks.yaml`.
### 2. Version
Show the installed version of CrewAI.
@@ -187,20 +185,7 @@ crewai chat
Ensure you execute these commands from your CrewAI project's root directory.
</Note>
<Note>
IMPORTANT: Set the `chat_llm` property in your crew definition to enable this command.
For JSON-first crews, add it to `crew.jsonc`:
```jsonc
{
"name": "My Crew",
"agents": ["researcher"],
"tasks": [],
"chat_llm": "openai/gpt-4o"
}
```
For classic Python/YAML crews, set it in `crew.py`:
IMPORTANT: Set the `chat_llm` property in your `crew.py` file to enable this command.
```python
@crew
@@ -351,7 +336,7 @@ Notes:
### 12. API Keys
When running the `crewai create crew` command, the CLI shows a list of available LLM providers, followed by model selection for your chosen provider. The selected model is saved in the generated `.env` file and each generated agent JSONC file can set its own `llm`.
When running `crewai create crew` command, the CLI will show you a list of available LLM providers to choose from, followed by model selection for your chosen provider.
Once you've selected an LLM provider and model, you will be prompted for API keys.

View File

@@ -48,74 +48,108 @@ A crew in crewAI represents a collaborative group of agents working together to
## Creating Crews
There are two common ways to create crews in CrewAI: using **JSONC project configuration (recommended for new crews)** or defining them **directly in code**.
There are two ways to create crews in CrewAI: using **YAML configuration (recommended)** or defining them **directly in code**.
### JSONC Configuration (Recommended)
### YAML Configuration (Recommended)
New projects created with `crewai create crew <name>` use `crew.jsonc` for crew-level settings and tasks, plus one file per agent in `agents/`.
Using YAML configuration provides a cleaner, more maintainable way to define crews and is consistent with how agents and tasks are defined in CrewAI projects.
`crewai run` automatically detects `crew.jsonc` or `crew.json`, loads the referenced agents, prompts for missing placeholders, and kicks off the crew.
After creating your CrewAI project as outlined in the [Installation](/en/installation) section, you can define your crew in a class that inherits from `CrewBase` and uses decorators to define agents, tasks, and the crew itself.
#### Example `crew.jsonc`
#### Example Crew Class with Decorators
```jsonc crew.jsonc
{
"name": "Market Research Crew",
"agents": ["researcher", "analyst"],
"tasks": [
{
"name": "research",
"description": "Research {topic} and collect the most relevant facts.",
"expected_output": "Structured research notes about {topic}.",
"agent": "researcher"
},
{
"name": "analysis",
"description": "Analyze the research and write a concise report.",
"expected_output": "A markdown report with findings and recommendations.",
"agent": "analyst",
"context": ["research"],
"output_file": "output/report.md"
}
],
"process": "sequential",
"verbose": true,
"memory": true,
"inputs": {
"topic": "AI Agents"
}
}
```python code
from crewai import Agent, Crew, Task, Process
from crewai.project import CrewBase, agent, task, crew, before_kickoff, after_kickoff
from crewai.agents.agent_builder.base_agent import BaseAgent
from typing import List
@CrewBase
class YourCrewName:
"""Description of your crew"""
agents: List[BaseAgent]
tasks: List[Task]
# Paths to your YAML configuration files
# To see an example agent and task defined in YAML, checkout the following:
# - Task: https://docs.crewai.com/concepts/tasks#yaml-configuration-recommended
# - Agents: https://docs.crewai.com/concepts/agents#yaml-configuration-recommended
agents_config = 'config/agents.yaml'
tasks_config = 'config/tasks.yaml'
@before_kickoff
def prepare_inputs(self, inputs):
# Modify inputs before the crew starts
inputs['additional_data'] = "Some extra information"
return inputs
@after_kickoff
def process_output(self, output):
# Modify output after the crew finishes
output.raw += "\nProcessed after kickoff."
return output
@agent
def agent_one(self) -> Agent:
return Agent(
config=self.agents_config['agent_one'], # type: ignore[index]
verbose=True
)
@agent
def agent_two(self) -> Agent:
return Agent(
config=self.agents_config['agent_two'], # type: ignore[index]
verbose=True
)
@task
def task_one(self) -> Task:
return Task(
config=self.tasks_config['task_one'] # type: ignore[index]
)
@task
def task_two(self) -> Task:
return Task(
config=self.tasks_config['task_two'] # type: ignore[index]
)
@crew
def crew(self) -> Crew:
return Crew(
agents=self.agents, # Automatically collected by the @agent decorator
tasks=self.tasks, # Automatically collected by the @task decorator.
process=Process.sequential,
verbose=True,
)
```
Each string in `agents` resolves to `agents/<name>.jsonc` first, then `agents/<name>.json`.
How to run the above code:
```jsonc agents/researcher.jsonc
{
"role": "{topic} Senior Researcher",
"goal": "Find accurate and current information about {topic}.",
"backstory": "You are a careful researcher who cites clear evidence.",
"llm": "openai/gpt-4o",
"tools": ["SerperDevTool"]
}
```python code
YourCrewName().crew().kickoff(inputs={"any": "input here"})
```
<Note>
Tasks run in the order they appear in `tasks` when `process` is `"sequential"`.
Tasks will be executed in the order they are defined.
</Note>
For hierarchical crews, set `"process": "hierarchical"` and provide either `manager_llm` or `manager_agent`. A `manager_agent` can reference an `agents/<name>.jsonc` file that is not included in the top-level `agents` list.
The `CrewBase` class, along with these decorators, automates the collection of agents and tasks, reducing the need for manual management.
JSON crew definitions support crew-level fields such as `process`, `verbose`, `memory`, `cache`, `max_rpm`, `planning`, `planning_llm`, `manager_llm`, `manager_agent`, `function_calling_llm`, `output_log_file`, `stream`, `tracing`, `before_kickoff_callbacks`, and `after_kickoff_callbacks`.
#### Decorators overview from `annotations.py`
Python callbacks and custom classes use `{"python": "module.attribute"}`. Custom tools use `"custom:<name>"` and load `tools/<name>.py` at runtime.
CrewAI provides several decorators in the `annotations.py` file that are used to mark methods within your crew class for special handling:
<Warning>
Only run JSON crew projects from sources you trust. `custom:<name>` tools and `{"python": "module.attribute"}` references execute local Python code when the crew loads.
</Warning>
- `@CrewBase`: Marks the class as a crew base class.
- `@agent`: Denotes a method that returns an `Agent` object.
- `@task`: Denotes a method that returns a `Task` object.
- `@crew`: Denotes the method that returns the `Crew` object.
- `@before_kickoff`: (Optional) Marks a method to be executed before the crew starts.
- `@after_kickoff`: (Optional) Marks a method to be executed after the crew finishes.
### Classic Python/YAML Configuration
Classic projects created with `crewai create crew <name> --classic` use `crew.py`, `config/agents.yaml`, `config/tasks.yaml`, and the `@CrewBase`, `@agent`, `@task`, and `@crew` decorators. That pattern remains supported and is documented in [Using Annotations](/en/learn/using-annotations).
These decorators help in organizing your crew's structure and automatically collecting agents and tasks without manually listing them.
### Direct Code Definition (Alternative)

View File

@@ -831,7 +831,7 @@ You can generate a new CrewAI project that includes all the scaffolding needed t
crewai create flow name_of_flow
```
This command will generate a new CrewAI project with the necessary folder structure. The generated project includes a prebuilt crew called `poem_crew` that is already working. The starter embedded crew uses the classic Python/YAML layout; new standalone crews created with `crewai create crew` use the JSON-first layout.
This command will generate a new CrewAI project with the necessary folder structure. The generated project includes a prebuilt crew called `poem_crew` that is already working. You can use this crew as a template by copying, pasting, and editing it to create other crews.
### Folder Structure
@@ -855,35 +855,13 @@ After running the `crewai create flow name_of_flow` command, you will see a fold
### Building Your Crews
In the `crews` folder, you can define multiple crews. The generated `poem_crew` uses the classic embedded-crew structure:
In the `crews` folder, you can define multiple crews. Each crew will have its own folder containing configuration files and the crew definition file. For example, the `poem_crew` folder contains:
- `config/agents.yaml`: Defines the agents for the crew.
- `config/tasks.yaml`: Defines the tasks for the crew.
- `poem_crew.py`: Contains the crew definition, including agents, tasks, and the crew itself.
You can copy, paste, and edit the `poem_crew` to create other classic embedded crews.
For JSON-first embedded crews, use a folder with `crew.jsonc` and `agents/*.jsonc` instead:
```text
crews/
└── research_crew/
├── agents/
│ └── researcher.jsonc
└── crew.jsonc
```
Then load it from a Flow step:
```python
from pathlib import Path
from crewai.project import load_crew
crew, default_inputs = load_crew(
Path(__file__).parent / "crews" / "research_crew" / "crew.jsonc"
)
result = crew.kickoff(inputs={**default_inputs, "topic": "AI Agents"})
```
You can copy, paste, and edit the `poem_crew` to create other crews.
### Connecting Crews in `main.py`

View File

@@ -74,54 +74,104 @@ crew = Crew(
## Creating Tasks
There are two common ways to create tasks in CrewAI: using **JSONC project configuration (recommended for new crews)** or defining them **directly in code**.
There are two ways to create tasks in CrewAI: using **YAML configuration (recommended)** or defining them **directly in code**.
### JSONC Configuration (Recommended)
### YAML Configuration (Recommended)
New projects created with `crewai create crew <name>` define tasks in `crew.jsonc`. The `agents` array points to files in `agents/`, and the `tasks` array defines the ordered work the crew should run.
Using YAML configuration provides a cleaner, more maintainable way to define tasks. We strongly recommend using this approach to define tasks in your CrewAI projects.
After creating your CrewAI project as outlined in the [Installation](/en/installation) section, edit the generated `crew.jsonc`.
After creating your CrewAI project as outlined in the [Installation](/en/installation) section, navigate to the `src/latest_ai_development/config/tasks.yaml` file and modify the template to match your specific task requirements.
<Note>
Use `{placeholder}` values in task `description`, `expected_output`, and `output_file`. Put defaults in the top-level `inputs` object; `crewai run` prompts for any missing values.
Variables in your YAML files (like `{topic}`) will be replaced with values from your inputs when running the crew:
```python Code
crew.kickoff(inputs={'topic': 'AI Agents'})
```
</Note>
Here's an example `crew.jsonc` with two ordered tasks:
Here's an example of how to configure tasks using YAML:
````jsonc crew.jsonc
{
"name": "Research Crew",
"agents": ["researcher", "reporting_analyst"],
"tasks": [
{
"name": "research_task",
"description": "Conduct thorough research about {topic}. Include current and relevant information.",
"expected_output": "A list of the most relevant information about {topic}.",
"agent": "researcher"
},
{
"name": "reporting_task",
"description": "Review the research and expand it into a detailed report.",
"expected_output": "A polished markdown report without fenced code blocks.",
"agent": "reporting_analyst",
"context": ["research_task"],
"markdown": true,
"output_file": "report.md"
}
],
"inputs": {
"topic": "AI Agents"
}
}
````yaml tasks.yaml
research_task:
description: >
Conduct a thorough research about {topic}
Make sure you find any interesting and relevant information given
the current year is 2025.
expected_output: >
A list with 10 bullet points of the most relevant information about {topic}
agent: researcher
reporting_task:
description: >
Review the context you got and expand each topic into a full section for a report.
Make sure the report is detailed and contains any and all relevant information.
expected_output: >
A fully fledge reports with the mains topics, each with a full section of information.
Formatted as markdown without '```'
agent: reporting_analyst
markdown: true
output_file: report.md
````
Each task must include `description` and `expected_output`. The `agent` value should match an agent name listed in `agents`. `context` is a list of prior task names; forward references are rejected so sequential context stays explicit.
To use this YAML configuration in your code, create a crew class that inherits from `CrewBase`:
Task entries support any public `Task` field. Common fields include `name`, `agent`, `context`, `output_file`, `tools`, `human_input`, `async_execution`, `guardrail`, `guardrails`, `guardrail_max_retries`, `markdown`, `input_files`, `output_json`, `output_pydantic`, `response_model`, and `converter_cls`. Use `"type": "ConditionalTask"` with a `condition` field for conditional tasks.
```python crew.py
# src/latest_ai_development/crew.py
### Classic YAML Configuration
from crewai import Agent, Crew, Process, Task
from crewai.project import CrewBase, agent, crew, task
from crewai_tools import SerperDevTool
Classic projects created with `crewai create crew <name> --classic` use `config/tasks.yaml` and a `@CrewBase` class in `crew.py`. This remains supported for existing YAML projects or teams that prefer decorator-based Python wiring.
@CrewBase
class LatestAiDevelopmentCrew():
"""LatestAiDevelopment crew"""
@agent
def researcher(self) -> Agent:
return Agent(
config=self.agents_config['researcher'], # type: ignore[index]
verbose=True,
tools=[SerperDevTool()]
)
@agent
def reporting_analyst(self) -> Agent:
return Agent(
config=self.agents_config['reporting_analyst'], # type: ignore[index]
verbose=True
)
@task
def research_task(self) -> Task:
return Task(
config=self.tasks_config['research_task'] # type: ignore[index]
)
@task
def reporting_task(self) -> Task:
return Task(
config=self.tasks_config['reporting_task'] # type: ignore[index]
)
@crew
def crew(self) -> Crew:
return Crew(
agents=[
self.researcher(),
self.reporting_analyst()
],
tasks=[
self.research_task(),
self.reporting_task()
],
process=Process.sequential
)
```
<Note>
The names you use in your YAML files (`agents.yaml` and `tasks.yaml`) should
match the method names in your Python code.
</Note>
### Direct Code Definition (Alternative)

View File

@@ -26,10 +26,10 @@ Before running this verification:
## Step 1 — Scaffold a Verification Crew
Create a classic crew project because this example wires a Python tool through `crew.py`:
Create a new crew project. The CrewAI CLI scaffolds the structure:
```bash
crewai create crew rotation_verifier --classic --skip_provider
crewai create crew rotation_verifier --skip_provider
cd rotation_verifier
```

View File

@@ -374,17 +374,17 @@ git push
**Solution**: Verify your project matches the expected structure:
- **JSON-first Crews**: Keep `crew.jsonc` or `crew.json` and `agents/` at the project root
- **Classic Crews**: Use `src/project_name/main.py` with a `run()` entry point
- **Flows**: Use `src/project_name/main.py` with a `kickoff()` entry point
- **Both Crews and Flows**: Must have entry point at `src/project_name/main.py`
- **Crews**: Use a `run()` function as entry point
- **Flows**: Use a `kickoff()` function as entry point
See [Prepare for Deployment](/en/enterprise/guides/prepare-for-deployment) for detailed structure diagrams.
#### Missing CrewBase Decorator in a Classic Crew
#### Missing CrewBase Decorator
**Symptom**: "Crew not found", "Config not found", or agent/task configuration errors
**Solution**: For classic Python/YAML crews, ensure all crew classes use the `@CrewBase` decorator. JSON-first crews do not need this decorator.
**Solution**: Ensure **all** crew classes use the `@CrewBase` decorator:
```python
from crewai.project import CrewBase, agent, crew, task
@@ -404,8 +404,8 @@ class YourCrew():
```
<Info>
This applies to classic Python crew classes, including classic crews embedded inside Flow projects.
JSON-first crews are validated from `crew.jsonc` and `agents/` instead.
This applies to standalone Crews AND crews embedded inside Flow projects.
Every crew class needs the decorator.
</Info>
#### Incorrect pyproject.toml Type
@@ -442,8 +442,8 @@ type = "flow"
**Solution**:
1. Check the execution logs in the AMP dashboard (Traces tab)
2. Verify all tools have required API keys configured
3. For JSON-first crews, validate `crew.jsonc` and the referenced files in `agents/`
4. For classic crews, ensure `agents.yaml` and `tasks.yaml` are valid
3. Ensure agent configurations in `agents.yaml` are valid
4. Check task configurations in `tasks.yaml` for syntax errors
<Card title="Need Help?" icon="headset" href="mailto:support@crewai.com">
Contact our support team for assistance with deployment issues or questions

View File

@@ -24,9 +24,10 @@ company-ai/
`-- crews/
|-- support_agent/
| |-- pyproject.toml
| |-- crew.jsonc
| `-- agents/
| `-- support_agent.jsonc
| `-- src/
| `-- support_agent/
| |-- main.py
| `-- crew.py
`-- research_flow/
|-- pyproject.toml
`-- src/
@@ -47,7 +48,7 @@ folder as the automation project root.
When a working directory is set, AMP uses that folder for:
- Project validation, including `pyproject.toml`, JSON crew files, and any classic Crew or Flow entry point
- Project validation, including `pyproject.toml`, `src/`, and the Crew or Flow entry point
- Dependency installation with `uv`
- The running process working directory
- The `CREW_ROOT_DIR` environment variable

View File

@@ -24,7 +24,7 @@ Understanding which type you're deploying is essential because they have differe
<CardGroup cols={2}>
<Card title="Crew Projects" icon="users">
Standalone AI agent teams. New crews are JSON-first with `crew.jsonc` and `agents/`; classic crews can still use `crew.py`.
Standalone AI agent teams with `crew.py` defining agents and tasks. Best for focused, collaborative tasks.
</Card>
<Card title="Flow Projects" icon="diagram-project">
Orchestrated workflows with embedded crews in a `crews/` folder. Best for complex, multi-stage processes.
@@ -33,19 +33,19 @@ Understanding which type you're deploying is essential because they have differe
| Aspect | Crew | Flow |
|--------|------|------|
| **Project structure** | Project root with `crew.jsonc` and `agents/` | `src/project_name/` with `crews/` folder |
| **Main logic location** | `crew.jsonc` (classic: `src/project_name/crew.py`) | `src/project_name/main.py` (Flow class) |
| **Entry point function** | Loaded from `crew.jsonc` (classic: `run()` in `main.py`) | `kickoff()` in `main.py` |
| **Project structure** | `src/project_name/` with `crew.py` | `src/project_name/` with `crews/` folder |
| **Main logic location** | `src/project_name/crew.py` | `src/project_name/main.py` (Flow class) |
| **Entry point function** | `run()` in `main.py` | `kickoff()` in `main.py` |
| **pyproject.toml type** | `type = "crew"` | `type = "flow"` |
| **CLI create command** | `crewai create crew name` | `crewai create flow name` |
| **Config location** | `crew.jsonc`, `agents/`, optional `tools/` | `src/project_name/crews/crew_name/config/` or embedded JSON crew folders |
| **Config location** | `src/project_name/config/` | `src/project_name/crews/crew_name/config/` |
| **Can contain other crews** | No | Yes (in `crews/` folder) |
## Project Structure Reference
### Crew Project Structure
When you run `crewai create crew my_crew`, you get the JSON-first structure:
When you run `crewai create crew my_crew`, you get this structure:
```
my_crew/
@@ -54,27 +54,24 @@ my_crew/
├── README.md
├── .env
├── uv.lock # REQUIRED for deployment
── crew.jsonc # Crew settings, tasks, process, inputs
├── agents/
└── researcher.jsonc # Agent definitions
├── tools/ # Optional custom:<name> tools
├── knowledge/
└── skills/
── src/
└── my_crew/
├── __init__.py
├── main.py # Entry point with run() function
├── crew.py # Crew class with @CrewBase decorator
├── tools/
│ ├── custom_tool.py
│ └── __init__.py
└── config/
├── agents.yaml # Agent definitions
└── tasks.yaml # Task definitions
```
<Warning>
For JSON-first crews, keep `crew.jsonc`, `agents/`, `tools/`, `knowledge/`, and `skills/`
at the project root. Placing them under `src/` will prevent `crewai run` and deployment
validation from finding the crew definition.
The nested `src/project_name/` structure is critical for Crews.
Placing files at the wrong level will cause deployment failures.
</Warning>
<Info>
Classic projects created with `crewai create crew my_crew --classic` use the older
`src/project_name/crew.py`, `src/project_name/config/agents.yaml`, and
`src/project_name/config/tasks.yaml` layout. That layout remains supported for
decorator-based Python crews.
</Info>
### Flow Project Structure
When you run `crewai create flow my_flow`, you get this structure:
@@ -103,9 +100,9 @@ my_flow/
```
<Info>
JSON-first standalone crews use project-root JSON files. Flows still use
`src/project_name/` and can contain either classic embedded crews or embedded
JSON crew folders loaded with `crewai.project.load_crew`.
Both Crews and Flows use the `src/project_name/` structure.
The key difference is that Flows have a `crews/` folder for embedded crews,
while Crews have `crew.py` directly in the project folder.
</Info>
## Pre-Deployment Checklist
@@ -157,91 +154,60 @@ git commit -m "Add uv.lock for deployment"
git push
```
### 3. Validate the Crew Definition
### 3. Validate CrewBase Decorator Usage
<Tabs>
<Tab title="JSON-first Crews">
JSON-first crews must have a `crew.jsonc` or `crew.json` file at the project root.
The `agents` array must reference files in `agents/`, and each task should reference
a valid agent name.
**Every crew class must use the `@CrewBase` decorator.** This applies to:
```jsonc crew.jsonc
{
"name": "Research Crew",
"agents": ["researcher"],
"tasks": [
{
"name": "research_task",
"description": "Research {topic}.",
"expected_output": "A concise report.",
"agent": "researcher"
}
],
"inputs": {
"topic": "AI Agents"
}
}
```
- Standalone crew projects
- Crews embedded inside Flow projects
Custom tools are referenced as `"custom:<name>"` and must be implemented in
`tools/<name>.py` with a `BaseTool` subclass.
</Tab>
<Tab title="Classic Python/YAML Crews">
Classic crews and Python crews embedded in Flows must use the `@CrewBase` decorator.
```python
from crewai import Agent, Crew, Process, Task
from crewai.project import CrewBase, agent, crew, task
from crewai.agents.agent_builder.base_agent import BaseAgent
from typing import List
```python
from crewai import Agent, Crew, Process, Task
from crewai.project import CrewBase, agent, crew, task
from crewai.agents.agent_builder.base_agent import BaseAgent
from typing import List
@CrewBase # This decorator is REQUIRED
class MyCrew():
"""My crew description"""
@CrewBase
class MyCrew():
"""My crew description"""
agents: List[BaseAgent]
tasks: List[Task]
agents: List[BaseAgent]
tasks: List[Task]
@agent
def my_agent(self) -> Agent:
return Agent(
config=self.agents_config['my_agent'], # type: ignore[index]
verbose=True
)
@agent
def my_agent(self) -> Agent:
return Agent(
config=self.agents_config['my_agent'], # type: ignore[index]
verbose=True
)
@task
def my_task(self) -> Task:
return Task(
config=self.tasks_config['my_task'] # type: ignore[index]
)
@task
def my_task(self) -> Task:
return Task(
config=self.tasks_config['my_task'] # type: ignore[index]
)
@crew
def crew(self) -> Crew:
return Crew(
agents=self.agents,
tasks=self.tasks,
process=Process.sequential,
verbose=True,
)
```
@crew
def crew(self) -> Crew:
return Crew(
agents=self.agents,
tasks=self.tasks,
process=Process.sequential,
verbose=True,
)
```
</Tab>
</Tabs>
<Warning>
If you forget the `@CrewBase` decorator, your deployment will fail with
errors about missing agents or tasks configurations.
</Warning>
### 4. Check Project Entry Points
JSON-first standalone crews do not need a hand-written `src/project_name/main.py`; `crewai run`
and deployment packaging load `crew.jsonc` directly. Classic crews and Flows use Python entry
points:
Both Crews and Flows have their entry point in `src/project_name/main.py`:
<Tabs>
<Tab title="JSON-first Crews">
Run locally from the project root:
```bash
crewai run
```
</Tab>
<Tab title="Classic Crews">
<Tab title="For Crews">
The entry point uses a `run()` function:
```python
@@ -312,17 +278,16 @@ grep -A2 "\[tool.crewai\]" pyproject.toml
# 2. Verify uv.lock exists
ls -la uv.lock || echo "ERROR: uv.lock missing! Run 'uv lock'"
# 3. For JSON-first crews, verify crew.jsonc and agents/ exist
([ -f crew.jsonc ] || [ -f crew.json ]) || echo "No crew.jsonc or crew.json found"
test -d agents || echo "No agents/ directory found"
# 3. Verify src/ structure exists
ls -la src/*/main.py 2>/dev/null || echo "No main.py found in src/"
# 4. For classic Crews - verify crew.py exists
# 4. For Crews - verify crew.py exists
ls -la src/*/crew.py 2>/dev/null || echo "No crew.py (expected for Crews)"
# 5. For Flows - verify crews/ folder exists
ls -la src/*/crews/ 2>/dev/null || echo "No crews/ folder (expected for Flows)"
# 6. For classic Python crews - check for CrewBase usage
# 6. Check for CrewBase usage
grep -r "@CrewBase" . --include="*.py"
```
@@ -332,9 +297,8 @@ grep -r "@CrewBase" . --include="*.py"
|---------|---------|-----|
| Missing `uv.lock` | Build fails during dependency resolution | Run `uv lock` and commit |
| Wrong `type` in pyproject.toml | Build succeeds but runtime fails | Change to correct type |
| Missing `crew.jsonc` or `agents/` in a JSON-first crew | Crew definition not found | Keep `crew.jsonc` and `agents/` at the project root |
| Missing `@CrewBase` decorator in a classic crew | "Config not found" errors | Add decorator to all classic crew classes |
| Classic files at root instead of `src/` | Entry point not found | Move classic Python files to `src/project_name/` |
| Missing `@CrewBase` decorator | "Config not found" errors | Add decorator to all crew classes |
| Files at root instead of `src/` | Entry point not found | Move to `src/project_name/` |
| Missing `run()` or `kickoff()` | Cannot start automation | Add correct entry function |
## Next Steps

View File

@@ -43,7 +43,7 @@ CrewAI is AI-native. This page brings together everything an AI coding agent nee
| Skill | When it runs |
|-------|--------------|
| `getting-started` | Scaffolding new projects, choosing between `LLM.call()` / `Agent` / `Crew` / `Flow`, wiring `crew.jsonc` / `main.py` |
| `getting-started` | Scaffolding new projects, choosing between `LLM.call()` / `Agent` / `Crew` / `Flow`, wiring `crew.py` / `main.py` |
| `design-agent` | Configuring agents — role, goal, backstory, tools, LLMs, memory, guardrails |
| `design-task` | Writing task descriptions, dependencies, structured output (`output_pydantic`, `output_json`), human review |
| `ask-docs` | Querying the live [CrewAI docs MCP server](https://docs.crewai.com/mcp) for up-to-date API details |

View File

@@ -1,162 +1,396 @@
---
title: Build Your First Crew
description: Step-by-step tutorial to create a collaborative AI team with JSON-first crew configuration.
description: Step-by-step tutorial to create a collaborative AI team that works together to solve complex problems.
icon: users-gear
mode: "wide"
---
## Build a Research Crew
## Unleashing the Power of Collaborative AI
In this guide, you will create a two-agent research crew that gathers information about a topic and writes a markdown report. New crew projects are JSON-first: agents are defined in `agents/*.jsonc`, tasks and crew settings are defined in `crew.jsonc`, and `crewai run` loads the JSON definition directly.
Imagine having a team of specialized AI agents working together seamlessly to solve complex problems, each contributing their unique skills to achieve a common goal. This is the power of CrewAI - a framework that enables you to create collaborative AI systems that can accomplish tasks far beyond what a single AI could achieve alone.
In this guide, we'll walk through creating a research crew that will help us research and analyze a topic, then create a comprehensive report. This practical example demonstrates how AI agents can collaborate to accomplish complex tasks, but it's just the beginning of what's possible with CrewAI.
### What You'll Build and Learn
By the end of this guide, you'll have:
1. **Created a specialized AI research team** with distinct roles and responsibilities
2. **Orchestrated collaboration** between multiple AI agents
3. **Automated a complex workflow** that involves gathering information, analysis, and report generation
4. **Built foundational skills** that you can apply to more ambitious projects
While we're building a simple research crew in this guide, the same patterns and techniques can be applied to create much more sophisticated teams for tasks like:
- Multi-stage content creation with specialized writers, editors, and fact-checkers
- Complex customer service systems with tiered support agents
- Autonomous business analysts that gather data, create visualizations, and generate insights
- Product development teams that ideate, design, and plan implementation
Let's get started building your first crew!
### Prerequisites
Before starting, make sure you have:
1. Installed CrewAI following the [installation guide](/en/installation)
2. Set up your LLM API key following the [LLM setup guide](/en/concepts/llms#setting-up-your-llm)
3. A [Serper.dev](https://serper.dev/) API key if you want the researcher to use web search
2. Set up your LLM API key in your environment, following the [LLM setup
guide](/en/concepts/llms#setting-up-your-llm)
3. Basic understanding of Python
## Step 1: Create a New Crew
## Step 1: Create a New CrewAI Project
First, let's create a new CrewAI project using the CLI. This command will set up a complete project structure with all the necessary files, allowing you to focus on defining your agents and their tasks rather than setting up boilerplate code.
```bash
crewai create crew research_crew
cd research_crew
```
The CLI creates a JSON-first project:
This will generate a project with the basic structure needed for your crew. The CLI automatically creates:
```text
- A project directory with the necessary files
- Configuration files for agents and tasks
- A basic crew implementation
- A main script to run the crew
<Frame caption="CrewAI Framework Overview">
<img src="/images/crews.png" alt="CrewAI Framework Overview" />
</Frame>
## Step 2: Explore the Project Structure
Let's take a moment to understand the project structure created by the CLI. CrewAI follows best practices for Python projects, making it easy to maintain and extend your code as your crews become more complex.
```
research_crew/
├── .gitignore
├── .env
├── agents/
│ └── researcher.jsonc
├── crew.jsonc
├── knowledge/
├── pyproject.toml
├── README.md
├── skills/
└── tools/
├── .env
└── src/
└── research_crew/
├── __init__.py
├── main.py
├── crew.py
├── tools/
│ ├── custom_tool.py
│ └── __init__.py
└── config/
├── agents.yaml
└── tasks.yaml
```
<Tip>
Need the older `crew.py`, `config/agents.yaml`, and `config/tasks.yaml` layout? Create it with `crewai create crew research_crew --classic`.
</Tip>
This structure follows best practices for Python projects and makes it easy to organize your code. The separation of configuration files (in YAML) from implementation code (in Python) makes it easy to modify your crew's behavior without changing the underlying code.
## Step 2: Define Your Agents
## Step 3: Configure Your Agents
Replace the generated `agents/researcher.jsonc` file and add `agents/analyst.jsonc`. The file names are the names you reference from `crew.jsonc`.
Now comes the fun part - defining your AI agents! In CrewAI, agents are specialized entities with specific roles, goals, and backstories that shape their behavior. Think of them as characters in a play, each with their own personality and purpose.
```jsonc agents/researcher.jsonc
{
"role": "Senior Research Specialist for {topic}",
"goal": "Find comprehensive and accurate information about {topic}, with a focus on recent developments and key insights.",
"backstory": "You are an experienced research specialist who organizes complex information into clear, useful notes.",
// Replace with your model, for example "openai/gpt-4o".
"llm": "provider/model-id",
"tools": ["SerperDevTool"],
"settings": {
"verbose": true,
"allow_delegation": false
}
}
For our research crew, we'll create two agents:
1. A **researcher** who excels at finding and organizing information
2. An **analyst** who can interpret research findings and create insightful reports
Let's modify the `agents.yaml` file to define these specialized agents. Be sure
to set `llm` to the provider you are using.
```yaml
# src/research_crew/config/agents.yaml
researcher:
role: >
Senior Research Specialist for {topic}
goal: >
Find comprehensive and accurate information about {topic}
with a focus on recent developments and key insights
backstory: >
You are an experienced research specialist with a talent for
finding relevant information from various sources. You excel at
organizing information in a clear and structured manner, making
complex topics accessible to others.
llm: provider/model-id # e.g. openai/gpt-4o, google/gemini-2.0-flash, anthropic/claude...
analyst:
role: >
Data Analyst and Report Writer for {topic}
goal: >
Analyze research findings and create a comprehensive, well-structured
report that presents insights in a clear and engaging way
backstory: >
You are a skilled analyst with a background in data interpretation
and technical writing. You have a talent for identifying patterns
and extracting meaningful insights from research data, then
communicating those insights effectively through well-crafted reports.
llm: provider/model-id # e.g. openai/gpt-4o, google/gemini-2.0-flash, anthropic/claude...
```
```jsonc agents/analyst.jsonc
{
"role": "Report Analyst for {topic}",
"goal": "Turn research findings into a clear, well-structured report.",
"backstory": "You are a careful analyst with strong technical writing skills and a talent for extracting useful insights.",
// Replace with your model, for example "openai/gpt-4o".
"llm": "provider/model-id",
"settings": {
"verbose": true,
"allow_delegation": false
}
}
Notice how each agent has a distinct role, goal, and backstory. These elements aren't just descriptive - they actively shape how the agent approaches its tasks. By crafting these carefully, you can create agents with specialized skills and perspectives that complement each other.
## Step 4: Define Your Tasks
With our agents defined, we now need to give them specific tasks to perform. Tasks in CrewAI represent the concrete work that agents will perform, with detailed instructions and expected outputs.
For our research crew, we'll define two main tasks:
1. A **research task** for gathering comprehensive information
2. An **analysis task** for creating an insightful report
Let's modify the `tasks.yaml` file:
```yaml
# src/research_crew/config/tasks.yaml
research_task:
description: >
Conduct thorough research on {topic}. Focus on:
1. Key concepts and definitions
2. Historical development and recent trends
3. Major challenges and opportunities
4. Notable applications or case studies
5. Future outlook and potential developments
Make sure to organize your findings in a structured format with clear sections.
expected_output: >
A comprehensive research document with well-organized sections covering
all the requested aspects of {topic}. Include specific facts, figures,
and examples where relevant.
agent: researcher
analysis_task:
description: >
Analyze the research findings and create a comprehensive report on {topic}.
Your report should:
1. Begin with an executive summary
2. Include all key information from the research
3. Provide insightful analysis of trends and patterns
4. Offer recommendations or future considerations
5. Be formatted in a professional, easy-to-read style with clear headings
expected_output: >
A polished, professional report on {topic} that presents the research
findings with added analysis and insights. The report should be well-structured
with an executive summary, main sections, and conclusion.
agent: analyst
context:
- research_task
output_file: output/report.md
```
Replace `provider/model-id` with the model you use, for example `openai/gpt-4o`, `anthropic/claude-sonnet-4-6`, or `gemini/gemini-2.0-flash-001`.
Note the `context` field in the analysis task - this is a powerful feature that allows the analyst to access the output of the research task. This creates a workflow where information flows naturally between agents, just as it would in a human team.
## Step 3: Define Tasks and Crew Settings
## Step 5: Configure Your Crew
Replace `crew.jsonc` with:
Now it's time to bring everything together by configuring our crew. The crew is the container that orchestrates how agents work together to complete tasks.
```jsonc crew.jsonc
{
"name": "Research Crew",
"agents": ["researcher", "analyst"],
"tasks": [
{
"name": "research_task",
"description": "Conduct thorough research on {topic}. Focus on key concepts, recent developments, major challenges, notable applications, and future outlook.",
"expected_output": "A comprehensive research document with organized sections, specific facts, and useful examples about {topic}.",
"agent": "researcher"
},
{
"name": "analysis_task",
"description": "Analyze the research findings and create a polished report on {topic}. Include an executive summary, key insights, trend analysis, and recommendations.",
"expected_output": "A professional markdown report with clear headings, a concise summary, main findings, and recommendations.",
"agent": "analyst",
"context": ["research_task"],
"output_file": "output/report.md",
"markdown": true
Let's modify the `crew.py` file:
```python
# src/research_crew/crew.py
from crewai import Agent, Crew, Process, Task
from crewai.project import CrewBase, agent, crew, task
from crewai_tools import SerperDevTool
from crewai.agents.agent_builder.base_agent import BaseAgent
from typing import List
@CrewBase
class ResearchCrew():
"""Research crew for comprehensive topic analysis and reporting"""
agents: List[BaseAgent]
tasks: List[Task]
@agent
def researcher(self) -> Agent:
return Agent(
config=self.agents_config['researcher'], # type: ignore[index]
verbose=True,
tools=[SerperDevTool()]
)
@agent
def analyst(self) -> Agent:
return Agent(
config=self.agents_config['analyst'], # type: ignore[index]
verbose=True
)
@task
def research_task(self) -> Task:
return Task(
config=self.tasks_config['research_task'] # type: ignore[index]
)
@task
def analysis_task(self) -> Task:
return Task(
config=self.tasks_config['analysis_task'], # type: ignore[index]
output_file='output/report.md'
)
@crew
def crew(self) -> Crew:
"""Creates the research crew"""
return Crew(
agents=self.agents,
tasks=self.tasks,
process=Process.sequential,
verbose=True,
)
```
In this code, we're:
1. Creating the researcher agent and equipping it with the SerperDevTool to search the web
2. Creating the analyst agent
3. Setting up the research and analysis tasks
4. Configuring the crew to run tasks sequentially (the analyst will wait for the researcher to finish)
This is where the magic happens - with just a few lines of code, we've defined a collaborative AI system where specialized agents work together in a coordinated process.
## Step 6: Set Up Your Main Script
Now, let's set up the main script that will run our crew. This is where we provide the specific topic we want our crew to research.
```python
#!/usr/bin/env python
# src/research_crew/main.py
import os
from research_crew.crew import ResearchCrew
# Create output directory if it doesn't exist
os.makedirs('output', exist_ok=True)
def run():
"""
Run the research crew.
"""
inputs = {
'topic': 'Artificial Intelligence in Healthcare'
}
],
"process": "sequential",
"verbose": true,
"memory": true,
"inputs": {
"topic": "Artificial Intelligence in Healthcare"
}
}
# Create and run the crew
result = ResearchCrew().crew().kickoff(inputs=inputs)
# Print the result
print("\n\n=== FINAL REPORT ===\n\n")
print(result.raw)
print("\n\nReport has been saved to output/report.md")
if __name__ == "__main__":
run()
```
`context` points to prior task names, so the analyst receives the research task output. The `inputs` object provides default values for `{topic}`. If you remove a default, `crewai run` prompts for it.
This script prepares the environment, specifies our research topic, and kicks off the crew's work. The power of CrewAI is evident in how simple this code is - all the complexity of managing multiple AI agents is handled by the framework.
## Step 4: Set Environment Variables
## Step 7: Set Up Your Environment Variables
Open `.env` and add the keys your model and tools need:
Create a `.env` file in your project root with your API keys:
```sh
SERPER_API_KEY=your_serper_api_key
# Add your model provider API key here too.
# Add your provider's API key here too.
```
See the [LLM setup guide](/en/concepts/llms#setting-up-your-llm) for provider-specific keys.
See the [LLM Setup guide](/en/concepts/llms#setting-up-your-llm) for details on configuring your provider of choice. You can get a Serper API key from [Serper.dev](https://serper.dev/).
## Step 5: Install and Run
## Step 8: Install Dependencies
Install the required dependencies using the CrewAI CLI:
```bash
crewai install
```
This command will:
1. Read the dependencies from your project configuration
2. Create a virtual environment if needed
3. Install all required packages
## Step 9: Run Your Crew
Now for the exciting moment - it's time to run your crew and see AI collaboration in action!
```bash
crewai run
```
`crewai run` detects `crew.jsonc`, loads the agents from `agents/`, prompts for missing placeholders, and runs the crew. When the run finishes, open `output/report.md`.
When you run this command, you'll see your crew spring to life. The researcher will gather information about the specified topic, and the analyst will then create a comprehensive report based on that research. You'll see the agents' thought processes, actions, and outputs in real-time as they work together to complete their tasks.
## How It Works
## Step 10: Review the Output
1. `crew.jsonc` defines the crew, task order, process, memory, and runtime inputs.
2. `agents/researcher.jsonc` and `agents/analyst.jsonc` define the agents.
3. The researcher runs first.
4. The analyst runs second with `context: ["research_task"]`.
5. The final task writes `output/report.md`.
Once the crew completes its work, you'll find the final report in the `output/report.md` file. The report will include:
## Extending Your Crew
1. An executive summary
2. Detailed information about the topic
3. Analysis and insights
4. Recommendations or future considerations
You can add:
Take a moment to appreciate what you've accomplished - you've created a system where multiple AI agents collaborated on a complex task, each contributing their specialized skills to produce a result that's greater than what any single agent could achieve alone.
- More agents by creating new `agents/<name>.jsonc` files and listing them in `crew.jsonc`
- More tasks by appending objects to the `tasks` array
- Built-in tools by adding tool class names such as `"FileReadTool"` or `"SerperDevTool"`
- Custom tools with `"custom:<name>"`, which loads `tools/<name>.py`
- Hierarchical execution with `"process": "hierarchical"` and a `manager_llm` or `manager_agent`
## Exploring Other CLI Commands
<Warning>
Only run JSON crew projects from sources you trust. `custom:<name>` tools and `{"python": "module.attribute"}` references execute local Python code when the crew loads.
</Warning>
CrewAI offers several other useful CLI commands for working with crews:
```bash
# View all available commands
crewai --help
# Run the crew
crewai run
# Test the crew
crewai test
# Reset crew memories
crewai reset-memories
# Replay from a specific task
crewai replay -t <task_id>
```
## The Art of the Possible: Beyond Your First Crew
What you've built in this guide is just the beginning. The skills and patterns you've learned can be applied to create increasingly sophisticated AI systems. Here are some ways you could extend this basic research crew:
### Expanding Your Crew
You could add more specialized agents to your crew:
- A **fact-checker** to verify research findings
- A **data visualizer** to create charts and graphs
- A **domain expert** with specialized knowledge in a particular area
- A **critic** to identify weaknesses in the analysis
### Adding Tools and Capabilities
You could enhance your agents with additional tools:
- Web browsing tools for real-time research
- CSV/database tools for data analysis
- Code execution tools for data processing
- API connections to external services
### Creating More Complex Workflows
You could implement more sophisticated processes:
- Hierarchical processes where manager agents delegate to worker agents
- Iterative processes with feedback loops for refinement
- Parallel processes where multiple agents work simultaneously
- Dynamic processes that adapt based on intermediate results
### Applying to Different Domains
The same patterns can be applied to create crews for:
- **Content creation**: Writers, editors, fact-checkers, and designers working together
- **Customer service**: Triage agents, specialists, and quality control working together
- **Product development**: Researchers, designers, and planners collaborating
- **Data analysis**: Data collectors, analysts, and visualization specialists
## Next Steps
Now that you've built your first crew, you can:
1. Experiment with different agent configurations and personalities
2. Try more complex task structures and workflows
3. Implement custom tools to give your agents new capabilities
4. Apply your crew to different topics or problem domains
5. Explore [CrewAI Flows](/en/guides/flows/first-flow) for more advanced workflows with procedural programming
<Check>
You now have a working JSON-first crew that researches a topic and writes a report.
Congratulations! You've successfully built your first CrewAI crew that can research and analyze any topic you provide. This foundational experience has equipped you with the skills to create increasingly sophisticated AI systems that can tackle complex, multi-stage problems through collaborative intelligence.
</Check>

View File

@@ -65,7 +65,7 @@ This will generate a project with the basic structure needed for your flow.
## Step 2: Understanding the Project Structure
The generated project has the following structure. The starter embedded crew uses the classic Python/YAML layout, and in Step 4 we will replace the content crew with a JSONC crew.
The generated project has the following structure. Take a moment to familiarize yourself with it, as understanding this structure will help you create more complex flows in the future.
```
guide_creator_flow/
@@ -103,82 +103,157 @@ This command automatically creates the necessary directories and template files
## Step 4: Configure the Content Writer Crew
Now, let's configure the content writer crew with JSONC. We'll set up two specialized agents - a writer and a reviewer - that collaborate to create high-quality content for our guide.
Now, let's modify the generated files for the content writer crew. We'll set up two specialized agents - a writer and a reviewer - that will collaborate to create high-quality content for our guide.
1. Create `src/guide_creator_flow/crews/content_crew/agents/content_writer.jsonc`:
1. First, update the agents configuration file to define our content creation team:
```jsonc
{
"role": "Educational Content Writer",
"goal": "Create engaging, informative content that thoroughly explains the assigned topic and provides valuable insights to the reader.",
"backstory": "You are a talented educational writer who explains complex concepts in accessible language and organizes information clearly.",
"llm": "provider/model-id",
"settings": {
"verbose": true
}
}
Remember to set `llm` to the provider you are using.
```yaml
# src/guide_creator_flow/crews/content_crew/config/agents.yaml
content_writer:
role: >
Educational Content Writer
goal: >
Create engaging, informative content that thoroughly explains the assigned topic
and provides valuable insights to the reader
backstory: >
You are a talented educational writer with expertise in creating clear, engaging
content. You have a gift for explaining complex concepts in accessible language
and organizing information in a way that helps readers build their understanding.
llm: provider/model-id # e.g. openai/gpt-4o, google/gemini-2.0-flash, anthropic/claude...
content_reviewer:
role: >
Educational Content Reviewer and Editor
goal: >
Ensure content is accurate, comprehensive, well-structured, and maintains
consistency with previously written sections
backstory: >
You are a meticulous editor with years of experience reviewing educational
content. You have an eye for detail, clarity, and coherence. You excel at
improving content while maintaining the original author's voice and ensuring
consistent quality across multiple sections.
llm: provider/model-id # e.g. openai/gpt-4o, google/gemini-2.0-flash, anthropic/claude...
```
2. Create `src/guide_creator_flow/crews/content_crew/agents/content_reviewer.jsonc`:
These agent definitions establish the specialized roles and perspectives that will shape how our AI agents approach content creation. Notice how each agent has a distinct purpose and expertise.
```jsonc
{
"role": "Educational Content Reviewer and Editor",
"goal": "Ensure content is accurate, comprehensive, well-structured, and consistent with previously written sections.",
"backstory": "You are a meticulous editor with an eye for detail, clarity, and coherence.",
"llm": "provider/model-id",
"settings": {
"verbose": true
}
}
2. Next, update the tasks configuration file to define the specific writing and reviewing tasks:
```yaml
# src/guide_creator_flow/crews/content_crew/config/tasks.yaml
write_section_task:
description: >
Write a comprehensive section on the topic: "{section_title}"
Section description: {section_description}
Target audience: {audience_level} level learners
Your content should:
1. Begin with a brief introduction to the section topic
2. Explain all key concepts clearly with examples
3. Include practical applications or exercises where appropriate
4. End with a summary of key points
5. Be approximately 500-800 words in length
Format your content in Markdown with appropriate headings, lists, and emphasis.
Previously written sections:
{previous_sections}
Make sure your content maintains consistency with previously written sections
and builds upon concepts that have already been explained.
expected_output: >
A well-structured, comprehensive section in Markdown format that thoroughly
explains the topic and is appropriate for the target audience.
agent: content_writer
review_section_task:
description: >
Review and improve the following section on "{section_title}":
{draft_content}
Target audience: {audience_level} level learners
Previously written sections:
{previous_sections}
Your review should:
1. Fix any grammatical or spelling errors
2. Improve clarity and readability
3. Ensure content is comprehensive and accurate
4. Verify consistency with previously written sections
5. Enhance the structure and flow
6. Add any missing key information
Provide the improved version of the section in Markdown format.
expected_output: >
An improved, polished version of the section that maintains the original
structure but enhances clarity, accuracy, and consistency.
agent: content_reviewer
context:
- write_section_task
```
Replace `provider/model-id` with the model you use, for example `openai/gpt-4o`, `gemini/gemini-2.0-flash-001`, or `anthropic/claude-sonnet-4-6`.
These task definitions provide detailed instructions to our agents, ensuring they produce content that meets our quality standards. Note how the `context` parameter in the review task creates a workflow where the reviewer has access to the writer's output.
3. Create `src/guide_creator_flow/crews/content_crew/crew.jsonc`:
```jsonc
{
"name": "Content Crew",
"agents": ["content_writer", "content_reviewer"],
"tasks": [
{
"name": "write_section_task",
"description": "Write a comprehensive section on the topic: \"{section_title}\".\n\nSection description: {section_description}\nTarget audience: {audience_level} level learners\n\nYour content should begin with a brief introduction, explain key concepts clearly with examples, include practical applications where appropriate, end with a summary, and be approximately 500-800 words.\n\nPreviously written sections:\n{previous_sections}",
"expected_output": "A well-structured, comprehensive section in Markdown format that thoroughly explains the topic and is appropriate for the target audience.",
"agent": "content_writer",
"markdown": true
},
{
"name": "review_section_task",
"description": "Review and improve this section on \"{section_title}\":\n\n{draft_content}\n\nTarget audience: {audience_level} level learners\nPreviously written sections:\n{previous_sections}\n\nFix errors, improve clarity, verify consistency, enhance structure, and add missing key information.",
"expected_output": "An improved, polished version of the section that maintains the original structure but enhances clarity, accuracy, and consistency.",
"agent": "content_reviewer",
"context": ["write_section_task"],
"markdown": true
}
],
"process": "sequential",
"verbose": true
}
```
The `context` field lets the reviewer use the writer's output.
4. Replace `src/guide_creator_flow/crews/content_crew/content_crew.py` with a small loader:
3. Now, update the crew implementation file to define how our agents and tasks work together:
```python
from pathlib import Path
# src/guide_creator_flow/crews/content_crew/content_crew.py
from crewai import Agent, Crew, Process, Task
from crewai.project import CrewBase, agent, crew, task
from crewai.agents.agent_builder.base_agent import BaseAgent
from typing import List
from crewai.project import load_crew
@CrewBase
class ContentCrew():
"""Content writing crew"""
agents: List[BaseAgent]
tasks: List[Task]
def kickoff_content_crew(inputs: dict):
crew, default_inputs = load_crew(Path(__file__).with_name("crew.jsonc"))
return crew.kickoff(inputs={**default_inputs, **inputs})
@agent
def content_writer(self) -> Agent:
return Agent(
config=self.agents_config['content_writer'], # type: ignore[index]
verbose=True
)
@agent
def content_reviewer(self) -> Agent:
return Agent(
config=self.agents_config['content_reviewer'], # type: ignore[index]
verbose=True
)
@task
def write_section_task(self) -> Task:
return Task(
config=self.tasks_config['write_section_task'] # type: ignore[index]
)
@task
def review_section_task(self) -> Task:
return Task(
config=self.tasks_config['review_section_task'], # type: ignore[index]
context=[self.write_section_task()]
)
@crew
def crew(self) -> Crew:
"""Creates the content writing crew"""
return Crew(
agents=self.agents,
tasks=self.tasks,
process=Process.sequential,
verbose=True,
)
```
This loader turns `crew.jsonc` into a `Crew` at runtime. While this crew can function independently, in our flow it will be orchestrated as part of a larger system.
This crew definition establishes the relationship between our agents and tasks, setting up a sequential process where the content writer creates a draft and then the reviewer improves it. While this crew can function independently, in our flow it will be orchestrated as part of a larger system.
## Step 5: Create the Flow
@@ -200,7 +275,7 @@ from typing import List, Dict
from pydantic import BaseModel, Field
from crewai import LLM
from crewai.flow.flow import Flow, listen, start
from guide_creator_flow.crews.content_crew.content_crew import kickoff_content_crew
from guide_creator_flow.crews.content_crew.content_crew import ContentCrew
# Define our models for structured data
class Section(BaseModel):
@@ -305,7 +380,7 @@ class GuideCreatorFlow(Flow[GuideCreatorState]):
previous_sections_text = "No previous sections written yet."
# Run the content crew for this section
result = kickoff_content_crew(inputs={
result = ContentCrew().crew().kickoff(inputs={
"section_title": section.title,
"section_description": section.description,
"audience_level": self.state.audience_level,
@@ -525,7 +600,7 @@ This provides a type-safe way to track and transform data throughout your flow.
Flows can seamlessly integrate with crews for complex collaborative tasks:
```python
result = kickoff_content_crew(inputs={
result = ContentCrew().crew().kickoff(inputs={
"section_title": section.title,
# ...
})

View File

@@ -116,7 +116,7 @@ If you haven't installed `uv` yet, follow **step 1** to quickly get it set up on
# Creating a CrewAI Project
`crewai create crew` now creates a JSON-first crew project. Agents live in `agents/*.jsonc`, tasks and crew-level settings live in `crew.jsonc`, and `crewai run` loads that JSON definition directly.
We recommend using the `YAML` template scaffolding for a structured approach to defining agents and tasks. Here's how to get started:
<Steps>
<Step title="Generate Project Scaffolding">
@@ -129,20 +129,21 @@ If you haven't installed `uv` yet, follow **step 1** to quickly get it set up on
```
my_project/
├── .gitignore
├── .env
├── agents/
│ └── researcher.jsonc
├── crew.jsonc
├── knowledge/
├── pyproject.toml
├── README.md
├── skills/
└── tools/
```
- If you need the older Python/YAML scaffold with `crew.py`, `config/agents.yaml`, and `config/tasks.yaml`, run:
```shell
crewai create crew <your_project_name> --classic
├── .env
└── src/
└── my_project/
├── __init__.py
├── main.py
├── crew.py
├── tools/
│ ├── custom_tool.py
│ └── __init__.py
└── config/
├── agents.yaml
└── tasks.yaml
```
</Step>
@@ -151,15 +152,15 @@ If you haven't installed `uv` yet, follow **step 1** to quickly get it set up on
- Your project will contain these essential files:
| File | Purpose |
| --- | --- |
| `crew.jsonc` | Configure the crew, task order, process, and input defaults |
| `agents/*.jsonc` | Define each agent's role, goal, backstory, LLM, tools, and behavior |
| `agents.yaml` | Define your AI agents and their roles |
| `tasks.yaml` | Set up agent tasks and workflows |
| `.env` | Store API keys and environment variables |
| `tools/` | Optional Python files for `custom:<name>` tools |
| `knowledge/` | Optional knowledge files for agents |
| `skills/` | Optional skill files applied to the crew |
| `main.py` | Project entry point and execution flow |
| `crew.py` | Crew orchestration and coordination |
| `tools/` | Directory for custom agent tools |
| `knowledge/` | Directory for knowledge base |
- Start by editing `crew.jsonc` and the files in `agents/` to define your crew's behavior.
- Use `{placeholder}` values in agent and task text, then set defaults in `crew.jsonc` under `inputs`. When you run `crewai run`, the CLI prompts for any missing values.
- Start by editing `agents.yaml` and `tasks.yaml` to define your crew's behavior.
- Keep sensitive information like API keys in `.env`.
</Step>

View File

@@ -1,19 +1,15 @@
---
title: "Using Annotations in crew.py"
description: "Learn how to use classic Python annotations to structure agents, tasks, and components in CrewAI"
description: "Learn how to use annotations to properly structure agents, tasks, and components in CrewAI"
icon: "at"
mode: "wide"
---
This guide explains how to use annotations to properly reference **agents**, **tasks**, and other components in a classic `crew.py` file.
<Note>
New crew projects created with `crewai create crew <name>` are JSON-first and use `crew.jsonc` plus `agents/*.jsonc`. Use this annotations guide when you are working in a classic project created with `crewai create crew <name> --classic`, migrating an existing Python/YAML project, or need decorator-based Python control.
</Note>
This guide explains how to use annotations to properly reference **agents**, **tasks**, and other components in the `crew.py` file.
## Introduction
Annotations in the CrewAI framework are used to decorate classes and methods, providing metadata and functionality to various components of your crew. In classic Python/YAML projects, these annotations help organize the code that loads `config/agents.yaml`, `config/tasks.yaml`, and returns the `Crew` object.
Annotations in the CrewAI framework are used to decorate classes and methods, providing metadata and functionality to various components of your crew. These annotations help in organizing and structuring your code, making it more readable and maintainable.
## Available Annotations
@@ -117,9 +113,9 @@ def crew(self) -> Crew:
The `@crew` annotation is used to decorate the method that creates and returns the `Crew` object. This method assembles all the components (agents and tasks) into a functional crew.
## Classic YAML Configuration
## YAML Configuration
In classic projects, agent configurations are typically stored in a YAML file. Here's an example of how the `agents.yaml` file might look for the researcher agent:
The agent configurations are typically stored in a YAML file. Here's an example of how the `agents.yaml` file might look for the researcher agent:
```yaml
researcher:
@@ -150,6 +146,6 @@ Note how the `llm` and `tools` in the YAML file correspond to the methods decora
- **Consistent Naming**: Use clear and consistent naming conventions for your methods. For example, agent methods could be named after their roles (e.g., researcher, reporting_analyst).
- **Environment Variables**: Use environment variables for sensitive information like API keys.
- **Flexibility**: Design your crew to be flexible by allowing easy addition or removal of agents and tasks.
- **YAML-Code Correspondence**: In classic projects, ensure that the names and structures in your YAML files correspond correctly to the decorated methods in your Python code.
- **YAML-Code Correspondence**: Ensure that the names and structures in your YAML files correspond correctly to the decorated methods in your Python code.
By following these guidelines and properly using annotations, you can maintain classic Python/YAML crews cleanly. For new crews, prefer the JSON-first structure covered in [Crews](/en/concepts/crews).
By following these guidelines and properly using annotations, you can create well-structured and maintainable crews using the CrewAI framework.

View File

@@ -39,60 +39,85 @@ If you have not installed CrewAI yet, follow the [installation guide](/en/instal
This creates a Flow app under `src/latest_ai_flow/`, including a starter crew under `crews/content_crew/` that you will replace with a minimal **single-agent** research crew in the next steps.
</Step>
<Step title="Configure one agent in JSONC">
Create `src/latest_ai_flow/crews/content_crew/agents/researcher.jsonc` (create the `agents/` directory if needed). Variables like `{topic}` are filled from `crew.kickoff(inputs=...)`.
<Step title="Configure one agent in `agents.yaml`">
Replace the contents of `src/latest_ai_flow/crews/content_crew/config/agents.yaml` with a single researcher. Variables like `{topic}` are filled from `crew.kickoff(inputs=...)`.
```jsonc agents/researcher.jsonc
{
"role": "{topic} Senior Data Researcher",
"goal": "Uncover cutting-edge developments in {topic}",
"backstory": "You're a seasoned researcher who finds relevant information and presents it clearly.",
"tools": ["SerperDevTool"],
"settings": {
"verbose": true
}
}
```yaml agents.yaml
# src/latest_ai_flow/crews/content_crew/config/agents.yaml
researcher:
role: >
{topic} Senior Data Researcher
goal: >
Uncover cutting-edge developments in {topic}
backstory: >
You're a seasoned researcher with a knack for uncovering the latest
developments in {topic}. You find the most relevant information and
present it clearly.
```
</Step>
<Step title="Configure the crew in `crew.jsonc`">
Create `src/latest_ai_flow/crews/content_crew/crew.jsonc`:
```jsonc crew.jsonc
{
"name": "Research Crew",
"agents": ["researcher"],
"tasks": [
{
"name": "research_task",
"description": "Conduct thorough research about {topic}. Use web search to find current, credible information. The current year is 2026.",
"expected_output": "A markdown report with clear sections: key trends, notable tools or companies, and implications. Aim for 800-1200 words. No fenced code blocks around the whole document.",
"agent": "researcher",
"output_file": "output/report.md",
"markdown": true
}
],
"process": "sequential",
"verbose": true
}
<Step title="Configure one task in `tasks.yaml`">
```yaml tasks.yaml
# src/latest_ai_flow/crews/content_crew/config/tasks.yaml
research_task:
description: >
Conduct thorough research about {topic}. Use web search to find current,
credible information. The current year is 2026.
expected_output: >
A markdown report with clear sections: key trends, notable tools or companies,
and implications. Aim for 8001200 words. No fenced code blocks around the whole document.
agent: researcher
output_file: output/report.md
```
</Step>
<Step title="Load the JSON crew (`content_crew.py`)">
Replace the generated `content_crew.py` with a small loader that turns `crew.jsonc` into a `Crew`.
<Step title="Wire the crew class (`content_crew.py`)">
Point the generated crew at your YAML and attach `SerperDevTool` to the researcher.
```python content_crew.py
# src/latest_ai_flow/crews/content_crew/content_crew.py
from pathlib import Path
from typing import List
from crewai.project import load_crew
from crewai import Agent, Crew, Process, Task
from crewai.agents.agent_builder.base_agent import BaseAgent
from crewai.project import CrewBase, agent, crew, task
from crewai_tools import SerperDevTool
def kickoff_content_crew(inputs: dict):
crew, default_inputs = load_crew(Path(__file__).with_name("crew.jsonc"))
return crew.kickoff(inputs={**default_inputs, **inputs})
@CrewBase
class ResearchCrew:
"""Single-agent research crew used inside the Flow."""
agents: List[BaseAgent]
tasks: List[Task]
agents_config = "config/agents.yaml"
tasks_config = "config/tasks.yaml"
@agent
def researcher(self) -> Agent:
return Agent(
config=self.agents_config["researcher"], # type: ignore[index]
verbose=True,
tools=[SerperDevTool()],
)
@task
def research_task(self) -> Task:
return Task(
config=self.tasks_config["research_task"], # type: ignore[index]
)
@crew
def crew(self) -> Crew:
return Crew(
agents=self.agents,
tasks=self.tasks,
process=Process.sequential,
verbose=True,
)
```
</Step>
@@ -106,7 +131,7 @@ If you have not installed CrewAI yet, follow the [installation guide](/en/instal
from crewai.flow import Flow, listen, start
from latest_ai_flow.crews.content_crew.content_crew import kickoff_content_crew
from latest_ai_flow.crews.content_crew.content_crew import ResearchCrew
class ResearchFlowState(BaseModel):
@@ -125,7 +150,7 @@ If you have not installed CrewAI yet, follow the [installation guide](/en/instal
@listen(prepare_topic)
def run_research(self):
result = kickoff_content_crew(inputs={"topic": self.state.topic})
result = ResearchCrew().crew().kickoff(inputs={"topic": self.state.topic})
self.state.report = result.raw
print("Research crew finished.")
@@ -147,7 +172,7 @@ If you have not installed CrewAI yet, follow the [installation guide](/en/instal
```
<Tip>
If your package name differs from `latest_ai_flow`, change the `kickoff_content_crew` import to match your projects module path.
If your package name differs from `latest_ai_flow`, change the import of `ResearchCrew` to match your projects module path.
</Tip>
</Step>
@@ -198,7 +223,7 @@ If you have not installed CrewAI yet, follow the [installation guide](/en/instal
## How this run fits together
1. **Flow** — `LatestAiFlow` runs `prepare_topic` first, then `run_research`, then `summarize`. State (`topic`, `report`) lives on the Flow.
2. **Crew** — `kickoff_content_crew` loads `crew.jsonc` and runs one task with one agent: the researcher uses **Serper** to search the web, then writes the structured report.
2. **Crew** — `ResearchCrew` runs one task with one agent: the researcher uses **Serper** to search the web, then writes the structured report.
3. **Artifact** — The tasks `output_file` writes the report under `output/report.md`.
To go deeper on Flow patterns (routing, persistence, human-in-the-loop), see [Build your first Flow](/en/guides/flows/first-flow) and [Flows](/en/concepts/flows). For crews without a Flow, see [Crews](/en/concepts/crews). For a single `Agent` and `kickoff()` without tasks, see [Agents](/en/concepts/agents#direct-agent-interaction-with-kickoff).
@@ -209,10 +234,7 @@ You now have an end-to-end Flow with an agent crew and a saved report — a soli
### Naming consistency
The names in `crew.jsonc` must match the files and task references you use:
- `agents: ["researcher"]` loads `agents/researcher.jsonc`
- `context: ["research_task"]` references a prior task named `research_task`
YAML keys (`researcher`, `research_task`) must match the method names on your `@CrewBase` class. See [Crews](/en/concepts/crews) for the full decorator pattern.
## Deploying

View File

@@ -66,39 +66,13 @@ CrewAI AOP에는 코드를 작성하지 않고도 에이전트 생성 및 구성
## 에이전트 생성
CrewAI에서 에이전트를 생성하는 일반적인 방법은 **JSONC 프로젝트 구성(새 crew 권장)** 또는 **코드에서 직접 정의**니다.
CrewAI에서 에이전트를 생성하는 방법에는 **YAML 구성(권장)**을 사용하는 방법과 **코드에서 직접 정의**하는 두 가지가 있습니다.
### JSONC 구성 (권장)
### YAML 구성 (권장)
`crewai create crew <name>`으로 만든 새 프로젝트는 JSON-first 구성을 사용합니다. 각 에이전트는 `agents/<agent_name>.jsonc`에 정의하고, `crew.jsonc`에서 crew에 포함할 에이전트를 나열합니다.
YAML 구성을 사용하면 에이전트를 보다 깔끔하고 유지 관리하기 쉽도록 정의할 수 있습니다. CrewAI 프로젝트에서 이 방식을 사용하는 것을 강력히 권장합니다.
```jsonc agents/researcher.jsonc
{
"role": "{topic} Senior Data Researcher",
"goal": "Uncover cutting-edge developments in {topic}",
"backstory": "You find the most relevant information and present it clearly.",
"llm": "openai/gpt-4o",
"tools": ["SerperDevTool"],
"settings": {
"verbose": true,
"allow_delegation": false
}
}
```
`role`, `goal`, `backstory`에 `{placeholder}`를 사용할 수 있습니다. 기본값은 `crew.jsonc`의 `inputs`에 넣고, 빠진 값은 `crewai run`이 실행 시 물어봅니다. `verbose`, `allow_delegation`, `max_iter`, `memory`, `cache`, `planning` 같은 동작 필드는 최상위 또는 `settings` 안에 둘 수 있습니다.
<Note>
JSONC는 주석과 trailing comma를 지원합니다. `agents/<name>.jsonc`와 `agents/<name>.json`이 모두 있으면 CrewAI는 JSONC 파일을 사용합니다.
</Note>
### 클래식 YAML 구성
`crewai create crew <name> --classic`으로 만든 클래식 프로젝트는 `config/agents.yaml`과 `crew.py`의 `@CrewBase` 클래스를 사용합니다.
YAML 구성은 기존 Python/YAML 프로젝트와 `@CrewBase` 클래스에서 에이전트를 정의하려는 팀을 위해 계속 지원됩니다.
클래식 프로젝트를 만든 후, `src/latest_ai_development/config/agents.yaml` 파일로 이동하여 템플릿을 여러분의 요구 사항에 맞게 수정하세요.
[설치](/ko/installation) 섹션에 설명된 대로 CrewAI 프로젝트를 생성한 후, `src/latest_ai_development/config/agents.yaml` 파일로 이동하여 템플릿을 여러분의 요구 사항에 맞게 수정하세요.
<Note>
YAML 파일의 변수(예: `{topic}`)는 crew를 실행할 때 입력값에서 가져온 값으로 대체됩니다:

View File

@@ -52,8 +52,6 @@ crewai create crew my_new_crew
crewai create flow my_new_flow
```
기본적으로 `crewai create crew`는 `crew.jsonc`와 `agents/*.jsonc`가 있는 JSON-first 프로젝트를 만듭니다. `crew.py`, `config/agents.yaml`, `config/tasks.yaml`을 사용하는 기존 Python/YAML 스캐폴드가 필요할 때만 `crewai create crew my_new_crew --classic`을 사용하세요.
### 2. 버전
설치된 CrewAI의 버전을 표시합니다.
@@ -185,20 +183,7 @@ crewai chat
이 명령어들은 CrewAI 프로젝트의 루트 디렉터리에서 실행해야 합니다.
</Note>
<Note>
중요: 이 명령어를 사용하려면 crew 정의에 `chat_llm` 속성을 설정해야 합니다.
JSON-first crew에서는 `crew.jsonc`에 추가합니다:
```jsonc
{
"name": "My Crew",
"agents": ["researcher"],
"tasks": [],
"chat_llm": "openai/gpt-4o"
}
```
클래식 Python/YAML crew에서는 `crew.py`에 설정합니다:
중요: 이 명령어를 사용하려면 `crew.py` 파일에서 `chat_llm` 속성을 설정해야 합니다.
```python
@crew
@@ -328,7 +313,7 @@ CLI를 사용하여 [CrewAI AMP](http://app.crewai.com)에 crew를 배포하는
### 11. API 키
`crewai create crew` 명령어를 실행하면, CLI에서 선택할 수 있는 LLM 제공업체 목록이 표시되고, 그 다음으로 선택한 제공업체에 대한 모델 선택이 이어집니다. 선택한 모델은 생성된 `.env`에 저장되며 각 에이전트 JSONC 파일은 자체 `llm`을 설정할 수 있습니다.
`crewai create crew` 명령어를 실행하면, CLI에서 선택할 수 있는 LLM 제공업체 목록이 표시되고, 그 다음으로 선택한 제공업체에 대한 모델 선택이 이어집니다.
LLM 제공업체와 모델을 선택하면, API 키를 입력하라는 메시지가 표시됩니다.

View File

@@ -41,54 +41,13 @@ crewAI에서 crew는 일련의 작업을 달성하기 위해 함께 협력하는
## 크루 생성하기
CrewAI에서 크루를 생성하는 주요 방법은 **JSONC 구성(새 crew 권장)**을 사용하는 방법과 클래식 프로젝트나 고급 사용 사례에서 **코드 직접 정의**하는 방법입니다.
CrewAI에서 크루를 생성하는 방법은 두 가지가 있습니다: **YAML 구성(권장)**을 사용하는 방법과 **코드에서 직접 정의**하는 방법입니다.
### JSONC 구성 (권장)
### YAML 구성 (권장)
`crewai create crew <name>`으로 만든 새 프로젝트는 crew 수준 설정과 태스크를 `crew.jsonc`에 두고, 각 에이전트를 `agents/`의 별도 파일에 둡니다. `crewai run`은 `crew.jsonc` 또는 `crew.json`을 감지해 에이전트를 로드하고, 빠진 placeholder 값을 물은 뒤 crew를 시작합니다.
YAML 구성을 사용하면 crew를 정의할 때 더 깔끔하고 유지 관리하기 쉬운 방법을 제공하며, CrewAI 프로젝트에서 agent 및 task를 정의하는 방식과 일관성을 유지할 수 있습니다.
```jsonc crew.jsonc
{
"name": "Market Research Crew",
"agents": ["researcher", "analyst"],
"tasks": [
{
"name": "research",
"description": "Research {topic} and collect the most relevant facts.",
"expected_output": "Structured research notes about {topic}.",
"agent": "researcher"
},
{
"name": "analysis",
"description": "Analyze the research and write a concise report.",
"expected_output": "A markdown report with findings and recommendations.",
"agent": "analyst",
"context": ["research"],
"output_file": "output/report.md"
}
],
"process": "sequential",
"verbose": true,
"memory": true,
"inputs": {
"topic": "AI Agents"
}
}
```
`agents`의 각 문자열은 먼저 `agents/<name>.jsonc`, 그 다음 `agents/<name>.json`으로 해석됩니다. 계층형 crew는 `"process": "hierarchical"`와 `manager_llm` 또는 `manager_agent`를 사용하세요.
<Warning>
신뢰하는 출처의 JSON crew 프로젝트만 실행하세요. `custom:<name>` 도구와 `{"python": "module.attribute"}` 참조는 crew 로드 시 로컬 Python 코드를 실행합니다.
</Warning>
### 클래식 YAML 구성
`crewai create crew <name> --classic`으로 만든 클래식 프로젝트는 `crew.py`, `config/agents.yaml`, `config/tasks.yaml`, `@CrewBase`, `@agent`, `@task`, `@crew` 데코레이터를 사용합니다.
이 방식은 기존 Python/YAML 프로젝트와 Python 데코레이터 제어가 필요한 팀을 위해 계속 지원됩니다.
클래식 프로젝트를 만든 후, `CrewBase`를 상속받는 클래스에서 데코레이터를 이용해 agent, task, 그리고 crew 자체를 정의할 수 있습니다.
[설치](/ko/installation) 섹션에 설명된 대로 CrewAI 프로젝트를 생성한 후, `CrewBase`를 상속받는 클래스에서 데코레이터를 이용해 agent, task, 그리고 crew 자체를 정의할 수 있습니다.
#### 데코레이터가 적용된 예시 Crew 클래스
@@ -457,4 +416,4 @@ crewai log-tasks-outputs
crewai replay -t <task_id>
```
이 명령어들을 사용하면 이전에 실행된 작업의 컨텍스트를 유지하면서 최신 kickoff 작업부터 다시 실행할 수 있습니다.
이 명령어들을 사용하면 이전에 실행된 작업의 컨텍스트를 유지하면서 최신 kickoff 작업부터 다시 실행할 수 있습니다.

View File

@@ -823,7 +823,7 @@ CrewAI에서 여러 crews로 flow를 생성하는 것은 간단합니다.
crewai create flow name_of_flow
```
이 명령어는 필요한 폴더 구조를 갖춘 새 CrewAI 프로젝트를 생성합니다. 생성된 프로젝트에는 이미 동작 중인 미리 구축된 crew인 `poem_crew`가 포함되어 있습니다. 시작용 embedded crew는 클래식 Python/YAML 레이아웃을 사용하며, `crewai create crew`로 만든 새 독립 실행형 crew는 JSON-first 레이아웃을 사용합니다.
이 명령어는 필요한 폴더 구조를 갖춘 새 CrewAI 프로젝트를 생성합니다. 생성된 프로젝트에는 이미 동작 중인 미리 구축된 crew인 `poem_crew`가 포함되어 있습니다. 이 crew를 템플릿으로 사용하여 복사, 붙여넣기, 수정함으로써 다른 crew를 만들 수 있습니다.
### 폴더 구조
@@ -853,29 +853,7 @@ crewai create flow name_of_flow
- `config/tasks.yaml`: 크루의 task를 정의합니다.
- `poem_crew.py`: agent, task, 그리고 크루 자체를 포함한 crew 정의가 들어 있습니다.
`poem_crew`를 복사, 붙여넣기, 그리고 편집하여 다른 클래식 embedded crew를 생성할 수 있습니다.
JSON-first embedded crew는 `crew.jsonc`와 `agents/*.jsonc`가 있는 폴더를 사용하세요:
```text
crews/
└── research_crew/
├── agents/
│ └── researcher.jsonc
└── crew.jsonc
```
그런 다음 Flow 단계에서 로드합니다:
```python
from pathlib import Path
from crewai.project import load_crew
crew, default_inputs = load_crew(
Path(__file__).parent / "crews" / "research_crew" / "crew.jsonc"
)
result = crew.kickoff(inputs={**default_inputs, "topic": "AI Agents"})
```
`poem_crew`를 복사, 붙여넣기, 그리고 편집하여 다른 크루를 생성할 수 있습니다.
### `main.py`에서 Crew 연결하기

View File

@@ -64,48 +64,13 @@ crew = Crew(
## 작업 생성하기
CrewAI에서 작업을 생성하는 일반적인 방법은 **JSONC 프로젝트 구성(새 crew 권장)** 또는 **코드에서 직접 정의**입니다.
CrewAI에서 작업을 생성하는 방법에는 **YAML 구성(권장)** 을 사용하는 방법과 **코드에서 직접 정의하는 방법** 두 가지가 있습니다.
### JSONC 구성 (권장)
### YAML 구성 (권장)
`crewai create crew <name>`으로 만든 새 프로젝트는 `crew.jsonc`에 태스크를 정의합니다.
YAML 구성을 사용하면 작업을 정의할 때 더 깔끔하고 유지 관리가 용이한 방법을 제공합니다. CrewAI 프로젝트에서 작업을 정의할 때 이 방식을 사용하는 것을 강력히 권장합니다.
```jsonc crew.jsonc
{
"name": "Research Crew",
"agents": ["researcher", "reporting_analyst"],
"tasks": [
{
"name": "research_task",
"description": "Conduct thorough research about {topic}.",
"expected_output": "A list of the most relevant information about {topic}.",
"agent": "researcher"
},
{
"name": "reporting_task",
"description": "Review the research and expand it into a detailed report.",
"expected_output": "A polished markdown report.",
"agent": "reporting_analyst",
"context": ["research_task"],
"markdown": true,
"output_file": "report.md"
}
],
"inputs": {
"topic": "AI Agents"
}
}
```
각 태스크에는 `description`과 `expected_output`이 필요합니다. `agent` 값은 `agents`에 나열된 에이전트 이름과 일치해야 합니다. `context`는 이전 태스크 이름만 참조할 수 있으며, 이후 태스크 참조는 거부됩니다.
### 클래식 YAML 구성
`crewai create crew <name> --classic`으로 만든 클래식 프로젝트는 `config/tasks.yaml`과 `crew.py`의 `@CrewBase` 클래스를 사용합니다.
YAML 구성은 기존 Python/YAML 프로젝트와 `@CrewBase` 클래스에서 태스크를 정의하려는 팀을 위해 계속 지원됩니다.
클래식 프로젝트를 만든 후, `src/latest_ai_development/config/tasks.yaml` 파일로 이동하여 템플릿을 귀하의 특정 작업 요구 사항에 맞게 수정하세요.
[설치](/ko/installation) 섹션에 따라 CrewAI 프로젝트를 생성한 후, `src/latest_ai_development/config/tasks.yaml` 파일로 이동하여 템플릿을 귀하의 특정 작업 요구 사항에 맞게 수정하세요.
<Note>
YAML 파일 내 변수(예: `{topic}`)는 크루를 실행할 때 입력값에서 가져온 값으로 대체됩니다:

View File

@@ -26,10 +26,10 @@ icon: "arrows-rotate"
## 1단계 — 검증 Crew 스캐폴딩
이 예제는 `crew.py`를 통해 Python 도구를 연결하므로 클래식 crew 프로젝트를 만듭니다:
새 Crew 프로젝트를 만듭니다. CrewAI CLI가 구조를 스캐폴딩합니다:
```bash
crewai create crew rotation_verifier --classic --skip_provider
crewai create crew rotation_verifier --skip_provider
cd rotation_verifier
```

View File

@@ -373,17 +373,17 @@ git push
**해결책**: 프로젝트가 예상 구조와 일치하는지 확인합니다:
- **JSON-first Crews**: `crew.jsonc` 또는 `crew.json`과 `agents/`를 프로젝트 루트에 둡니다
- **클래식 Crews**: `src/project_name/main.py`에 `run()` 진입점을 둡니다
- **Flows**: `src/project_name/main.py`에 `kickoff()` 진입점을 둡니다
- **Crews와 Flows 모두**: 진입점이 `src/project_name/main.py`에 있어야 합니다
- **Crews**: 진입점으로 `run()` 함수 사용
- **Flows**: 진입점으로 `kickoff()` 함수 사용
자세한 구조 다이어그램은 [배포 준비하기](/ko/enterprise/guides/prepare-for-deployment)를 참조하세요.
#### 클래식 Crew의 CrewBase 데코레이터 누락
#### CrewBase 데코레이터 누락
**증상**: "Crew not found", "Config not found" 또는 agent/task 구성 오류
**해결책**: 클래식 Python/YAML crew에서는 모든 crew 클래스가 `@CrewBase` 데코레이터를 사용하는지 확인합니다. JSON-first crew에는 이 데코레이터가 필요하지 않습니다.
**해결책**: **모든** crew 클래스가 `@CrewBase` 데코레이터를 사용하는지 확인합니다:
```python
from crewai.project import CrewBase, agent, crew, task
@@ -403,8 +403,8 @@ class YourCrew():
```
<Info>
이것은 Flow 프로젝트에 포함된 클래식 crew를 포함하여 클래식 Python crew 클래스에 적용됩니다.
JSON-first crew는 `crew.jsonc`와 `agents/`를 기준으로 검증됩니다.
이것은 독립 실행형 Crews와 Flow 프로젝트에 포함된 crews 모두에 적용됩니다.
모든 crew 클래스에 데코레이터가 필요합니다.
</Info>
#### 잘못된 pyproject.toml 타입
@@ -441,8 +441,8 @@ type = "flow"
**해결책**:
1. AMP 대시보드에서 실행 로그를 확인합니다 (Traces 탭)
2. 모든 도구에 필요한 API 키가 구성되어 있는지 확인합니다
3. JSON-first crew의 경우 `crew.jsonc`와 `agents/`에서 참조한 파일을 검증합니다
4. 클래식 crew의 경우 `agents.yaml`과 `tasks.yaml`이 유효한지 확인합니다
3. `agents.yaml`의 agent 구성이 유효한지 확인합니다
4. `tasks.yaml`task 구성에 구문 오류가 없는지 확인합니다
<Card title="도움이 필요하신가요?" icon="headset" href="mailto:support@crewai.com">
배포 문제 또는 AMP 플랫폼에 대한 문의 사항이 있으시면 지원팀에 연락해 주세요.

View File

@@ -24,9 +24,10 @@ company-ai/
`-- crews/
|-- support_agent/
| |-- pyproject.toml
| |-- crew.jsonc
| `-- agents/
| `-- support_agent.jsonc
| `-- src/
| `-- support_agent/
| |-- main.py
| `-- crew.py
`-- research_flow/
|-- pyproject.toml
`-- src/
@@ -47,7 +48,7 @@ AMP는 여전히 전체 저장소를 가져오거나 업로드하지만, 선택
작업 디렉터리가 설정되면 AMP는 해당 폴더를 다음 용도로 사용합니다:
- `pyproject.toml`, JSON crew 파일, 클래식 Crew 또는 Flow 진입점을 포함한 프로젝트 검증
- `pyproject.toml`, `src/`, Crew 또는 Flow 진입점을 포함한 프로젝트 검증
- `uv`를 사용한 종속성 설치
- 실행 중인 프로세스의 작업 디렉터리
- `CREW_ROOT_DIR` 환경 변수

View File

@@ -24,7 +24,7 @@ CrewAI AMP에서 **자동화(automations)**는 배포 가능한 Agentic AI 프
<CardGroup cols={2}>
<Card title="Crew 프로젝트" icon="users">
독립 실행형 AI 에이전트 팀입니다. 새 crew는 `crew.jsonc`와 `agents/`를 사용하는 JSON-first 구조이며, 클래식 crew는 계속 `crew.py`를 사용할 수 있습니다.
에이전트와 작업을 정의하는 `crew.py`가 있는 독립 실행형 AI 에이전트 팀. 집중적이고 협업적인 작업에 적합합니다.
</Card>
<Card title="Flow 프로젝트" icon="diagram-project">
`crews/` 폴더에 포함된 crew가 있는 오케스트레이션된 워크플로우. 복잡한 다단계 프로세스에 적합합니다.
@@ -33,19 +33,19 @@ CrewAI AMP에서 **자동화(automations)**는 배포 가능한 Agentic AI 프
| 측면 | Crew | Flow |
|------|------|------|
| **프로젝트 구조** | 프로젝트 루트의 `crew.jsonc`와 `agents/` | `crews/` 폴더가 있는 `src/project_name/` |
| **메인 로직 위치** | `crew.jsonc` (클래식: `src/project_name/crew.py`) | `src/project_name/main.py` (Flow 클래스) |
| **진입점 함수** | `crew.jsonc`에서 로드됨 (클래식: `main.py`의 `run()`) | `main.py`의 `kickoff()` |
| **프로젝트 구조** | `crew.py`가 있는 `src/project_name/` | `crews/` 폴더가 있는 `src/project_name/` |
| **메인 로직 위치** | `src/project_name/crew.py` | `src/project_name/main.py` (Flow 클래스) |
| **진입점 함수** | `main.py`의 `run()` | `main.py`의 `kickoff()` |
| **pyproject.toml 타입** | `type = "crew"` | `type = "flow"` |
| **CLI 생성 명령어** | `crewai create crew name` | `crewai create flow name` |
| **설정 위치** | `crew.jsonc`, `agents/`, 선택적 `tools/` | `src/project_name/crews/crew_name/config/` 또는 포함된 JSON crew 폴더 |
| **설정 위치** | `src/project_name/config/` | `src/project_name/crews/crew_name/config/` |
| **다른 crew 포함 가능** | 아니오 | 예 (`crews/` 폴더 내) |
## 프로젝트 구조 참조
### Crew 프로젝트 구조
`crewai create crew my_crew`를 실행하면 JSON-first 구조를 얻습니다:
`crewai create crew my_crew`를 실행하면 다음 구조를 얻습니다:
```
my_crew/
@@ -54,25 +54,24 @@ my_crew/
├── README.md
├── .env
├── uv.lock # 배포에 필수
── crew.jsonc # Crew 설정, 태스크, 프로세스, 입력
├── agents/
└── researcher.jsonc # 에이전트 정의
├── tools/ # 선택적 custom:<name> 도구
├── knowledge/
└── skills/
── src/
└── my_crew/
├── __init__.py
├── main.py # run() 함수가 있는 진입점
├── crew.py # @CrewBase 데코레이터가 있는 Crew 클래스
├── tools/
│ ├── custom_tool.py
│ └── __init__.py
└── config/
├── agents.yaml # 에이전트 정의
└── tasks.yaml # 작업 정의
```
<Warning>
JSON-first crew에서는 `crew.jsonc`, `agents/`, `tools/`, `knowledge/`, `skills/`를
프로젝트 루트에 두세요. 이를 `src/` 아래에 두면 `crewai run`과 배포 검증이 crew 정의를 찾지 못합니다.
중첩된 `src/project_name/` 구조는 Crews에 매우 중요합니다.
잘못된 레벨에 파일을 배치하면 배포 실패의 원인이 됩니다.
</Warning>
<Info>
`crewai create crew my_crew --classic`으로 만든 클래식 프로젝트는 기존
`src/project_name/crew.py`, `src/project_name/config/agents.yaml`,
`src/project_name/config/tasks.yaml` 구조를 사용합니다. 이 구조는 decorator 기반 Python crew를 위해 계속 지원됩니다.
</Info>
### Flow 프로젝트 구조
`crewai create flow my_flow`를 실행하면 다음 구조를 얻습니다:
@@ -101,9 +100,9 @@ my_flow/
```
<Info>
JSON-first 독립 실행형 crew는 프로젝트 루트의 JSON 파일을 사용합니다.
Flow는 여전히 `src/project_name/`을 사용하며, 클래식 포함 crew나
`crewai.project.load_crew`로 로드하는 포함 JSON crew 폴더를 둘 수 있습니다.
Crews와 Flows 모두 `src/project_name/` 구조를 사용합니다.
핵심 차이점은 Flows포함된 crews를 위한 `crews/` 폴더가 있고,
Crews는 프로젝트 폴더에 직접 `crew.py`가 있다는 것입니다.
</Info>
## 배포 전 체크리스트
@@ -155,88 +154,60 @@ git commit -m "Add uv.lock for deployment"
git push
```
### 3. Crew 정의 검증
### 3. CrewBase 데코레이터 사용 확인
<Tabs>
<Tab title="JSON-first Crews">
JSON-first crew는 프로젝트 루트에 `crew.jsonc` 또는 `crew.json` 파일이 있어야 합니다.
`agents` 배열은 `agents/` 안의 파일을 참조해야 하며, 각 task는 유효한 agent 이름을 참조해야 합니다.
**모든 crew 클래스는 `@CrewBase` 데코레이터를 사용해야 합니다.** 이것은 다음에 적용됩니다:
```jsonc crew.jsonc
{
"name": "Research Crew",
"agents": ["researcher"],
"tasks": [
{
"name": "research_task",
"description": "Research {topic}.",
"expected_output": "A concise report.",
"agent": "researcher"
}
],
"inputs": {
"topic": "AI Agents"
}
}
```
- 독립 실행형 crew 프로젝트
- Flow 프로젝트 내에 포함된 crews
커스텀 도구는 `"custom:<name>"`으로 참조하며, `tools/<name>.py`에 `BaseTool` 서브클래스로 구현해야 합니다.
</Tab>
<Tab title="클래식 Python/YAML Crews">
클래식 crew와 Flow 안에 포함된 Python crew는 `@CrewBase` 데코레이터를 사용해야 합니다.
```python
from crewai import Agent, Crew, Process, Task
from crewai.project import CrewBase, agent, crew, task
from crewai.agents.agent_builder.base_agent import BaseAgent
from typing import List
```python
from crewai import Agent, Crew, Process, Task
from crewai.project import CrewBase, agent, crew, task
from crewai.agents.agent_builder.base_agent import BaseAgent
from typing import List
@CrewBase # 이 데코레이터는 필수입니다
class MyCrew():
"""내 crew 설명"""
@CrewBase
class MyCrew():
"""내 crew 설명"""
agents: List[BaseAgent]
tasks: List[Task]
agents: List[BaseAgent]
tasks: List[Task]
@agent
def my_agent(self) -> Agent:
return Agent(
config=self.agents_config['my_agent'], # type: ignore[index]
verbose=True
)
@agent
def my_agent(self) -> Agent:
return Agent(
config=self.agents_config['my_agent'], # type: ignore[index]
verbose=True
)
@task
def my_task(self) -> Task:
return Task(
config=self.tasks_config['my_task'] # type: ignore[index]
)
@task
def my_task(self) -> Task:
return Task(
config=self.tasks_config['my_task'] # type: ignore[index]
)
@crew
def crew(self) -> Crew:
return Crew(
agents=self.agents,
tasks=self.tasks,
process=Process.sequential,
verbose=True,
)
```
@crew
def crew(self) -> Crew:
return Crew(
agents=self.agents,
tasks=self.tasks,
process=Process.sequential,
verbose=True,
)
```
</Tab>
</Tabs>
<Warning>
`@CrewBase` 데코레이터를 잊으면 에이전트나 작업 구성이 누락되었다는
오류와 함께 배포가 실패합니다.
</Warning>
### 4. 프로젝트 진입점 확인
JSON-first 독립 실행형 crew는 직접 작성한 `src/project_name/main.py`가 필요하지 않습니다.
`crewai run`과 배포 패키징이 `crew.jsonc`를 직접 로드합니다. 클래식 crew와 Flow는 Python 진입점을 사용합니다:
Crews와 Flows 모두 `src/project_name/main.py`에 진입점이 있습니다:
<Tabs>
<Tab title="JSON-first Crews">
프로젝트 루트에서 로컬 실행합니다:
```bash
crewai run
```
</Tab>
<Tab title="클래식 Crews">
<Tab title="Crews의 경우">
진입점은 `run()` 함수를 사용합니다:
```python
@@ -307,17 +278,16 @@ grep -A2 "\[tool.crewai\]" pyproject.toml
# 2. uv.lock 존재 확인
ls -la uv.lock || echo "오류: uv.lock이 없습니다! 'uv lock'을 실행하세요"
# 3. JSON-first crew의 경우 crew.jsonc와 agents/ 확인
([ -f crew.jsonc ] || [ -f crew.json ]) || echo "crew.jsonc 또는 crew.json을 찾을 수 없습니다"
test -d agents || echo "agents/ 디렉터리를 찾을 수 없습니다"
# 3. src/ 구조 존재 확인
ls -la src/*/main.py 2>/dev/null || echo "src/에서 main.py를 찾을 수 없습니다"
# 4. 클래식 Crews의 경우 - crew.py 존재 확인
# 4. Crews의 경우 - crew.py 존재 확인
ls -la src/*/crew.py 2>/dev/null || echo "crew.py가 없습니다 (Crews에서 예상됨)"
# 5. Flows의 경우 - crews/ 폴더 존재 확인
ls -la src/*/crews/ 2>/dev/null || echo "crews/ 폴더가 없습니다 (Flows에서 예상됨)"
# 6. 클래식 Python crews의 경우 - CrewBase 사용 확인
# 6. CrewBase 사용 확인
grep -r "@CrewBase" . --include="*.py"
```
@@ -327,9 +297,8 @@ grep -r "@CrewBase" . --include="*.py"
|------|------|----------|
| `uv.lock` 누락 | 의존성 해결 중 빌드 실패 | `uv lock` 실행 후 커밋 |
| pyproject.toml의 잘못된 `type` | 빌드 성공하지만 런타임 실패 | 올바른 타입으로 변경 |
| JSON-first crew에서 `crew.jsonc` 또는 `agents/` 누락 | Crew 정의를 찾을 수 없음 | `crew.jsonc`와 `agents/`를 프로젝트 루트에 둠 |
| 클래식 crew에서 `@CrewBase` 데코레이터 누락 | "Config not found" 오류 | 모든 클래식 crew 클래스에 데코레이터 추가 |
| 클래식 파일을 `src/` 대신 루트에 배치 | 진입점을 찾을 수 없음 | 클래식 Python 파일을 `src/project_name/`으로 이동 |
| `@CrewBase` 데코레이터 누락 | "Config not found" 오류 | 모든 crew 클래스에 데코레이터 추가 |
| `src/` 대신 루트에 파일 배치 | 진입점을 찾을 수 없음 | `src/project_name/`으로 이동 |
| `run()` 또는 `kickoff()` 누락 | 자동화를 시작할 수 없음 | 올바른 진입 함수 추가 |
## 다음 단계

View File

@@ -43,7 +43,7 @@ CrewAI는 AI 네이티브입니다. 이 페이지는 Claude Code, Codex, Cursor,
| 스킬 | 실행 시점 |
|------|-------------|
| `getting-started` | 새 프로젝트 스캐폴딩, `LLM.call()` / `Agent` / `Crew` / `Flow` 선택, `crew.jsonc` / `main.py` 연결 |
| `getting-started` | 새 프로젝트 스캐폴딩, `LLM.call()` / `Agent` / `Crew` / `Flow` 선택, `crew.py` / `main.py` 연결 |
| `design-agent` | 에이전트 구성 — 역할, 목표, 배경 이야기, 도구, LLM, 메모리, 가드레일 |
| `design-task` | 태스크 설명, 의존성, 구조화된 출력(`output_pydantic`, `output_json`), 사람 검토 |
| `ask-docs` | 최신 API 정보를 위해 [CrewAI 문서 MCP 서버](https://docs.crewai.com/mcp) 조회 |

View File

@@ -1,140 +1,392 @@
---
title: 첫 번째 Crew 만들기
description: JSON-first crew 설정으로 협업 AI 팀을 만드는 단계별 튜토리얼입니다.
title: 첫 번째 크루 만들기
description: 복잡한 문제를 함께 해결할 수 있는 협업 AI 팀을 만드는 단계별 튜토리얼입니다.
icon: users-gear
mode: "wide"
---
## 리서치 Crew 만들
## 협업 AI의 힘을 발휘하
이 가이드에서는 두 에이전트가 주제를 조사하고 markdown 보고서를 작성하는 crew를 만듭니다. 새 crew 프로젝트는 JSON-first입니다. 에이전트는 `agents/*.jsonc`, 태스크와 crew 설정은 `crew.jsonc`에 두며, `crewai run`이 이 정의를 직접 로드합니다.
여러 AI 에이전트가 각자의 전문성을 바탕으로 원활하게 협력하며 복잡한 문제를 해결한다고 상상해 보세요. 각자 고유한 기술을 발휘해 공동의 목표를 달성합니다. 이것이 바로 CrewAI의 힘입니다. CrewAI 프레임워크를 통해 단일 AI로는 달성할 수 없는 과업을 협업 AI 시스템으로 실현할 수 있습니다.
### 준비 사항
이 가이드에서는 연구 크루를 만들어 주제를 조사 및 분석하고, 종합적인 보고서를 작성하는 과정을 안내합니다. 이 실용적인 예시는 AI 에이전트들이 어떻게 협력하여 복잡한 작업을 수행할 수 있는지 보여 주지만, CrewAI로 실현할 수 있는 가능성의 시작에 불과합니다.
1. [설치 가이드](/ko/installation)에 따라 CrewAI 설치
2. [LLM 설정](/ko/concepts/llms#setting-up-your-llm)에 따라 모델 API 키 설정
3. 웹 검색을 사용할 경우 [Serper.dev](https://serper.dev/) API 키 준비
### 무엇을 만들고 배우게 될까요
## 1단계: 새 Crew 만들기
이 가이드를 마치면 다음을 할 수 있게 됩니다:
1. **특화된 AI 연구팀 조직**: 각기 다른 역할과 책임을 가진 연구팀을 만듭니다
2. **여러 AI 에이전트 간의 협업 조율**
3. **정보 수집, 분석, 보고서 생성을 포함한 복잡한 workflow 자동화**
4. **더 야심찬 프로젝트에도 적용할 수 있는 기초 역량 구축**
이 가이드에서는 간단한 research crew를 만들지만, 동일한 패턴과 기법을 활용하여 다음과 같은 훨씬 더 정교한 팀도 만들 수 있습니다:
- 전문 writer, editor, fact-checker가 참여하는 다단계 콘텐츠 생성
- 단계별 지원 에이전트가 있는 복잡한 고객 서비스 시스템
- 데이터 수집, 시각화, 인사이트 생성까지 하는 자율 business analyst
- 아이디어 구상, 디자인, 구현 계획까지 진행하는 product development 팀
이제 여러분의 첫 crew를 만들어 봅시다!
### 필수 조건
시작하기 전에 다음을 확인하세요:
1. [설치 가이드](/ko/installation)를 참고하여 CrewAI를 설치했는지 확인하세요.
2. [LLM 설정 가이드](/ko/concepts/llms#setting-up-your-llm)를 참고하여 환경에 LLM API 키를 설정했는지 확인하세요.
3. Python에 대한 기본적인 이해
## 1단계: 새로운 CrewAI 프로젝트 생성
먼저, CLI를 사용하여 새로운 CrewAI 프로젝트를 생성해봅시다. 이 명령어는 필요한 모든 파일을 포함한 전체 프로젝트 구조를 설정해 주어, 보일러플레이트 코드를 설정하는 대신 에이전트와 그들의 작업 정의에 집중할 수 있습니다.
```bash
crewai create crew research_crew
cd research_crew
```
생성되는 구조:
이렇게 하면 crew에 필요한 기본 구조를 갖춘 프로젝트가 생성됩니다. CLI는 다음을 자동으로 생성합니다:
```text
- 필요한 파일이 포함된 프로젝트 디렉터리
- 에이전트와 작업에 대한 구성 파일
- 기본 crew 구현
- crew를 실행하는 메인 스크립트
<Frame caption="CrewAI 프레임워크 개요">
<img src="/images/crews.png" alt="CrewAI Framework Overview" />
</Frame>
## 2단계: 프로젝트 구조 살펴보기
CLI가 생성한 프로젝트 구조를 이해하는 시간을 가져봅시다. CrewAI는 Python 프로젝트의 모범 사례를 따르므로, crew가 더 복잡해질수록 코드를 쉽게 유지 관리하고 확장할 수 있습니다.
```
research_crew/
├── .gitignore
├── .env
├── agents/
│ └── researcher.jsonc
├── crew.jsonc
├── knowledge/
├── pyproject.toml
├── README.md
├── skills/
└── tools/
├── .env
└── src/
└── research_crew/
├── __init__.py
├── main.py
├── crew.py
├── tools/
│ ├── custom_tool.py
│ └── __init__.py
└── config/
├── agents.yaml
└── tasks.yaml
```
<Tip>
`crew.py`, `config/agents.yaml`, `config/tasks.yaml`을 쓰는 기존 레이아웃이 필요하면 `crewai create crew research_crew --classic`을 사용하세요.
</Tip>
이 구조는 Python 프로젝트의 모범 사례를 따르며, 코드를 체계적으로 구성할 수 있도록 해줍니다. 설정 파일(YAML)과 구현 코드(Python)의 분리로 인해, 기본 코드를 변경하지 않고도 crew의 동작을 쉽게 수정할 수 있습니다.
## 2단계: 에이전트 정의
## 3단계: 에이전트 구성하기
생성된 `agents/researcher.jsonc` 파일을 교체하고 `agents/analyst.jsonc`를 추가합니다. 파일 이름이 `crew.jsonc`에서 참조하는 에이전트 이름입니다.
이제 재미있는 단계가 시작됩니다 - 여러분의 AI 에이전트를 정의하는 것입니다! CrewAI에서 에이전트는 특정 역할, 목표 및 배경을 가진 전문화된 엔터티로, 이들이 어떻게 행동할지를 결정합니다. 각각 고유한 성격과 목적을 지닌 연극의 등장인물로 생각하면 됩니다.
```jsonc agents/researcher.jsonc
{
"role": "Senior Research Specialist for {topic}",
"goal": "Find comprehensive and accurate information about {topic}, with a focus on recent developments and key insights.",
"backstory": "You are an experienced research specialist who organizes complex information into clear, useful notes.",
// 사용하는 모델로 바꾸세요. 예: "openai/gpt-4o".
"llm": "provider/model-id",
"tools": ["SerperDevTool"],
"settings": {
"verbose": true,
"allow_delegation": false
}
}
우리의 리서치 crew를 위해 두 명의 에이전트를 만들겠습니다:
1. 정보를 찾아 정리하는 데 뛰어난 **리서처**
2. 연구 결과를 해석하고 통찰력 있는 보고서를 작성할 수 있는 **애널리스트**
이러한 전문화된 에이전트를 정의하기 위해 `agents.yaml` 파일을 수정해봅시다. `llm` 항목은 사용 중인 제공업체에 맞게 설정하세요.
```yaml
# src/research_crew/config/agents.yaml
researcher:
role: >
Senior Research Specialist for {topic}
goal: >
Find comprehensive and accurate information about {topic}
with a focus on recent developments and key insights
backstory: >
You are an experienced research specialist with a talent for
finding relevant information from various sources. You excel at
organizing information in a clear and structured manner, making
complex topics accessible to others.
llm: provider/model-id # e.g. openai/gpt-4o, google/gemini-2.0-flash, anthropic/claude...
analyst:
role: >
Data Analyst and Report Writer for {topic}
goal: >
Analyze research findings and create a comprehensive, well-structured
report that presents insights in a clear and engaging way
backstory: >
You are a skilled analyst with a background in data interpretation
and technical writing. You have a talent for identifying patterns
and extracting meaningful insights from research data, then
communicating those insights effectively through well-crafted reports.
llm: provider/model-id # e.g. openai/gpt-4o, google/gemini-2.0-flash, anthropic/claude...
```
```jsonc agents/analyst.jsonc
{
"role": "Report Analyst for {topic}",
"goal": "Turn research findings into a clear, well-structured report.",
"backstory": "You are a careful analyst with strong technical writing skills and a talent for extracting useful insights.",
// 사용하는 모델로 바꾸세요. 예: "openai/gpt-4o".
"llm": "provider/model-id",
"settings": {
"verbose": true,
"allow_delegation": false
}
}
각 에이전트가 고유한 역할, 목표, 그리고 배경을 가지고 있다는 점에 주목하세요. 이 요소들은 단순한 설명 그 이상으로, 실제로 에이전트가 자신의 과업을 어떻게 접근하는지에 적극적으로 영향을 미칩니다. 이러한 부분을 신중하게 설계함으로써 서로 보완하는 전문적인 역량과 관점을 가진 에이전트를 만들 수 있습니다.
## 4단계: 작업 정의하기
이제 agent들을 정의했으니, 이들에게 수행할 구체적인 작업을 지정해야 합니다. CrewAI의 작업(task)은 agent가 수행할 구체적인 업무를 나타내며, 자세한 지침과 예상 결과물이 포함됩니다.
연구 crew를 위해 두 가지 주요 작업을 정의하겠습니다:
1. 포괄적인 정보 수집을 위한 **연구 작업**
2. 인사이트 있는 보고서 생성을 위한 **분석 작업**
`tasks.yaml` 파일을 다음과 같이 수정해 보겠습니다:
```yaml
# src/research_crew/config/tasks.yaml
research_task:
description: >
{topic}에 대해 철저한 연구를 수행하세요. 다음에 중점을 두세요:
1. 주요 개념 및 정의
2. 역사적 발전과 최근 동향
3. 주요 과제와 기회
4. 주목할 만한 적용 사례 또는 케이스 스터디
5. 향후 전망과 잠재적 발전
반드시 명확한 섹션으로 구성된 구조화된 형식으로 결과를 정리하세요.
expected_output: >
{topic}의 모든 요구 사항을 다루는, 잘 구성된 섹션이 포함된 포괄적인 연구 문서.
필요에 따라 구체적인 사실, 수치, 예시를 포함하세요.
agent: researcher
analysis_task:
description: >
연구 결과를 분석하고 {topic}에 대한 포괄적인 보고서를 작성하세요.
보고서에는 다음 내용이 포함되어야 합니다:
1. 간결한 요약(executive summary)으로 시작
2. 연구의 모든 주요 정보 포함
3. 동향과 패턴에 대한 통찰력 있는 분석 제공
4. 추천사항 또는 미래 고려 사항 제시
5. 명확한 제목과 함께 전문적이고 읽기 쉬운 형식으로 작성
expected_output: >
연구 결과와 추가 분석, 인사이트를 포함한 {topic}에 대한 정제되고 전문적인 보고서.
보고서는 간결한 요약, 본문, 결론 등으로 잘 구조화되어 있어야 합니다.
agent: analyst
context:
- research_task
output_file: output/report.md
```
`provider/model-id`를 `openai/gpt-4o`, `anthropic/claude-sonnet-4-6`, `gemini/gemini-2.0-flash-001` 같은 모델로 바꾸세요.
분석 작업 내의 `context` 필드에 주목하세요. 이 강력한 기능을 통해 analyst가 연구 작업의 결과물을 참조할 수 있습니다. 이를 통해 정보가 human team에서처럼 agent 간에 자연스럽게 흐르는 워크플로우가 만들어집니다.
## 3단계: 태스크와 Crew 설정
## 5단계: 크루 구성 설정하기
`crew.jsonc`를 다음으로 교체합니다:
이제 크루를 구성하여 모든 것을 하나로 모을 시간입니다. 크루는 에이전트들이 함께 작업을 완료하는 방식을 조율하는 컨테이너 역할을 합니다.
```jsonc crew.jsonc
{
"name": "Research Crew",
"agents": ["researcher", "analyst"],
"tasks": [
{
"name": "research_task",
"description": "Conduct thorough research on {topic}. Focus on key concepts, recent developments, major challenges, notable applications, and future outlook.",
"expected_output": "A comprehensive research document with organized sections, specific facts, and useful examples about {topic}.",
"agent": "researcher"
},
{
"name": "analysis_task",
"description": "Analyze the research findings and create a polished report on {topic}. Include an executive summary, key insights, trend analysis, and recommendations.",
"expected_output": "A professional markdown report with clear headings, a concise summary, main findings, and recommendations.",
"agent": "analyst",
"context": ["research_task"],
"output_file": "output/report.md",
"markdown": true
`crew.py` 파일을 다음과 같이 수정해보겠습니다:
```python
# src/research_crew/crew.py
from crewai import Agent, Crew, Process, Task
from crewai.project import CrewBase, agent, crew, task
from crewai_tools import SerperDevTool
from crewai.agents.agent_builder.base_agent import BaseAgent
from typing import List
@CrewBase
class ResearchCrew():
"""Research crew for comprehensive topic analysis and reporting"""
agents: List[BaseAgent]
tasks: List[Task]
@agent
def researcher(self) -> Agent:
return Agent(
config=self.agents_config['researcher'], # type: ignore[index]
verbose=True,
tools=[SerperDevTool()]
)
@agent
def analyst(self) -> Agent:
return Agent(
config=self.agents_config['analyst'], # type: ignore[index]
verbose=True
)
@task
def research_task(self) -> Task:
return Task(
config=self.tasks_config['research_task'] # type: ignore[index]
)
@task
def analysis_task(self) -> Task:
return Task(
config=self.tasks_config['analysis_task'], # type: ignore[index]
output_file='output/report.md'
)
@crew
def crew(self) -> Crew:
"""Creates the research crew"""
return Crew(
agents=self.agents,
tasks=self.tasks,
process=Process.sequential,
verbose=True,
)
```
이 코드에서는 다음을 수행합니다:
1. researcher 에이전트를 생성하고, SerperDevTool을 장착하여 웹 검색 기능을 추가합니다.
2. analyst 에이전트를 생성합니다.
3. research와 analysis 작업(task)을 설정합니다.
4. 크루가 작업을 순차적으로 수행하도록 설정합니다(analyst가 researcher가 끝날 때까지 대기).
여기서 마법이 일어납니다. 몇 줄의 코드만으로도, 특화된 에이전트들이 조율된 프로세스 내에서 협업하는 협동 AI 시스템을 정의할 수 있습니다.
## 6단계: 메인 스크립트 설정
이제 우리 crew를 실행할 메인 스크립트를 설정해 보겠습니다. 이곳에서 crew가 리서치할 구체적인 주제를 지정합니다.
```python
#!/usr/bin/env python
# src/research_crew/main.py
import os
from research_crew.crew import ResearchCrew
# Create output directory if it doesn't exist
os.makedirs('output', exist_ok=True)
def run():
"""
Run the research crew.
"""
inputs = {
'topic': 'Artificial Intelligence in Healthcare'
}
],
"process": "sequential",
"verbose": true,
"memory": true,
"inputs": {
"topic": "Artificial Intelligence in Healthcare"
}
}
# Create and run the crew
result = ResearchCrew().crew().kickoff(inputs=inputs)
# Print the result
print("\n\n=== FINAL REPORT ===\n\n")
print(result.raw)
print("\n\nReport has been saved to output/report.md")
if __name__ == "__main__":
run()
```
`context`는 이전 태스크 이름을 가리키므로 analyst가 research 태스크 출력을 받습니다. `inputs`는 `{topic}`의 기본값을 제공합니다. 기본값이 없으면 `crewai run`이 실행 중에 물어봅니다.
이 스크립트는 환경을 준비하고, 리서치 주제를 지정하며, crew의 작업을 시작합니다. CrewAI의 강력함은 이 코드가 얼마나 간단한지에서 드러납니다. 여러 AI 에이전트를 관리하는 모든 복잡함이 프레임워크에 의해 처리됩니다.
## 4단계: 환경 변수 설정
## 7단계: 환경 변수 설정하기
`.env`를 편집합니다:
프로젝트 루트에 `.env` 파일을 생성하고 API 키를 입력하세요:
```sh
SERPER_API_KEY=your_serper_api_key
# 모델 제공자 API 키도 추가하세요.
# Add your provider's API key here too.
```
## 5단계: 설치 및 실행
선택한 provider를 구성하는 방법에 대한 자세한 내용은 [LLM 설정 가이드](/ko/concepts/llms#setting-up-your-llm)를 참고하세요. Serper API 키는 [Serper.dev](https://serper.dev/)에서 받을 수 있습니다.
## 8단계: 필수 종속성 설치
CrewAI CLI를 사용하여 필요한 종속성을 설치하세요:
```bash
crewai install
```
이 명령어는 다음을 수행합니다:
1. 프로젝트 구성에서 종속성을 읽어옵니다
2. 필요하다면 가상 환경을 생성합니다
3. 모든 필수 패키지를 설치합니다
## 9단계: Crew 실행하기
이제 흥미로운 순간입니다 - crew를 실행하여 AI 협업이 어떻게 이루어지는지 직접 확인해보세요!
```bash
crewai run
```
실행이 끝나면 `output/report.md`를 확인하세요.
이 명령어를 실행하면 crew가 즉시 작동하는 모습을 볼 수 있습니다. researcher는 지정된 주제에 대한 정보를 수집하고, analyst가 그 연구를 바탕으로 종합 보고서를 작성합니다. 에이전트들의 사고 과정, 행동, 결과물이 실시간으로 표시되며 서로 협력하여 작업을 완수하는 모습을 확인할 수 있습니다.
<Warning>
신뢰하는 출처의 JSON crew 프로젝트만 실행하세요. `custom:<name>` 도구와 `{"python": "module.attribute"}` 참조는 crew 로드 시 로컬 Python 코드를 실행합니다.
</Warning>
## 10단계: 결과물 검토
crew가 작업을 완료하면, 최종 보고서는 `output/report.md` 파일에서 확인할 수 있습니다. 보고서에는 다음과 같은 내용이 포함됩니다:
1. 요약 보고서
2. 주제에 대한 상세 정보
3. 분석 및 인사이트
4. 권장사항 또는 향후 고려사항
지금까지 달성한 것을 잠시 돌아보세요. 여러분은 여러 AI 에이전트가 협업하여 각자의 전문적인 기술을 발휘함으로써, 단일 에이전트가 혼자서 이루어낼 수 있는 것보다 더 뛰어난 결과를 만들어내는 시스템을 구축한 것입니다.
## 기타 CLI 명령어 탐색
CrewAI는 crew 작업을 위한 몇 가지 유용한 CLI 명령어를 추가로 제공합니다:
```bash
# 모든 사용 가능한 명령어 보기
crewai --help
# crew 실행
crewai run
# crew 테스트
crewai test
# crew 메모리 초기화
crewai reset-memories
# 특정 task에서 재실행
crewai replay -t <task_id>
```
## 가능한 것의 예술: 당신의 첫 crew를 넘어서
이 가이드에서 구축한 것은 시작에 불과합니다. 여러분이 배운 기술과 패턴은 점점 더 정교한 AI 시스템을 만드는 데 적용할 수 있습니다. 다음은 이 기본 research crew를 확장할 수 있는 몇 가지 방법입니다:
### 팀원 확장하기
더 전문화된 에이전트를 팀원으로 추가할 수 있습니다:
- 연구 결과를 검증하는 **팩트체커**
- 차트와 그래프를 만드는 **데이터 시각화 담당자**
- 특정 분야에 전문 지식을 가진 **도메인 전문가**
- 분석의 약점을 파악하는 **비평가**
### 도구 및 기능 추가
에이전트에 추가 도구를 통해 기능을 확장할 수 있습니다:
- 실시간 연구를 위한 웹 브라우징 도구
- 데이터 분석을 위한 CSV/데이터베이스 도구
- 데이터 처리를 위한 코드 실행 도구
- 외부 서비스와의 API 연결
### 더 복잡한 워크플로우 생성
더 정교한 프로세스를 구현할 수 있습니다:
- 매니저 에이전트가 워커 에이전트에게 위임하는 계층적 프로세스
- 반복적 피드백 루프로 정제하는 반복 프로세스
- 여러 에이전트가 동시에 작업하는 병렬 프로세스
- 중간 결과에 따라 적응하는 동적 프로세스
### 다양한 도메인에 적용하기
동일한 패턴은 다음과 같은 분야에서 crew를 구성하는 데 적용할 수 있습니다:
- **콘텐츠 제작**: 작가, 에디터, 팩트체커, 디자이너가 함께 협업
- **고객 서비스**: 분류 담당자, 전문가, 품질 관리자가 함께 협업
- **제품 개발**: 연구원, 디자이너, 기획자가 협업
- **데이터 분석**: 데이터 수집가, 분석가, 시각화 전문가
## 다음 단계
이제 첫 crew를 구축했으니, 다음과 같은 작업을 시도해 볼 수 있습니다:
1. 다양한 에이전트 구성 및 성격을 실험해 보세요
2. 더 복잡한 작업 구조와 워크플로우를 시도해 보세요
3. 맞춤 도구를 구현하여 에이전트에게 새로운 기능을 제공하세요
4. crew를 다양한 주제나 문제 도메인에 적용해 보세요
5. [CrewAI Flows](/ko/guides/flows/first-flow)를 탐색하여 절차적 프로그래밍을 활용한 더 고급 워크플로우를 경험해 보세요
<Check>
주제를 조사하고 보고서를 작성하는 JSON-first crew를 만들었습니다.
</Check>
축하합니다! 이제 주어진 모든 주제를 조사하고 분석할 수 있는 첫 번째 CrewAI crew를 성공적으로 구축하셨습니다. 이 기본적인 경험은 협업 인텔리전스를 통해 복잡하고 다단계의 문제를 해결할 수 있는 점점 더 정교한 AI 시스템을 제작하는 데 필요한 역량을 갖추는 데 도움이 됩니다.
</Check>

View File

@@ -64,7 +64,7 @@ cd guide_creator_flow
## 2단계: 프로젝트 구조 이해하기
생성된 프로젝트는 다음과 같은 구조를 가지고 있습니다. 시작용 embedded crew는 클래식 Python/YAML 레이아웃을 사용합니다. Flow 안에서 JSON-first crew를 사용하려면 crew 폴더에 `crew.jsonc`와 `agents/*.jsonc`를 만들고 `crewai.project.load_crew`로 로드하세요. 예시는 [Flows](/ko/concepts/flows#building-your-crews)를 참고하세요.
생성된 프로젝트는 다음과 같은 구조를 가지고 있습니다. 잠시 시간을 내어 이 구조에 익숙해지세요. 구조를 이해하면 앞으로 더 복잡한 flow를 만드는 데 도움이 됩니다.
```
guide_creator_flow/
@@ -102,82 +102,149 @@ crewai flow add-crew content-crew
## 4단계: 콘텐츠 작가 Crew 구성
이제 콘텐츠 작가 crew를 JSONC로 구성합니다. 가이드의 고품질 콘텐츠를 만들기 위해 협업하는 두 명의 전문 에이전트 - 작가와 리뷰어 - 를 설정니다.
이제 콘텐츠 작가 crew를 위해 생성된 파일을 수정해보겠습니다. 우리는 가이드의 고품질 콘텐츠를 만들기 위해 협업하는 두 명의 전문 에이전트 - 작가와 리뷰어 - 를 설정할 것입니다.
1. `src/guide_creator_flow/crews/content_crew/agents/content_writer.jsonc`를 만듭니다:
1. 먼저, 에이전트 구성 파일을 업데이트하여 콘텐츠 제작 팀을 정의합니다:
```jsonc
{
"role": "Educational Content Writer",
"goal": "Create engaging, informative content that thoroughly explains the assigned topic and provides valuable insights to the reader.",
"backstory": "You are a talented educational writer who explains complex concepts in accessible language and organizes information clearly.",
"llm": "provider/model-id",
"settings": {
"verbose": true
}
}
`llm`을 사용 중인 공급자로 설정해야 함을 기억하세요.
```yaml
# src/guide_creator_flow/crews/content_crew/config/agents.yaml
content_writer:
role: >
교육 콘텐츠 작가
goal: >
할당된 주제를 철저히 설명하고 독자에게 소중한 통찰력을 제공하는 흥미롭고 유익한 콘텐츠를 제작합니다
backstory: >
당신은 명확하고 흥미로운 콘텐츠를 만드는 데 능숙한 교육 전문 작가입니다. 복잡한 개념도 쉽게 설명하며,
정보를 독자가 이해하기 쉽게 조직할 수 있습니다.
llm: provider/model-id # 예: openai/gpt-4o, google/gemini-2.0-flash, anthropic/claude...
content_reviewer:
role: >
교육 콘텐츠 검토자 및 에디터
goal: >
콘텐츠가 정확하고, 포괄적이며, 잘 구조화되어 있고, 이전에 작성된 섹션과의 일관성을 유지하도록 합니다
backstory: >
당신은 수년간 교육 콘텐츠를 검토해 온 꼼꼼한 에디터입니다. 세부 사항, 명확성, 일관성에 뛰어나며,
원 저자의 목소리를 유지하면서도 콘텐츠의 품질을 향상시키는 데 능숙합니다.
llm: provider/model-id # 예: openai/gpt-4o, google/gemini-2.0-flash, anthropic/claude...
```
2. `src/guide_creator_flow/crews/content_crew/agents/content_reviewer.jsonc`를 만듭니다:
이 에이전트 정의는 AI 에이전트가 콘텐츠 제작을 접근하는 전문화된 역할과 관점을 구성합니다. 각 에이전트가 뚜렷한 목적과 전문성을 지니고 있음을 확인하세요.
```jsonc
{
"role": "Educational Content Reviewer and Editor",
"goal": "Ensure content is accurate, comprehensive, well-structured, and consistent with previously written sections.",
"backstory": "You are a meticulous editor with an eye for detail, clarity, and coherence.",
"llm": "provider/model-id",
"settings": {
"verbose": true
}
}
2. 다음으로, 작업 구성 파일을 업데이트하여 구체적인 작성 및 검토 작업을 정의합니다:
```yaml
# src/guide_creator_flow/crews/content_crew/config/tasks.yaml
write_section_task:
description: >
주제에 대한 포괄적인 섹션을 작성하세요: "{section_title}"
섹션 설명: {section_description}
대상 독자: {audience_level} 수준 학습자
작성 시 아래 사항을 반드시 지켜주세요:
1. 섹션 주제에 대한 간략한 소개로 시작
2. 모든 주요 개념을 예시와 함께 명확하게 설명
3. 적절하다면 실용적인 활용 사례나 연습문제 포함
4. 주요 포인트 요약으로 마무리
5. 대략 500-800단어 분량
콘텐츠는 적절한 제목, 목록, 강조를 포함해 Markdown 형식으로 작성하세요.
이전에 작성된 섹션:
{previous_sections}
반드시 콘텐츠가 이전에 쓴 섹션과 일관성을 유지하고 앞에서 설명된 개념을 바탕으로 작성되도록 하세요.
expected_output: >
주제를 철저히 설명하고 대상 독자에게 적합한, 구조가 잘 잡힌 Markdown 형식의 포괄적 섹션
agent: content_writer
review_section_task:
description: >
아래 "{section_title}" 섹션의 내용을 검토하고 개선하세요:
{draft_content}
대상 독자: {audience_level} 수준 학습자
이전에 작성된 섹션:
{previous_sections}
검토 시 아래 사항을 반드시 지켜주세요:
1. 문법/철자 오류 수정
2. 명확성 및 가독성 향상
3. 내용이 포괄적이고 정확한지 확인
4. 이전에 쓴 섹션과 일관성 유지
5. 구조와 흐름 강화
6. 누락된 핵심 정보 추가
개선된 버전의 섹션을 Markdown 형식으로 제공하세요.
expected_output: >
원래의 구조를 유지하면서도 명확성, 정확성, 일관성을 향상시킨 세련된 개선본
agent: content_reviewer
context:
- write_section_task
```
`provider/model-id`를 사용하는 모델로 바꾸세요. 예: `openai/gpt-4o`, `gemini/gemini-2.0-flash-001`, `anthropic/claude-sonnet-4-6`.
이 작업 정의는 에이전트에게 세부적인 지침을 제공하여 우리의 품질 기준에 부합하는 콘텐츠를 생산하게 합니다. review 작업의 `context` 파라미터를 통해 리뷰어가 작가의 결과물에 접근할 수 있는 워크플로우가 생성됨에 주의하세요.
3. `src/guide_creator_flow/crews/content_crew/crew.jsonc`를 만듭니다:
```jsonc
{
"name": "Content Crew",
"agents": ["content_writer", "content_reviewer"],
"tasks": [
{
"name": "write_section_task",
"description": "Write a comprehensive section on the topic: \"{section_title}\".\n\nSection description: {section_description}\nTarget audience: {audience_level} level learners\n\nYour content should begin with a brief introduction, explain key concepts clearly with examples, include practical applications where appropriate, end with a summary, and be approximately 500-800 words.\n\nPreviously written sections:\n{previous_sections}",
"expected_output": "A well-structured, comprehensive section in Markdown format that thoroughly explains the topic and is appropriate for the target audience.",
"agent": "content_writer",
"markdown": true
},
{
"name": "review_section_task",
"description": "Review and improve this section on \"{section_title}\":\n\n{draft_content}\n\nTarget audience: {audience_level} level learners\nPreviously written sections:\n{previous_sections}\n\nFix errors, improve clarity, verify consistency, enhance structure, and add missing key information.",
"expected_output": "An improved, polished version of the section that maintains the original structure but enhances clarity, accuracy, and consistency.",
"agent": "content_reviewer",
"context": ["write_section_task"],
"markdown": true
}
],
"process": "sequential",
"verbose": true
}
```
`context` 필드를 통해 리뷰어가 작가의 출력을 사용할 수 있습니다.
4. `src/guide_creator_flow/crews/content_crew/content_crew.py`를 작은 loader로 교체합니다:
3. 이제 crew 구현 파일을 업데이트하여 에이전트와 작업이 어떻게 연동되는지 정의합니다:
```python
from pathlib import Path
# src/guide_creator_flow/crews/content_crew/content_crew.py
from crewai import Agent, Crew, Process, Task
from crewai.project import CrewBase, agent, crew, task
from crewai.agents.agent_builder.base_agent import BaseAgent
from typing import List
from crewai.project import load_crew
@CrewBase
class ContentCrew():
"""Content writing crew"""
agents: List[BaseAgent]
tasks: List[Task]
def kickoff_content_crew(inputs: dict):
crew, default_inputs = load_crew(Path(__file__).with_name("crew.jsonc"))
return crew.kickoff(inputs={**default_inputs, **inputs})
@agent
def content_writer(self) -> Agent:
return Agent(
config=self.agents_config['content_writer'], # type: ignore[index]
verbose=True
)
@agent
def content_reviewer(self) -> Agent:
return Agent(
config=self.agents_config['content_reviewer'], # type: ignore[index]
verbose=True
)
@task
def write_section_task(self) -> Task:
return Task(
config=self.tasks_config['write_section_task'] # type: ignore[index]
)
@task
def review_section_task(self) -> Task:
return Task(
config=self.tasks_config['review_section_task'], # type: ignore[index]
context=[self.write_section_task()]
)
@crew
def crew(self) -> Crew:
"""Creates the content writing crew"""
return Crew(
agents=self.agents,
tasks=self.tasks,
process=Process.sequential,
verbose=True,
)
```
loader는 런타임에 `crew.jsonc`를 `Crew`로 바꿉니다. 이 crew는 독립적으로도 작동할 수 있지만, 우리의 플로우에서 더 큰 시스템의 일부로 오케스트레이션니다.
crew 정의는 에이전트와 작업 간의 관계를 설정하여, 콘텐츠 작가가 초안을 작성하고 리뷰어가 이를 개선하는 순차적 과정을 만듭니다. 이 crew는 독립적으로도 작동할 수 있지만, 우리의 플로우에서 더 큰 시스템의 일부로 오케스트레이션될 예정입니다.
## 5단계: 플로우(Flow) 생성
@@ -199,7 +266,7 @@ from typing import List, Dict
from pydantic import BaseModel, Field
from crewai import LLM
from crewai.flow.flow import Flow, listen, start
from guide_creator_flow.crews.content_crew.content_crew import kickoff_content_crew
from guide_creator_flow.crews.content_crew.content_crew import ContentCrew
# Define our models for structured data
class Section(BaseModel):
@@ -304,7 +371,7 @@ class GuideCreatorFlow(Flow[GuideCreatorState]):
previous_sections_text = "No previous sections written yet."
# Run the content crew for this section
result = kickoff_content_crew(inputs={
result = ContentCrew().crew().kickoff(inputs={
"section_title": section.title,
"section_description": section.description,
"audience_level": self.state.audience_level,
@@ -523,7 +590,7 @@ class GuideCreatorState(BaseModel):
Flow는 복잡한 협업 작업을 위해 crew와 원활하게 통합될 수 있습니다:
```python
result = kickoff_content_crew(inputs={
result = ContentCrew().crew().kickoff(inputs={
"section_title": section.title,
# ...
})
@@ -544,4 +611,4 @@ result = kickoff_content_crew(inputs={
<Check>
축하합니다! 정규 코드, 직접적인 LLM 호출, crew 기반 처리를 결합하여 포괄적인 가이드를 생성하는 첫 번째 CrewAI Flow를 성공적으로 구축하셨습니다. 이러한 기초적인 역량을 바탕으로 절차적 제어와 협업적 인텔리전스를 결합하여 복잡하고 다단계의 문제를 해결할 수 있는 점점 더 정교한 AI 애플리케이션을 만들 수 있습니다.
</Check>
</Check>

View File

@@ -106,7 +106,7 @@ CrewAI는 의존성 관리와 패키지 처리를 위해 `uv`를 사용합니다
# CrewAI 프로젝트 생성하기
`crewai create crew`는 이제 JSON-first crew 프로젝트를 생성합니다. 에이전트는 `agents/*.jsonc`에, 태스크와 crew 수준 설정은 `crew.jsonc`에 두며, `crewai run`은 이 JSON 정의를 직접 로드합니다.
에이전트 및 태스크를 정의할 때 구조적인 접근 방식을 위해 `YAML` 템플릿 스캐폴딩을 사용하는 것을 권장합니다. 다음은 시작 방법입니다:
<Steps>
<Step title="프로젝트 스캐폴딩 생성">
@@ -119,20 +119,21 @@ CrewAI는 의존성 관리와 패키지 처리를 위해 `uv`를 사용합니다
```
my_project/
├── .gitignore
├── .env
├── agents/
│ └── researcher.jsonc
├── crew.jsonc
├── knowledge/
├── pyproject.toml
├── README.md
├── skills/
└── tools/
```
- `crew.py`, `config/agents.yaml`, `config/tasks.yaml`을 사용하는 기존 Python/YAML 스캐폴드가 필요하다면 다음을 실행하세요:
```shell
crewai create crew <your_project_name> --classic
├── .env
└── src/
└── my_project/
├── __init__.py
├── main.py
├── crew.py
├── tools/
│ ├── custom_tool.py
│ └── __init__.py
└── config/
├── agents.yaml
└── tasks.yaml
```
</Step>
@@ -141,15 +142,15 @@ CrewAI는 의존성 관리와 패키지 처리를 위해 `uv`를 사용합니다
- 프로젝트에는 다음과 같은 주요 파일들이 포함되어 있습니다:
| 파일 | 용도 |
| --- | --- |
| `crew.jsonc` | crew, 태스크 순서, 프로세스, 기본 입력값 설정 |
| `agents/*.jsonc` | 에이전트의 역할, 목표, backstory, LLM, 도구, 동작 정의 |
| `agents.yaml` | AI 에이전트 및 역할 정의 |
| `tasks.yaml` | 에이전트 태스크 및 워크플로우 설정 |
| `.env` | API 키 및 환경 변수 저장 |
| `tools/` | `custom:<name>` 도구를 위한 선택적 Python 파일 |
| `knowledge/` | 에이전트용 선택적 지식 파일 |
| `skills/` | crew에 적용할 선택적 skill 파일 |
| `main.py` | 프로젝트 진입점 및 실행 흐름 |
| `crew.py` | Crew 오케스트레이션 및 코디네이션 |
| `tools/` | 커스텀 에이전트 도구 디렉터리 |
| `knowledge/` | 지식 베이스 디렉터리 |
- `crew.jsonc`와 `agents/` 안의 파일을 편집하여 crew 동작을 정의하세요.
- 에이전트와 태스크 텍스트에 `{placeholder}`를 사용하고, `crew.jsonc`의 `inputs`에 기본값을 넣으세요. `crewai run` 실행 시 빠진 값은 CLI가 묻습니다.
- `agents.yaml` 및 `tasks.yaml`을 편집하여 crew 동작을 정의하는 것부터 시작하세요.
- API 키와 같은 민감한 정보는 `.env` 파일에 보관하세요.
</Step>

View File

@@ -5,15 +5,11 @@ icon: "at"
mode: "wide"
---
이 가이드는 클래식 `crew.py` 파일에서 **agent**, **task**, 및 기타 구성 요소를 올바르게 참조하기 위해 어노테이션을 사용하는 방법을 설명합니다.
<Note>
`crewai create crew <name>`으로 만든 새 프로젝트는 JSON-first이며 `crew.jsonc`와 `agents/*.jsonc`를 사용합니다. 이 가이드는 `crewai create crew <name> --classic`으로 만든 클래식 프로젝트, 기존 Python/YAML 프로젝트 마이그레이션, 또는 Python 데코레이터 제어가 필요한 경우에 사용하세요.
</Note>
이 가이드는 `crew.py` 파일에서 **agent**, **task**, 및 기타 구성 요소를 올바르게 참조하기 위해 주석을 사용하는 방법을 설명합니다.
## 소개
CrewAI 프레임워크에서 어노테이션은 클래스와 메소드를 데코레이트하는 데 사용되며, crew의 다양한 컴포넌트에 메타데이터와 기능을 제공합니다. 클래식 Python/YAML 프로젝트에서는 `config/agents.yaml`, `config/tasks.yaml`을 로드하고 `Crew` 객체를 반환하는 코드를 구조화합니다.
CrewAI 프레임워크에서 어노테이션은 클래스와 메소드를 데코레이트하는 데 사용되며, crew의 다양한 컴포넌트에 메타데이터와 기능을 제공합니다. 이러한 어노테이션은 코드의 구성과 구조화를 돕고, 코드의 가독성과 유지 관리를 용이하게 만듭니다.
## 사용 가능한 어노테이션
@@ -117,9 +113,9 @@ def crew(self) -> Crew:
`@crew` 어노테이션은 `Crew` 객체를 생성하고 반환하는 메서드를 데코레이션하는 데 사용됩니다. 이 메서드는 모든 구성 요소(agents와 tasks)를 기능적인 crew로 조합합니다.
## 클래식 YAML 구성
## YAML 구성
클래식 프로젝트에서 에이전트 구성은 일반적으로 YAML 파일에 저장됩니다. 아래는 연구원 에이전트에 대한 `agents.yaml` 파일 예시입니다.
에이전트 구성은 일반적으로 YAML 파일에 저장됩니다. 아래는 연구원 에이전트에 대한 `agents.yaml` 파일 예시입니다.
```yaml
researcher:
@@ -150,6 +146,6 @@ YAML 파일의 `llm`과 `tools`가 Python 클래스에서 `@llm` 및 `@tool`로
- **일관성 있는 명명**: 메서드에 대해 명확하고 일관성 있는 명명 규칙을 사용하세요. 예를 들어, agent 메서드는 역할에 따라 이름을 지정할 수 있습니다(예: researcher, reporting_analyst).
- **환경 변수**: API 키와 같은 민감한 정보를 위해 환경 변수를 사용하세요.
- **유연성**: agent와 task를 쉽게 추가 및 제거할 수 있도록 crew를 유연하게 설계하세요.
- **YAML-코드 일치**: 클래식 프로젝트에서는 YAML 파일의 이름과 구조가 Python 코드의 데코레이터가 적용된 메서드와 정확히 일치하는지 확인하세요.
- **YAML-코드 일치**: YAML 파일의 이름과 구조가 Python 코드의 데코레이터가 적용된 메서드와 정확히 일치하는지 확인하세요.
이 지침을 따르고 어노테이션을 올바르게 사용하면 클래식 crew를 구조적이고 유지보수하기 쉽게 유지할 수 있습니다. 새 crew에는 [Crews](/ko/concepts/crews)의 JSON-first 구조를 권장합니다.
이 지침을 따르고 주석을 올바르게 사용하면 CrewAI 프레임워크를 이용해 구조적이고 유지보수가 쉬운 crew를 만들 수 있습니다.

View File

@@ -39,60 +39,84 @@ CrewAI를 아직 설치하지 않았다면 먼저 [설치 가이드](/ko/install
이렇게 하면 `src/latest_ai_flow/` 아래에 Flow 앱이 만들어지고, 다음 단계에서 **단일 에이전트** 연구 crew로 바꿀 시작용 crew가 `crews/content_crew/`에 포함됩니다.
</Step>
<Step title="JSONC로 에이전트 하나 설정">
`src/latest_ai_flow/crews/content_crew/agents/researcher.jsonc`를 만듭니다(`agents/` 디렉터리가 없으면 생성). `{topic}` 같은 변수는 `crew.kickoff(inputs=...)`로 채워집니다.
<Step title="`agents.yaml`에 에이전트 하나 설정">
`src/latest_ai_flow/crews/content_crew/config/agents.yaml` 내용을 한 명의 연구원만 남기도록 바꿉니다. `{topic}` 같은 변수는 `crew.kickoff(inputs=...)`로 채워집니다.
```jsonc agents/researcher.jsonc
{
"role": "{topic} 시니어 데이터 리서처",
"goal": "{topic} 분야의 최신 동향을 파악한다",
"backstory": "당신은 가장 관련성 높은 정보를 찾아 명확하게 전달하는 연구원입니다.",
"tools": ["SerperDevTool"],
"settings": {
"verbose": true
}
}
```yaml agents.yaml
# src/latest_ai_flow/crews/content_crew/config/agents.yaml
researcher:
role: >
{topic} 시니어 데이터 리서처
goal: >
{topic} 분야의 최신 동향을 파악한다
backstory: >
당신은 {topic}의 최신 흐름을 찾아내는 데 능숙한 연구원입니다.
가장 관련성 높은 정보를 찾아 명확하게 전달합니다.
```
</Step>
<Step title="`crew.jsonc`에 crew 설정">
`src/latest_ai_flow/crews/content_crew/crew.jsonc`를 만듭니다:
```jsonc crew.jsonc
{
"name": "Research Crew",
"agents": ["researcher"],
"tasks": [
{
"name": "research_task",
"description": "{topic}에 대해 철저히 조사하세요. 웹 검색으로 최신이고 신뢰할 수 있는 정보를 찾으세요. 현재 연도는 2026년입니다.",
"expected_output": "마크다운 보고서로, 주요 트렌드·주목할 도구나 기업·시사점 등으로 섹션을 나누세요. 분량은 약 800~1200단어. 문서 전체를 코드 펜스로 감싸지 마세요.",
"agent": "researcher",
"output_file": "output/report.md",
"markdown": true
}
],
"process": "sequential",
"verbose": true
}
<Step title="`tasks.yaml`에 작업 하나 설정">
```yaml tasks.yaml
# src/latest_ai_flow/crews/content_crew/config/tasks.yaml
research_task:
description: >
{topic}에 대해 철저히 조사하세요. 웹 검색으로 최신이고 신뢰할 수 있는 정보를 찾으세요.
현재 연도는 2026년입니다.
expected_output: >
마크다운 보고서로, 주요 트렌드·주목할 도구나 기업·시사점 등으로 섹션을 나누세요.
분량은 약 800~1200단어. 문서 전체를 코드 펜스로 감싸지 마세요.
agent: researcher
output_file: output/report.md
```
</Step>
<Step title="JSON crew 로드 (`content_crew.py`)">
생성된 `content_crew.py`를 `crew.jsonc`를 `Crew`로 바꾸는 작은 loader로 교체합니다.
<Step title="crew 클래스 연결 (`content_crew.py`)">
생성된 crew가 YAML을 읽고 연구원에게 `SerperDevTool`을 붙이도록 합니다.
```python content_crew.py
# src/latest_ai_flow/crews/content_crew/content_crew.py
from pathlib import Path
from typing import List
from crewai.project import load_crew
from crewai import Agent, Crew, Process, Task
from crewai.agents.agent_builder.base_agent import BaseAgent
from crewai.project import CrewBase, agent, crew, task
from crewai_tools import SerperDevTool
def kickoff_content_crew(inputs: dict):
crew, default_inputs = load_crew(Path(__file__).with_name("crew.jsonc"))
return crew.kickoff(inputs={**default_inputs, **inputs})
@CrewBase
class ResearchCrew:
"""Flow 안에서 사용하는 단일 에이전트 연구 crew."""
agents: List[BaseAgent]
tasks: List[Task]
agents_config = "config/agents.yaml"
tasks_config = "config/tasks.yaml"
@agent
def researcher(self) -> Agent:
return Agent(
config=self.agents_config["researcher"], # type: ignore[index]
verbose=True,
tools=[SerperDevTool()],
)
@task
def research_task(self) -> Task:
return Task(
config=self.tasks_config["research_task"], # type: ignore[index]
)
@crew
def crew(self) -> Crew:
return Crew(
agents=self.agents,
tasks=self.tasks,
process=Process.sequential,
verbose=True,
)
```
</Step>
@@ -106,7 +130,7 @@ CrewAI를 아직 설치하지 않았다면 먼저 [설치 가이드](/ko/install
from crewai.flow import Flow, listen, start
from latest_ai_flow.crews.content_crew.content_crew import kickoff_content_crew
from latest_ai_flow.crews.content_crew.content_crew import ResearchCrew
class ResearchFlowState(BaseModel):
@@ -125,7 +149,7 @@ CrewAI를 아직 설치하지 않았다면 먼저 [설치 가이드](/ko/install
@listen(prepare_topic)
def run_research(self):
result = kickoff_content_crew(inputs={"topic": self.state.topic})
result = ResearchCrew().crew().kickoff(inputs={"topic": self.state.topic})
self.state.report = result.raw
print("연구 crew 실행 완료.")
@@ -147,7 +171,7 @@ CrewAI를 아직 설치하지 않았다면 먼저 [설치 가이드](/ko/install
```
<Tip>
패키지 이름이 `latest_ai_flow`가 아니면 `kickoff_content_crew` import 경로를 프로젝트 모듈 경로에 맞게 바꾸세요.
패키지 이름이 `latest_ai_flow`가 아니면 `ResearchCrew` import 경로를 프로젝트 모듈 경로에 맞게 바꾸세요.
</Tip>
</Step>
@@ -195,7 +219,7 @@ CrewAI를 아직 설치하지 않았다면 먼저 [설치 가이드](/ko/install
## 한 번에 이해하기
1. **Flow** — `LatestAiFlow`는 `prepare_topic` → `run_research` → `summarize` 순으로 실행됩니다. 상태(`topic`, `report`)는 Flow에 있습니다.
2. **Crew** — `kickoff_content_crew`가 `crew.jsonc`를 로드하고 에이전트 한 명·작업 하나로 실행니다. 연구원이 **Serper**로 웹을 검색하고 구조화된 보고서를 씁니다.
2. **Crew** — `ResearchCrew`는 에이전트 한 명·작업 하나로 실행니다. 연구원이 **Serper**로 웹을 검색하고 구조화된 보고서를 씁니다.
3. **결과물** — 작업의 `output_file`이 `output/report.md`에 보고서를 씁니다.
Flow 패턴(라우팅, 지속성, human-in-the-loop)을 더 보려면 [첫 Flow 만들기](/ko/guides/flows/first-flow)와 [Flows](/ko/concepts/flows)를 참고하세요. Flow 없이 crew만 쓰려면 [Crews](/ko/concepts/crews)를, 작업 없이 단일 `Agent`의 `kickoff()`만 쓰려면 [Agents](/ko/concepts/agents#direct-agent-interaction-with-kickoff)를 참고하세요.
@@ -206,10 +230,7 @@ Flow 패턴(라우팅, 지속성, human-in-the-loop)을 더 보려면 [첫 Flow
### 이름 일치
`crew.jsonc`의 이름은 파일과 참조에 맞아야 합니다:
- `agents: ["researcher"]`는 `agents/researcher.jsonc`를 로드합니다.
- `context: ["research_task"]`는 이전 태스크 `research_task`를 참조합니다.
YAML 키(`researcher`, `research_task`)는 `@CrewBase` 클래스의 메서드 이름과 같아야 합니다. 전체 데코레이터 패턴은 [Crews](/ko/concepts/crews)를 참고하세요.
## 배포

View File

@@ -71,39 +71,13 @@ O Construtor Visual de Agentes permite:
## Criando Agentes
Existem duas formas comuns de criar agentes no CrewAI: usando **configuração JSONC (recomendado para novas crews)** ou definindo-os **diretamente em código**.
Existem duas maneiras de criar agentes no CrewAI: usando **configuração YAML (recomendado)** ou definindo-os **diretamente em código**.
### Configuração JSONC (Recomendado)
### Configuração em YAML (Recomendado)
Novos projetos criados com `crewai create crew <name>` usam configuração JSON-first. Cada agente fica em `agents/<agent_name>.jsonc`, e `crew.jsonc` lista quais agentes fazem parte da crew.
Usar configuração em YAML proporciona uma maneira mais limpa e fácil de manter para definir agentes. Recomendamos fortemente esse método em seus projetos CrewAI.
```jsonc agents/researcher.jsonc
{
"role": "{topic} Senior Data Researcher",
"goal": "Uncover cutting-edge developments in {topic}",
"backstory": "You find the most relevant information and present it clearly.",
"llm": "openai/gpt-4o",
"tools": ["SerperDevTool"],
"settings": {
"verbose": true,
"allow_delegation": false
}
}
```
Use `{placeholder}` em `role`, `goal` ou `backstory`. Defina padrões em `crew.jsonc` dentro de `inputs`; `crewai run` pergunta por valores que estiverem faltando. Campos de comportamento como `verbose`, `allow_delegation`, `max_iter`, `memory`, `cache` e `planning` podem ficar no topo ou em `settings`.
<Note>
JSONC aceita comentários e vírgulas finais. Se `agents/<name>.jsonc` e `agents/<name>.json` existirem, CrewAI usa o arquivo JSONC.
</Note>
### Configuração YAML Clássica
Projetos clássicos criados com `crewai create crew <name> --classic` usam `config/agents.yaml` e uma classe `@CrewBase` em `crew.py`.
A configuração YAML continua suportada para projetos existentes em Python/YAML e para equipes que preferem definir agentes a partir de uma classe `@CrewBase`.
Depois de criar um projeto clássico, navegue até o arquivo `src/latest_ai_development/config/agents.yaml` e edite o template para atender aos seus requisitos.
Depois de criar seu projeto CrewAI conforme descrito na seção de [Instalação](/pt-BR/installation), navegue até o arquivo `src/latest_ai_development/config/agents.yaml` e edite o template para atender aos seus requisitos.
<Note>
Variáveis em seus arquivos YAML (como `{topic}`) serão substituídas pelos valores fornecidos em seus inputs ao executar o crew:

View File

@@ -53,8 +53,6 @@ crewai create crew my_new_crew
crewai create flow my_new_flow
```
Por padrão, `crewai create crew` cria um projeto JSON-first com `crew.jsonc` e `agents/*.jsonc`. Use `crewai create crew my_new_crew --classic` somente quando quiser o scaffold antigo em Python/YAML com `crew.py`, `config/agents.yaml` e `config/tasks.yaml`.
### 2. Version
Mostre a versão instalada do CrewAI.
@@ -205,20 +203,7 @@ crewai chat
Garanta que você execute estes comandos a partir do diretório raiz do seu projeto CrewAI.
</Note>
<Note>
IMPORTANTE: Defina a propriedade `chat_llm` na definição da sua crew para habilitar este comando.
Para crews JSON-first, adicione em `crew.jsonc`:
```jsonc
{
"name": "My Crew",
"agents": ["researcher"],
"tasks": [],
"chat_llm": "openai/gpt-4o"
}
```
Para crews clássicas Python/YAML, defina em `crew.py`:
IMPORTANTE: Defina a propriedade `chat_llm` no seu arquivo `crew.py` para habilitar este comando.
```python
@crew
@@ -349,7 +334,7 @@ Assista ao vídeo tutorial para uma demonstração passo-a-passo de implantaçã
### 11. Chaves de API
Ao executar o comando `crewai create crew`, o CLI mostrará provedores de LLM disponíveis e depois a seleção de modelo para o provedor escolhido. O modelo selecionado é salvo no `.env` gerado, e cada agente JSONC pode definir seu próprio `llm`.
Ao executar o comando `crewai create crew`, o CLI primeiro mostrará os 5 provedores de LLM mais comuns e pedirá para você selecionar um.
Após selecionar um provedor de LLM, será solicitado que você informe as chaves de API.

View File

@@ -41,54 +41,13 @@ Uma crew no crewAI representa um grupo colaborativo de agentes trabalhando em co
## Criando Crews
Existem duas maneiras principais de criar crews no CrewAI: utilizando **configuração JSONC (recomendada para novas crews)** ou definindo a crew **em código** para projetos clássicos e casos avançados.
Existem duas maneiras de criar crews no CrewAI: utilizando **configuração YAML (recomendado)** ou definindo diretamente **em código**.
### Configuração JSONC (Recomendado)
### Configuração YAML (Recomendado)
Novos projetos criados com `crewai create crew <name>` usam `crew.jsonc` para configurações da crew e tarefas, além de um arquivo por agente em `agents/`. `crewai run` detecta `crew.jsonc` ou `crew.json`, carrega os agentes referenciados, pergunta por placeholders ausentes e inicia a crew.
O uso da configuração YAML proporciona uma forma mais limpa e fácil de manter para definir crews, sendo consistente com a definição de agentes e tasks em projetos CrewAI.
```jsonc crew.jsonc
{
"name": "Market Research Crew",
"agents": ["researcher", "analyst"],
"tasks": [
{
"name": "research",
"description": "Research {topic} and collect the most relevant facts.",
"expected_output": "Structured research notes about {topic}.",
"agent": "researcher"
},
{
"name": "analysis",
"description": "Analyze the research and write a concise report.",
"expected_output": "A markdown report with findings and recommendations.",
"agent": "analyst",
"context": ["research"],
"output_file": "output/report.md"
}
],
"process": "sequential",
"verbose": true,
"memory": true,
"inputs": {
"topic": "AI Agents"
}
}
```
Cada string em `agents` resolve primeiro para `agents/<name>.jsonc` e depois para `agents/<name>.json`. Para crews hierárquicas, use `"process": "hierarchical"` com `manager_llm` ou `manager_agent`.
<Warning>
Execute projetos JSON apenas de fontes confiáveis. Ferramentas `custom:<name>` e referências `{"python": "module.attribute"}` executam código Python local quando a crew é carregada.
</Warning>
### Configuração YAML Clássica
Projetos clássicos criados com `crewai create crew <name> --classic` usam `crew.py`, `config/agents.yaml`, `config/tasks.yaml` e os decorators `@CrewBase`, `@agent`, `@task` e `@crew`.
Essa abordagem continua suportada para projetos existentes em Python/YAML e para equipes que precisam de controle explícito via decorators.
Após criar um projeto clássico, você pode definir sua crew em uma classe que herda de `CrewBase` e utiliza decorators para definir agentes, tarefas e a própria crew.
Após criar seu projeto CrewAI conforme descrito na seção [Instalação](/pt-BR/installation), você pode definir sua crew em uma classe que herda de `CrewBase` e utiliza decorators para definir agentes, tarefas e a própria crew.
#### Exemplo de Classe Crew com Decorators

View File

@@ -820,7 +820,7 @@ Você pode gerar um novo projeto CrewAI que já inclui toda a estrutura para cri
crewai create flow name_of_flow
```
Esse comando irá gerar um novo projeto CrewAI com a estrutura de pastas necessária. O projeto gerado inclui uma crew pré-criada chamada `poem_crew`, já funcional. A crew embutida inicial usa a estrutura clássica Python/YAML; novas crews independentes criadas com `crewai create crew` usam a estrutura JSON-first.
Esse comando irá gerar um novo projeto CrewAI com a estrutura de pastas necessária. O projeto gerado inclui uma crew pré-criada chamada `poem_crew`, já funcional. Você pode usar essa crew como modelo, copiando, colando e editando para criar outras crews.
### Estrutura de Pastas
@@ -850,29 +850,7 @@ Na pasta `crews`, você pode definir múltiplas crews. Cada crew tem sua própri
- `config/tasks.yaml`: Define as tarefas da crew.
- `poem_crew.py`: Contém a definição da crew, incluindo agentes, tarefas, etc.
Você pode copiar, colar e editar a `poem_crew` para criar outras crews clássicas embutidas.
Para crews embutidas JSON-first, use uma pasta com `crew.jsonc` e `agents/*.jsonc`:
```text
crews/
└── research_crew/
├── agents/
│ └── researcher.jsonc
└── crew.jsonc
```
Depois carregue a crew em uma etapa do Flow:
```python
from pathlib import Path
from crewai.project import load_crew
crew, default_inputs = load_crew(
Path(__file__).parent / "crews" / "research_crew" / "crew.jsonc"
)
result = crew.kickoff(inputs={**default_inputs, "topic": "AI Agents"})
```
Você pode copiar, colar e editar a `poem_crew` para criar outras crews.
### Conectando Crews no `main.py`

View File

@@ -67,48 +67,13 @@ crew = Crew(
## Criando Tarefas
Existem duas formas comuns de criar tarefas no CrewAI: usando **configuração JSONC (recomendado para novas crews)** ou definindo-as **diretamente no código**.
Existem duas maneiras de criar tarefas no CrewAI: utilizando **configuração YAML (recomendado)** ou definindo-as **diretamente no código**.
### Configuração JSONC (Recomendado)
### Configuração YAML (Recomendado)
Novos projetos criados com `crewai create crew <name>` definem tarefas no `crew.jsonc`.
Utilizar configuração YAML oferece uma forma mais limpa e de fácil manutenção para definir tarefas. Recomendamos fortemente esse método em seus projetos CrewAI.
````jsonc crew.jsonc
{
"name": "Research Crew",
"agents": ["researcher", "reporting_analyst"],
"tasks": [
{
"name": "research_task",
"description": "Conduct thorough research about {topic}.",
"expected_output": "A list of the most relevant information about {topic}.",
"agent": "researcher"
},
{
"name": "reporting_task",
"description": "Review the research and expand it into a detailed report.",
"expected_output": "A polished markdown report.",
"agent": "reporting_analyst",
"context": ["research_task"],
"markdown": true,
"output_file": "report.md"
}
],
"inputs": {
"topic": "AI Agents"
}
}
````
Cada tarefa precisa de `description` e `expected_output`. O valor de `agent` deve corresponder a um agente listado em `agents`. `context` referencia nomes de tarefas anteriores; referências futuras são rejeitadas. Campos comuns incluem `name`, `agent`, `context`, `output_file`, `tools`, `human_input`, `async_execution`, `guardrail`, `guardrails`, `markdown`, `output_json`, `output_pydantic` e `response_model`.
### Configuração YAML Clássica
Projetos clássicos criados com `crewai create crew <name> --classic` usam `config/tasks.yaml` e uma classe `@CrewBase` em `crew.py`.
A configuração YAML continua suportada para projetos existentes em Python/YAML e para equipes que preferem definir tarefas a partir de uma classe `@CrewBase`.
Após criar um projeto clássico, navegue até o arquivo `src/latest_ai_development/config/tasks.yaml` e modifique o template para refletir os requisitos específicos das tarefas.
Após criar seu projeto CrewAI conforme indicado na seção [Instalação](/pt-BR/installation), navegue até o arquivo `src/latest_ai_development/config/tasks.yaml` e modifique o template para refletir os requisitos específicos das tarefas.
<Note>
Variáveis em seus arquivos YAML (como `{topic}`) serão substituídas por valores vindos dos seus inputs ao executar o crew:

View File

@@ -26,10 +26,10 @@ Antes de executar esta verificação:
## Passo 1 — Estruturar um Crew de Verificação
Crie um projeto de crew clássico porque este exemplo conecta uma ferramenta Python via `crew.py`:
Crie um novo projeto de crew. O CrewAI CLI estrutura tudo:
```bash
crewai create crew rotation_verifier --classic --skip_provider
crewai create crew rotation_verifier --skip_provider
cd rotation_verifier
```

View File

@@ -373,17 +373,17 @@ git push
**Solução**: Verifique se seu projeto corresponde à estrutura esperada:
- **Crews JSON-first**: Mantenha `crew.jsonc` ou `crew.json` e `agents/` na raiz do projeto
- **Crews clássicas**: Use `src/project_name/main.py` com uma função de entrada `run()`
- **Flows**: Use `src/project_name/main.py` com uma função de entrada `kickoff()`
- **Tanto Crews quanto Flows**: Devem ter ponto de entrada em `src/project_name/main.py`
- **Crews**: Usam uma função `run()` como ponto de entrada
- **Flows**: Usam uma função `kickoff()` como ponto de entrada
Veja [Preparar para Implantação](/pt-BR/enterprise/guides/prepare-for-deployment) para diagramas de estrutura detalhados.
#### Decorador CrewBase Ausente em uma Crew Clássica
#### Decorador CrewBase Ausente
**Sintoma**: Erros "Crew not found", "Config not found" ou erros de configuração de agent/task
**Solução**: Para crews clássicas Python/YAML, certifique-se de que todas as classes crew usam o decorador `@CrewBase`. Crews JSON-first não precisam desse decorador.
**Solução**: Certifique-se de que **todas** as classes crew usam o decorador `@CrewBase`:
```python
from crewai.project import CrewBase, agent, crew, task
@@ -403,8 +403,8 @@ class YourCrew():
```
<Info>
Isso se aplica a classes crew Python clássicas, incluindo crews clássicas embutidas em projetos Flow.
Crews JSON-first são validadas a partir de `crew.jsonc` e `agents/`.
Isso se aplica a Crews independentes E crews embutidos dentro de projetos Flow.
Toda classe crew precisa do decorador.
</Info>
#### Tipo Incorreto no pyproject.toml
@@ -441,8 +441,8 @@ type = "flow"
**Solução**:
1. Verifique os logs de execução no dashboard AMP (aba Traces)
2. Verifique se todas as ferramentas têm as chaves API necessárias configuradas
3. Para crews JSON-first, valide `crew.jsonc` e os arquivos referenciados em `agents/`
4. Para crews clássicas, verifique se `agents.yaml` e `tasks.yaml` são válidos
3. Certifique-se de que as configurações de agents em `agents.yaml` são válidas
4. Verifique se há erros de sintaxe nas configurações de tasks em `tasks.yaml`
<Card title="Precisa de Ajuda?" icon="headset" href="mailto:support@crewai.com">
Entre em contato com nossa equipe de suporte para ajuda com questões de

View File

@@ -24,9 +24,10 @@ company-ai/
`-- crews/
|-- support_agent/
| |-- pyproject.toml
| |-- crew.jsonc
| `-- agents/
| `-- support_agent.jsonc
| `-- src/
| `-- support_agent/
| |-- main.py
| `-- crew.py
`-- research_flow/
|-- pyproject.toml
`-- src/
@@ -47,7 +48,7 @@ selecionada como a raiz do projeto da automação.
Quando um diretório de trabalho é definido, o AMP usa essa pasta para:
- Validação do projeto, incluindo `pyproject.toml`, arquivos de crew JSON e qualquer ponto de entrada clássico de Crew ou Flow
- Validação do projeto, incluindo `pyproject.toml`, `src/` e o ponto de entrada do Crew ou Flow
- Instalação de dependências com `uv`
- O diretório de trabalho do processo em execução
- A variável de ambiente `CREW_ROOT_DIR`

View File

@@ -24,7 +24,7 @@ Entender qual tipo você está implantando é essencial porque eles têm estrutu
<CardGroup cols={2}>
<Card title="Projetos Crew" icon="users">
Equipes independentes de agentes de IA. Novas crews são JSON-first com `crew.jsonc` e `agents/`; crews clássicas ainda podem usar `crew.py`.
Equipes de agentes de IA independentes com `crew.py` definindo agentes e tarefas. Ideal para tarefas focadas e colaborativas.
</Card>
<Card title="Projetos Flow" icon="diagram-project">
Workflows orquestrados com crews embutidos em uma pasta `crews/`. Ideal para processos complexos de múltiplas etapas.
@@ -33,19 +33,19 @@ Entender qual tipo você está implantando é essencial porque eles têm estrutu
| Aspecto | Crew | Flow |
|---------|------|------|
| **Estrutura do projeto** | Raiz do projeto com `crew.jsonc` e `agents/` | `src/project_name/` com pasta `crews/` |
| **Localização da lógica principal** | `crew.jsonc` (clássico: `src/project_name/crew.py`) | `src/project_name/main.py` (classe Flow) |
| **Função de ponto de entrada** | Carregada a partir de `crew.jsonc` (clássico: `run()` em `main.py`) | `kickoff()` em `main.py` |
| **Estrutura do projeto** | `src/project_name/` com `crew.py` | `src/project_name/` com pasta `crews/` |
| **Localização da lógica principal** | `src/project_name/crew.py` | `src/project_name/main.py` (classe Flow) |
| **Função de ponto de entrada** | `run()` em `main.py` | `kickoff()` em `main.py` |
| **Tipo no pyproject.toml** | `type = "crew"` | `type = "flow"` |
| **Comando CLI de criação** | `crewai create crew name` | `crewai create flow name` |
| **Localização da configuração** | `crew.jsonc`, `agents/`, `tools/` opcional | `src/project_name/crews/crew_name/config/` ou pastas de crew JSON embutidas |
| **Localização da configuração** | `src/project_name/config/` | `src/project_name/crews/crew_name/config/` |
| **Pode conter outros crews** | Não | Sim (na pasta `crews/`) |
## Referência de Estrutura de Projeto
### Estrutura de Projeto Crew
Quando você executa `crewai create crew my_crew`, recebe a estrutura JSON-first:
Quando você executa `crewai create crew my_crew`, você obtém esta estrutura:
```
my_crew/
@@ -54,26 +54,24 @@ my_crew/
├── README.md
├── .env
├── uv.lock # OBRIGATÓRIO para implantação
── crew.jsonc # Configurações, tarefas, processo e inputs
├── agents/
└── researcher.jsonc # Definições de agentes
├── tools/ # Ferramentas custom:<name> opcionais
├── knowledge/
└── skills/
── src/
└── my_crew/
├── __init__.py
├── main.py # Ponto de entrada com função run()
├── crew.py # Classe Crew com decorador @CrewBase
├── tools/
│ ├── custom_tool.py
│ └── __init__.py
└── config/
├── agents.yaml # Definições de agentes
└── tasks.yaml # Definições de tarefas
```
<Warning>
Para crews JSON-first, mantenha `crew.jsonc`, `agents/`, `tools/`, `knowledge/` e `skills/`
na raiz do projeto. Colocá-los dentro de `src/` impede que `crewai run` e a validação de
implantação encontrem a definição da crew.
A estrutura aninhada `src/project_name/` é crítica para Crews.
Colocar arquivos no nível errado causará falhas na implantação.
</Warning>
<Info>
Projetos clássicos criados com `crewai create crew my_crew --classic` usam a estrutura antiga
`src/project_name/crew.py`, `src/project_name/config/agents.yaml` e
`src/project_name/config/tasks.yaml`. Essa estrutura continua suportada para crews Python com decorators.
</Info>
### Estrutura de Projeto Flow
Quando você executa `crewai create flow my_flow`, você obtém esta estrutura:
@@ -102,9 +100,9 @@ my_flow/
```
<Info>
Crews independentes JSON-first usam arquivos JSON na raiz do projeto. Flows ainda usam
`src/project_name/` e podem conter crews embutidas clássicas ou pastas de crew JSON carregadas com
`crewai.project.load_crew`.
Tanto Crews quanto Flows usam a estrutura `src/project_name/`.
A diferença chave é que Flows têm uma pasta `crews/` para crews embutidos,
enquanto Crews têm `crew.py` diretamente na pasta do projeto.
</Info>
## Checklist Pré-Implantação
@@ -156,90 +154,60 @@ git commit -m "Add uv.lock for deployment"
git push
```
### 3. Validar a Definição da Crew
### 3. Validar Uso do Decorador CrewBase
<Tabs>
<Tab title="Crews JSON-first">
Crews JSON-first precisam ter `crew.jsonc` ou `crew.json` na raiz do projeto.
O array `agents` deve apontar para arquivos em `agents/`, e cada task deve referenciar
um nome de agent válido.
**Toda classe crew deve usar o decorador `@CrewBase`.** Isso se aplica a:
```jsonc crew.jsonc
{
"name": "Research Crew",
"agents": ["researcher"],
"tasks": [
{
"name": "research_task",
"description": "Research {topic}.",
"expected_output": "A concise report.",
"agent": "researcher"
}
],
"inputs": {
"topic": "AI Agents"
}
}
```
- Projetos crew independentes
- Crews embutidos dentro de projetos Flow
Ferramentas customizadas são referenciadas como `"custom:<name>"` e devem existir em
`tools/<name>.py` com uma subclasse de `BaseTool`.
</Tab>
<Tab title="Crews Python/YAML Clássicas">
Crews clássicas e crews Python embutidas em Flows devem usar o decorador `@CrewBase`.
```python
from crewai import Agent, Crew, Process, Task
from crewai.project import CrewBase, agent, crew, task
from crewai.agents.agent_builder.base_agent import BaseAgent
from typing import List
```python
from crewai import Agent, Crew, Process, Task
from crewai.project import CrewBase, agent, crew, task
from crewai.agents.agent_builder.base_agent import BaseAgent
from typing import List
@CrewBase # Este decorador é OBRIGATÓRIO
class MyCrew():
"""Descrição do meu crew"""
@CrewBase
class MyCrew():
"""Descrição do meu crew"""
agents: List[BaseAgent]
tasks: List[Task]
agents: List[BaseAgent]
tasks: List[Task]
@agent
def my_agent(self) -> Agent:
return Agent(
config=self.agents_config['my_agent'], # type: ignore[index]
verbose=True
)
@agent
def my_agent(self) -> Agent:
return Agent(
config=self.agents_config['my_agent'], # type: ignore[index]
verbose=True
)
@task
def my_task(self) -> Task:
return Task(
config=self.tasks_config['my_task'] # type: ignore[index]
)
@task
def my_task(self) -> Task:
return Task(
config=self.tasks_config['my_task'] # type: ignore[index]
)
@crew
def crew(self) -> Crew:
return Crew(
agents=self.agents,
tasks=self.tasks,
process=Process.sequential,
verbose=True,
)
```
@crew
def crew(self) -> Crew:
return Crew(
agents=self.agents,
tasks=self.tasks,
process=Process.sequential,
verbose=True,
)
```
</Tab>
</Tabs>
<Warning>
Se você esquecer o decorador `@CrewBase`, sua implantação falhará com
erros sobre configurações de agents ou tasks ausentes.
</Warning>
### 4. Verificar Pontos de Entrada do Projeto
Crews JSON-first independentes não precisam de um `src/project_name/main.py` escrito manualmente;
`crewai run` e o empacotamento de implantação carregam `crew.jsonc` diretamente. Crews clássicas e Flows usam pontos de entrada Python:
Tanto Crews quanto Flows têm seu ponto de entrada em `src/project_name/main.py`:
<Tabs>
<Tab title="Crews JSON-first">
Execute localmente a partir da raiz do projeto:
```bash
crewai run
```
</Tab>
<Tab title="Crews Clássicas">
<Tab title="Para Crews">
O ponto de entrada usa uma função `run()`:
```python
@@ -310,17 +278,16 @@ grep -A2 "\[tool.crewai\]" pyproject.toml
# 2. Verificar se uv.lock existe
ls -la uv.lock || echo "ERRO: uv.lock ausente! Execute 'uv lock'"
# 3. Para crews JSON-first, verificar crew.jsonc e agents/
([ -f crew.jsonc ] || [ -f crew.json ]) || echo "Nenhum crew.jsonc ou crew.json encontrado"
test -d agents || echo "Nenhum diretório agents/ encontrado"
# 3. Verificar se estrutura src/ existe
ls -la src/*/main.py 2>/dev/null || echo "Nenhum main.py encontrado em src/"
# 4. Para Crews clássicas - verificar se crew.py existe
# 4. Para Crews - verificar se crew.py existe
ls -la src/*/crew.py 2>/dev/null || echo "Nenhum crew.py (esperado para Crews)"
# 5. Para Flows - verificar se pasta crews/ existe
ls -la src/*/crews/ 2>/dev/null || echo "Nenhuma pasta crews/ (esperado para Flows)"
# 6. Para crews Python clássicas - verificar uso do CrewBase
# 6. Verificar uso do CrewBase
grep -r "@CrewBase" . --include="*.py"
```
@@ -330,9 +297,8 @@ grep -r "@CrewBase" . --include="*.py"
|------|---------|----------|
| `uv.lock` ausente | Build falha durante resolução de dependências | Execute `uv lock` e faça commit |
| `type` errado no pyproject.toml | Build bem-sucedido mas falha em runtime | Altere para o tipo correto |
| `crew.jsonc` ou `agents/` ausente em uma crew JSON-first | Definição da crew não encontrada | Mantenha `crew.jsonc` e `agents/` na raiz do projeto |
| Decorador `@CrewBase` ausente em uma crew clássica | Erros "Config not found" | Adicione o decorador a todas as classes crew clássicas |
| Arquivos clássicos na raiz ao invés de `src/` | Ponto de entrada não encontrado | Mova arquivos Python clássicos para `src/project_name/` |
| Decorador `@CrewBase` ausente | Erros "Config not found" | Adicione decorador a todas as classes crew |
| Arquivos na raiz ao invés de `src/` | Ponto de entrada não encontrado | Mova para `src/project_name/` |
| `run()` ou `kickoff()` ausente | Não é possível iniciar automação | Adicione a função de entrada correta |
## Próximos Passos

View File

@@ -43,7 +43,7 @@ O CrewAI é nativo de IA. Esta página reúne o que um agente de codificação c
| Skill | Quando é usada |
|-------|----------------|
| `getting-started` | Novos projetos, escolha entre `LLM.call()` / `Agent` / `Crew` / `Flow`, arquivos `crew.jsonc` / `main.py` |
| `getting-started` | Novos projetos, escolha entre `LLM.call()` / `Agent` / `Crew` / `Flow`, arquivos `crew.py` / `main.py` |
| `design-agent` | Configurar agentes — papel, objetivo, história, ferramentas, LLMs, memória, guardrails |
| `design-task` | Descrever tarefas, dependências, saída estruturada (`output_pydantic`, `output_json`), revisão humana |
| `ask-docs` | Consultar o [servidor MCP da documentação CrewAI](https://docs.crewai.com/mcp) em tempo real para detalhes de API |

View File

@@ -1,142 +1,393 @@
---
title: Crie sua primeira Crew
description: Tutorial passo a passo para criar uma equipe colaborativa de IA com configuração JSON-first.
title: Monte sua Primeira Crew
description: Tutorial passo a passo para criar uma equipe colaborativa de IA que trabalha junta para resolver problemas complexos.
icon: users-gear
mode: "wide"
---
## Crie uma Crew de Pesquisa
## Liberando o Poder da IA Colaborativa
Neste guia, você criará uma crew com dois agentes que pesquisa um tópico e escreve um relatório em markdown. Novos projetos de crew são JSON-first: agentes ficam em `agents/*.jsonc`, tarefas e configurações ficam em `crew.jsonc`, e `crewai run` carrega essa definição diretamente.
Imagine ter uma equipe de agentes de IA especializados trabalhando juntos de forma harmoniosa para resolver problemas complexos, cada um contribuindo com suas habilidades únicas para alcançar um objetivo comum. Esse é o poder da CrewAI um framework que permite criar sistemas colaborativos de IA que podem realizar tarefas muito além do que uma única IA conseguiria sozinha.
Neste guia, vamos criar uma crew de pesquisa que irá nos ajudar a pesquisar e analisar um tema, e então criar um relatório abrangente. Este exemplo prático demonstra como agentes de IA podem colaborar para realizar tarefas complexas, mas é apenas o começo do que é possível com a CrewAI.
### O que Você Vai Construir e Aprender
Ao final deste guia, você terá:
1. **Criado uma equipe de pesquisa em IA especializada** com papéis e responsabilidades distintas
2. **Orquestrado a colaboração** entre múltiplos agentes de IA
3. **Automatizado um fluxo de trabalho complexo** que envolve coleta de informações, análise e geração de relatórios
4. **Desenvolvido habilidades fundamentais** que podem ser aplicadas em projetos mais ambiciosos
Embora estejamos criando uma crew de pesquisa simples neste guia, os mesmos padrões e técnicas podem ser aplicados para criar equipes muito mais sofisticadas para tarefas como:
- Criação de conteúdo em múltiplas etapas com redatores, editores e checadores de fatos especializados
- Sistemas de atendimento ao cliente complexos com agentes de suporte em diferentes níveis
- Analistas de negócios autônomos que coletam dados, criam visualizações e geram insights
- Equipes de desenvolvimento de produto que idealizam, projetam e planejam a implementação
Vamos começar a construir sua primeira crew!
### Pré-requisitos
Antes de começar:
Antes de começar, certifique-se de que você:
1. Instale o CrewAI seguindo o [guia de instalação](/pt-BR/installation)
2. Configure sua chave de LLM seguindo o [guia de LLMs](/pt-BR/concepts/llms#setting-up-your-llm)
3. Tenha uma chave [Serper.dev](https://serper.dev/) se quiser usar busca web
1. Instalou a CrewAI seguindo o [guia de instalação](/pt-BR/installation)
2. Configurou sua chave de API de LLM no ambiente, conforme o [guia de configuração do LLM](/pt-BR/concepts/llms#setting-up-your-llm)
3. Tem conhecimento básico de Python
## Etapa 1: Criar uma nova Crew
## Passo 1: Crie um Novo Projeto CrewAI
Primeiro, vamos criar um novo projeto CrewAI usando a CLI. Este comando irá configurar toda a estrutura do projeto com os arquivos necessários, permitindo que você foque em definir seus agentes e suas tarefas, em vez de se preocupar com código boilerplate.
```bash
crewai create crew research_crew
cd research_crew
```
Estrutura criada:
Isso irá gerar um projeto com a estrutura básica necessária para sua crew. A CLI cria automaticamente:
```text
- Um diretório de projeto com os arquivos necessários
- Arquivos de configuração para agentes e tarefas
- Uma implementação básica da crew
- Um script principal para rodar a crew
<Frame caption="CrewAI Framework Overview">
<img src="/images/crews.png" alt="CrewAI Framework Overview" />
</Frame>
## Passo 2: Explore a Estrutura do Projeto
Vamos dedicar um momento para entender a estrutura do projeto criada pela CLI. A CrewAI segue boas práticas para projetos Python, tornando fácil manter e estender seu código à medida que suas crews se tornam mais complexas.
```
research_crew/
├── .gitignore
├── .env
├── agents/
│ └── researcher.jsonc
├── crew.jsonc
├── knowledge/
├── pyproject.toml
├── README.md
├── skills/
└── tools/
├── .env
└── src/
└── research_crew/
├── __init__.py
├── main.py
├── crew.py
├── tools/
│ ├── custom_tool.py
│ └── __init__.py
└── config/
├── agents.yaml
└── tasks.yaml
```
<Tip>
Precisa do layout antigo com `crew.py`, `config/agents.yaml` e `config/tasks.yaml`? Use `crewai create crew research_crew --classic`.
</Tip>
Esta estrutura segue as melhores práticas para projetos Python e facilita a organização do seu código. A separação dos arquivos de configuração (em YAML) do código de implementação (em Python) permite modificar o comportamento da sua crew sem alterar o código subjacente.
## Etapa 2: Definir os agentes
## Passo 3: Configure seus Agentes
Substitua o arquivo gerado `agents/researcher.jsonc` e adicione `agents/analyst.jsonc`. Os nomes dos arquivos são os nomes referenciados em `crew.jsonc`.
Agora vem a parte divertida definir seus agentes de IA! Na CrewAI, agentes são entidades especializadas com papéis, objetivos e históricos específicos que moldam seu comportamento. Pense neles como personagens em uma peça, cada um com sua personalidade e propósito próprios.
```jsonc agents/researcher.jsonc
{
"role": "Senior Research Specialist for {topic}",
"goal": "Find comprehensive and accurate information about {topic}, with a focus on recent developments and key insights.",
"backstory": "You are an experienced research specialist who organizes complex information into clear, useful notes.",
// Substitua pelo seu modelo, por exemplo "openai/gpt-4o".
"llm": "provider/model-id",
"tools": ["SerperDevTool"],
"settings": {
"verbose": true,
"allow_delegation": false
}
}
Para nossa crew de pesquisa, vamos criar dois agentes:
1. Um **pesquisador** que é especialista em encontrar e organizar informações
2. Um **analista** que pode interpretar os resultados da pesquisa e criar relatórios perspicazes
Vamos modificar o arquivo `agents.yaml` para definir esses agentes especializados. Certifique-se de
definir `llm` para o provedor que você está utilizando.
```yaml
# src/research_crew/config/agents.yaml
researcher:
role: >
Especialista Sênior em Pesquisa para {topic}
goal: >
Encontrar informações abrangentes e precisas sobre {topic}
com foco em desenvolvimentos recentes e insights chave
backstory: >
Você é um especialista em pesquisa experiente com talento para
encontrar informações relevantes de diversas fontes. Você se destaca em
organizar informações de forma clara e estruturada, tornando temas complexos acessíveis para outros.
llm: provider/model-id # ex: openai/gpt-4o, google/gemini-2.0-flash, anthropic/claude...
analyst:
role: >
Analista de Dados e Redator de Relatórios para {topic}
goal: >
Analisar os resultados da pesquisa e criar um relatório abrangente e bem estruturado
que apresente os insights de forma clara e envolvente
backstory: >
Você é um analista habilidoso com experiência em interpretação de dados
e redação técnica. Tem talento para identificar padrões
e extrair insights relevantes dos dados de pesquisa, comunicando esses insights de forma eficaz por meio de relatórios bem elaborados.
llm: provider/model-id # ex: openai/gpt-4o, google/gemini-2.0-flash, anthropic/claude...
```
```jsonc agents/analyst.jsonc
{
"role": "Report Analyst for {topic}",
"goal": "Turn research findings into a clear, well-structured report.",
"backstory": "You are a careful analyst with strong technical writing skills and a talent for extracting useful insights.",
// Substitua pelo seu modelo, por exemplo "openai/gpt-4o".
"llm": "provider/model-id",
"settings": {
"verbose": true,
"allow_delegation": false
}
}
Perceba como cada agente tem um papel, objetivo e histórico distintos. Esses elementos não são apenas descritivos eles efetivamente moldam como o agente aborda suas tarefas. Ao criar cuidadosamente esses detalhes, você pode ter agentes com habilidades e perspectivas que se complementam.
## Passo 4: Defina suas Tarefas
Com nossos agentes definidos, agora precisamos atribuir tarefas específicas para eles realizarem. Tarefas na CrewAI representam o trabalho concreto que os agentes irão executar, com instruções detalhadas e saídas esperadas.
Para nossa crew de pesquisa, vamos definir duas tarefas principais:
1. Uma **tarefa de pesquisa** para coletar informações abrangentes
2. Uma **tarefa de análise** para criar um relatório com insights
Vamos modificar o arquivo `tasks.yaml`:
```yaml
# src/research_crew/config/tasks.yaml
research_task:
description: >
Realize uma pesquisa aprofundada sobre {topic}. Foque em:
1. Conceitos e definições chave
2. Desenvolvimento histórico e tendências recentes
3. Principais desafios e oportunidades
4. Aplicações relevantes ou estudos de caso
5. Perspectivas futuras e novos desenvolvimentos
Certifique-se de organizar seus achados em um formato estruturado, com seções claras.
expected_output: >
Um documento de pesquisa abrangente com seções bem organizadas cobrindo
todos os aspectos solicitados de {topic}. Inclua fatos, números
e exemplos específicos sempre que possível.
agent: researcher
analysis_task:
description: >
Analise os resultados da pesquisa e crie um relatório abrangente sobre {topic}.
Seu relatório deve:
1. Iniciar com um resumo executivo
2. Incluir todas as informações relevantes da pesquisa
3. Oferecer uma análise perspicaz de tendências e padrões
4. Apresentar recomendações ou considerações futuras
5. Estar formatado de forma profissional, clara e com títulos bem definidos
expected_output: >
Um relatório profissional, polido e estruturado sobre {topic} com apresentação dos resultados da pesquisa,
acrescentando análise e insights. O relatório deve ser bem estruturado,
incluindo resumo executivo, sessões principais e conclusão.
agent: analyst
context:
- research_task
output_file: output/report.md
```
Substitua `provider/model-id` pelo modelo usado, como `openai/gpt-4o`, `anthropic/claude-sonnet-4-6` ou `gemini/gemini-2.0-flash-001`.
Note o campo `context` na tarefa de análise esse é um recurso poderoso que permite ao analista acessar a saída da tarefa de pesquisa. Isso cria um fluxo de trabalho em que a informação circula naturalmente entre os agentes, como aconteceria em uma equipe humana.
## Etapa 3: Definir tarefas e configurações
## Passo 5: Configure sua Crew
Substitua `crew.jsonc` por:
Agora é hora de juntar tudo configurando nossa crew. A crew é o container que orquestra como os agentes trabalham juntos para completar as tarefas.
```jsonc crew.jsonc
{
"name": "Research Crew",
"agents": ["researcher", "analyst"],
"tasks": [
{
"name": "research_task",
"description": "Conduct thorough research on {topic}. Focus on key concepts, recent developments, major challenges, notable applications, and future outlook.",
"expected_output": "A comprehensive research document with organized sections, specific facts, and useful examples about {topic}.",
"agent": "researcher"
},
{
"name": "analysis_task",
"description": "Analyze the research findings and create a polished report on {topic}. Include an executive summary, key insights, trend analysis, and recommendations.",
"expected_output": "A professional markdown report with clear headings, a concise summary, main findings, and recommendations.",
"agent": "analyst",
"context": ["research_task"],
"output_file": "output/report.md",
"markdown": true
Vamos modificar o arquivo `crew.py`:
```python
# src/research_crew/crew.py
from crewai import Agent, Crew, Process, Task
from crewai.project import CrewBase, agent, crew, task
from crewai_tools import SerperDevTool
from crewai.agents.agent_builder.base_agent import BaseAgent
from typing import List
@CrewBase
class ResearchCrew():
"""Research crew for comprehensive topic analysis and reporting"""
agents: List[BaseAgent]
tasks: List[Task]
@agent
def researcher(self) -> Agent:
return Agent(
config=self.agents_config['researcher'], # type: ignore[index]
verbose=True,
tools=[SerperDevTool()]
)
@agent
def analyst(self) -> Agent:
return Agent(
config=self.agents_config['analyst'], # type: ignore[index]
verbose=True
)
@task
def research_task(self) -> Task:
return Task(
config=self.tasks_config['research_task'] # type: ignore[index]
)
@task
def analysis_task(self) -> Task:
return Task(
config=self.tasks_config['analysis_task'], # type: ignore[index]
output_file='output/report.md'
)
@crew
def crew(self) -> Crew:
"""Creates the research crew"""
return Crew(
agents=self.agents,
tasks=self.tasks,
process=Process.sequential,
verbose=True,
)
```
Neste código, estamos:
1. Criando o agente pesquisador e equipando-o com o SerperDevTool para buscas web
2. Criando o agente analista
3. Definindo as tarefas de pesquisa e análise
4. Configurando a crew para executar as tarefas sequencialmente (o analista espera o pesquisador terminar)
É aqui que a mágica acontece com poucas linhas de código, definimos um sistema colaborativo de IA onde agentes especializados trabalham juntos em um processo coordenado.
## Passo 6: Prepare seu Script Principal
Agora, vamos preparar o script principal que irá rodar nossa crew. É aqui que informamos o tema específico que queremos pesquisar.
```python
#!/usr/bin/env python
# src/research_crew/main.py
import os
from research_crew.crew import ResearchCrew
# Crie o diretório de saída se não existir
os.makedirs('output', exist_ok=True)
def run():
"""
Rodar a crew de pesquisa.
"""
inputs = {
'topic': 'Inteligência Artificial na Saúde'
}
],
"process": "sequential",
"verbose": true,
"memory": true,
"inputs": {
"topic": "Artificial Intelligence in Healthcare"
}
}
# Criar e rodar a crew
result = ResearchCrew().crew().kickoff(inputs=inputs)
# Imprimir o resultado
print("\n\n=== RELATÓRIO FINAL ===\n\n")
print(result.raw)
print("\n\nRelatório salvo em output/report.md")
if __name__ == "__main__":
run()
```
`context` aponta para tarefas anteriores, então o analista recebe a saída da pesquisa. `inputs` define valores padrão para `{topic}`; se um valor faltar, `crewai run` perguntará no terminal.
Este script prepara o ambiente, define o tema de pesquisa e inicia o trabalho da crew. O poder da CrewAI fica evidente em como esse código é simples toda a complexidade do gerenciamento de múltiplos agentes de IA é tratada pelo framework.
## Etapa 4: Variáveis de ambiente
## Passo 7: Defina suas Variáveis de Ambiente
Edite `.env`:
Crie um arquivo `.env` na raiz do seu projeto com suas chaves de API:
```sh
SERPER_API_KEY=your_serper_api_key
# Adicione também a chave do seu provedor de modelo.
SERPER_API_KEY=sua_serper_api_key
# Adicione a chave de API do seu provedor também.
```
## Etapa 5: Instalar e executar
Confira o [guia de configuração do LLM](/pt-BR/concepts/llms#setting-up-your-llm) para detalhes sobre como configurar o provedor de sua escolha. Você pode obter a chave da Serper em [Serper.dev](https://serper.dev/).
## Passo 8: Instale as Dependências
Instale as dependências necessárias usando a CLI da CrewAI:
```bash
crewai install
```
Este comando irá:
1. Ler as dependências da configuração do seu projeto
2. Criar um ambiente virtual se necessário
3. Instalar todos os pacotes necessários
## Passo 9: Execute sua Crew
Agora chega o momento empolgante é hora de rodar sua crew e assistir à colaboração de IA em ação!
```bash
crewai run
```
Quando a execução terminar, abra `output/report.md`.
Ao rodar esse comando, você verá sua crew ganhando vida. O pesquisador irá coletar informações sobre o tema especificado, e o analista irá criar um relatório abrangente baseado nessa pesquisa. Você poderá acompanhar em tempo real o raciocínio, as ações e os resultados dos agentes à medida que colaboram para concluir as tarefas.
<Warning>
Execute projetos JSON crew apenas de fontes confiáveis. Ferramentas `custom:<name>` e referências `{"python": "module.attribute"}` executam Python local ao carregar a crew.
</Warning>
## Passo 10: Revise o Resultado
Após a conclusão do trabalho da crew, você encontrará o relatório final em `output/report.md`. O relatório incluirá:
1. Um resumo executivo
2. Informações detalhadas sobre o tema
3. Análises e insights
4. Recomendações ou considerações futuras
Tire um momento para valorizar o que você realizou você criou um sistema no qual múltiplos agentes de IA colaboraram em uma tarefa complexa, cada um contribuindo com suas habilidades especializadas para gerar um resultado maior do que qualquer agente conseguiria sozinho.
## Explorando Outros Comandos da CLI
A CrewAI oferece vários outros comandos úteis de CLI para trabalhar com crews:
```bash
# Ver todos os comandos disponíveis
crewai --help
# Rodar a crew
crewai run
# Testar a crew
crewai test
# Resetar as memórias da crew
crewai reset-memories
# Repetir a partir de uma tarefa específica
crewai replay -t <task_id>
```
## O que Mais é Possível: Além da sua Primeira Crew
O que você construiu neste guia é só o começo. As habilidades e padrões aprendidos aqui podem ser aplicados para criar sistemas de IA cada vez mais sofisticados. Veja algumas maneiras de expandir sua crew de pesquisa básica:
### Expandindo sua Crew
Você pode adicionar mais agentes especializados à sua crew:
- Um **checador de fatos** para verificar as informações encontradas
- Um **visualizador de dados** para criar gráficos e tabelas
- Um **especialista de domínio** com conhecimento aprofundado em uma área específica
- Um **crítico** para identificar pontos fracos na análise
### Adicionando Ferramentas e Capacidades
Você pode potencializar seus agentes com ferramentas adicionais:
- Ferramentas de navegação web para pesquisa em tempo real
- Ferramentas para CSV ou bancos de dados para análise de dados
- Ferramentas de execução de código para processamento de dados
- Conexões de API com serviços externos
### Criando Fluxos de Trabalho Mais Complexos
Você pode implementar processos mais sofisticados:
- Processos hierárquicos em que agentes gestores delegam para agentes
- Processos iterativos com loops de feedback para refinamento
- Processos paralelos onde múltiplos agentes trabalham simultaneamente
- Processos dinâmicos que se adaptam a resultados intermediários
### Aplicando em Diferentes Domínios
Os mesmos padrões podem ser aplicados para criar crews para:
- **Criação de conteúdo:** Redatores, editores, checadores de fatos e designers trabalhando juntos
- **Atendimento ao cliente:** Agentes de triagem, especialistas e controle de qualidade atuando colaborativamente
- **Desenvolvimento de produto:** Pesquisadores, designers e planejadores trabalhando em conjunto
- **Análise de dados:** Coletores de dados, analistas e especialistas em visualização
## Próximos Passos
Agora que você montou sua primeira crew, você pode:
1. Experimentar diferentes configurações e personalidades de agentes
2. Testar estruturas de tarefas e fluxos de trabalho mais complexos
3. Implementar ferramentas customizadas para dar novas capacidades aos agentes
4. Aplicar sua crew em outros temas ou domínios de problemas
5. Explorar [CrewAI Flows](/pt-BR/guides/flows/first-flow) para fluxos de trabalho avançados usando programação procedural
<Check>
Você criou uma crew JSON-first funcional que pesquisa um tópico e escreve um relatório.
Parabéns! Você construiu com sucesso sua primeira crew com o CrewAI, capaz de pesquisar e analisar qualquer tema que desejar. Essa experiência fundamental lhe deu as habilidades para criar sistemas de IA cada vez mais sofisticados, aptos a encarar problemas complexos e de múltiplas etapas por meio da inteligência colaborativa.
</Check>

View File

@@ -64,7 +64,7 @@ Isso gerará um projeto com a estrutura básica necessária para seu flow.
## Passo 2: Entendendo a Estrutura do Projeto
O projeto gerado possui a seguinte estrutura. A crew inicial embutida usa o layout clássico Python/YAML. Para usar uma crew JSON-first dentro de um Flow, crie `crew.jsonc` e `agents/*.jsonc` na pasta da crew e carregue com `crewai.project.load_crew`, como mostrado em [Flows](/pt-BR/concepts/flows#building-your-crews).
O projeto gerado possui a seguinte estrutura. Reserve um momento para conhecê-la, pois isso ajudará você a criar flows mais complexos no futuro.
```
guide_creator_flow/
@@ -102,82 +102,156 @@ Este comando cria automaticamente os diretórios e arquivos de template necessá
## Passo 4: Configure o Crew de Redator de Conteúdo
Agora, vamos configurar o crew de redatores com JSONC. Vamos definir dois agentes especializados - um escritor e um revisor - que colaboram para criar conteúdo de alta qualidade para o guia.
Agora, vamos modificar os arquivos gerados para o crew de redatores. Vamos configurar dois agentes especializados um escritor e um revisor que irão colaborar para criar um conteúdo de alta qualidade para o nosso guia.
1. Crie `src/guide_creator_flow/crews/content_crew/agents/content_writer.jsonc`:
1. Primeiro, atualize o arquivo de configuração de agents para definir a equipe de criação de conteúdo:
```jsonc
{
"role": "Educational Content Writer",
"goal": "Create engaging, informative content that thoroughly explains the assigned topic and provides valuable insights to the reader.",
"backstory": "You are a talented educational writer who explains complex concepts in accessible language and organizes information clearly.",
"llm": "provider/model-id",
"settings": {
"verbose": true
}
}
Lembre-se de configurar o `llm` com o provedor que está utilizando.
```yaml
# src/guide_creator_flow/crews/content_crew/config/agents.yaml
content_writer:
role: >
Redator de Conteúdo Educacional
goal: >
Criar conteúdo envolvente e informativo que explique completamente o tema proposto
e forneça insights valiosos ao leitor
backstory: >
Você é um talentoso escritor educacional com experiência em criar conteúdo claro
e atraente. Você tem facilidade para explicar conceitos complexos em linguagem acessível
e organizar as informações de forma a ajudar o leitor a construir seu entendimento.
llm: provider/model-id # e.g. openai/gpt-4o, google/gemini-2.0-flash, anthropic/claude...
content_reviewer:
role: >
Revisor(a) e Editor(a) de Conteúdo Educacional
goal: >
Garantir que o conteúdo seja preciso, abrangente, bem estruturado e mantenha
consistência com as seções previamente escritas
backstory: >
Você é um editor(a) meticuloso(a) com anos de experiência revisando conteúdo educacional.
Tem atenção aos detalhes, clareza e coesão. Você se destaca em aprimorar conteúdo
mantendo o estilo do autor original e garantindo qualidade consistente em várias seções.
llm: provider/model-id # e.g. openai/gpt-4o, google/gemini-2.0-flash, anthropic/claude...
```
2. Crie `src/guide_creator_flow/crews/content_crew/agents/content_reviewer.jsonc`:
Essas definições de agents estabelecem papéis e perspectivas especializadas que irão moldar como nossos agentes de IA abordam a criação de conteúdo. Note como cada agent possui um propósito e expertise distintos.
```jsonc
{
"role": "Educational Content Reviewer and Editor",
"goal": "Ensure content is accurate, comprehensive, well-structured, and consistent with previously written sections.",
"backstory": "You are a meticulous editor with an eye for detail, clarity, and coherence.",
"llm": "provider/model-id",
"settings": {
"verbose": true
}
}
2. Em seguida, atualize o arquivo de configuração de tarefas para definir as tarefas específicas de escrita e revisão:
```yaml
# src/guide_creator_flow/crews/content_crew/config/tasks.yaml
write_section_task:
description: >
Escreva uma seção abrangente sobre o tema: "{section_title}"
Descrição da seção: {section_description}
Público-alvo: {audience_level} aprendizes
Seu conteúdo deve:
1. Começar com uma breve introdução ao tema da seção
2. Explicar claramente todos os conceitos principais com exemplos
3. Incluir aplicações práticas ou exercícios onde apropriado
4. Terminar com um resumo dos pontos principais
5. Ter aproximadamente 500-800 palavras
Formate seu conteúdo em Markdown com títulos, listas e ênfase apropriados.
Seções previamente escritas:
{previous_sections}
Certifique-se de que seu conteúdo mantenha consistência com as seções já escritas
e amplie os conceitos que já foram explicados.
expected_output: >
Uma seção bem estruturada e abrangente em formato Markdown que explique
totalmente o tema e é apropriada para o público-alvo.
agent: content_writer
review_section_task:
description: >
Revise e melhore a seguinte seção sobre "{section_title}":
{draft_content}
Público-alvo: {audience_level} aprendizes
Seções previamente escritas:
{previous_sections}
Sua revisão deve:
1. Corrigir qualquer erro gramatical ou de ortografia
2. Melhorar clareza e legibilidade
3. Garantir que o conteúdo seja abrangente e preciso
4. Verificar a consistência com as seções já escritas
5. Aprimorar a estrutura e o fluxo
6. Adicionar qualquer informação-chave ausente
Forneça a versão aprimorada da seção em formato Markdown.
expected_output: >
Uma versão melhorada e refinada da seção, mantendo a estrutura original,
mas aprimorando clareza, precisão e consistência.
agent: content_reviewer
context:
- write_section_task
```
Substitua `provider/model-id` pelo modelo que você usa, como `openai/gpt-4o`, `gemini/gemini-2.0-flash-001` ou `anthropic/claude-sonnet-4-6`.
Essas definições de tarefas fornecem instruções detalhadas para nossos agents, garantindo que eles produzam conteúdo que atenda aos padrões de qualidade. Observe como o parâmetro `context` na tarefa de revisão cria um fluxo onde o revisor tem acesso à produção do redator.
3. Crie `src/guide_creator_flow/crews/content_crew/crew.jsonc`:
```jsonc
{
"name": "Content Crew",
"agents": ["content_writer", "content_reviewer"],
"tasks": [
{
"name": "write_section_task",
"description": "Write a comprehensive section on the topic: \"{section_title}\".\n\nSection description: {section_description}\nTarget audience: {audience_level} level learners\n\nYour content should begin with a brief introduction, explain key concepts clearly with examples, include practical applications where appropriate, end with a summary, and be approximately 500-800 words.\n\nPreviously written sections:\n{previous_sections}",
"expected_output": "A well-structured, comprehensive section in Markdown format that thoroughly explains the topic and is appropriate for the target audience.",
"agent": "content_writer",
"markdown": true
},
{
"name": "review_section_task",
"description": "Review and improve this section on \"{section_title}\":\n\n{draft_content}\n\nTarget audience: {audience_level} level learners\nPreviously written sections:\n{previous_sections}\n\nFix errors, improve clarity, verify consistency, enhance structure, and add missing key information.",
"expected_output": "An improved, polished version of the section that maintains the original structure but enhances clarity, accuracy, and consistency.",
"agent": "content_reviewer",
"context": ["write_section_task"],
"markdown": true
}
],
"process": "sequential",
"verbose": true
}
```
O campo `context` permite que o revisor use a saída do escritor.
4. Substitua `src/guide_creator_flow/crews/content_crew/content_crew.py` por um pequeno loader:
3. Agora, atualize o arquivo de implementação do crew para definir como nossos agents e tasks trabalham juntos:
```python
from pathlib import Path
# src/guide_creator_flow/crews/content_crew/content_crew.py
from crewai import Agent, Crew, Process, Task
from crewai.project import CrewBase, agent, crew, task
from crewai.agents.agent_builder.base_agent import BaseAgent
from typing import List
from crewai.project import load_crew
@CrewBase
class ContentCrew():
"""Crew de redação de conteúdo"""
agents: List[BaseAgent]
tasks: List[Task]
def kickoff_content_crew(inputs: dict):
crew, default_inputs = load_crew(Path(__file__).with_name("crew.jsonc"))
return crew.kickoff(inputs={**default_inputs, **inputs})
@agent
def content_writer(self) -> Agent:
return Agent(
config=self.agents_config['content_writer'], # type: ignore[index]
verbose=True
)
@agent
def content_reviewer(self) -> Agent:
return Agent(
config=self.agents_config['content_reviewer'], # type: ignore[index]
verbose=True
)
@task
def write_section_task(self) -> Task:
return Task(
config=self.tasks_config['write_section_task'] # type: ignore[index]
)
@task
def review_section_task(self) -> Task:
return Task(
config=self.tasks_config['review_section_task'], # type: ignore[index]
context=[self.write_section_task()]
)
@crew
def crew(self) -> Crew:
"""Cria o crew de redação de conteúdo"""
return Crew(
agents=self.agents,
tasks=self.tasks,
process=Process.sequential,
verbose=True,
)
```
Esse loader transforma `crew.jsonc` em uma `Crew` em runtime. Embora essa crew possa funcionar de forma independente, no nosso flow ela será orquestrada como parte de um sistema maior.
Essa definição de crew estabelece o relacionamento entre nossos agents e tasks, definindo um processo sequencial onde o redator cria o rascunho e o revisor o aprimora. Embora este crew possa funcionar de forma independente, em nosso flow ele será orquestrado como parte de um sistema maior.
## Passo 5: Crie o Flow
@@ -199,7 +273,7 @@ from typing import List, Dict
from pydantic import BaseModel, Field
from crewai import LLM
from crewai.flow.flow import Flow, listen, start
from guide_creator_flow.crews.content_crew.content_crew import kickoff_content_crew
from guide_creator_flow.crews.content_crew.content_crew import ContentCrew
# Definir nossos modelos para dados estruturados
class Section(BaseModel):
@@ -304,7 +378,7 @@ class GuideCreatorFlow(Flow[GuideCreatorState]):
previous_sections_text = "No previous sections written yet."
# Executar a crew de conteúdo para esta seção
result = kickoff_content_crew(inputs={
result = ContentCrew().crew().kickoff(inputs={
"section_title": section.title,
"section_description": section.description,
"audience_level": self.state.audience_level,
@@ -523,7 +597,7 @@ Isso fornece uma maneira segura e tipada de rastrear e transformar dados ao long
Flows podem integrar crews para tarefas colaborativas complexas:
```python
result = kickoff_content_crew(inputs={
result = ContentCrew().crew().kickoff(inputs={
"section_title": section.title,
# ...
})

View File

@@ -106,7 +106,7 @@ Se você ainda não instalou o `uv`, siga o **passo 1** para instalá-lo rapidam
# Criando um Projeto CrewAI
`crewai create crew` agora cria um projeto de crew JSON-first. Os agentes ficam em `agents/*.jsonc`, as tarefas e configurações da crew ficam em `crew.jsonc`, e `crewai run` carrega essa definição JSON diretamente.
Recomendamos utilizar o template de scaffolding `YAML` para uma abordagem estruturada na definição dos agentes e tarefas. Veja como começar:
<Steps>
<Step title="Gerar Scaffolding do Projeto">
@@ -120,38 +120,39 @@ Se você ainda não instalou o `uv`, siga o **passo 1** para instalá-lo rapidam
```
my_project/
├── .gitignore
├── .env
├── agents/
│ └── researcher.jsonc
├── crew.jsonc
├── knowledge/
├── pyproject.toml
├── README.md
├── skills/
└── tools/
├── .env
└── src/
└── my_project/
├── __init__.py
├── main.py
├── crew.py
├── tools/
│ ├── custom_tool.py
│ └── __init__.py
└── config/
├── agents.yaml
└── tasks.yaml
```
</Frame>
- Se você precisar do scaffold antigo em Python/YAML com `crew.py`, `config/agents.yaml` e `config/tasks.yaml`, execute:
```shell
crewai create crew <your_project_name> --classic
```
</Step>
<Step title="Personalize Seu Projeto">
- Seu projeto conterá estes arquivos essenciais:
| Arquivo | Finalidade |
| --- | --- |
| `crew.jsonc` | Configure a crew, a ordem das tarefas, o processo e os inputs padrão |
| `agents/*.jsonc` | Defina o papel, objetivo, backstory, LLM, ferramentas e comportamento de cada agente |
| `agents.yaml` | Defina seus agentes de IA e seus papéis |
| `tasks.yaml` | Configure as tarefas e fluxos de trabalho dos agentes |
| `.env` | Armazene chaves de API e variáveis de ambiente |
| `tools/` | Arquivos Python opcionais para ferramentas `custom:<name>` |
| `knowledge/` | Arquivos opcionais de conhecimento para agentes |
| `skills/` | Arquivos opcionais de skills aplicadas à crew |
| `main.py` | Ponto de entrada e fluxo de execução do projeto |
| `crew.py` | Orquestração e coordenação do crew |
| `tools/` | Diretório para ferramentas customizadas dos agentes |
| `knowledge/` | Diretório para base de conhecimento |
- Comece editando `crew.jsonc` e os arquivos em `agents/` para definir o comportamento da crew.
- Use valores `{placeholder}` nos textos de agentes e tarefas e defina padrões em `crew.jsonc` dentro de `inputs`. Ao executar `crewai run`, a CLI pergunta por valores que estiverem faltando.
- Comece editando `agents.yaml` e `tasks.yaml` para definir o comportamento do seu crew.
- Mantenha informações sensíveis como chaves de API no arquivo `.env`.
</Step>

View File

@@ -5,15 +5,11 @@ icon: "at"
mode: "wide"
---
Este guia explica como utilizar anotações para referenciar corretamente **agentes**, **tarefas** e outros componentes em um arquivo `crew.py` clássico.
<Note>
Novos projetos criados com `crewai create crew <name>` são JSON-first e usam `crew.jsonc` com `agents/*.jsonc`. Use este guia ao trabalhar em um projeto clássico criado com `crewai create crew <name> --classic`, ao migrar um projeto Python/YAML existente ou quando precisar de controle via decorators em Python.
</Note>
Este guia explica como utilizar anotações para referenciar corretamente **agentes**, **tarefas** e outros componentes no arquivo `crew.py`.
## Introdução
As anotações no framework CrewAI são utilizadas para decorar classes e métodos, fornecendo metadados e funcionalidades para diversos componentes do seu crew. Em projetos clássicos Python/YAML, elas organizam o código que carrega `config/agents.yaml`, `config/tasks.yaml` e retorna o objeto `Crew`.
As anotações no framework CrewAI são utilizadas para decorar classes e métodos, fornecendo metadados e funcionalidades para diversos componentes do seu crew. Essas anotações auxiliam na organização e estruturação do seu código, tornando-o mais legível e fácil de manter.
## Anotações Disponíveis
@@ -117,9 +113,9 @@ def crew(self) -> Crew:
A anotação `@crew` é usada para decorar o método que cria e retorna o objeto `Crew`. Este método reúne todos os componentes (agentes e tarefas) em um crew funcional.
## Configuração YAML Clássica
## Configuração YAML
Em projetos clássicos, as configurações dos agentes geralmente são armazenadas em um arquivo YAML. Veja um exemplo de como o arquivo `agents.yaml` pode ser estruturado para o agente researcher:
As configurações dos agentes geralmente são armazenadas em um arquivo YAML. Veja um exemplo de como o arquivo `agents.yaml` pode ser estruturado para o agente researcher:
```yaml
researcher:
@@ -150,6 +146,6 @@ Repare como os campos `llm` e `tools` no arquivo YAML correspondem aos métodos
- **Nomenclatura Consistente**: Utilize nomenclatura clara e consistente para seus métodos. Por exemplo, métodos de agentes podem ser nomeados de acordo com suas funções (ex: researcher, reporting_analyst).
- **Variáveis de Ambiente**: Utilize variáveis de ambiente para informações sensíveis como chaves de API.
- **Flexibilidade**: Estruture seu crew de forma flexível, permitindo fácil adição ou remoção de agentes e tarefas.
- **Correspondência YAML-Código**: Em projetos clássicos, assegure que os nomes e estruturas nos arquivos YAML correspondam corretamente aos métodos decorados em seu código Python.
- **Correspondência YAML-Código**: Assegure que os nomes e estruturas nos arquivos YAML correspondam corretamente aos métodos decorados em seu código Python.
Seguindo essas orientações e utilizando corretamente as anotações, você conseguirá manter crews clássicos bem estruturados. Para novas crews, prefira a estrutura JSON-first em [Crews](/pt-BR/concepts/crews).
Seguindo essas orientações e utilizando corretamente as anotações, você conseguirá criar crews bem estruturados e de fácil manutenção utilizando o framework CrewAI.

View File

@@ -39,60 +39,84 @@ Se ainda não instalou o CrewAI, siga primeiro o [guia de instalação](/pt-BR/i
Isso cria um app Flow em `src/latest_ai_flow/`, incluindo um crew inicial em `crews/content_crew/` que você substituirá por um crew de pesquisa **com um único agente** nos próximos passos.
</Step>
<Step title="Configure um agente em JSONC">
Crie `src/latest_ai_flow/crews/content_crew/agents/researcher.jsonc` (crie o diretório `agents/` se necessário). Variáveis como `{topic}` são preenchidas a partir de `crew.kickoff(inputs=...)`.
<Step title="Configure um agente em `agents.yaml`">
Substitua o conteúdo de `src/latest_ai_flow/crews/content_crew/config/agents.yaml` por um único pesquisador. Variáveis como `{topic}` são preenchidas a partir de `crew.kickoff(inputs=...)`.
```jsonc agents/researcher.jsonc
{
"role": "Pesquisador(a) Sênior de Dados em {topic}",
"goal": "Descobrir os desenvolvimentos mais recentes em {topic}",
"backstory": "Você é um pesquisador experiente que encontra as informações mais relevantes e apresenta tudo com clareza.",
"tools": ["SerperDevTool"],
"settings": {
"verbose": true
}
}
```yaml agents.yaml
# src/latest_ai_flow/crews/content_crew/config/agents.yaml
researcher:
role: >
Pesquisador(a) Sênior de Dados em {topic}
goal: >
Descobrir os desenvolvimentos mais recentes em {topic}
backstory: >
Você é um pesquisador experiente que descobre os últimos avanços em {topic}.
Encontra as informações mais relevantes e apresenta tudo com clareza.
```
</Step>
<Step title="Configure a crew em `crew.jsonc`">
Crie `src/latest_ai_flow/crews/content_crew/crew.jsonc`:
```jsonc crew.jsonc
{
"name": "Research Crew",
"agents": ["researcher"],
"tasks": [
{
"name": "research_task",
"description": "Faça uma pesquisa aprofundada sobre {topic}. Use busca na web para obter informações atuais e confiáveis. O ano atual é 2026.",
"expected_output": "Um relatório em markdown com seções claras: tendências principais, ferramentas ou empresas relevantes e implicações. Entre 800 e 1200 palavras. Sem cercas de código em volta do documento inteiro.",
"agent": "researcher",
"output_file": "output/report.md",
"markdown": true
}
],
"process": "sequential",
"verbose": true
}
<Step title="Configure uma tarefa em `tasks.yaml`">
```yaml tasks.yaml
# src/latest_ai_flow/crews/content_crew/config/tasks.yaml
research_task:
description: >
Faça uma pesquisa aprofundada sobre {topic}. Use busca na web para obter
informações atuais e confiáveis. O ano atual é 2026.
expected_output: >
Um relatório em markdown com seções claras: tendências principais, ferramentas
ou empresas relevantes e implicações. Entre 800 e 1200 palavras. Sem cercas de código em volta do documento inteiro.
agent: researcher
output_file: output/report.md
```
</Step>
<Step title="Carregue a crew JSON (`content_crew.py`)">
Substitua o `content_crew.py` gerado por um pequeno loader que transforma `crew.jsonc` em uma `Crew`.
<Step title="Conecte a classe do crew (`content_crew.py`)">
Aponte o crew gerado para o YAML e anexe `SerperDevTool` ao pesquisador.
```python content_crew.py
# src/latest_ai_flow/crews/content_crew/content_crew.py
from pathlib import Path
from typing import List
from crewai.project import load_crew
from crewai import Agent, Crew, Process, Task
from crewai.agents.agent_builder.base_agent import BaseAgent
from crewai.project import CrewBase, agent, crew, task
from crewai_tools import SerperDevTool
def kickoff_content_crew(inputs: dict):
crew, default_inputs = load_crew(Path(__file__).with_name("crew.jsonc"))
return crew.kickoff(inputs={**default_inputs, **inputs})
@CrewBase
class ResearchCrew:
"""Crew de pesquisa com um agente, usado dentro do Flow."""
agents: List[BaseAgent]
tasks: List[Task]
agents_config = "config/agents.yaml"
tasks_config = "config/tasks.yaml"
@agent
def researcher(self) -> Agent:
return Agent(
config=self.agents_config["researcher"], # type: ignore[index]
verbose=True,
tools=[SerperDevTool()],
)
@task
def research_task(self) -> Task:
return Task(
config=self.tasks_config["research_task"], # type: ignore[index]
)
@crew
def crew(self) -> Crew:
return Crew(
agents=self.agents,
tasks=self.tasks,
process=Process.sequential,
verbose=True,
)
```
</Step>
@@ -106,7 +130,7 @@ Se ainda não instalou o CrewAI, siga primeiro o [guia de instalação](/pt-BR/i
from crewai.flow import Flow, listen, start
from latest_ai_flow.crews.content_crew.content_crew import kickoff_content_crew
from latest_ai_flow.crews.content_crew.content_crew import ResearchCrew
class ResearchFlowState(BaseModel):
@@ -125,7 +149,7 @@ Se ainda não instalou o CrewAI, siga primeiro o [guia de instalação](/pt-BR/i
@listen(prepare_topic)
def run_research(self):
result = kickoff_content_crew(inputs={"topic": self.state.topic})
result = ResearchCrew().crew().kickoff(inputs={"topic": self.state.topic})
self.state.report = result.raw
print("Crew de pesquisa concluído.")
@@ -147,7 +171,7 @@ Se ainda não instalou o CrewAI, siga primeiro o [guia de instalação](/pt-BR/i
```
<Tip>
Se o nome do pacote não for `latest_ai_flow`, ajuste o import de `kickoff_content_crew` para o caminho de módulo do seu projeto.
Se o nome do pacote não for `latest_ai_flow`, ajuste o import de `ResearchCrew` para o caminho de módulo do seu projeto.
</Tip>
</Step>
@@ -195,7 +219,7 @@ Se ainda não instalou o CrewAI, siga primeiro o [guia de instalação](/pt-BR/i
## Como isso se encaixa
1. **Flow** — `LatestAiFlow` executa `prepare_topic`, depois `run_research`, depois `summarize`. O estado (`topic`, `report`) fica no Flow.
2. **Crew** — `kickoff_content_crew` carrega `crew.jsonc` e executa uma tarefa com um agente: o pesquisador usa **Serper** na web e escreve o relatório.
2. **Crew** — `ResearchCrew` executa uma tarefa com um agente: o pesquisador usa **Serper** na web e escreve o relatório.
3. **Artefato** — O `output_file` da tarefa grava o relatório em `output/report.md`.
Para ir além em Flows (roteamento, persistência, human-in-the-loop), veja [Construa seu primeiro Flow](/pt-BR/guides/flows/first-flow) e [Flows](/pt-BR/concepts/flows). Para crews sem Flow, veja [Crews](/pt-BR/concepts/crews). Para um único `Agent` com `kickoff()` sem tarefas, veja [Agents](/pt-BR/concepts/agents#direct-agent-interaction-with-kickoff).
@@ -206,10 +230,7 @@ Você tem um Flow ponta a ponta com um crew de agente e um relatório salvo —
### Consistência de nomes
Os nomes em `crew.jsonc` devem coincidir com os arquivos e referências:
- `agents: ["researcher"]` carrega `agents/researcher.jsonc`
- `context: ["research_task"]` referencia uma tarefa anterior chamada `research_task`
As chaves do YAML (`researcher`, `research_task`) devem coincidir com os nomes dos métodos na classe `@CrewBase`. Veja [Crews](/pt-BR/concepts/crews) para o padrão completo com decoradores.
## Implantação

View File

@@ -0,0 +1,23 @@
import logging
from typing import Literal
from crewai.tools import BaseTool
from pydantic import BaseModel, Field
logger = logging.getLogger("lead_flow")
class LogLeadInput(BaseModel):
message: str = Field(description="The message to log.")
level: Literal["debug", "info", "warning", "error"] = "info"
class LogLeadTool(BaseTool):
name: str = "log_lead"
description: str = "Log a message about a lead that was not pursued."
args_schema: type[BaseModel] = LogLeadInput
def _run(self, message: str, level: str = "info") -> str:
logger.log(logging.getLevelName(level.upper()), message)
return message

View File

@@ -0,0 +1,98 @@
# uv run --project lib/crewai crewai run --definition lib/crewai/examples/flows/lead_scoring_flow.yaml --inputs '{"lead":{"name":"Dana Lee","company":"Acme","employees":1200}}'
# uv run --project lib/crewai crewai run --definition lib/crewai/examples/flows/lead_scoring_flow.yaml --inputs '{"lead":{"name":"Sam Poe","company":"Tiny LLC","employees":3}}'
schema: crewai.flow/v1
name: LeadScoringFlow
description: Score an inbound lead, then route high-scoring leads to outreach and the rest to a log tool.
state:
type: dict
default:
lead: {}
methods:
score_lead:
start: true
do:
call: crew
with:
name: lead_scoring_crew
verbose: true
agents:
scorer:
role: Lead Qualification Analyst
goal: Assign a 0-100 fit score to inbound lead {name} from {company}
backstory: >
A revenue-ops veteran who scores leads against a clear ideal
customer profile: company size is the dominant signal.
tasks:
- name: score_lead_task
agent: scorer
description: >
Evaluate the inbound lead {name} from {company} ({employees}
employees) against this rubric, where company size dominates:
1000+ employees scores 85-100 (hot), 200-999 scores 70-84 (warm),
and under 200 scores 0-69 (cold). Return an integer score with a
one-line rationale.
expected_output: >
A LeadScore with an integer `score` (0-100), a short `reasoning`,
and a `tier` of "hot", "warm", or "cold".
output_pydantic:
type: object
properties:
score:
type: integer
reasoning:
type: string
tier:
type: string
enum: [hot, warm, cold]
required: [score, reasoning, tier]
inputs:
name: "${state.lead.name}"
company: "${state.lead.company}"
employees: "${state.lead.employees}"
route_by_score:
listen: score_lead
router: true
emit: [qualified, unqualified]
do:
call: expression
expr: "outputs.score_lead.pydantic.score >= 80 ? 'qualified' : 'unqualified'"
run_outreach:
listen: qualified
do:
call: crew
with:
name: outreach_crew
verbose: true
agents:
sdr:
role: Outbound SDR
goal: Draft a tailored first-touch email to {name} at {company}
backstory: >
A top-performing SDR who writes concise, personalized outreach
that earns replies from busy buyers.
tasks:
- name: draft_outreach_task
agent: sdr
description: >
Write a short, personalized first-touch email to {name} at
{company}. Ground the hook in this qualification rationale:
"{reasoning}".
expected_output: A ready-to-send outreach email with a subject line and body.
inputs:
name: "${state.lead.name}"
company: "${state.lead.company}"
reasoning: "${outputs.score_lead.pydantic.reasoning}"
log_unqualified:
listen: unqualified
do:
call: tool
ref: lead_flow.tools:LogLeadTool
with:
message: "${'Skipped low-fit lead ' + state.lead.name + ' (score ' + string(outputs.score_lead.pydantic.score) + ')'}"
level: info

View File

@@ -28,7 +28,6 @@ from crewai.flow.conversational_definition import (
FlowConversationalDefinition,
FlowConversationalRouterDefinition,
)
from crewai.project.crew_definition import CrewDefinition
logger = logging.getLogger(__name__)
@@ -42,7 +41,6 @@ __all__ = [
"FlowConfigDefinition",
"FlowConversationalDefinition",
"FlowConversationalRouterDefinition",
"FlowCrewActionDefinition",
"FlowDefinition",
"FlowDefinitionCondition",
"FlowDefinitionDiagnostic",
@@ -178,15 +176,6 @@ class FlowToolActionDefinition(BaseModel):
with_: dict[str, Any] | None = Field(default=None, alias="with")
class FlowCrewActionDefinition(BaseModel):
"""A Flow method action that builds and kicks off a CrewAI crew."""
model_config = ConfigDict(populate_by_name=True, extra="forbid")
call: TypingLiteral["crew"]
with_: CrewDefinition = Field(alias="with")
class FlowExpressionActionDefinition(BaseModel):
"""A Flow method action that evaluates a CEL expression."""
@@ -197,10 +186,7 @@ class FlowExpressionActionDefinition(BaseModel):
FlowInnerActionDefinition = (
FlowCodeActionDefinition
| FlowToolActionDefinition
| FlowCrewActionDefinition
| FlowExpressionActionDefinition
FlowCodeActionDefinition | FlowToolActionDefinition | FlowExpressionActionDefinition
)
@@ -250,7 +236,6 @@ class FlowEachActionDefinition(BaseModel):
FlowActionDefinition = (
FlowCodeActionDefinition
| FlowToolActionDefinition
| FlowCrewActionDefinition
| FlowExpressionActionDefinition
| FlowEachActionDefinition
)

View File

@@ -11,7 +11,6 @@ from typing import TYPE_CHECKING, Any, Protocol, cast
from crewai.flow.flow_definition import (
FlowActionDefinition,
FlowCodeActionDefinition,
FlowCrewActionDefinition,
FlowEachActionDefinition,
FlowEachInnerActionDefinition,
FlowExpressionActionDefinition,
@@ -105,25 +104,6 @@ class ToolAction:
) from e
class CrewAction:
definition_type = FlowCrewActionDefinition
def __init__(self, flow: Flow[Any], definition: FlowCrewActionDefinition) -> None:
self.flow = flow
self.definition = definition
async def run(self, *_args: Any, **kwargs: Any) -> Any:
from crewai.project.crew_loader import load_crew_from_definition
local_context = _pop_local_context(kwargs)
crew_definition = self.definition.with_
inputs = render_with_block(
self.flow, crew_definition.inputs, local_context=local_context
)
crew, _ = load_crew_from_definition(crew_definition, source="crew action")
return await crew.kickoff_async(inputs=inputs)
class ExpressionAction:
definition_type = FlowExpressionActionDefinition
@@ -197,7 +177,6 @@ _ACTION_TYPES: tuple[_ActionType, ...] = (
EachAction,
CodeAction,
ToolAction,
CrewAction,
ExpressionAction,
)

View File

@@ -14,22 +14,12 @@ from crewai.project.annotations import (
tool,
)
from crewai.project.crew_base import CrewBase
from crewai.project.crew_definition import (
CrewAgentDefinition,
CrewDefinition,
CrewTaskDefinition,
PythonReferenceDefinition,
)
from crewai.project.crew_loader import load_crew, load_crew_and_kickoff
from crewai.project.json_loader import load_agent, strip_jsonc_comments
__all__ = [
"CrewAgentDefinition",
"CrewBase",
"CrewDefinition",
"CrewTaskDefinition",
"PythonReferenceDefinition",
"after_kickoff",
"agent",
"before_kickoff",

View File

@@ -1,129 +0,0 @@
"""Definition models for inline CrewAI crew configurations."""
from __future__ import annotations
from typing import Any, TypeAlias
from pydantic import BaseModel, ConfigDict, Field, field_validator, model_validator
__all__ = [
"CrewAgentDefinition",
"CrewDefinition",
"CrewTaskDefinition",
"PythonReferenceDefinition",
]
class PythonReferenceDefinition(BaseModel):
"""Dotted Python reference used by crew definitions."""
python: str
@field_validator("python")
@classmethod
def _validate_python_ref(cls, value: str) -> str:
path = value.strip()
if not path:
raise ValueError("Python reference 'python' must be a string")
if "." not in path:
raise ValueError(
f"Python reference '{path}' must be a dotted import path "
"like 'module.attribute'"
)
return path
class CrewAgentDefinition(BaseModel):
"""Inline agent definition used by a crew definition."""
model_config = ConfigDict(extra="allow")
role: str
goal: str
backstory: str
type: str | PythonReferenceDefinition | None = None
settings: dict[str, Any] = Field(default_factory=dict)
@field_validator("settings", mode="before")
@classmethod
def _validate_settings(cls, value: Any) -> Any:
if value is not None and not isinstance(value, dict):
raise ValueError("agent.settings must be a mapping")
return value or {}
class CrewTaskDefinition(BaseModel):
"""Task definition used by a crew definition."""
model_config = ConfigDict(extra="allow")
description: str
expected_output: str
name: str | None = None
agent: str | None = None
context: list[str] | None = None
type: str | PythonReferenceDefinition | None = None
_CrewAgentsInput: TypeAlias = dict[str, CrewAgentDefinition] | list[dict[str, Any]]
class CrewDefinition(BaseModel):
"""In-memory JSON/YAML crew definition with inline agents and tasks."""
model_config = ConfigDict(extra="allow")
agents: dict[str, CrewAgentDefinition]
tasks: list[CrewTaskDefinition]
inputs: dict[str, Any] = Field(default_factory=dict)
manager_agent: str | PythonReferenceDefinition | None = None
@field_validator("inputs", mode="before")
@classmethod
def _validate_inputs(cls, value: Any) -> Any:
if value is not None and not isinstance(value, dict):
raise ValueError("crew.inputs must be a mapping")
return value or {}
@field_validator(
"agents",
mode="before",
json_schema_input_type=_CrewAgentsInput,
)
@classmethod
def _validate_inline_agents(cls, value: Any) -> Any:
if isinstance(value, dict):
return value
if not isinstance(value, list):
return value
agents: dict[str, Any] = {}
for index, item in enumerate(value):
if not isinstance(item, dict):
raise ValueError(f"agents[{index}] must be an inline agent mapping")
if "name" in item:
name = item["name"]
if not isinstance(name, str) or not name:
raise ValueError(f"agents[{index}].name must be a non-empty string")
agents[name] = {key: val for key, val in item.items() if key != "name"}
continue
if len(item) != 1:
raise ValueError(
f"agents[{index}] must include a name field or be a one-key mapping"
)
name, definition = next(iter(item.items()))
agents[str(name)] = definition
return agents
@model_validator(mode="after")
def _validate_inline_shape(self) -> CrewDefinition:
if not self.agents:
raise ValueError("crew action requires inline agent definitions")
if not self.tasks:
raise ValueError("crew action requires a non-empty tasks list")
return self

View File

@@ -7,15 +7,10 @@ from typing import Any
from pydantic import ValidationError
from crewai.project.crew_definition import CrewDefinition
from crewai.project.json_loader import (
JSONAgentDefinition,
JSONCrewProject,
JSONProjectError,
JSONProjectValidationError,
_AgentDefinitionSource,
_crew_kwargs_from_definition,
_load_json_crew_project_definition,
_task_class_from_definition,
_task_kwargs_from_definition,
load_json_crew_project,
@@ -32,73 +27,12 @@ def load_crew(
default inputs. Agent definitions are resolved from individual
``<name>.jsonc`` / ``<name>.json`` files inside an ``agents/`` directory.
"""
crew_path = Path(source)
project = load_json_crew_project(crew_path, agents_dir=agents_dir)
return _load_crew_project(project, project_root=crew_path.parent)
def load_crew_from_definition(
definition: CrewDefinition | dict[str, Any],
*,
source: str | Path = "<inline crew>",
project_root: str | Path | None = None,
) -> tuple[Any, dict[str, Any]]:
"""Load a ``Crew`` from an in-memory JSON/YAML crew definition."""
root = Path(project_root) if project_root is not None else Path.cwd()
source_label = str(source)
crew_definition = (
definition
if isinstance(definition, CrewDefinition)
else CrewDefinition.model_validate(definition)
)
definition_data = crew_definition.model_dump(mode="python", exclude_none=True)
project = _crew_project_from_definition(
definition_data,
source=source_label,
project_root=root,
)
return _load_crew_project(project, project_root=root)
def _crew_project_from_definition(
definition: dict[str, Any],
*,
source: str,
project_root: Path,
) -> JSONCrewProject:
agent_bodies: dict[str, Any] = definition["agents"]
agent_names = list(agent_bodies)
manager_agent = definition.get("manager_agent")
if isinstance(manager_agent, str):
agent_names = [name for name in agent_names if name != manager_agent]
def load_agent_definition_source(agent_name: str) -> _AgentDefinitionSource | None:
body = agent_bodies.get(agent_name)
if body is None:
return None
return body, f"{source}: agents.{agent_name}"
return _load_json_crew_project_definition(
{**definition, "agents": agent_names},
source=source,
agents_dir=project_root / "agents",
project_root=project_root,
load_agent_definition_source=load_agent_definition_source,
missing_agent_hint=None,
collect_errors=False,
)
def _load_crew_project(
project: JSONCrewProject,
*,
project_root: Path,
) -> tuple[Any, dict[str, Any]]:
from crewai import Crew, Task
source_label = str(project.crew_path)
crew_path = Path(source)
project = load_json_crew_project(crew_path, agents_dir=agents_dir)
def build_agent(agent_def: JSONAgentDefinition) -> Any:
def build_agent(agent_def: Any) -> Any:
try:
return agent_def.agent_class(**agent_def.kwargs)
except ValidationError as exc:
@@ -118,26 +52,22 @@ def _load_crew_project(
task_name_map: dict[str, Task] = {}
for index, task_defn in enumerate(project.task_definitions):
task_source = f"{source_label}: tasks[{index}]"
task_class = _task_class_from_definition(
task_defn,
f"{task_source}: type",
project_root=project_root,
)
source_label = f"{crew_path}: tasks[{index}]"
task_class = _task_class_from_definition(task_defn, f"{source_label}: type")
task_kwargs = _task_kwargs_from_definition(
task_defn,
agents_map=agents_map,
task_name_map=task_name_map,
source=task_source,
project_root=project_root,
source=source_label,
project_root=crew_path.parent,
)
try:
task = task_class(**task_kwargs)
except ValidationError as exc:
raise JSONProjectError(f"{task_source}: validation failed: {exc}") from exc
raise JSONProjectError(f"{source_label}: validation failed: {exc}") from exc
except Exception as exc:
raise JSONProjectError(
f"{task_source}: failed to load task: {exc}"
f"{source_label}: failed to load task: {exc}"
) from exc
tasks_list.append(task)
@@ -150,18 +80,17 @@ def _load_crew_project(
agents=[agents_map[name] for name in project.agent_names],
tasks=tasks_list,
agents_map=agents_map,
source=source_label,
project_root=project_root,
source=crew_path,
)
try:
crew = Crew(**crew_kwargs)
except ValidationError as exc:
raise JSONProjectError(f"{source_label}: validation failed: {exc}") from exc
raise JSONProjectError(f"{crew_path}: validation failed: {exc}") from exc
except JSONProjectValidationError:
raise
except Exception as exc:
raise JSONProjectError(f"{source_label}: failed to load crew: {exc}") from exc
raise JSONProjectError(f"{crew_path}: failed to load crew: {exc}") from exc
return crew, project.definition.get("inputs", {})

File diff suppressed because it is too large Load Diff

View File

@@ -99,7 +99,7 @@ def to_serializable(
if isinstance(obj, BaseModel):
try:
return to_serializable(
obj=obj.model_dump(mode="json", exclude=exclude, serialize_as_any=True),
obj=obj.model_dump(mode="json", exclude=exclude),
max_depth=max_depth,
_current_depth=_current_depth + 1,
_ancestors=new_ancestors,

View File

@@ -4,14 +4,12 @@ from __future__ import annotations
import json
from pathlib import Path
import sys
import types
import pytest
from crewai.llms.base_llm import BaseLLM
from crewai.project.json_loader import JSONProjectError, JSONProjectValidationError
from crewai.project.crew_loader import load_crew, load_crew_from_definition
from crewai.project.crew_loader import load_crew
def _write_python_defs(tmp_path: Path) -> None:
@@ -72,91 +70,6 @@ def _input_file_path(value) -> Path:
class TestLoadCrew:
def test_load_crew_from_inline_definition(self):
crew, inputs = load_crew_from_definition(
{
"name": "inline_crew",
"agents": {
"researcher": {
"role": "Researcher",
"goal": "Research {topic}",
"backstory": "Knows things.",
}
},
"tasks": [
{
"name": "research",
"description": "Research {topic}",
"expected_output": "Findings about {topic}",
"agent": "researcher",
}
],
"inputs": {"topic": "AI"},
}
)
assert crew.name == "inline_crew"
assert crew.agents[0].role == "Researcher"
assert crew.tasks[0].description == "Research {topic}"
assert inputs == {"topic": "AI"}
def test_inline_definition_accepts_null_inputs(self):
_, inputs = load_crew_from_definition(
{
"agents": {
"researcher": {
"role": "Researcher",
"goal": "Research",
"backstory": "Knows things.",
}
},
"tasks": [
{
"description": "Research",
"expected_output": "Findings",
"agent": "researcher",
}
],
"inputs": None,
}
)
assert inputs == {}
def test_inline_hierarchical_manager_agent_is_not_duplicated(self):
crew, _ = load_crew_from_definition(
{
"name": "inline_hier_manager_crew",
"agents": {
"worker": {
"role": "Worker",
"goal": "Do work",
"backstory": "Does things.",
},
"manager": {
"role": "Manager",
"goal": "Coordinate work",
"backstory": "Keeps the work moving.",
},
},
"tasks": [
{
"description": "Do work",
"expected_output": "Work done",
"agent": "manager",
}
],
"process": "hierarchical",
"manager_agent": "manager",
}
)
assert len(crew.agents) == 1
assert crew.agents[0].role == "Worker"
assert crew.manager_agent is not None
assert crew.manager_agent.role == "Manager"
assert crew.tasks[0].agent is crew.manager_agent
def test_minimal_crew(self, tmp_path: Path):
agents_dir = tmp_path / "agents"
agents_dir.mkdir()
@@ -562,98 +475,6 @@ class TestLoadCrew:
assert "summary" in task.output_json.model_fields
assert task.converter_cls.__name__ == "SpecialConverter"
def test_crew_rejects_stdlib_python_ref_for_agent_callback(
self, tmp_path: Path
):
agents_dir = tmp_path / "agents"
agents_dir.mkdir()
_write_agent(
agents_dir,
"worker",
step_callback={"python": "os.system"},
)
crew_def = {
"name": "unsafe_callback_crew",
"agents": ["worker"],
"tasks": [
{
"name": "work",
"description": "Do work",
"expected_output": "Work done",
"agent": "worker",
}
],
}
crew_file = _write_crew(tmp_path, crew_def)
with pytest.raises(JSONProjectError, match="project root"):
load_crew(crew_file)
def test_crew_rejects_stdlib_python_ref_for_mcp_tool_filter(
self, tmp_path: Path
):
agents_dir = tmp_path / "agents"
agents_dir.mkdir()
_write_agent(
agents_dir,
"worker",
mcps=[
{
"command": "python",
"args": ["server.py"],
"tool_filter": {"python": "os.system"},
}
],
)
crew_def = {
"name": "unsafe_mcp_filter_crew",
"agents": ["worker"],
"tasks": [
{
"name": "work",
"description": "Do work",
"expected_output": "Work done",
"agent": "worker",
}
],
}
crew_file = _write_crew(tmp_path, crew_def)
with pytest.raises(JSONProjectError, match="project root"):
load_crew(crew_file)
def test_crew_rejects_callable_python_ref_for_object_field(
self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch
):
_write_python_defs(tmp_path)
monkeypatch.syspath_prepend(str(tmp_path))
agents_dir = tmp_path / "agents"
agents_dir.mkdir()
_write_agent(
agents_dir,
"worker",
security_config={"python": "json_refs.always_true"},
)
crew_def = {
"name": "unsafe_object_ref_crew",
"agents": ["worker"],
"tasks": [
{
"name": "work",
"description": "Do work",
"expected_output": "Work done",
"agent": "worker",
}
],
}
crew_file = _write_crew(tmp_path, crew_def)
with pytest.raises(JSONProjectError, match="supported object reference"):
load_crew(crew_file)
def test_crew_loads_project_relative_input_files(self, tmp_path: Path):
agents_dir = tmp_path / "agents"
agents_dir.mkdir()
@@ -689,147 +510,6 @@ class TestLoadCrew:
assert _input_file_path(input_files["brief"]) == brief_path
assert _input_file_path(input_files["spec"]) == spec_path
def test_crew_rejects_relative_input_file_outside_project(self, tmp_path: Path):
agents_dir = tmp_path / "agents"
agents_dir.mkdir()
_write_agent(agents_dir, "reader")
crew_def = {
"name": "unsafe_input_files_crew",
"agents": ["reader"],
"tasks": [
{
"name": "read",
"description": "Read files",
"expected_output": "File summary",
"agent": "reader",
"input_files": {"secret": "../secret.txt"},
}
],
}
crew_file = _write_crew(tmp_path, crew_def)
with pytest.raises(JSONProjectValidationError, match="outside the project root"):
load_crew(crew_file)
def test_crew_rejects_absolute_input_file_outside_project(self, tmp_path: Path):
agents_dir = tmp_path / "agents"
agents_dir.mkdir()
_write_agent(agents_dir, "reader")
outside_path = tmp_path.parent / "secret.txt"
crew_def = {
"name": "unsafe_absolute_input_files_crew",
"agents": ["reader"],
"tasks": [
{
"name": "read",
"description": "Read files",
"expected_output": "File summary",
"agent": "reader",
"input_files": {"secret": str(outside_path)},
}
],
}
crew_file = _write_crew(tmp_path, crew_def)
with pytest.raises(JSONProjectValidationError, match="outside the project root"):
load_crew(crew_file)
def test_crew_rejects_file_uri_input_file_outside_project(self, tmp_path: Path):
agents_dir = tmp_path / "agents"
agents_dir.mkdir()
_write_agent(agents_dir, "reader")
outside_uri = (tmp_path.parent / "secret.txt").as_uri()
crew_def = {
"name": "unsafe_file_uri_input_files_crew",
"agents": ["reader"],
"tasks": [
{
"name": "read",
"description": "Read files",
"expected_output": "File summary",
"agent": "reader",
"input_files": {"secret": outside_uri},
}
],
}
crew_file = _write_crew(tmp_path, crew_def)
with pytest.raises(JSONProjectValidationError, match="outside the project root"):
load_crew(crew_file)
@pytest.mark.parametrize(
"outside_path",
[
r"C:\Users\alice\.ssh\id_rsa",
"C:/Users/alice/.ssh/id_rsa",
r"\\server\share\secret.txt",
"//server/share/secret.txt",
],
)
def test_crew_rejects_windows_input_file_outside_project(
self, tmp_path: Path, outside_path: str
):
agents_dir = tmp_path / "agents"
agents_dir.mkdir()
_write_agent(agents_dir, "reader")
crew_def = {
"name": "unsafe_windows_input_files_crew",
"agents": ["reader"],
"tasks": [
{
"name": "read",
"description": "Read files",
"expected_output": "File summary",
"agent": "reader",
"input_files": {"secret": outside_path},
}
],
}
crew_file = _write_crew(tmp_path, crew_def)
with pytest.raises(JSONProjectValidationError, match="outside the project root"):
load_crew(crew_file)
def test_crew_restores_external_module_cache_after_project_ref(
self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch
):
_write_python_defs(tmp_path)
external_module = types.ModuleType("json_refs")
external_module.__file__ = str(tmp_path.parent / "json_refs.py")
external_module.marker = "external"
monkeypatch.setitem(sys.modules, "json_refs", external_module)
agents_dir = tmp_path / "agents"
agents_dir.mkdir()
_write_agent(
agents_dir,
"worker",
step_callback={"python": "json_refs.task_callback"},
)
crew_def = {
"name": "cache_restore_crew",
"agents": ["worker"],
"tasks": [
{
"name": "work",
"description": "Do work",
"expected_output": "Work done",
"agent": "worker",
}
],
}
crew_file = _write_crew(tmp_path, crew_def)
crew, _ = load_crew(crew_file)
assert crew.agents[0].step_callback.__name__ == "task_callback"
assert sys.modules["json_refs"] is external_module
def test_missing_agent_file_raises(self, tmp_path: Path):
agents_dir = tmp_path / "agents"
agents_dir.mkdir()

View File

@@ -11,7 +11,6 @@ import pytest
from crewai.llms.base_llm import BaseLLM
from crewai.project.json_loader import (
JSONProjectValidationError,
_looks_like_windows_absolute_path,
find_json_project_file,
load_agent,
strip_jsonc_comments,
@@ -75,31 +74,6 @@ def test_find_json_project_file_prefers_jsonc(tmp_path: Path):
assert find_json_project_file(tmp_path, "agent") == jsonc_path
@pytest.mark.parametrize(
"path_value",
[
r"C:\Users\alice\.ssh\id_rsa",
"C:/Users/alice/.ssh/id_rsa",
r"\\server\share\secret.txt",
"//server/share/secret.txt",
],
)
def test_windows_absolute_path_detection(path_value: str):
assert _looks_like_windows_absolute_path(path_value)
@pytest.mark.parametrize(
"path_value",
[
r"folder\file.txt",
"folder/file.txt",
r"\server\share\secret.txt",
],
)
def test_windows_absolute_path_detection_ignores_relative_paths(path_value: str):
assert not _looks_like_windows_absolute_path(path_value)
class TestLoadAgent:
def test_load_minimal_agent(self, tmp_path: Path):
agent_def = {
@@ -506,28 +480,6 @@ class TestValidationDoesNotExecuteTools:
assert "Invalid custom tool name" in str(exc_info.value)
def test_validate_rejects_deep_python_ref_nesting(self, tmp_path):
from crewai.project.json_loader import validate_crew_project
crew_path = self._write_project(
tmp_path,
tool_line='{"tool_type": "some.module.Tool"}',
)
agent_file = tmp_path / "agents" / "worker.jsonc"
agent_def = json.loads(agent_file.read_text())
nested: dict[str, object] = {}
current = nested
for _ in range(70):
child: dict[str, object] = {}
current["nested"] = child
current = child
current["ref"] = {"python": "callbacks.step_callback"}
agent_def["security_config"] = nested
agent_file.write_text(json.dumps(agent_def))
with pytest.raises(JSONProjectValidationError, match="maximum depth"):
validate_crew_project(crew_path, tmp_path / "agents")
class TestCustomToolPathSafety:
@pytest.mark.parametrize(

View File

@@ -3830,6 +3830,7 @@ def test_crew_testing_function(researcher):
assert isinstance(received_events[1], CrewTestCompletedEvent)
@pytest.mark.vcr()
def test_hierarchical_verbose_manager_agent(researcher, writer):
task = Task(
description="Come up with a list of 5 interesting ideas to explore for an article, then write one amazing paragraph highlight for each idea that showcases how good an article about this topic could be. Return the list of ideas with their paragraph and your notes.",
@@ -3844,18 +3845,13 @@ def test_hierarchical_verbose_manager_agent(researcher, writer):
verbose=True,
)
mock_task_output = TaskOutput(
description="Mock description", raw="mocked output", agent="mocked agent", messages=[]
)
task.output = mock_task_output
with patch.object(Task, "execute_sync", return_value=mock_task_output):
crew.kickoff()
crew.kickoff()
assert crew.manager_agent is not None
assert crew.manager_agent.verbose
@pytest.mark.vcr()
def test_hierarchical_verbose_false_manager_agent(researcher, writer):
task = Task(
description="Come up with a list of 5 interesting ideas to explore for an article, then write one amazing paragraph highlight for each idea that showcases how good an article about this topic could be. Return the list of ideas with their paragraph and your notes.",
@@ -3870,13 +3866,7 @@ def test_hierarchical_verbose_false_manager_agent(researcher, writer):
verbose=False,
)
mock_task_output = TaskOutput(
description="Mock description", raw="mocked output", agent="mocked agent", messages=[]
)
task.output = mock_task_output
with patch.object(Task, "execute_sync", return_value=mock_task_output):
crew.kickoff()
crew.kickoff()
assert crew.manager_agent is not None
assert not crew.manager_agent.verbose

View File

@@ -41,7 +41,6 @@ def test_flow_public_exports_are_explicit():
"FlowConfigDefinition",
"FlowConversationalDefinition",
"FlowConversationalRouterDefinition",
"FlowCrewActionDefinition",
"FlowDefinition",
"FlowDefinitionCondition",
"FlowDefinitionDiagnostic",

View File

@@ -765,252 +765,6 @@ methods:
)
def test_crew_action_runs_inline_yaml_definition(monkeypatch: pytest.MonkeyPatch):
from crewai import Crew
async def fake_kickoff_async(
self: Crew, inputs: dict[str, Any] | None = None, **_kwargs: Any
) -> dict[str, Any]:
return {
"crew": self.name,
"agents": [agent.role for agent in self.agents],
"tasks": [task.description for task in self.tasks],
"inputs": inputs,
}
monkeypatch.setattr(Crew, "kickoff_async", fake_kickoff_async)
yaml_str = """
schema: crewai.flow/v1
name: CrewFlow
methods:
research:
do:
call: crew
with:
name: inline_research
agents:
researcher:
role: Researcher
goal: Research {topic}
backstory: Knows things.
tasks:
- name: research_task
description: Research {topic}
expected_output: Findings about {topic}
agent: researcher
inputs:
topic: "${state.topic}"
start: true
"""
flow = Flow.from_definition(FlowDefinition.from_yaml(yaml_str))
assert flow.kickoff(inputs={"topic": "AI"}) == {
"crew": "inline_research",
"agents": ["Researcher"],
"tasks": ["Research {topic}"],
"inputs": {"topic": "AI"},
}
def test_crew_action_round_trips_with_inline_definition():
definition = FlowDefinition.from_dict(
{
"schema": "crewai.flow/v1",
"name": "CrewFlow",
"methods": {
"research": {
"start": True,
"do": {
"call": "crew",
"with": {
"name": "inline_research",
"agents": {
"researcher": {
"role": "Researcher",
"goal": "Research {topic}",
"backstory": "Knows things.",
}
},
"tasks": [
{
"name": "research_task",
"description": "Research {topic}",
"expected_output": "Findings about {topic}",
"agent": "researcher",
}
],
"inputs": {"topic": "${state.topic}"},
},
},
}
},
}
)
assert definition.to_dict()["methods"]["research"]["do"]["call"] == "crew"
assert (
definition.to_dict()["methods"]["research"]["do"]["with"]["agents"][
"researcher"
]["role"]
== "Researcher"
)
def test_crew_action_normalizes_named_agent_list_definition():
definition = FlowDefinition.from_dict(
{
"schema": "crewai.flow/v1",
"name": "CrewFlow",
"methods": {
"research": {
"start": True,
"do": {
"call": "crew",
"with": {
"agents": [
{
"name": "researcher",
"role": "Researcher",
"goal": "Research {topic}",
"backstory": "Knows things.",
}
],
"tasks": [
{
"description": "Research {topic}",
"expected_output": "Findings about {topic}",
"agent": "researcher",
}
],
},
},
}
},
}
)
assert (
definition.to_dict()["methods"]["research"]["do"]["with"]["agents"][
"researcher"
]["role"]
== "Researcher"
)
def test_crew_action_json_schema_describes_inline_crew_definitions():
schema_defs = FlowDefinition.json_schema()["$defs"]
agents_schema = schema_defs["CrewDefinition"]["properties"]["agents"]
assert set(schema_defs["CrewDefinition"]["properties"]) >= {
"agents",
"tasks",
"inputs",
}
assert {option["type"] for option in agents_schema["anyOf"]} == {"array", "object"}
assert set(schema_defs["CrewAgentDefinition"]["properties"]) >= {
"role",
"goal",
"backstory",
"settings",
}
assert set(schema_defs["CrewTaskDefinition"]["properties"]) >= {
"description",
"expected_output",
"agent",
"context",
}
def test_crew_action_rejects_incomplete_inline_agent_definition():
with pytest.raises(ValidationError, match="goal"):
FlowDefinition.from_dict(
{
"schema": "crewai.flow/v1",
"name": "CrewFlow",
"methods": {
"research": {
"start": True,
"do": {
"call": "crew",
"with": {
"agents": {
"researcher": {
"role": "Researcher",
"backstory": "Knows things.",
}
},
"tasks": [
{
"description": "Research",
"expected_output": "Findings",
"agent": "researcher",
}
],
},
},
}
},
}
)
def test_crew_action_rejects_ref():
with pytest.raises(ValidationError, match="ref"):
FlowDefinition.from_dict(
{
"schema": "crewai.flow/v1",
"name": "CrewFlow",
"methods": {
"research": {
"start": True,
"do": {
"call": "crew",
"ref": "project.crew:build_crew",
"with": {"inputs": {"topic": "AI"}},
},
}
},
}
)
def test_crew_action_rejects_non_mapping_inputs_in_definition():
with pytest.raises(ValidationError, match="crew.inputs must be a mapping"):
FlowDefinition.from_dict(
{
"schema": "crewai.flow/v1",
"name": "CrewFlow",
"methods": {
"research": {
"start": True,
"do": {
"call": "crew",
"with": {
"agents": {
"researcher": {
"role": "Researcher",
"goal": "Research",
"backstory": "Knows things.",
}
},
"tasks": [
{
"description": "Research",
"expected_output": "Findings",
"agent": "researcher",
}
],
"inputs": "topic",
},
},
}
},
}
)
def test_tool_action_reports_invalid_cel_expression():
yaml_str = f"""
schema: crewai.flow/v1

View File

@@ -21,10 +21,6 @@ class Person(BaseModel):
skills: List[str]
class Container(BaseModel):
payload: BaseModel | None = None
@dataclass
class DataclassPerson:
name: str
@@ -118,16 +114,6 @@ def test_pydantic_model_serialization():
)
def test_polymorphic_field_serializes_concrete_subclass():
container = Container(
payload=Address(street="1 Main", city="Tech City", country="Pythonia")
)
assert to_serializable(container) == {
"payload": {"street": "1 Main", "city": "Tech City", "country": "Pythonia"}
}
def test_dataclass_serialization_recurses_into_nested_values():
person = DataclassPerson(
name="Ada",