mirror of
https://github.com/crewAIInc/crewAI.git
synced 2026-04-11 13:32:34 +00:00
Compare commits
30 Commits
docs/file-
...
devin/1775
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
da4b610d55 | ||
|
|
baac6668ab | ||
|
|
7bec692878 | ||
|
|
b23b2696fe | ||
|
|
8700e3db33 | ||
|
|
75f162fd3c | ||
|
|
c0f3151e13 | ||
|
|
25eb4adc49 | ||
|
|
1534ba202d | ||
|
|
868416bfe0 | ||
|
|
a5df7c798c | ||
|
|
5958a16ade | ||
|
|
9325e2f6a4 | ||
|
|
25e7ca03c4 | ||
|
|
5b4a0e8734 | ||
|
|
e64b37c5fc | ||
|
|
c132d57a36 | ||
|
|
ad24c3d56e | ||
|
|
0c307f1621 | ||
|
|
f98dde6c62 | ||
|
|
6b6e191532 | ||
|
|
c4e2d7ea3b | ||
|
|
86ce54fc82 | ||
|
|
bf2f4dbce6 | ||
|
|
fdb9b6f090 | ||
|
|
71b4667a0e | ||
|
|
c393bd2ee6 | ||
|
|
baf15a409b | ||
|
|
c907ce473b | ||
|
|
e46402d10d |
2
.github/workflows/build-uv-cache.yml
vendored
2
.github/workflows/build-uv-cache.yml
vendored
@@ -28,7 +28,7 @@ jobs:
|
||||
- name: Install uv
|
||||
uses: astral-sh/setup-uv@v6
|
||||
with:
|
||||
version: "0.8.4"
|
||||
version: "0.11.3"
|
||||
python-version: ${{ matrix.python-version }}
|
||||
enable-cache: false
|
||||
|
||||
|
||||
2
.github/workflows/generate-tool-specs.yml
vendored
2
.github/workflows/generate-tool-specs.yml
vendored
@@ -35,7 +35,7 @@ jobs:
|
||||
- name: Install uv
|
||||
uses: astral-sh/setup-uv@v6
|
||||
with:
|
||||
version: "0.8.4"
|
||||
version: "0.11.3"
|
||||
python-version: "3.12"
|
||||
enable-cache: true
|
||||
|
||||
|
||||
2
.github/workflows/linter.yml
vendored
2
.github/workflows/linter.yml
vendored
@@ -26,7 +26,7 @@ jobs:
|
||||
- name: Install uv
|
||||
uses: astral-sh/setup-uv@v6
|
||||
with:
|
||||
version: "0.8.4"
|
||||
version: "0.11.3"
|
||||
python-version: "3.11"
|
||||
enable-cache: false
|
||||
|
||||
|
||||
2
.github/workflows/nightly.yml
vendored
2
.github/workflows/nightly.yml
vendored
@@ -95,7 +95,7 @@ jobs:
|
||||
- name: Install uv
|
||||
uses: astral-sh/setup-uv@v6
|
||||
with:
|
||||
version: "0.8.4"
|
||||
version: "0.11.3"
|
||||
python-version: "3.12"
|
||||
enable-cache: false
|
||||
|
||||
|
||||
2
.github/workflows/publish.yml
vendored
2
.github/workflows/publish.yml
vendored
@@ -65,7 +65,7 @@ jobs:
|
||||
- name: Install uv
|
||||
uses: astral-sh/setup-uv@v6
|
||||
with:
|
||||
version: "0.8.4"
|
||||
version: "0.11.3"
|
||||
python-version: "3.12"
|
||||
enable-cache: false
|
||||
|
||||
|
||||
2
.github/workflows/tests.yml
vendored
2
.github/workflows/tests.yml
vendored
@@ -36,7 +36,7 @@ jobs:
|
||||
- name: Install uv
|
||||
uses: astral-sh/setup-uv@v6
|
||||
with:
|
||||
version: "0.8.4"
|
||||
version: "0.11.3"
|
||||
python-version: ${{ matrix.python-version }}
|
||||
enable-cache: false
|
||||
|
||||
|
||||
2
.github/workflows/type-checker.yml
vendored
2
.github/workflows/type-checker.yml
vendored
@@ -33,7 +33,7 @@ jobs:
|
||||
- name: Install uv
|
||||
uses: astral-sh/setup-uv@v6
|
||||
with:
|
||||
version: "0.8.4"
|
||||
version: "0.11.3"
|
||||
python-version: ${{ matrix.python-version }}
|
||||
enable-cache: false
|
||||
|
||||
|
||||
2
.github/workflows/update-test-durations.yml
vendored
2
.github/workflows/update-test-durations.yml
vendored
@@ -40,7 +40,7 @@ jobs:
|
||||
- name: Install uv
|
||||
uses: astral-sh/setup-uv@v6
|
||||
with:
|
||||
version: "0.8.4"
|
||||
version: "0.11.3"
|
||||
python-version: ${{ matrix.python-version }}
|
||||
enable-cache: false
|
||||
|
||||
|
||||
2
.github/workflows/vulnerability-scan.yml
vendored
2
.github/workflows/vulnerability-scan.yml
vendored
@@ -33,7 +33,7 @@ jobs:
|
||||
- name: Install uv
|
||||
uses: astral-sh/setup-uv@v6
|
||||
with:
|
||||
version: "0.8.4"
|
||||
version: "0.11.3"
|
||||
python-version: "3.11"
|
||||
enable-cache: false
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ repos:
|
||||
types: [python]
|
||||
exclude: ^(lib/crewai/src/crewai/cli/templates/|lib/crewai/tests/|lib/crewai-tools/tests/|lib/crewai-files/tests/)
|
||||
- repo: https://github.com/astral-sh/uv-pre-commit
|
||||
rev: 0.9.3
|
||||
rev: 0.11.3
|
||||
hooks:
|
||||
- id: uv-lock
|
||||
- repo: https://github.com/commitizen-tools/commitizen
|
||||
|
||||
@@ -4,6 +4,123 @@ description: "تحديثات المنتج والتحسينات وإصلاحات
|
||||
icon: "clock"
|
||||
mode: "wide"
|
||||
---
|
||||
<Update label="7 أبريل 2026">
|
||||
## v1.14.0
|
||||
|
||||
[عرض الإصدار على GitHub](https://github.com/crewAIInc/crewAI/releases/tag/1.14.0)
|
||||
|
||||
## ما الذي تغير
|
||||
|
||||
### الميزات
|
||||
- إضافة أوامر CLI لقائمة/معلومات نقاط التحقق
|
||||
- إضافة guardrail_type و name لتمييز التتبع
|
||||
- إضافة SqliteProvider لتخزين نقاط التحقق
|
||||
- إضافة CheckpointConfig للتسجيل التلقائي لنقاط التحقق
|
||||
- تنفيذ تسجيل حالة وقت التشغيل، نظام الأحداث، وإعادة هيكلة المنفذ
|
||||
|
||||
### إصلاحات الأخطاء
|
||||
- إضافة حماية من SSRF وتجاوز المسار
|
||||
- إضافة التحقق من المسار وعنوان URL لأدوات RAG
|
||||
- استبعاد متجهات التضمين من تسلسل الذاكرة لتوفير الرموز
|
||||
- التأكد من وجود دليل الإخراج قبل الكتابة في قالب التدفق
|
||||
- رفع litellm إلى >=1.83.0 لمعالجة CVE-2026-35030
|
||||
- إزالة حقل فهرسة SEO الذي يتسبب في عرض الصفحة العربية بشكل غير صحيح
|
||||
|
||||
### الوثائق
|
||||
- تحديث سجل التغييرات والإصدار لـ v1.14.0
|
||||
- تحديث أدلة البدء السريع والتثبيت لتحسين الوضوح
|
||||
- إضافة قسم مزودي التخزين، تصدير JsonProvider
|
||||
- إضافة دليل علامة AMP التدريبية
|
||||
|
||||
### إعادة الهيكلة
|
||||
- تنظيف واجهة برمجة تطبيقات نقاط التحقق
|
||||
- إزالة CodeInterpreterTool وإهمال معلمات تنفيذ الكود
|
||||
|
||||
## المساهمون
|
||||
|
||||
@alex-clawd, @github-actions[bot], @greysonlalonde, @iris-clawd, @joaomdmoura, @lorenzejay, @lucasgomide
|
||||
|
||||
</Update>
|
||||
|
||||
<Update label="7 أبريل 2026">
|
||||
## v1.14.0a4
|
||||
|
||||
[عرض الإصدار على GitHub](https://github.com/crewAIInc/crewAI/releases/tag/1.14.0a4)
|
||||
|
||||
## ما الذي تغير
|
||||
|
||||
### الميزات
|
||||
- إضافة guardrail_type و name لتمييز الآثار
|
||||
- إضافة SqliteProvider لتخزين نقاط التحقق
|
||||
- إضافة CheckpointConfig للتخزين التلقائي لنقاط التحقق
|
||||
- تنفيذ نقاط التحقق لحالة التشغيل، نظام الأحداث، وإعادة هيكلة المنفذ
|
||||
|
||||
### إصلاحات الأخطاء
|
||||
- استبعاد متجهات التضمين من تسلسل الذاكرة لتوفير الرموز
|
||||
- رفع litellm إلى >=1.83.0 لمعالجة CVE-2026-35030
|
||||
|
||||
### الوثائق
|
||||
- تحديث أدلة البدء السريع والتثبيت لتحسين الوضوح
|
||||
- إضافة قسم مقدمي التخزين وتصدير JsonProvider
|
||||
|
||||
### الأداء
|
||||
- استخدام JSONB لعمود بيانات نقاط التحقق
|
||||
|
||||
### إعادة الهيكلة
|
||||
- إزالة CodeInterpreterTool وإهمال معلمات تنفيذ الكود
|
||||
|
||||
## المساهمون
|
||||
|
||||
@alex-clawd, @github-actions[bot], @greysonlalonde, @joaomdmoura, @lorenzejay, @lucasgomide
|
||||
|
||||
</Update>
|
||||
|
||||
<Update label="6 أبريل 2026">
|
||||
## v1.14.0a3
|
||||
|
||||
[عرض الإصدار على GitHub](https://github.com/crewAIInc/crewAI/releases/tag/1.14.0a3)
|
||||
|
||||
## ما الذي تغير
|
||||
|
||||
### الوثائق
|
||||
- تحديث سجل التغييرات والإصدار لـ v1.14.0a2
|
||||
|
||||
## المساهمون
|
||||
|
||||
@joaomdmoura
|
||||
|
||||
</Update>
|
||||
|
||||
<Update label="6 أبريل 2026">
|
||||
## v1.14.0a2
|
||||
|
||||
[عرض الإصدار على GitHub](https://github.com/crewAIInc/crewAI/releases/tag/1.14.0a2)
|
||||
|
||||
# ملاحظات الإصدار 1.14.0a2
|
||||
|
||||
## التعليمات:
|
||||
- ترجم جميع عناوين الأقسام والوصف بشكل طبيعي
|
||||
- احتفظ بتنسيق markdown (##، ###، -، إلخ) كما هو
|
||||
- احتفظ بجميع الأسماء الصحيحة، ومعرفات الشيفرة، وأسماء الفئات، والمصطلحات التقنية دون تغيير
|
||||
(مثل "CrewAI"، "LiteAgent"، "ChromaDB"، "MCP"، "@username")
|
||||
- احتفظ بقسم ## المساهمون وأسماء مستخدمي GitHub كما هي
|
||||
- لا تضف أو تزيل أي محتوى، فقط ترجم
|
||||
|
||||
## المميزات الجديدة
|
||||
- تمت إضافة دعم لـ "ChromaDB" لتحسين أداء قاعدة البيانات.
|
||||
- تحسينات على "LiteAgent" لزيادة الكفاءة.
|
||||
|
||||
## الإصلاحات
|
||||
- إصلاح مشكلة تتعلق بـ "MCP" التي كانت تؤدي إلى تعطل التطبيق.
|
||||
- معالجة الأخطاء المتعلقة بواجهة المستخدم في "CrewAI".
|
||||
|
||||
## المساهمون
|
||||
- @username1
|
||||
- @username2
|
||||
- @username3
|
||||
|
||||
</Update>
|
||||
|
||||
<Update label="2 أبريل 2026">
|
||||
## v1.13.0
|
||||
|
||||
|
||||
@@ -250,16 +250,12 @@ analysis_agent = Agent(
|
||||
|
||||
#### تنفيذ الكود
|
||||
|
||||
- `allow_code_execution`: يجب أن يكون True لتشغيل الكود
|
||||
- `code_execution_mode`:
|
||||
- `"safe"`: يستخدم Docker (موصى به للإنتاج)
|
||||
- `"unsafe"`: تنفيذ مباشر (استخدم فقط في بيئات موثوقة)
|
||||
<Warning>
|
||||
`allow_code_execution` و`code_execution_mode` مهجوران. تمت إزالة `CodeInterpreterTool` من `crewai-tools`. استخدم خدمة بيئة معزولة مخصصة مثل [E2B](https://e2b.dev) أو [Modal](https://modal.com) لتنفيذ الكود بأمان.
|
||||
</Warning>
|
||||
|
||||
<Note>
|
||||
يشغّل هذا صورة Docker افتراضية. إذا أردت تهيئة صورة Docker،
|
||||
راجع أداة Code Interpreter في قسم الأدوات. أضف أداة
|
||||
مفسر الكود كأداة في معامل أداة الوكيل.
|
||||
</Note>
|
||||
- `allow_code_execution` _(مهجور)_: كان يُمكّن تنفيذ الكود المدمج عبر `CodeInterpreterTool`.
|
||||
- `code_execution_mode` _(مهجور)_: كان يتحكم في وضع التنفيذ (`"safe"` لـ Docker، `"unsafe"` للتنفيذ المباشر).
|
||||
|
||||
#### الميزات المتقدمة
|
||||
|
||||
@@ -332,9 +328,9 @@ print(result.raw)
|
||||
|
||||
### الأمان وتنفيذ الكود
|
||||
|
||||
- عند استخدام `allow_code_execution`، كن حذرًا مع مدخلات المستخدم وتحقق منها دائمًا
|
||||
- استخدم `code_execution_mode: "safe"` (Docker) في بيئات الإنتاج
|
||||
- فكّر في تعيين حدود `max_execution_time` مناسبة لمنع الحلقات اللانهائية
|
||||
<Warning>
|
||||
`allow_code_execution` و`code_execution_mode` مهجوران وتمت إزالة `CodeInterpreterTool`. استخدم خدمة بيئة معزولة مخصصة مثل [E2B](https://e2b.dev) أو [Modal](https://modal.com) لتنفيذ الكود بأمان.
|
||||
</Warning>
|
||||
|
||||
### تحسين الأداء
|
||||
|
||||
|
||||
229
docs/ar/concepts/checkpointing.mdx
Normal file
229
docs/ar/concepts/checkpointing.mdx
Normal file
@@ -0,0 +1,229 @@
|
||||
---
|
||||
title: Checkpointing
|
||||
description: حفظ حالة التنفيذ تلقائيا حتى تتمكن الطواقم والتدفقات والوكلاء من الاستئناف بعد الفشل.
|
||||
icon: floppy-disk
|
||||
mode: "wide"
|
||||
---
|
||||
|
||||
<Warning>
|
||||
الـ Checkpointing في اصدار مبكر. قد تتغير واجهات البرمجة في الاصدارات المستقبلية.
|
||||
</Warning>
|
||||
|
||||
## نظرة عامة
|
||||
|
||||
يقوم الـ Checkpointing بحفظ حالة التنفيذ تلقائيا اثناء التشغيل. اذا فشل طاقم او تدفق او وكيل اثناء التنفيذ، يمكنك الاستعادة من اخر نقطة حفظ والاستئناف دون اعادة تنفيذ العمل المكتمل.
|
||||
|
||||
## البداية السريعة
|
||||
|
||||
```python
|
||||
from crewai import Crew, CheckpointConfig
|
||||
|
||||
crew = Crew(
|
||||
agents=[...],
|
||||
tasks=[...],
|
||||
checkpoint=True, # يستخدم الافتراضيات: ./.checkpoints, عند task_completed
|
||||
)
|
||||
result = crew.kickoff()
|
||||
```
|
||||
|
||||
تتم كتابة ملفات نقاط الحفظ في `./.checkpoints/` بعد اكتمال كل مهمة.
|
||||
|
||||
## التكوين
|
||||
|
||||
استخدم `CheckpointConfig` للتحكم الكامل:
|
||||
|
||||
```python
|
||||
from crewai import Crew, CheckpointConfig
|
||||
|
||||
crew = Crew(
|
||||
agents=[...],
|
||||
tasks=[...],
|
||||
checkpoint=CheckpointConfig(
|
||||
location="./my_checkpoints",
|
||||
on_events=["task_completed", "crew_kickoff_completed"],
|
||||
max_checkpoints=5,
|
||||
),
|
||||
)
|
||||
```
|
||||
|
||||
### حقول CheckpointConfig
|
||||
|
||||
| الحقل | النوع | الافتراضي | الوصف |
|
||||
|:------|:------|:----------|:------|
|
||||
| `location` | `str` | `"./.checkpoints"` | مسار ملفات نقاط الحفظ |
|
||||
| `on_events` | `list[str]` | `["task_completed"]` | انواع الاحداث التي تطلق نقطة حفظ |
|
||||
| `provider` | `BaseProvider` | `JsonProvider()` | واجهة التخزين |
|
||||
| `max_checkpoints` | `int \| None` | `None` | الحد الاقصى للملفات؛ يتم حذف الاقدم اولا |
|
||||
|
||||
### الوراثة والانسحاب
|
||||
|
||||
يقبل حقل `checkpoint` في Crew و Flow و Agent قيم `CheckpointConfig` او `True` او `False` او `None`:
|
||||
|
||||
| القيمة | السلوك |
|
||||
|:-------|:-------|
|
||||
| `None` (افتراضي) | يرث من الاصل. الوكيل يرث اعدادات الطاقم. |
|
||||
| `True` | تفعيل بالاعدادات الافتراضية. |
|
||||
| `False` | انسحاب صريح. يوقف الوراثة من الاصل. |
|
||||
| `CheckpointConfig(...)` | اعدادات مخصصة. |
|
||||
|
||||
```python
|
||||
crew = Crew(
|
||||
agents=[
|
||||
Agent(role="Researcher", ...), # يرث checkpoint من الطاقم
|
||||
Agent(role="Writer", ..., checkpoint=False), # منسحب، بدون نقاط حفظ
|
||||
],
|
||||
tasks=[...],
|
||||
checkpoint=True,
|
||||
)
|
||||
```
|
||||
|
||||
## الاستئناف من نقطة حفظ
|
||||
|
||||
```python
|
||||
# استعادة واستئناف
|
||||
crew = Crew.from_checkpoint("./my_checkpoints/20260407T120000_abc123.json")
|
||||
result = crew.kickoff() # يستأنف من اخر مهمة مكتملة
|
||||
```
|
||||
|
||||
يتخطى الطاقم المستعاد المهام المكتملة ويستأنف من اول مهمة غير مكتملة.
|
||||
|
||||
## يعمل على Crew و Flow و Agent
|
||||
|
||||
### Crew
|
||||
|
||||
```python
|
||||
crew = Crew(
|
||||
agents=[researcher, writer],
|
||||
tasks=[research_task, write_task, review_task],
|
||||
checkpoint=CheckpointConfig(location="./crew_cp"),
|
||||
)
|
||||
```
|
||||
|
||||
المشغل الافتراضي: `task_completed` (نقطة حفظ واحدة لكل مهمة مكتملة).
|
||||
|
||||
### Flow
|
||||
|
||||
```python
|
||||
from crewai.flow.flow import Flow, start, listen
|
||||
from crewai import CheckpointConfig
|
||||
|
||||
class MyFlow(Flow):
|
||||
@start()
|
||||
def step_one(self):
|
||||
return "data"
|
||||
|
||||
@listen(step_one)
|
||||
def step_two(self, data):
|
||||
return process(data)
|
||||
|
||||
flow = MyFlow(
|
||||
checkpoint=CheckpointConfig(
|
||||
location="./flow_cp",
|
||||
on_events=["method_execution_finished"],
|
||||
),
|
||||
)
|
||||
result = flow.kickoff()
|
||||
|
||||
# استئناف
|
||||
flow = MyFlow.from_checkpoint("./flow_cp/20260407T120000_abc123.json")
|
||||
result = flow.kickoff()
|
||||
```
|
||||
|
||||
### Agent
|
||||
|
||||
```python
|
||||
agent = Agent(
|
||||
role="Researcher",
|
||||
goal="Research topics",
|
||||
backstory="Expert researcher",
|
||||
checkpoint=CheckpointConfig(
|
||||
location="./agent_cp",
|
||||
on_events=["lite_agent_execution_completed"],
|
||||
),
|
||||
)
|
||||
result = agent.kickoff(messages=[{"role": "user", "content": "Research AI trends"}])
|
||||
```
|
||||
|
||||
## مزودات التخزين
|
||||
|
||||
يتضمن CrewAI مزودي تخزين لنقاط الحفظ.
|
||||
|
||||
### JsonProvider (افتراضي)
|
||||
|
||||
يكتب كل نقطة حفظ كملف JSON منفصل.
|
||||
|
||||
```python
|
||||
from crewai import Crew, CheckpointConfig
|
||||
from crewai.state import JsonProvider
|
||||
|
||||
crew = Crew(
|
||||
agents=[...],
|
||||
tasks=[...],
|
||||
checkpoint=CheckpointConfig(
|
||||
location="./my_checkpoints",
|
||||
provider=JsonProvider(),
|
||||
max_checkpoints=5,
|
||||
),
|
||||
)
|
||||
```
|
||||
|
||||
### SqliteProvider
|
||||
|
||||
يخزن جميع نقاط الحفظ في ملف قاعدة بيانات SQLite واحد.
|
||||
|
||||
```python
|
||||
from crewai import Crew, CheckpointConfig
|
||||
from crewai.state import SqliteProvider
|
||||
|
||||
crew = Crew(
|
||||
agents=[...],
|
||||
tasks=[...],
|
||||
checkpoint=CheckpointConfig(
|
||||
location="./.checkpoints.db",
|
||||
provider=SqliteProvider(),
|
||||
),
|
||||
)
|
||||
```
|
||||
|
||||
|
||||
## انواع الاحداث
|
||||
|
||||
يقبل حقل `on_events` اي مجموعة من سلاسل انواع الاحداث. الخيارات الشائعة:
|
||||
|
||||
| حالة الاستخدام | الاحداث |
|
||||
|:---------------|:--------|
|
||||
| بعد كل مهمة (Crew) | `["task_completed"]` |
|
||||
| بعد كل طريقة في التدفق | `["method_execution_finished"]` |
|
||||
| بعد تنفيذ الوكيل | `["agent_execution_completed"]`, `["lite_agent_execution_completed"]` |
|
||||
| عند اكتمال الطاقم فقط | `["crew_kickoff_completed"]` |
|
||||
| بعد كل استدعاء LLM | `["llm_call_completed"]` |
|
||||
| على كل شيء | `["*"]` |
|
||||
|
||||
<Warning>
|
||||
استخدام `["*"]` او احداث عالية التردد مثل `llm_call_completed` سيكتب العديد من ملفات نقاط الحفظ وقد يؤثر على الاداء. استخدم `max_checkpoints` للحد من استخدام المساحة.
|
||||
</Warning>
|
||||
|
||||
## نقاط الحفظ اليدوية
|
||||
|
||||
للتحكم الكامل، سجل معالج الاحداث الخاص بك واستدع `state.checkpoint()` مباشرة:
|
||||
|
||||
```python
|
||||
from crewai.events.event_bus import crewai_event_bus
|
||||
from crewai.events.types.llm_events import LLMCallCompletedEvent
|
||||
|
||||
# معالج متزامن
|
||||
@crewai_event_bus.on(LLMCallCompletedEvent)
|
||||
def on_llm_done(source, event, state):
|
||||
path = state.checkpoint("./my_checkpoints")
|
||||
print(f"تم حفظ نقطة الحفظ: {path}")
|
||||
|
||||
# معالج غير متزامن
|
||||
@crewai_event_bus.on(LLMCallCompletedEvent)
|
||||
async def on_llm_done_async(source, event, state):
|
||||
path = await state.acheckpoint("./my_checkpoints")
|
||||
print(f"تم حفظ نقطة الحفظ: {path}")
|
||||
```
|
||||
|
||||
وسيط `state` هو `RuntimeState` الذي يتم تمريره تلقائيا بواسطة ناقل الاحداث عندما يقبل المعالج 3 معاملات. يمكنك تسجيل معالجات على اي نوع حدث مدرج في وثائق [Event Listeners](/ar/concepts/event-listener).
|
||||
|
||||
الـ Checkpointing يعمل بافضل جهد: اذا فشلت كتابة نقطة حفظ، يتم تسجيل الخطأ ولكن التنفيذ يستمر دون انقطاع.
|
||||
@@ -117,35 +117,23 @@ task = Task(
|
||||
|
||||
### مع التدفقات
|
||||
|
||||
تعمل الحقول من نوع الملف (`File`، `ImageFile`، `PDFFile`) في مخطط حالة التدفق كإشارة لواجهة المنصة. عند النشر، تُعرض هذه الحقول كمناطق سحب وإفلات لرفع الملفات. يمكن أيضًا تمرير الملفات عبر `input_files` في API.
|
||||
مرر الملفات إلى التدفقات، والتي تنتقل تلقائيًا إلى الأطقم:
|
||||
|
||||
```python
|
||||
from crewai.flow.flow import Flow, start
|
||||
from crewai_files import File, ImageFile
|
||||
from pydantic import BaseModel
|
||||
from crewai_files import ImageFile
|
||||
|
||||
class MyState(BaseModel):
|
||||
document: File # Renders as file dropzone in Platform UI
|
||||
cover_image: ImageFile # Image-specific dropzone
|
||||
title: str = ""
|
||||
|
||||
class AnalysisFlow(Flow[MyState]):
|
||||
class AnalysisFlow(Flow):
|
||||
@start()
|
||||
def analyze(self):
|
||||
# Files are automatically populated in state
|
||||
content = self.state.document.read()
|
||||
return self.analysis_crew.kickoff()
|
||||
|
||||
flow = AnalysisFlow()
|
||||
result = flow.kickoff(
|
||||
input_files={"document": File(source="report.pdf")}
|
||||
input_files={"image": ImageFile(source="data.png")}
|
||||
)
|
||||
```
|
||||
|
||||
<Note type="info" title="تكامل منصة CrewAI">
|
||||
عند النشر على منصة CrewAI، تحصل الحقول من نوع الملف مثل `ImageFile` و `PDFFile` وغيرها في حالة التدفق تلقائيًا على واجهة رفع ملفات. يمكن للمستخدمين سحب وإفلات الملفات مباشرة في واجهة المنصة. يتم تخزين الملفات بشكل آمن وتمريرها إلى الوكلاء باستخدام تحسينات خاصة بالمزود (base64 مضمّن، أو واجهات برمجة لرفع الملفات، أو مراجع URL حسب المزود). للاطلاع على أمثلة استخدام API، راجع [مدخلات الملفات في التدفقات](/ar/concepts/flows#مدخلات-الملفات).
|
||||
</Note>
|
||||
|
||||
### مع الوكلاء المستقلين
|
||||
|
||||
مرر الملفات مباشرة إلى تشغيل الوكيل:
|
||||
|
||||
@@ -341,90 +341,6 @@ flow.kickoff()
|
||||
|
||||
من خلال توفير خيارات إدارة الحالة غير المهيكلة والمهيكلة، تمكّن تدفقات CrewAI المطورين من بناء سير عمل ذكاء اصطناعي مرن ومتين في آن واحد، ملبيةً مجموعة واسعة من متطلبات التطبيقات.
|
||||
|
||||
### مدخلات الملفات
|
||||
|
||||
عند استخدام الحالة المهيكلة، يمكنك تضمين حقول من نوع الملف باستخدام فئات من `crewai-files`. تعمل الحقول من نوع الملف في حالة التدفق كإشارة للمنصة — فهي تُعرض تلقائيًا كمناطق سحب وإفلات لرفع الملفات في واجهة علامة تبويب Run ويتم تعبئتها عند رفع الملفات عبر المنصة أو تمريرها عبر `input_files` في API.
|
||||
|
||||
```python
|
||||
from crewai.flow.flow import Flow, start
|
||||
from crewai_files import File, ImageFile, PDFFile
|
||||
from pydantic import BaseModel
|
||||
|
||||
class MyState(BaseModel):
|
||||
document: File # Renders as file dropzone in Platform
|
||||
title: str = ""
|
||||
|
||||
class MyFlow(Flow[MyState]):
|
||||
@start()
|
||||
def process(self):
|
||||
# File object is automatically populated in state
|
||||
# when uploaded via Platform UI or passed via API
|
||||
content = self.state.document.read()
|
||||
print(f"Processing {self.state.title}: {len(content)} bytes")
|
||||
return content
|
||||
```
|
||||
|
||||
عند النشر على **منصة CrewAI**، تُعرض الحقول من نوع الملف (`File`، `ImageFile`، `PDFFile` من `crewai-files`) تلقائيًا كمناطق سحب وإفلات لرفع الملفات في واجهة المستخدم. يمكن للمستخدمين سحب وإفلات الملفات، والتي تُملأ بعد ذلك في حالة التدفق الخاص بك.
|
||||
|
||||
**بدء التشغيل مع الملفات عبر API:**
|
||||
|
||||
تكتشف نقطة النهاية `/kickoff` تنسيق الطلب تلقائيًا:
|
||||
- **جسم JSON** ← بدء تشغيل عادي
|
||||
- **multipart/form-data** ← رفع ملف + بدء تشغيل
|
||||
|
||||
يمكن لمستخدمي API أيضًا تمرير سلاسل URL مباشرة إلى الحقول من نوع الملف — يقوم Pydantic بتحويلها تلقائيًا.
|
||||
|
||||
### استخدام API
|
||||
|
||||
#### الخيار 1: بدء تشغيل multipart (موصى به)
|
||||
|
||||
أرسل الملفات مباشرة مع طلب بدء التشغيل:
|
||||
|
||||
```bash
|
||||
# With files (multipart) — same endpoint
|
||||
curl -X POST https://your-deployment.crewai.com/kickoff \
|
||||
-H 'Authorization: Bearer YOUR_TOKEN' \
|
||||
-F 'inputs={"company_name": "Einstein"}' \
|
||||
-F 'cover_image=@/path/to/photo.jpg'
|
||||
```
|
||||
|
||||
يتم تخزين الملفات تلقائيًا وتحويلها إلى كائنات `FileInput`. يتلقى الوكيل الملف مع تحسين خاص بالمزود (base64 مضمّن، أو API لرفع الملفات، أو مرجع URL حسب مزود LLM).
|
||||
|
||||
#### الخيار 2: بدء تشغيل JSON (بدون ملفات)
|
||||
|
||||
```bash
|
||||
# Without files (JSON) — same endpoint
|
||||
curl -X POST https://your-deployment.crewai.com/kickoff \
|
||||
-H 'Authorization: Bearer YOUR_TOKEN' \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d '{"inputs": {"company_name": "Einstein"}}'
|
||||
```
|
||||
|
||||
#### الخيار 3: رفع منفصل + بدء تشغيل
|
||||
|
||||
هذا بديل لرفع multipart عندما تحتاج إلى رفع الملفات بشكل منفصل عن طلب بدء التشغيل. ارفع الملفات أولاً، ثم أشِر إليها بواسطة URL:
|
||||
|
||||
```bash
|
||||
# Step 1: Upload
|
||||
curl -X POST https://your-deployment.crewai.com/files \
|
||||
-H 'Authorization: Bearer YOUR_TOKEN' \
|
||||
-F 'file=@/path/to/photo.jpg' \
|
||||
-F 'field_name=cover_image'
|
||||
# Returns: {"url": "https://...", "field_name": "cover_image"}
|
||||
|
||||
# Step 2: Kickoff with URL
|
||||
curl -X POST https://your-deployment.crewai.com/kickoff \
|
||||
-H 'Authorization: Bearer YOUR_TOKEN' \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d '{"inputs": {"company_name": "Einstein"}, "input_files": {"cover_image": "https://..."}}'
|
||||
```
|
||||
|
||||
راجع وثائق Platform API للحصول على تفاصيل كاملة حول نقطة النهاية `/files`.
|
||||
|
||||
#### على منصة CrewAI
|
||||
|
||||
عند استخدام واجهة المنصة، تُعرض الحقول من نوع الملف تلقائيًا كمناطق سحب وإفلات للرفع. لا حاجة لاستدعاءات API — فقط أفلِت الملف وانقر على تشغيل.
|
||||
|
||||
## استمرارية التدفق
|
||||
|
||||
يتيح مزخرف @persist الاستمرارية التلقائية للحالة في تدفقات CrewAI، مما يسمح لك بالحفاظ على حالة التدفق عبر عمليات إعادة التشغيل أو تنفيذات سير العمل المختلفة. يمكن تطبيق هذا المزخرف على مستوى الفئة أو مستوى الدالة، مما يوفر مرونة في كيفية إدارة استمرارية الحالة.
|
||||
|
||||
@@ -106,7 +106,7 @@ mode: "wide"
|
||||
```
|
||||
|
||||
<Tip>
|
||||
يستغرق النشر الأول عادة 10-15 دقيقة لبناء صور الحاويات. عمليات النشر اللاحقة أسرع بكثير.
|
||||
يستغرق النشر الأول عادة حوالي دقيقة واحدة.
|
||||
</Tip>
|
||||
|
||||
</Step>
|
||||
@@ -188,7 +188,7 @@ crewai deploy remove <deployment_id>
|
||||
|
||||
1. انقر على زر "Deploy" لبدء عملية النشر
|
||||
2. يمكنك مراقبة التقدم عبر شريط التقدم
|
||||
3. يستغرق النشر الأول عادة حوالي 10-15 دقيقة؛ عمليات النشر اللاحقة ستكون أسرع
|
||||
3. يستغرق النشر الأول عادة حوالي دقيقة واحدة
|
||||
|
||||
<Frame>
|
||||

|
||||
|
||||
@@ -86,60 +86,6 @@ curl -H "Authorization: Bearer YOUR_CREW_TOKEN" https://your-crew-url.crewai.com
|
||||
|
||||
رمز الحامل متاح في علامة تبويب Status في صفحة تفاصيل طاقمك.
|
||||
|
||||
## رفع الملفات
|
||||
|
||||
عندما يتضمن طاقمك أو تدفقك حقول حالة من نوع الملف (باستخدام `ImageFile` أو `PDFFile` أو `File` من `crewai-files`)، تُعرض هذه الحقول تلقائيًا كمناطق سحب وإفلات لرفع الملفات في واجهة علامة تبويب Run. يمكن للمستخدمين سحب وإفلات الملفات مباشرة، وتتولى المنصة التخزين والتسليم إلى وكلائك.
|
||||
|
||||
### بدء تشغيل Multipart (موصى به)
|
||||
|
||||
أرسل الملفات مباشرة مع طلب بدء التشغيل باستخدام `multipart/form-data`:
|
||||
|
||||
```bash
|
||||
curl -X POST https://your-deployment.crewai.com/kickoff \
|
||||
-H 'Authorization: Bearer YOUR_TOKEN' \
|
||||
-F 'inputs={"title": "Report"}' \
|
||||
-F 'document=@/path/to/file.pdf'
|
||||
```
|
||||
|
||||
يتم تخزين الملفات تلقائيًا وتحويلها إلى كائنات ملفات. يتلقى الوكيل الملف مع تحسين خاص بالمزود (base64 مضمّن، أو API لرفع الملفات، أو مرجع URL حسب مزود LLM).
|
||||
|
||||
### بدء تشغيل JSON مع عناوين URL للملفات
|
||||
|
||||
إذا كانت لديك ملفات مستضافة بالفعل على عناوين URL، مررها عبر `input_files`:
|
||||
|
||||
```bash
|
||||
curl -X POST https://your-deployment.crewai.com/kickoff \
|
||||
-H 'Authorization: Bearer YOUR_TOKEN' \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d '{
|
||||
"inputs": {"title": "Report"},
|
||||
"input_files": {"document": "https://example.com/file.pdf"}
|
||||
}'
|
||||
```
|
||||
|
||||
### رفع منفصل + بدء تشغيل
|
||||
|
||||
ارفع الملفات أولاً، ثم أشِر إليها بواسطة URL:
|
||||
|
||||
```bash
|
||||
# Step 1: Upload
|
||||
curl -X POST https://your-deployment.crewai.com/files \
|
||||
-H 'Authorization: Bearer YOUR_TOKEN' \
|
||||
-F 'file=@/path/to/file.pdf' \
|
||||
-F 'field_name=document'
|
||||
# Returns: {"url": "https://...", "field_name": "document"}
|
||||
|
||||
# Step 2: Kickoff with URL
|
||||
curl -X POST https://your-deployment.crewai.com/kickoff \
|
||||
-H 'Authorization: Bearer YOUR_TOKEN' \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d '{"inputs": {"title": "Report"}, "input_files": {"document": "https://..."}}'
|
||||
```
|
||||
|
||||
<Note type="info">
|
||||
يعمل رفع الملفات بنفس الطريقة لكل من الطواقم والتدفقات. عرّف حقول من نوع الملف في مخطط حالتك، وستتولى واجهة المنصة وAPI الرفع تلقائيًا.
|
||||
</Note>
|
||||
|
||||
### التحقق من صحة الطاقم
|
||||
|
||||
قبل تنفيذ العمليات، يمكنك التحقق من أن طاقمك يعمل بشكل صحيح:
|
||||
|
||||
@@ -204,8 +204,8 @@ python3 --version
|
||||
## الخطوات التالية
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="ابنِ أول Agent لك" icon="code" href="/ar/quickstart">
|
||||
اتبع دليل البداية السريعة لإنشاء أول Agent في CrewAI والحصول على تجربة عملية.
|
||||
<Card title="بدء سريع: Flow + وكيل" icon="code" href="/ar/quickstart">
|
||||
اتبع البداية السريعة لإنشاء Flow وتشغيل طاقم بوكيل واحد وإنتاج تقرير.
|
||||
</Card>
|
||||
<Card
|
||||
title="انضم إلى المجتمع"
|
||||
|
||||
@@ -138,9 +138,9 @@ mode: "wide"
|
||||
<Card
|
||||
title="البداية السريعة"
|
||||
icon="bolt"
|
||||
href="en/quickstart"
|
||||
href="/ar/quickstart"
|
||||
>
|
||||
اتبع دليل البداية السريعة لإنشاء أول Agent في CrewAI والحصول على تجربة عملية.
|
||||
أنشئ Flow وشغّل طاقمًا بوكيل واحد وأنشئ تقريرًا من البداية للنهاية.
|
||||
</Card>
|
||||
<Card
|
||||
title="انضم إلى المجتمع"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
title: البدء السريع
|
||||
description: ابنِ أول وكيل ذكاء اصطناعي مع CrewAI في أقل من 5 دقائق.
|
||||
description: ابنِ أول Flow في CrewAI خلال دقائق — التنسيق والحالة وفريقًا بوكيل واحد ينتج تقريرًا فعليًا.
|
||||
icon: rocket
|
||||
mode: "wide"
|
||||
---
|
||||
@@ -13,376 +13,266 @@ mode: "wide"
|
||||
|
||||
<iframe src="https://www.loom.com/embed/befb9f68b81f42ad8112bfdd95a780af" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen style={{width: "100%", height: "400px"}}></iframe>
|
||||
|
||||
## ابنِ أول وكيل CrewAI
|
||||
في هذا الدليل ستُنشئ **Flow** يحدد موضوع بحث، ويشغّل **طاقمًا بوكيل واحد** (باحث يستخدم البحث على الويب)، وينتهي بتقرير **Markdown** على القرص. يُعد Flow الطريقة الموصى بها لتنظيم التطبيقات الإنتاجية: يمتلك **الحالة** و**ترتيب التنفيذ**، بينما **الوكلاء** ينفّذون العمل داخل خطوة الطاقم.
|
||||
|
||||
لننشئ طاقماً بسيطاً يساعدنا في `البحث` و`إعداد التقارير` عن `أحدث تطورات الذكاء الاصطناعي` لموضوع أو مجال معين.
|
||||
إذا لم تُكمل تثبيت CrewAI بعد، اتبع [دليل التثبيت](/ar/installation) أولًا.
|
||||
|
||||
قبل المتابعة، تأكد من إنهاء تثبيت CrewAI.
|
||||
إذا لم تكن قد ثبّتها بعد، يمكنك القيام بذلك باتباع [دليل التثبيت](/ar/installation).
|
||||
## المتطلبات الأساسية
|
||||
|
||||
اتبع الخطوات أدناه للبدء!
|
||||
- بيئة Python وواجهة سطر أوامر CrewAI (راجع [التثبيت](/ar/installation))
|
||||
- نموذج لغوي مهيأ بالمفاتيح الصحيحة — راجع [LLMs](/ar/concepts/llms#setting-up-your-llm)
|
||||
- مفتاح API من [Serper.dev](https://serper.dev/) (`SERPER_API_KEY`) للبحث على الويب في هذا الدرس
|
||||
|
||||
## ابنِ أول Flow لك
|
||||
|
||||
<Steps>
|
||||
<Step title="إنشاء طاقمك">
|
||||
أنشئ مشروع طاقم جديد عبر تشغيل الأمر التالي في الطرفية.
|
||||
سينشئ هذا مجلداً جديداً باسم `latest-ai-development` مع البنية الأساسية لطاقمك.
|
||||
<Step title="أنشئ مشروع Flow">
|
||||
من الطرفية، أنشئ مشروع Flow (اسم المجلد يستخدم شرطة سفلية، مثل `latest_ai_flow`):
|
||||
|
||||
<CodeGroup>
|
||||
```shell Terminal
|
||||
crewai create crew latest-ai-development
|
||||
crewai create flow latest-ai-flow
|
||||
cd latest_ai_flow
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
يُنشئ ذلك تطبيق Flow ضمن `src/latest_ai_flow/`، بما في ذلك طاقمًا أوليًا في `crews/content_crew/` ستستبدله بطاقم بحث **بوكيل واحد** في الخطوات التالية.
|
||||
</Step>
|
||||
<Step title="الانتقال إلى مشروع الطاقم الجديد">
|
||||
<CodeGroup>
|
||||
```shell Terminal
|
||||
cd latest_ai_development
|
||||
```
|
||||
</CodeGroup>
|
||||
</Step>
|
||||
<Step title="تعديل ملف `agents.yaml`">
|
||||
<Tip>
|
||||
يمكنك أيضاً تعديل الوكلاء حسب الحاجة ليناسبوا حالة الاستخدام الخاصة بك أو نسخ ولصق كما هو في مشروعك.
|
||||
أي متغير مُستكمل في ملفات `agents.yaml` و`tasks.yaml` مثل `{topic}` سيُستبدل بقيمة المتغير في ملف `main.py`.
|
||||
</Tip>
|
||||
|
||||
<Step title="اضبط وكيلًا واحدًا في `agents.yaml`">
|
||||
استبدل محتوى `src/latest_ai_flow/crews/content_crew/config/agents.yaml` بباحث واحد. تُملأ المتغيرات مثل `{topic}` من `crew.kickoff(inputs=...)`.
|
||||
|
||||
```yaml agents.yaml
|
||||
# src/latest_ai_development/config/agents.yaml
|
||||
# src/latest_ai_flow/crews/content_crew/config/agents.yaml
|
||||
researcher:
|
||||
role: >
|
||||
{topic} Senior Data Researcher
|
||||
باحث بيانات أول في {topic}
|
||||
goal: >
|
||||
Uncover cutting-edge developments in {topic}
|
||||
اكتشاف أحدث التطورات في {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.
|
||||
أنت باحث مخضرم تكشف أحدث المستجدات في {topic}.
|
||||
تجد المعلومات الأكثر صلة وتعرضها بوضوح.
|
||||
```
|
||||
|
||||
</Step>
|
||||
<Step title="تعديل ملف `tasks.yaml`">
|
||||
|
||||
<Step title="اضبط مهمة واحدة في `tasks.yaml`">
|
||||
```yaml tasks.yaml
|
||||
# src/latest_ai_development/config/tasks.yaml
|
||||
# src/latest_ai_flow/crews/content_crew/config/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.
|
||||
أجرِ بحثًا معمقًا عن {topic}. استخدم البحث على الويب للعثور على معلومات
|
||||
حديثة وموثوقة. السنة الحالية 2026.
|
||||
expected_output: >
|
||||
A list with 10 bullet points of the most relevant information about {topic}
|
||||
تقرير بصيغة Markdown بأقسام واضحة: الاتجاهات الرئيسية، أدوات أو شركات بارزة،
|
||||
والآثار. بين 800 و1200 كلمة تقريبًا. دون إحاطة المستند بأكمله بكتل كود.
|
||||
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
|
||||
output_file: report.md
|
||||
output_file: output/report.md
|
||||
```
|
||||
|
||||
</Step>
|
||||
<Step title="تعديل ملف `crew.py`">
|
||||
```python crew.py
|
||||
# src/latest_ai_development/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
|
||||
|
||||
<Step title="اربط صف الطاقم (`content_crew.py`)">
|
||||
اجعل الطاقم المُولَّد يشير إلى YAML وأرفق `SerperDevTool` بالباحث.
|
||||
|
||||
```python content_crew.py
|
||||
# src/latest_ai_flow/crews/content_crew/content_crew.py
|
||||
from typing import List
|
||||
|
||||
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
|
||||
|
||||
|
||||
@CrewBase
|
||||
class LatestAiDevelopmentCrew():
|
||||
"""LatestAiDevelopment crew"""
|
||||
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]
|
||||
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
|
||||
tools=[SerperDevTool()],
|
||||
)
|
||||
|
||||
@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]
|
||||
output_file='output/report.md' # This is the file that will be contain the final report.
|
||||
config=self.tasks_config["research_task"], # type: ignore[index]
|
||||
)
|
||||
|
||||
@crew
|
||||
def crew(self) -> Crew:
|
||||
"""Creates the LatestAiDevelopment crew"""
|
||||
return Crew(
|
||||
agents=self.agents, # Automatically created by the @agent decorator
|
||||
tasks=self.tasks, # Automatically created by the @task decorator
|
||||
agents=self.agents,
|
||||
tasks=self.tasks,
|
||||
process=Process.sequential,
|
||||
verbose=True,
|
||||
)
|
||||
```
|
||||
|
||||
</Step>
|
||||
<Step title="[اختياري] إضافة دوال قبل وبعد تشغيل الطاقم">
|
||||
```python crew.py
|
||||
# src/latest_ai_development/crew.py
|
||||
from crewai import Agent, Crew, Process, Task
|
||||
from crewai.project import CrewBase, agent, crew, task, before_kickoff, after_kickoff
|
||||
from crewai_tools import SerperDevTool
|
||||
|
||||
@CrewBase
|
||||
class LatestAiDevelopmentCrew():
|
||||
"""LatestAiDevelopment crew"""
|
||||
<Step title="عرّف Flow في `main.py`">
|
||||
اربط الطاقم بـ Flow: خطوة `@start()` تضبط الموضوع في **الحالة**، وخطوة `@listen` تشغّل الطاقم. يظل `output_file` للمهمة يكتب `output/report.md`.
|
||||
|
||||
@before_kickoff
|
||||
def before_kickoff_function(self, inputs):
|
||||
print(f"Before kickoff function with inputs: {inputs}")
|
||||
return inputs # You can return the inputs or modify them as needed
|
||||
|
||||
@after_kickoff
|
||||
def after_kickoff_function(self, result):
|
||||
print(f"After kickoff function with result: {result}")
|
||||
return result # You can return the result or modify it as needed
|
||||
|
||||
# ... remaining code
|
||||
```
|
||||
|
||||
</Step>
|
||||
<Step title="لا تتردد في تمرير مدخلات مخصصة لطاقمك">
|
||||
على سبيل المثال، يمكنك تمرير مدخل `topic` لطاقمك لتخصيص البحث وإعداد التقارير.
|
||||
```python main.py
|
||||
#!/usr/bin/env python
|
||||
# src/latest_ai_development/main.py
|
||||
import sys
|
||||
from latest_ai_development.crew import LatestAiDevelopmentCrew
|
||||
# src/latest_ai_flow/main.py
|
||||
from pydantic import BaseModel
|
||||
|
||||
def run():
|
||||
"""
|
||||
Run the crew.
|
||||
"""
|
||||
inputs = {
|
||||
'topic': 'AI Agents'
|
||||
}
|
||||
LatestAiDevelopmentCrew().crew().kickoff(inputs=inputs)
|
||||
from crewai.flow import Flow, listen, start
|
||||
|
||||
from latest_ai_flow.crews.content_crew.content_crew import ResearchCrew
|
||||
|
||||
|
||||
class ResearchFlowState(BaseModel):
|
||||
topic: str = ""
|
||||
report: str = ""
|
||||
|
||||
|
||||
class LatestAiFlow(Flow[ResearchFlowState]):
|
||||
@start()
|
||||
def prepare_topic(self, crewai_trigger_payload: dict | None = None):
|
||||
if crewai_trigger_payload:
|
||||
self.state.topic = crewai_trigger_payload.get("topic", "AI Agents")
|
||||
else:
|
||||
self.state.topic = "AI Agents"
|
||||
print(f"الموضوع: {self.state.topic}")
|
||||
|
||||
@listen(prepare_topic)
|
||||
def run_research(self):
|
||||
result = ResearchCrew().crew().kickoff(inputs={"topic": self.state.topic})
|
||||
self.state.report = result.raw
|
||||
print("اكتمل طاقم البحث.")
|
||||
|
||||
@listen(run_research)
|
||||
def summarize(self):
|
||||
print("مسار التقرير: output/report.md")
|
||||
|
||||
|
||||
def kickoff():
|
||||
LatestAiFlow().kickoff()
|
||||
|
||||
|
||||
def plot():
|
||||
LatestAiFlow().plot()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
kickoff()
|
||||
```
|
||||
|
||||
</Step>
|
||||
<Step title="تعيين متغيرات البيئة">
|
||||
قبل تشغيل طاقمك، تأكد من تعيين المفاتيح التالية كمتغيرات بيئة في ملف `.env`:
|
||||
- مفتاح API لـ [Serper.dev](https://serper.dev/): `SERPER_API_KEY=YOUR_KEY_HERE`
|
||||
- إعداد النموذج الذي اخترته، مثل مفتاح API. راجع
|
||||
[دليل إعداد LLM](/ar/concepts/llms#setting-up-your-llm) لمعرفة كيفية إعداد النماذج من أي مزود.
|
||||
</Step>
|
||||
<Step title="قفل وتثبيت التبعيات">
|
||||
- اقفل التبعيات وثبّتها باستخدام أمر CLI:
|
||||
<CodeGroup>
|
||||
```shell Terminal
|
||||
crewai install
|
||||
```
|
||||
</CodeGroup>
|
||||
- إذا كانت لديك حزم إضافية تريد تثبيتها، يمكنك القيام بذلك عبر:
|
||||
<CodeGroup>
|
||||
```shell Terminal
|
||||
uv add <package-name>
|
||||
```
|
||||
</CodeGroup>
|
||||
</Step>
|
||||
<Step title="تشغيل طاقمك">
|
||||
- لتشغيل طاقمك، نفّذ الأمر التالي في جذر مشروعك:
|
||||
<CodeGroup>
|
||||
```bash Terminal
|
||||
crewai run
|
||||
```
|
||||
</CodeGroup>
|
||||
<Tip>
|
||||
إذا كان اسم الحزمة ليس `latest_ai_flow`، عدّل استيراد `ResearchCrew` ليطابق مسار الوحدة في مشروعك.
|
||||
</Tip>
|
||||
</Step>
|
||||
|
||||
<Step title="البديل المؤسسي: الإنشاء في Crew Studio">
|
||||
لمستخدمي CrewAI AMP، يمكنك إنشاء نفس الطاقم دون كتابة كود:
|
||||
<Step title="متغيرات البيئة">
|
||||
في جذر المشروع، ضبط `.env`:
|
||||
|
||||
1. سجّل الدخول إلى حساب CrewAI AMP (أنشئ حساباً مجانياً على [app.crewai.com](https://app.crewai.com))
|
||||
2. افتح Crew Studio
|
||||
3. اكتب ما هي الأتمتة التي تحاول بناءها
|
||||
4. أنشئ مهامك بصرياً واربطها بالتسلسل
|
||||
5. هيئ مدخلاتك وانقر "تحميل الكود" أو "نشر"
|
||||
|
||||

|
||||
|
||||
<Card title="جرّب CrewAI AMP" icon="rocket" href="https://app.crewai.com">
|
||||
ابدأ حسابك المجاني في CrewAI AMP
|
||||
</Card>
|
||||
- `SERPER_API_KEY` — من [Serper.dev](https://serper.dev/)
|
||||
- مفاتيح مزوّد النموذج حسب الحاجة — راجع [إعداد LLM](/ar/concepts/llms#setting-up-your-llm)
|
||||
</Step>
|
||||
<Step title="عرض التقرير النهائي">
|
||||
يجب أن ترى المخرجات في وحدة التحكم ويجب إنشاء ملف `report.md` في جذر مشروعك مع التقرير النهائي.
|
||||
|
||||
إليك مثالاً على شكل التقرير:
|
||||
<Step title="التثبيت والتشغيل">
|
||||
<CodeGroup>
|
||||
```shell Terminal
|
||||
crewai install
|
||||
crewai run
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
يُنفّذ `crewai run` نقطة دخول Flow المعرّفة في المشروع (نفس أمر الطواقم؛ نوع المشروع `"flow"` في `pyproject.toml`).
|
||||
</Step>
|
||||
|
||||
<Step title="تحقق من المخرجات">
|
||||
يجب أن ترى سجلات من Flow والطاقم. افتح **`output/report.md`** للتقرير المُولَّد (مقتطف):
|
||||
|
||||
<CodeGroup>
|
||||
```markdown output/report.md
|
||||
# Comprehensive Report on the Rise and Impact of AI Agents in 2025
|
||||
# وكلاء الذكاء الاصطناعي في 2026: المشهد والاتجاهات
|
||||
|
||||
## 1. Introduction to AI Agents
|
||||
In 2025, Artificial Intelligence (AI) agents are at the forefront of innovation across various industries. As intelligent systems that can perform tasks typically requiring human cognition, AI agents are paving the way for significant advancements in operational efficiency, decision-making, and overall productivity within sectors like Human Resources (HR) and Finance. This report aims to detail the rise of AI agents, their frameworks, applications, and potential implications on the workforce.
|
||||
## ملخص تنفيذي
|
||||
…
|
||||
|
||||
## 2. Benefits of AI Agents
|
||||
AI agents bring numerous advantages that are transforming traditional work environments. Key benefits include:
|
||||
## أبرز الاتجاهات
|
||||
- **استخدام الأدوات والتنسيق** — …
|
||||
- **التبني المؤسسي** — …
|
||||
|
||||
- **Task Automation**: AI agents can carry out repetitive tasks such as data entry, scheduling, and payroll processing without human intervention, greatly reducing the time and resources spent on these activities.
|
||||
- **Improved Efficiency**: By quickly processing large datasets and performing analyses that would take humans significantly longer, AI agents enhance operational efficiency. This allows teams to focus on strategic tasks that require higher-level thinking.
|
||||
- **Enhanced Decision-Making**: AI agents can analyze trends and patterns in data, provide insights, and even suggest actions, helping stakeholders make informed decisions based on factual data rather than intuition alone.
|
||||
|
||||
## 3. Popular AI Agent Frameworks
|
||||
Several frameworks have emerged to facilitate the development of AI agents, each with its own unique features and capabilities. Some of the most popular frameworks include:
|
||||
|
||||
- **Autogen**: A framework designed to streamline the development of AI agents through automation of code generation.
|
||||
- **Semantic Kernel**: Focuses on natural language processing and understanding, enabling agents to comprehend user intentions better.
|
||||
- **Promptflow**: Provides tools for developers to create conversational agents that can navigate complex interactions seamlessly.
|
||||
- **Langchain**: Specializes in leveraging various APIs to ensure agents can access and utilize external data effectively.
|
||||
- **CrewAI**: Aimed at collaborative environments, CrewAI strengthens teamwork by facilitating communication through AI-driven insights.
|
||||
- **MemGPT**: Combines memory-optimized architectures with generative capabilities, allowing for more personalized interactions with users.
|
||||
|
||||
These frameworks empower developers to build versatile and intelligent agents that can engage users, perform advanced analytics, and execute various tasks aligned with organizational goals.
|
||||
|
||||
## 4. AI Agents in Human Resources
|
||||
AI agents are revolutionizing HR practices by automating and optimizing key functions:
|
||||
|
||||
- **Recruiting**: AI agents can screen resumes, schedule interviews, and even conduct initial assessments, thus accelerating the hiring process while minimizing biases.
|
||||
- **Succession Planning**: AI systems analyze employee performance data and potential, helping organizations identify future leaders and plan appropriate training.
|
||||
- **Employee Engagement**: Chatbots powered by AI can facilitate feedback loops between employees and management, promoting an open culture and addressing concerns promptly.
|
||||
|
||||
As AI continues to evolve, HR departments leveraging these agents can realize substantial improvements in both efficiency and employee satisfaction.
|
||||
|
||||
## 5. AI Agents in Finance
|
||||
The finance sector is seeing extensive integration of AI agents that enhance financial practices:
|
||||
|
||||
- **Expense Tracking**: Automated systems manage and monitor expenses, flagging anomalies and offering recommendations based on spending patterns.
|
||||
- **Risk Assessment**: AI models assess credit risk and uncover potential fraud by analyzing transaction data and behavioral patterns.
|
||||
- **Investment Decisions**: AI agents provide stock predictions and analytics based on historical data and current market conditions, empowering investors with informative insights.
|
||||
|
||||
The incorporation of AI agents into finance is fostering a more responsive and risk-aware financial landscape.
|
||||
|
||||
## 6. Market Trends and Investments
|
||||
The growth of AI agents has attracted significant investment, especially amidst the rising popularity of chatbots and generative AI technologies. Companies and entrepreneurs are eager to explore the potential of these systems, recognizing their ability to streamline operations and improve customer engagement.
|
||||
|
||||
Conversely, corporations like Microsoft are taking strides to integrate AI agents into their product offerings, with enhancements to their Copilot 365 applications. This strategic move emphasizes the importance of AI literacy in the modern workplace and indicates the stabilizing of AI agents as essential business tools.
|
||||
|
||||
## 7. Future Predictions and Implications
|
||||
Experts predict that AI agents will transform essential aspects of work life. As we look toward the future, several anticipated changes include:
|
||||
|
||||
- Enhanced integration of AI agents across all business functions, creating interconnected systems that leverage data from various departmental silos for comprehensive decision-making.
|
||||
- Continued advancement of AI technologies, resulting in smarter, more adaptable agents capable of learning and evolving from user interactions.
|
||||
- Increased regulatory scrutiny to ensure ethical use, especially concerning data privacy and employee surveillance as AI agents become more prevalent.
|
||||
|
||||
To stay competitive and harness the full potential of AI agents, organizations must remain vigilant about latest developments in AI technology and consider continuous learning and adaptation in their strategic planning.
|
||||
|
||||
## 8. Conclusion
|
||||
The emergence of AI agents is undeniably reshaping the workplace landscape in 5. With their ability to automate tasks, enhance efficiency, and improve decision-making, AI agents are critical in driving operational success. Organizations must embrace and adapt to AI developments to thrive in an increasingly digital business environment.
|
||||
## الآثار
|
||||
…
|
||||
```
|
||||
|
||||
</CodeGroup>
|
||||
|
||||
سيكون الملف الفعلي أطول ويعكس نتائج بحث مباشرة.
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
## كيف يترابط هذا
|
||||
|
||||
1. **Flow** — يشغّل `LatestAiFlow` أولًا `prepare_topic` ثم `run_research` ثم `summarize`. الحالة (`topic`، `report`) على Flow.
|
||||
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).
|
||||
|
||||
<Check>
|
||||
تهانينا!
|
||||
|
||||
لقد أعددت مشروع طاقمك بنجاح وأنت جاهز للبدء في بناء سير العمل الوكيلي الخاص بك!
|
||||
|
||||
أصبح لديك Flow كامل مع طاقم وكيل وتقرير محفوظ — قاعدة قوية لإضافة خطوات أو طواقم أو أدوات.
|
||||
</Check>
|
||||
|
||||
### ملاحظة حول اتساق التسمية
|
||||
### اتساق التسمية
|
||||
|
||||
يجب أن تتطابق الأسماء التي تستخدمها في ملفات YAML (`agents.yaml` و`tasks.yaml`) مع أسماء الدوال في كود Python الخاص بك.
|
||||
على سبيل المثال، يمكنك الإشارة إلى الوكيل لمهام محددة من ملف `tasks.yaml`.
|
||||
يتيح اتساق التسمية هذا لـ CrewAI ربط تكويناتك بكودك تلقائياً؛ وإلا فلن تتعرف مهمتك على المرجع بشكل صحيح.
|
||||
يجب أن تطابق مفاتيح YAML (`researcher`، `research_task`) أسماء الدوال في صف `@CrewBase`. راجع [Crews](/ar/concepts/crews) لنمط الديكورات الكامل.
|
||||
|
||||
#### أمثلة على المراجع
|
||||
## النشر
|
||||
|
||||
<Tip>
|
||||
لاحظ كيف نستخدم نفس الاسم للوكيل في ملف `agents.yaml`
|
||||
(`email_summarizer`) واسم الدالة في ملف `crew.py`
|
||||
(`email_summarizer`).
|
||||
</Tip>
|
||||
ادفع Flow إلى **[CrewAI AMP](https://app.crewai.com)** بعد أن يعمل محليًا ويكون المشروع في مستودع **GitHub**. من جذر المشروع:
|
||||
|
||||
```yaml agents.yaml
|
||||
email_summarizer:
|
||||
role: >
|
||||
Email Summarizer
|
||||
goal: >
|
||||
Summarize emails into a concise and clear summary
|
||||
backstory: >
|
||||
You will create a 5 bullet point summary of the report
|
||||
llm: provider/model-id # Add your choice of model here
|
||||
<CodeGroup>
|
||||
```bash المصادقة
|
||||
crewai login
|
||||
```
|
||||
|
||||
<Tip>
|
||||
لاحظ كيف نستخدم نفس الاسم للمهمة في ملف `tasks.yaml`
|
||||
(`email_summarizer_task`) واسم الدالة في ملف `crew.py`
|
||||
(`email_summarizer_task`).
|
||||
</Tip>
|
||||
|
||||
```yaml tasks.yaml
|
||||
email_summarizer_task:
|
||||
description: >
|
||||
Summarize the email into a 5 bullet point summary
|
||||
expected_output: >
|
||||
A 5 bullet point summary of the email
|
||||
agent: email_summarizer
|
||||
context:
|
||||
- reporting_task
|
||||
- research_task
|
||||
```bash إنشاء نشر
|
||||
crewai deploy create
|
||||
```
|
||||
|
||||
## نشر طاقمك
|
||||
```bash الحالة والسجلات
|
||||
crewai deploy status
|
||||
crewai deploy logs
|
||||
```
|
||||
|
||||
أسهل طريقة لنشر طاقمك في الإنتاج هي من خلال [CrewAI AMP](http://app.crewai.com).
|
||||
```bash إرسال التحديثات بعد تغيير الكود
|
||||
crewai deploy push
|
||||
```
|
||||
|
||||
شاهد هذا الفيديو التعليمي لعرض خطوة بخطوة لنشر طاقمك على [CrewAI AMP](http://app.crewai.com) باستخدام CLI.
|
||||
```bash عرض النشرات أو حذفها
|
||||
crewai deploy list
|
||||
crewai deploy remove <deployment_id>
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
<iframe
|
||||
className="w-full aspect-video rounded-xl"
|
||||
src="https://www.youtube.com/embed/3EqSV-CYDZA"
|
||||
title="CrewAI Deployment Guide"
|
||||
frameBorder="0"
|
||||
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
|
||||
allowFullScreen
|
||||
></iframe>
|
||||
<Tip>
|
||||
غالبًا ما يستغرق **النشر الأول حوالي دقيقة**. المتطلبات الكاملة ومسار الواجهة الويب في [النشر على AMP](/ar/enterprise/guides/deploy-to-amp).
|
||||
</Tip>
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="النشر على المؤسسة" icon="rocket" href="http://app.crewai.com">
|
||||
ابدأ مع CrewAI AMP وانشر طاقمك في بيئة إنتاج
|
||||
بنقرات قليلة فقط.
|
||||
<Card title="دليل النشر" icon="book" href="/ar/enterprise/guides/deploy-to-amp">
|
||||
النشر على AMP خطوة بخطوة (CLI ولوحة التحكم).
|
||||
</Card>
|
||||
<Card
|
||||
title="انضم إلى المجتمع"
|
||||
title="المجتمع"
|
||||
icon="comments"
|
||||
href="https://community.crewai.com"
|
||||
>
|
||||
انضم إلى مجتمعنا مفتوح المصدر لمناقشة الأفكار ومشاركة مشاريعك والتواصل
|
||||
مع مطورين آخرين لـ CrewAI.
|
||||
ناقش الأفكار وشارك مشاريعك وتواصل مع مطوري CrewAI.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
@@ -7,6 +7,10 @@ mode: "wide"
|
||||
|
||||
# `CodeInterpreterTool`
|
||||
|
||||
<Warning>
|
||||
**مهجور:** تمت إزالة `CodeInterpreterTool` من `crewai-tools`. كما أن معاملَي `allow_code_execution` و`code_execution_mode` على `Agent` أصبحا مهجورَين. استخدم خدمة بيئة معزولة مخصصة — [E2B](https://e2b.dev) أو [Modal](https://modal.com) — لتنفيذ الكود بشكل آمن ومعزول.
|
||||
</Warning>
|
||||
|
||||
## الوصف
|
||||
|
||||
تمكّن `CodeInterpreterTool` وكلاء CrewAI من تنفيذ كود Python 3 الذي يولّدونه بشكل مستقل. هذه الوظيفة ذات قيمة خاصة لأنها تتيح للوكلاء إنشاء الكود وتنفيذه والحصول على النتائج واستخدام تلك المعلومات لاتخاذ القرارات والإجراءات اللاحقة.
|
||||
|
||||
@@ -74,3 +74,19 @@ tool = CSVSearchTool(
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
## الأمان
|
||||
|
||||
### التحقق من صحة المسارات
|
||||
|
||||
يتم التحقق من مسارات الملفات المقدمة لهذه الأداة مقابل مجلد العمل الحالي. يتم رفض المسارات التي تحل خارج مجلد العمل وإطلاق `ValueError`.
|
||||
|
||||
للسماح بالمسارات خارج مجلد العمل (مثلاً في الاختبارات أو خطوط الأنابيب الموثوقة)، عيّن متغير البيئة التالي:
|
||||
|
||||
```shell
|
||||
CREWAI_TOOLS_ALLOW_UNSAFE_PATHS=true
|
||||
```
|
||||
|
||||
### التحقق من صحة الروابط
|
||||
|
||||
يتم التحقق من مدخلات الروابط: يتم حظر مخطط `file://` والطلبات التي تستهدف نطاقات IP الخاصة أو المحجوزة لمنع هجمات تزوير الطلبات من جانب الخادم (SSRF).
|
||||
|
||||
@@ -68,3 +68,15 @@ tool = DirectorySearchTool(
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
## الأمان
|
||||
|
||||
### التحقق من صحة المسارات
|
||||
|
||||
يتم التحقق من مسارات المجلدات المقدمة لهذه الأداة مقابل مجلد العمل الحالي. يتم رفض المسارات التي تحل خارج مجلد العمل وإطلاق `ValueError`.
|
||||
|
||||
للسماح بالمسارات خارج مجلد العمل (مثلاً في الاختبارات أو خطوط الأنابيب الموثوقة)، عيّن متغير البيئة التالي:
|
||||
|
||||
```shell
|
||||
CREWAI_TOOLS_ALLOW_UNSAFE_PATHS=true
|
||||
```
|
||||
|
||||
@@ -73,3 +73,19 @@ tool = JSONSearchTool(
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
## الأمان
|
||||
|
||||
### التحقق من صحة المسارات
|
||||
|
||||
يتم التحقق من مسارات الملفات المقدمة لهذه الأداة مقابل مجلد العمل الحالي. يتم رفض المسارات التي تحل خارج مجلد العمل وإطلاق `ValueError`.
|
||||
|
||||
للسماح بالمسارات خارج مجلد العمل (مثلاً في الاختبارات أو خطوط الأنابيب الموثوقة)، عيّن متغير البيئة التالي:
|
||||
|
||||
```shell
|
||||
CREWAI_TOOLS_ALLOW_UNSAFE_PATHS=true
|
||||
```
|
||||
|
||||
### التحقق من صحة الروابط
|
||||
|
||||
يتم التحقق من مدخلات الروابط: يتم حظر مخطط `file://` والطلبات التي تستهدف نطاقات IP الخاصة أو المحجوزة لمنع هجمات تزوير الطلبات من جانب الخادم (SSRF).
|
||||
|
||||
@@ -105,3 +105,19 @@ tool = PDFSearchTool(
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
## الأمان
|
||||
|
||||
### التحقق من صحة المسارات
|
||||
|
||||
يتم التحقق من مسارات الملفات المقدمة لهذه الأداة مقابل مجلد العمل الحالي. يتم رفض المسارات التي تحل خارج مجلد العمل وإطلاق `ValueError`.
|
||||
|
||||
للسماح بالمسارات خارج مجلد العمل (مثلاً في الاختبارات أو خطوط الأنابيب الموثوقة)، عيّن متغير البيئة التالي:
|
||||
|
||||
```shell
|
||||
CREWAI_TOOLS_ALLOW_UNSAFE_PATHS=true
|
||||
```
|
||||
|
||||
### التحقق من صحة الروابط
|
||||
|
||||
يتم التحقق من مدخلات الروابط: يتم حظر مخطط `file://` والطلبات التي تستهدف نطاقات IP الخاصة أو المحجوزة لمنع هجمات تزوير الطلبات من جانب الخادم (SSRF).
|
||||
|
||||
1971
docs/docs.json
1971
docs/docs.json
File diff suppressed because it is too large
Load Diff
@@ -4,6 +4,102 @@ description: "Product updates, improvements, and bug fixes for CrewAI"
|
||||
icon: "clock"
|
||||
mode: "wide"
|
||||
---
|
||||
<Update label="Apr 07, 2026">
|
||||
## v1.14.0
|
||||
|
||||
[View release on GitHub](https://github.com/crewAIInc/crewAI/releases/tag/1.14.0)
|
||||
|
||||
## What's Changed
|
||||
|
||||
### Features
|
||||
- Add checkpoint list/info CLI commands
|
||||
- Add guardrail_type and name to distinguish traces
|
||||
- Add SqliteProvider for checkpoint storage
|
||||
- Add CheckpointConfig for automatic checkpointing
|
||||
- Implement runtime state checkpointing, event system, and executor refactor
|
||||
|
||||
### Bug Fixes
|
||||
- Add SSRF and path traversal protections
|
||||
- Add path and URL validation to RAG tools
|
||||
- Exclude embedding vectors from memory serialization to save tokens
|
||||
- Ensure output directory exists before writing in flow template
|
||||
- Bump litellm to >=1.83.0 to address CVE-2026-35030
|
||||
- Remove SEO indexing field causing Arabic page rendering
|
||||
|
||||
### Documentation
|
||||
- Update changelog and version for v1.14.0
|
||||
- Update quickstart and installation guides for improved clarity
|
||||
- Add storage providers section, export JsonProvider
|
||||
- Add AMP Training Tab guide
|
||||
|
||||
### Refactoring
|
||||
- Clean up checkpoint API
|
||||
- Remove CodeInterpreterTool and deprecate code execution parameters
|
||||
|
||||
## Contributors
|
||||
|
||||
@alex-clawd, @github-actions[bot], @greysonlalonde, @iris-clawd, @joaomdmoura, @lorenzejay, @lucasgomide
|
||||
|
||||
</Update>
|
||||
|
||||
<Update label="Apr 07, 2026">
|
||||
## v1.14.0a4
|
||||
|
||||
[View release on GitHub](https://github.com/crewAIInc/crewAI/releases/tag/1.14.0a4)
|
||||
|
||||
## What's Changed
|
||||
|
||||
### Features
|
||||
- Add guardrail_type and name to distinguish traces
|
||||
- Add SqliteProvider for checkpoint storage
|
||||
- Add CheckpointConfig for automatic checkpointing
|
||||
- Implement runtime state checkpointing, event system, and executor refactor
|
||||
|
||||
### Bug Fixes
|
||||
- Exclude embedding vectors from memory serialization to save tokens
|
||||
- Bump litellm to >=1.83.0 to address CVE-2026-35030
|
||||
|
||||
### Documentation
|
||||
- Update quickstart and installation guides for improved clarity
|
||||
- Add storage providers section and export JsonProvider
|
||||
|
||||
### Performance
|
||||
- Use JSONB for checkpoint data column
|
||||
|
||||
### Refactoring
|
||||
- Remove CodeInterpreterTool and deprecate code execution params
|
||||
|
||||
## Contributors
|
||||
|
||||
@alex-clawd, @github-actions[bot], @greysonlalonde, @joaomdmoura, @lorenzejay, @lucasgomide
|
||||
|
||||
</Update>
|
||||
|
||||
<Update label="Apr 06, 2026">
|
||||
## v1.14.0a3
|
||||
|
||||
[View release on GitHub](https://github.com/crewAIInc/crewAI/releases/tag/1.14.0a3)
|
||||
|
||||
## What's Changed
|
||||
|
||||
### Documentation
|
||||
- Update changelog and version for v1.14.0a2
|
||||
|
||||
## Contributors
|
||||
|
||||
@joaomdmoura
|
||||
|
||||
</Update>
|
||||
|
||||
<Update label="Apr 06, 2026">
|
||||
## v1.14.0a2
|
||||
|
||||
[View release on GitHub](https://github.com/crewAIInc/crewAI/releases/tag/1.14.0a2)
|
||||
|
||||
Release 1.14.0a2
|
||||
|
||||
</Update>
|
||||
|
||||
<Update label="Apr 02, 2026">
|
||||
## v1.13.0
|
||||
|
||||
|
||||
@@ -308,16 +308,12 @@ multimodal_agent = Agent(
|
||||
|
||||
#### Code Execution
|
||||
|
||||
- `allow_code_execution`: Must be True to run code
|
||||
- `code_execution_mode`:
|
||||
- `"safe"`: Uses Docker (recommended for production)
|
||||
- `"unsafe"`: Direct execution (use only in trusted environments)
|
||||
<Warning>
|
||||
`allow_code_execution` and `code_execution_mode` are deprecated. `CodeInterpreterTool` has been removed from `crewai-tools`. Use a dedicated sandbox service such as [E2B](https://e2b.dev) or [Modal](https://modal.com) for secure code execution.
|
||||
</Warning>
|
||||
|
||||
<Note>
|
||||
This runs a default Docker image. If you want to configure the docker image,
|
||||
the checkout the Code Interpreter Tool in the tools section. Add the code
|
||||
interpreter tool as a tool in the agent as a tool parameter.
|
||||
</Note>
|
||||
- `allow_code_execution` _(deprecated)_: Previously enabled built-in code execution via `CodeInterpreterTool`.
|
||||
- `code_execution_mode` _(deprecated)_: Previously controlled execution mode (`"safe"` for Docker, `"unsafe"` for direct execution).
|
||||
|
||||
#### Advanced Features
|
||||
|
||||
@@ -667,9 +663,9 @@ asyncio.run(main())
|
||||
|
||||
### Security and Code Execution
|
||||
|
||||
- When using `allow_code_execution`, be cautious with user input and always validate it
|
||||
- Use `code_execution_mode: "safe"` (Docker) in production environments
|
||||
- Consider setting appropriate `max_execution_time` limits to prevent infinite loops
|
||||
<Warning>
|
||||
`allow_code_execution` and `code_execution_mode` are deprecated and `CodeInterpreterTool` has been removed. Use a dedicated sandbox service such as [E2B](https://e2b.dev) or [Modal](https://modal.com) for secure code execution.
|
||||
</Warning>
|
||||
|
||||
### Performance Optimization
|
||||
|
||||
|
||||
233
docs/en/concepts/checkpointing.mdx
Normal file
233
docs/en/concepts/checkpointing.mdx
Normal file
@@ -0,0 +1,233 @@
|
||||
---
|
||||
title: Checkpointing
|
||||
description: Automatically save execution state so crews, flows, and agents can resume after failures.
|
||||
icon: floppy-disk
|
||||
mode: "wide"
|
||||
---
|
||||
|
||||
<Warning>
|
||||
Checkpointing is in early release. APIs may change in future versions.
|
||||
</Warning>
|
||||
|
||||
## Overview
|
||||
|
||||
Checkpointing automatically saves execution state during a run. If a crew, flow, or agent fails mid-execution, you can restore from the last checkpoint and resume without re-running completed work.
|
||||
|
||||
## Quick Start
|
||||
|
||||
```python
|
||||
from crewai import Crew, CheckpointConfig
|
||||
|
||||
crew = Crew(
|
||||
agents=[...],
|
||||
tasks=[...],
|
||||
checkpoint=True, # uses defaults: ./.checkpoints, on task_completed
|
||||
)
|
||||
result = crew.kickoff()
|
||||
```
|
||||
|
||||
Checkpoint files are written to `./.checkpoints/` after each completed task.
|
||||
|
||||
## Configuration
|
||||
|
||||
Use `CheckpointConfig` for full control:
|
||||
|
||||
```python
|
||||
from crewai import Crew, CheckpointConfig
|
||||
|
||||
crew = Crew(
|
||||
agents=[...],
|
||||
tasks=[...],
|
||||
checkpoint=CheckpointConfig(
|
||||
location="./my_checkpoints",
|
||||
on_events=["task_completed", "crew_kickoff_completed"],
|
||||
max_checkpoints=5,
|
||||
),
|
||||
)
|
||||
```
|
||||
|
||||
### CheckpointConfig Fields
|
||||
|
||||
| Field | Type | Default | Description |
|
||||
|:------|:-----|:--------|:------------|
|
||||
| `location` | `str` | `"./.checkpoints"` | Storage destination — a directory for `JsonProvider`, a database file path for `SqliteProvider` |
|
||||
| `on_events` | `list[str]` | `["task_completed"]` | Event types that trigger a checkpoint |
|
||||
| `provider` | `BaseProvider` | `JsonProvider()` | Storage backend |
|
||||
| `max_checkpoints` | `int \| None` | `None` | Max checkpoints to keep. Oldest are pruned after each write. Pruning is handled by the provider. |
|
||||
|
||||
### Inheritance and Opt-Out
|
||||
|
||||
The `checkpoint` field on Crew, Flow, and Agent accepts `CheckpointConfig`, `True`, `False`, or `None`:
|
||||
|
||||
| Value | Behavior |
|
||||
|:------|:---------|
|
||||
| `None` (default) | Inherit from parent. An agent inherits its crew's config. |
|
||||
| `True` | Enable with defaults. |
|
||||
| `False` | Explicit opt-out. Stops inheritance from parent. |
|
||||
| `CheckpointConfig(...)` | Custom configuration. |
|
||||
|
||||
```python
|
||||
crew = Crew(
|
||||
agents=[
|
||||
Agent(role="Researcher", ...), # inherits crew's checkpoint
|
||||
Agent(role="Writer", ..., checkpoint=False), # opted out, no checkpoints
|
||||
],
|
||||
tasks=[...],
|
||||
checkpoint=True,
|
||||
)
|
||||
```
|
||||
|
||||
## Resuming from a Checkpoint
|
||||
|
||||
```python
|
||||
# Restore and resume
|
||||
crew = Crew.from_checkpoint("./my_checkpoints/20260407T120000_abc123.json")
|
||||
result = crew.kickoff() # picks up from last completed task
|
||||
```
|
||||
|
||||
The restored crew skips already-completed tasks and resumes from the first incomplete one.
|
||||
|
||||
## Works on Crew, Flow, and Agent
|
||||
|
||||
### Crew
|
||||
|
||||
```python
|
||||
crew = Crew(
|
||||
agents=[researcher, writer],
|
||||
tasks=[research_task, write_task, review_task],
|
||||
checkpoint=CheckpointConfig(location="./crew_cp"),
|
||||
)
|
||||
```
|
||||
|
||||
Default trigger: `task_completed` (one checkpoint per finished task).
|
||||
|
||||
### Flow
|
||||
|
||||
```python
|
||||
from crewai.flow.flow import Flow, start, listen
|
||||
from crewai import CheckpointConfig
|
||||
|
||||
class MyFlow(Flow):
|
||||
@start()
|
||||
def step_one(self):
|
||||
return "data"
|
||||
|
||||
@listen(step_one)
|
||||
def step_two(self, data):
|
||||
return process(data)
|
||||
|
||||
flow = MyFlow(
|
||||
checkpoint=CheckpointConfig(
|
||||
location="./flow_cp",
|
||||
on_events=["method_execution_finished"],
|
||||
),
|
||||
)
|
||||
result = flow.kickoff()
|
||||
|
||||
# Resume
|
||||
flow = MyFlow.from_checkpoint("./flow_cp/20260407T120000_abc123.json")
|
||||
result = flow.kickoff()
|
||||
```
|
||||
|
||||
### Agent
|
||||
|
||||
```python
|
||||
agent = Agent(
|
||||
role="Researcher",
|
||||
goal="Research topics",
|
||||
backstory="Expert researcher",
|
||||
checkpoint=CheckpointConfig(
|
||||
location="./agent_cp",
|
||||
on_events=["lite_agent_execution_completed"],
|
||||
),
|
||||
)
|
||||
result = agent.kickoff(messages=[{"role": "user", "content": "Research AI trends"}])
|
||||
```
|
||||
|
||||
## Storage Providers
|
||||
|
||||
CrewAI ships with two checkpoint storage providers.
|
||||
|
||||
### JsonProvider (default)
|
||||
|
||||
Writes each checkpoint as a separate JSON file. Simple, human-readable, easy to inspect.
|
||||
|
||||
```python
|
||||
from crewai import Crew, CheckpointConfig
|
||||
from crewai.state import JsonProvider
|
||||
|
||||
crew = Crew(
|
||||
agents=[...],
|
||||
tasks=[...],
|
||||
checkpoint=CheckpointConfig(
|
||||
location="./my_checkpoints",
|
||||
provider=JsonProvider(), # this is the default
|
||||
max_checkpoints=5, # prunes oldest files
|
||||
),
|
||||
)
|
||||
```
|
||||
|
||||
Files are named `<timestamp>_<uuid>.json` inside the location directory.
|
||||
|
||||
### SqliteProvider
|
||||
|
||||
Stores all checkpoints in a single SQLite database file. Better for high-frequency checkpointing and avoids many small files.
|
||||
|
||||
```python
|
||||
from crewai import Crew, CheckpointConfig
|
||||
from crewai.state import SqliteProvider
|
||||
|
||||
crew = Crew(
|
||||
agents=[...],
|
||||
tasks=[...],
|
||||
checkpoint=CheckpointConfig(
|
||||
location="./.checkpoints.db",
|
||||
provider=SqliteProvider(),
|
||||
max_checkpoints=50,
|
||||
),
|
||||
)
|
||||
```
|
||||
|
||||
WAL journal mode is enabled for concurrent read access.
|
||||
|
||||
## Event Types
|
||||
|
||||
The `on_events` field accepts any combination of event type strings. Common choices:
|
||||
|
||||
| Use Case | Events |
|
||||
|:---------|:-------|
|
||||
| After each task (Crew) | `["task_completed"]` |
|
||||
| After each flow method | `["method_execution_finished"]` |
|
||||
| After agent execution | `["agent_execution_completed"]`, `["lite_agent_execution_completed"]` |
|
||||
| On crew completion only | `["crew_kickoff_completed"]` |
|
||||
| After every LLM call | `["llm_call_completed"]` |
|
||||
| On everything | `["*"]` |
|
||||
|
||||
<Warning>
|
||||
Using `["*"]` or high-frequency events like `llm_call_completed` will write many checkpoint files and may impact performance. Use `max_checkpoints` to limit disk usage.
|
||||
</Warning>
|
||||
|
||||
## Manual Checkpointing
|
||||
|
||||
For full control, register your own event handler and call `state.checkpoint()` directly:
|
||||
|
||||
```python
|
||||
from crewai.events.event_bus import crewai_event_bus
|
||||
from crewai.events.types.llm_events import LLMCallCompletedEvent
|
||||
|
||||
# Sync handler
|
||||
@crewai_event_bus.on(LLMCallCompletedEvent)
|
||||
def on_llm_done(source, event, state):
|
||||
path = state.checkpoint("./my_checkpoints")
|
||||
print(f"Saved checkpoint: {path}")
|
||||
|
||||
# Async handler
|
||||
@crewai_event_bus.on(LLMCallCompletedEvent)
|
||||
async def on_llm_done_async(source, event, state):
|
||||
path = await state.acheckpoint("./my_checkpoints")
|
||||
print(f"Saved checkpoint: {path}")
|
||||
```
|
||||
|
||||
The `state` argument is the `RuntimeState` passed automatically by the event bus when your handler accepts 3 parameters. You can register handlers on any event type listed in the [Event Listeners](/en/concepts/event-listener) documentation.
|
||||
|
||||
Checkpointing is best-effort: if a checkpoint write fails, the error is logged but execution continues uninterrupted.
|
||||
@@ -117,35 +117,23 @@ task = Task(
|
||||
|
||||
### With Flows
|
||||
|
||||
File-typed fields (`File`, `ImageFile`, `PDFFile`) in your flow's state schema serve as the signal to the Platform UI. When deployed, these fields render as file upload dropzones. Files can also be passed via `input_files` in the API.
|
||||
Pass files to flows, which automatically inherit to crews:
|
||||
|
||||
```python
|
||||
from crewai.flow.flow import Flow, start
|
||||
from crewai_files import File, ImageFile
|
||||
from pydantic import BaseModel
|
||||
from crewai_files import ImageFile
|
||||
|
||||
class MyState(BaseModel):
|
||||
document: File # Renders as file dropzone in Platform UI
|
||||
cover_image: ImageFile # Image-specific dropzone
|
||||
title: str = ""
|
||||
|
||||
class AnalysisFlow(Flow[MyState]):
|
||||
class AnalysisFlow(Flow):
|
||||
@start()
|
||||
def analyze(self):
|
||||
# Files are automatically populated in state
|
||||
content = self.state.document.read()
|
||||
return self.analysis_crew.kickoff()
|
||||
|
||||
flow = AnalysisFlow()
|
||||
result = flow.kickoff(
|
||||
input_files={"document": File(source="report.pdf")}
|
||||
input_files={"image": ImageFile(source="data.png")}
|
||||
)
|
||||
```
|
||||
|
||||
<Note type="info" title="CrewAI Platform Integration">
|
||||
When deployed on CrewAI Platform, `ImageFile`, `PDFFile`, and other file-typed fields in your flow state automatically get a file upload UI. Users can drag and drop files directly in the Platform interface. Files are stored securely and passed to agents using provider-specific optimizations (inline base64, file upload APIs, or URL references depending on the provider). For API usage examples, see [File Inputs in Flows](/concepts/flows#file-inputs).
|
||||
</Note>
|
||||
|
||||
### With Standalone Agents
|
||||
|
||||
Pass files directly to agent kickoff:
|
||||
|
||||
@@ -341,90 +341,6 @@ flow.kickoff()
|
||||
|
||||
By providing both unstructured and structured state management options, CrewAI Flows empowers developers to build AI workflows that are both flexible and robust, catering to a wide range of application requirements.
|
||||
|
||||
### File Inputs
|
||||
|
||||
When using structured state, you can include file-typed fields using classes from `crewai-files`. File-typed fields in your flow state serve as the signal to the Platform—they automatically render as file upload dropzones in the Run tab UI and get populated when files are uploaded via the Platform or passed via `input_files` in the API.
|
||||
|
||||
```python
|
||||
from crewai.flow.flow import Flow, start
|
||||
from crewai_files import File, ImageFile, PDFFile
|
||||
from pydantic import BaseModel
|
||||
|
||||
class MyState(BaseModel):
|
||||
document: File # Renders as file dropzone in Platform
|
||||
title: str = ""
|
||||
|
||||
class MyFlow(Flow[MyState]):
|
||||
@start()
|
||||
def process(self):
|
||||
# File object is automatically populated in state
|
||||
# when uploaded via Platform UI or passed via API
|
||||
content = self.state.document.read()
|
||||
print(f"Processing {self.state.title}: {len(content)} bytes")
|
||||
return content
|
||||
```
|
||||
|
||||
When deployed on **CrewAI Platform**, file-typed fields (`File`, `ImageFile`, `PDFFile` from `crewai-files`) automatically render as file upload dropzones in the UI. Users can drag and drop files, which are then populated into your flow's state.
|
||||
|
||||
**Kicking off with files via API:**
|
||||
|
||||
The `/kickoff` endpoint auto-detects the request format:
|
||||
- **JSON body** → normal kickoff
|
||||
- **multipart/form-data** → file upload + kickoff
|
||||
|
||||
API users can also pass URL strings directly to file-typed fields—Pydantic coerces them automatically.
|
||||
|
||||
### API Usage
|
||||
|
||||
#### Option 1: Multipart kickoff (recommended)
|
||||
|
||||
Send files directly with the kickoff request:
|
||||
|
||||
```bash
|
||||
# With files (multipart) — same endpoint
|
||||
curl -X POST https://your-deployment.crewai.com/kickoff \
|
||||
-H 'Authorization: Bearer YOUR_TOKEN' \
|
||||
-F 'inputs={"company_name": "Einstein"}' \
|
||||
-F 'cover_image=@/path/to/photo.jpg'
|
||||
```
|
||||
|
||||
Files are automatically stored and converted to `FileInput` objects. The agent receives the file with provider-specific optimization (inline base64, file upload API, or URL reference depending on the LLM provider).
|
||||
|
||||
#### Option 2: JSON kickoff (no files)
|
||||
|
||||
```bash
|
||||
# Without files (JSON) — same endpoint
|
||||
curl -X POST https://your-deployment.crewai.com/kickoff \
|
||||
-H 'Authorization: Bearer YOUR_TOKEN' \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d '{"inputs": {"company_name": "Einstein"}}'
|
||||
```
|
||||
|
||||
#### Option 3: Separate upload + kickoff
|
||||
|
||||
This is an alternative to multipart upload when you need to upload files separately from the kickoff request. Upload files first, then reference them by URL:
|
||||
|
||||
```bash
|
||||
# Step 1: Upload
|
||||
curl -X POST https://your-deployment.crewai.com/files \
|
||||
-H 'Authorization: Bearer YOUR_TOKEN' \
|
||||
-F 'file=@/path/to/photo.jpg' \
|
||||
-F 'field_name=cover_image'
|
||||
# Returns: {"url": "https://...", "field_name": "cover_image"}
|
||||
|
||||
# Step 2: Kickoff with URL
|
||||
curl -X POST https://your-deployment.crewai.com/kickoff \
|
||||
-H 'Authorization: Bearer YOUR_TOKEN' \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d '{"inputs": {"company_name": "Einstein"}, "input_files": {"cover_image": "https://..."}}'
|
||||
```
|
||||
|
||||
See the Platform API documentation for full `/files` endpoint details.
|
||||
|
||||
#### On CrewAI Platform
|
||||
|
||||
When using the Platform UI, file-typed fields automatically render as drag-and-drop upload zones. No API calls needed—just drop the file and click Run.
|
||||
|
||||
## Flow Persistence
|
||||
|
||||
The @persist decorator enables automatic state persistence in CrewAI Flows, allowing you to maintain flow state across restarts or different workflow executions. This decorator can be applied at either the class level or method level, providing flexibility in how you manage state persistence.
|
||||
|
||||
@@ -106,7 +106,7 @@ The CLI automatically detects your project type from `pyproject.toml` and builds
|
||||
```
|
||||
|
||||
<Tip>
|
||||
The first deployment typically takes 10-15 minutes as it builds the container images. Subsequent deployments are much faster.
|
||||
The first deployment typically takes around 1 minute.
|
||||
</Tip>
|
||||
|
||||
</Step>
|
||||
@@ -188,7 +188,7 @@ You need to push your crew to a GitHub repository. If you haven't created a crew
|
||||
|
||||
1. Click the "Deploy" button to start the deployment process
|
||||
2. You can monitor the progress through the progress bar
|
||||
3. The first deployment typically takes around 10-15 minutes; subsequent deployments will be faster
|
||||
3. The first deployment typically takes around 1 minute
|
||||
|
||||
<Frame>
|
||||

|
||||
|
||||
@@ -86,60 +86,6 @@ curl -H "Authorization: Bearer YOUR_CREW_TOKEN" https://your-crew-url.crewai.com
|
||||
|
||||
Your bearer token is available on the Status tab of your crew's detail page.
|
||||
|
||||
## File Uploads
|
||||
|
||||
When your crew or flow includes file-typed state fields (using `ImageFile`, `PDFFile`, or `File` from `crewai-files`), these fields automatically render as file upload dropzones in the Run tab UI. Users can drag and drop files directly, and the Platform handles storage and delivery to your agents.
|
||||
|
||||
### Multipart Kickoff (Recommended)
|
||||
|
||||
Send files directly with the kickoff request using `multipart/form-data`:
|
||||
|
||||
```bash
|
||||
curl -X POST https://your-deployment.crewai.com/kickoff \
|
||||
-H 'Authorization: Bearer YOUR_TOKEN' \
|
||||
-F 'inputs={"title": "Report"}' \
|
||||
-F 'document=@/path/to/file.pdf'
|
||||
```
|
||||
|
||||
Files are automatically stored and converted to file objects. The agent receives the file with provider-specific optimization (inline base64, file upload API, or URL reference depending on the LLM provider).
|
||||
|
||||
### JSON Kickoff with File URLs
|
||||
|
||||
If you have files already hosted at URLs, pass them via `input_files`:
|
||||
|
||||
```bash
|
||||
curl -X POST https://your-deployment.crewai.com/kickoff \
|
||||
-H 'Authorization: Bearer YOUR_TOKEN' \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d '{
|
||||
"inputs": {"title": "Report"},
|
||||
"input_files": {"document": "https://example.com/file.pdf"}
|
||||
}'
|
||||
```
|
||||
|
||||
### Separate Upload + Kickoff
|
||||
|
||||
Upload files first, then reference them by URL:
|
||||
|
||||
```bash
|
||||
# Step 1: Upload
|
||||
curl -X POST https://your-deployment.crewai.com/files \
|
||||
-H 'Authorization: Bearer YOUR_TOKEN' \
|
||||
-F 'file=@/path/to/file.pdf' \
|
||||
-F 'field_name=document'
|
||||
# Returns: {"url": "https://...", "field_name": "document"}
|
||||
|
||||
# Step 2: Kickoff with URL
|
||||
curl -X POST https://your-deployment.crewai.com/kickoff \
|
||||
-H 'Authorization: Bearer YOUR_TOKEN' \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d '{"inputs": {"title": "Report"}, "input_files": {"document": "https://..."}}'
|
||||
```
|
||||
|
||||
<Note type="info">
|
||||
File uploads work the same way for both crews and flows. Define file-typed fields in your state schema, and the Platform UI and API will handle uploads automatically.
|
||||
</Note>
|
||||
|
||||
### Checking Crew Health
|
||||
|
||||
Before executing operations, you can verify that your crew is running properly:
|
||||
|
||||
@@ -207,9 +207,8 @@ For teams and organizations, CrewAI offers enterprise deployment options that el
|
||||
## Next Steps
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Build Your First Agent" icon="code" href="/en/quickstart">
|
||||
Follow our quickstart guide to create your first CrewAI agent and get
|
||||
hands-on experience.
|
||||
<Card title="Quickstart: Flow + agent" icon="code" href="/en/quickstart">
|
||||
Follow the quickstart to scaffold a Flow, run a one-agent crew, and produce a report.
|
||||
</Card>
|
||||
<Card
|
||||
title="Join the Community"
|
||||
|
||||
@@ -140,7 +140,7 @@ For any production-ready application, **start with a Flow**.
|
||||
icon="bolt"
|
||||
href="en/quickstart"
|
||||
>
|
||||
Follow our quickstart guide to create your first CrewAI agent and get hands-on experience.
|
||||
Scaffold a Flow, run a crew with one agent, and generate a report end to end.
|
||||
</Card>
|
||||
<Card
|
||||
title="Join the Community"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
title: Quickstart
|
||||
description: Build your first AI agent with CrewAI in under 5 minutes.
|
||||
description: Build your first CrewAI Flow in minutes — orchestration, state, and an agent crew that produces a real report.
|
||||
icon: rocket
|
||||
mode: "wide"
|
||||
---
|
||||
@@ -13,39 +13,37 @@ You can install it with `npx skills add crewaiinc/skills`
|
||||
|
||||
<iframe src="https://www.loom.com/embed/befb9f68b81f42ad8112bfdd95a780af" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen style={{width: "100%", height: "400px"}}></iframe>
|
||||
|
||||
## Build your first CrewAI Agent
|
||||
In this guide you will **create a Flow** that sets a research topic, runs a **crew with one agent** (a researcher using web search), and ends with a **markdown report** on disk. Flows are the recommended way to structure production apps: they own **state** and **execution order**, while **agents** do the work inside a crew step.
|
||||
|
||||
Let's create a simple crew that will help us `research` and `report` on the `latest AI developments` for a given topic or subject.
|
||||
If you have not installed CrewAI yet, follow the [installation guide](/en/installation) first.
|
||||
|
||||
Before we proceed, make sure you have finished installing CrewAI.
|
||||
If you haven't installed them yet, you can do so by following the [installation guide](/en/installation).
|
||||
## Prerequisites
|
||||
|
||||
Follow the steps below to get Crewing! 🚣♂️
|
||||
- Python environment and the CrewAI CLI (see [installation](/en/installation))
|
||||
- An LLM configured with the right API keys — see [LLMs](/en/concepts/llms#setting-up-your-llm)
|
||||
- A [Serper.dev](https://serper.dev/) API key (`SERPER_API_KEY`) for web search in this tutorial
|
||||
|
||||
## Build your first Flow
|
||||
|
||||
<Steps>
|
||||
<Step title="Create your crew">
|
||||
Create a new crew project by running the following command in your terminal.
|
||||
This will create a new directory called `latest-ai-development` with the basic structure for your crew.
|
||||
<Step title="Create a Flow project">
|
||||
From your terminal, scaffold a Flow project (the folder name uses underscores, e.g. `latest_ai_flow`):
|
||||
|
||||
<CodeGroup>
|
||||
```shell Terminal
|
||||
crewai create crew latest-ai-development
|
||||
crewai create flow latest-ai-flow
|
||||
cd latest_ai_flow
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
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="Navigate to your new crew project">
|
||||
<CodeGroup>
|
||||
```shell Terminal
|
||||
cd latest_ai_development
|
||||
```
|
||||
</CodeGroup>
|
||||
</Step>
|
||||
<Step title="Modify your `agents.yaml` file">
|
||||
<Tip>
|
||||
You can also modify the agents as needed to fit your use case or copy and paste as is to your project.
|
||||
Any variable interpolated in your `agents.yaml` and `tasks.yaml` files like `{topic}` will be replaced by the value of the variable in the `main.py` file.
|
||||
</Tip>
|
||||
|
||||
<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=...)`.
|
||||
|
||||
```yaml agents.yaml
|
||||
# src/latest_ai_development/config/agents.yaml
|
||||
# src/latest_ai_flow/crews/content_crew/config/agents.yaml
|
||||
researcher:
|
||||
role: >
|
||||
{topic} Senior Data Researcher
|
||||
@@ -53,336 +51,232 @@ Follow the steps below to get Crewing! 🚣♂️
|
||||
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.
|
||||
developments in {topic}. You find the most relevant information and
|
||||
present it clearly.
|
||||
```
|
||||
|
||||
</Step>
|
||||
<Step title="Modify your `tasks.yaml` file">
|
||||
|
||||
<Step title="Configure one task in `tasks.yaml`">
|
||||
```yaml tasks.yaml
|
||||
# src/latest_ai_development/config/tasks.yaml
|
||||
# src/latest_ai_flow/crews/content_crew/config/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.
|
||||
Conduct thorough research about {topic}. Use web search to find current,
|
||||
credible information. The current year is 2026.
|
||||
expected_output: >
|
||||
A list with 10 bullet points of the most relevant information about {topic}
|
||||
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
|
||||
|
||||
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
|
||||
output_file: report.md
|
||||
output_file: output/report.md
|
||||
```
|
||||
|
||||
</Step>
|
||||
<Step title="Modify your `crew.py` file">
|
||||
```python crew.py
|
||||
# src/latest_ai_development/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
|
||||
|
||||
<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 typing import List
|
||||
|
||||
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
|
||||
|
||||
|
||||
@CrewBase
|
||||
class LatestAiDevelopmentCrew():
|
||||
"""LatestAiDevelopment crew"""
|
||||
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]
|
||||
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
|
||||
tools=[SerperDevTool()],
|
||||
)
|
||||
|
||||
@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]
|
||||
output_file='output/report.md' # This is the file that will be contain the final report.
|
||||
config=self.tasks_config["research_task"], # type: ignore[index]
|
||||
)
|
||||
|
||||
@crew
|
||||
def crew(self) -> Crew:
|
||||
"""Creates the LatestAiDevelopment crew"""
|
||||
return Crew(
|
||||
agents=self.agents, # Automatically created by the @agent decorator
|
||||
tasks=self.tasks, # Automatically created by the @task decorator
|
||||
agents=self.agents,
|
||||
tasks=self.tasks,
|
||||
process=Process.sequential,
|
||||
verbose=True,
|
||||
)
|
||||
```
|
||||
|
||||
</Step>
|
||||
<Step title="[Optional] Add before and after crew functions">
|
||||
```python crew.py
|
||||
# src/latest_ai_development/crew.py
|
||||
from crewai import Agent, Crew, Process, Task
|
||||
from crewai.project import CrewBase, agent, crew, task, before_kickoff, after_kickoff
|
||||
from crewai_tools import SerperDevTool
|
||||
|
||||
@CrewBase
|
||||
class LatestAiDevelopmentCrew():
|
||||
"""LatestAiDevelopment crew"""
|
||||
<Step title="Define the Flow in `main.py`">
|
||||
Connect the crew to a Flow: a `@start()` step sets the topic in **state**, and a `@listen` step runs the crew. The task’s `output_file` still writes `output/report.md`.
|
||||
|
||||
@before_kickoff
|
||||
def before_kickoff_function(self, inputs):
|
||||
print(f"Before kickoff function with inputs: {inputs}")
|
||||
return inputs # You can return the inputs or modify them as needed
|
||||
|
||||
@after_kickoff
|
||||
def after_kickoff_function(self, result):
|
||||
print(f"After kickoff function with result: {result}")
|
||||
return result # You can return the result or modify it as needed
|
||||
|
||||
# ... remaining code
|
||||
```
|
||||
|
||||
</Step>
|
||||
<Step title="Feel free to pass custom inputs to your crew">
|
||||
For example, you can pass the `topic` input to your crew to customize the research and reporting.
|
||||
```python main.py
|
||||
#!/usr/bin/env python
|
||||
# src/latest_ai_development/main.py
|
||||
import sys
|
||||
from latest_ai_development.crew import LatestAiDevelopmentCrew
|
||||
# src/latest_ai_flow/main.py
|
||||
from pydantic import BaseModel
|
||||
|
||||
def run():
|
||||
"""
|
||||
Run the crew.
|
||||
"""
|
||||
inputs = {
|
||||
'topic': 'AI Agents'
|
||||
}
|
||||
LatestAiDevelopmentCrew().crew().kickoff(inputs=inputs)
|
||||
from crewai.flow import Flow, listen, start
|
||||
|
||||
from latest_ai_flow.crews.content_crew.content_crew import ResearchCrew
|
||||
|
||||
|
||||
class ResearchFlowState(BaseModel):
|
||||
topic: str = ""
|
||||
report: str = ""
|
||||
|
||||
|
||||
class LatestAiFlow(Flow[ResearchFlowState]):
|
||||
@start()
|
||||
def prepare_topic(self, crewai_trigger_payload: dict | None = None):
|
||||
if crewai_trigger_payload:
|
||||
self.state.topic = crewai_trigger_payload.get("topic", "AI Agents")
|
||||
else:
|
||||
self.state.topic = "AI Agents"
|
||||
print(f"Topic: {self.state.topic}")
|
||||
|
||||
@listen(prepare_topic)
|
||||
def run_research(self):
|
||||
result = ResearchCrew().crew().kickoff(inputs={"topic": self.state.topic})
|
||||
self.state.report = result.raw
|
||||
print("Research crew finished.")
|
||||
|
||||
@listen(run_research)
|
||||
def summarize(self):
|
||||
print("Report path: output/report.md")
|
||||
|
||||
|
||||
def kickoff():
|
||||
LatestAiFlow().kickoff()
|
||||
|
||||
|
||||
def plot():
|
||||
LatestAiFlow().plot()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
kickoff()
|
||||
```
|
||||
|
||||
</Step>
|
||||
<Step title="Set your environment variables">
|
||||
Before running your crew, make sure you have the following keys set as environment variables in your `.env` file:
|
||||
- A [Serper.dev](https://serper.dev/) API key: `SERPER_API_KEY=YOUR_KEY_HERE`
|
||||
- The configuration for your choice of model, such as an API key. See the
|
||||
[LLM setup guide](/en/concepts/llms#setting-up-your-llm) to learn how to configure models from any provider.
|
||||
</Step>
|
||||
<Step title="Lock and install the dependencies">
|
||||
- Lock the dependencies and install them by using the CLI command:
|
||||
<CodeGroup>
|
||||
```shell Terminal
|
||||
crewai install
|
||||
```
|
||||
</CodeGroup>
|
||||
- If you have additional packages that you want to install, you can do so by running:
|
||||
<CodeGroup>
|
||||
```shell Terminal
|
||||
uv add <package-name>
|
||||
```
|
||||
</CodeGroup>
|
||||
</Step>
|
||||
<Step title="Run your crew">
|
||||
- To run your crew, execute the following command in the root of your project:
|
||||
<CodeGroup>
|
||||
```bash Terminal
|
||||
crewai run
|
||||
```
|
||||
</CodeGroup>
|
||||
<Tip>
|
||||
If your package name differs from `latest_ai_flow`, change the import of `ResearchCrew` to match your project’s module path.
|
||||
</Tip>
|
||||
</Step>
|
||||
|
||||
<Step title="Enterprise Alternative: Create in Crew Studio">
|
||||
For CrewAI AMP users, you can create the same crew without writing code:
|
||||
<Step title="Set environment variables">
|
||||
In `.env` at the project root, set:
|
||||
|
||||
1. Log in to your CrewAI AMP account (create a free account at [app.crewai.com](https://app.crewai.com))
|
||||
2. Open Crew Studio
|
||||
3. Type what is the automation you're trying to build
|
||||
4. Create your tasks visually and connect them in sequence
|
||||
5. Configure your inputs and click "Download Code" or "Deploy"
|
||||
|
||||

|
||||
|
||||
<Card title="Try CrewAI AMP" icon="rocket" href="https://app.crewai.com">
|
||||
Start your free account at CrewAI AMP
|
||||
</Card>
|
||||
- `SERPER_API_KEY` — from [Serper.dev](https://serper.dev/)
|
||||
- Your model provider keys as required — see [LLM setup](/en/concepts/llms#setting-up-your-llm)
|
||||
</Step>
|
||||
<Step title="View your final report">
|
||||
You should see the output in the console and the `report.md` file should be created in the root of your project with the final report.
|
||||
|
||||
Here's an example of what the report should look like:
|
||||
<Step title="Install and run">
|
||||
<CodeGroup>
|
||||
```shell Terminal
|
||||
crewai install
|
||||
crewai run
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
`crewai run` executes the Flow entrypoint defined in your project (same command as for crews; project type is `"flow"` in `pyproject.toml`).
|
||||
</Step>
|
||||
|
||||
|
||||
|
||||
|
||||
<Step title="Check the output">
|
||||
You should see logs from the Flow and the crew. Open **`output/report.md`** for the generated report (excerpt):
|
||||
|
||||
<CodeGroup>
|
||||
```markdown output/report.md
|
||||
# Comprehensive Report on the Rise and Impact of AI Agents in 2025
|
||||
# AI Agents in 2026: Landscape and Trends
|
||||
|
||||
## 1. Introduction to AI Agents
|
||||
In 2025, Artificial Intelligence (AI) agents are at the forefront of innovation across various industries. As intelligent systems that can perform tasks typically requiring human cognition, AI agents are paving the way for significant advancements in operational efficiency, decision-making, and overall productivity within sectors like Human Resources (HR) and Finance. This report aims to detail the rise of AI agents, their frameworks, applications, and potential implications on the workforce.
|
||||
## Executive summary
|
||||
…
|
||||
|
||||
## 2. Benefits of AI Agents
|
||||
AI agents bring numerous advantages that are transforming traditional work environments. Key benefits include:
|
||||
## Key trends
|
||||
- **Tool use and orchestration** — …
|
||||
- **Enterprise adoption** — …
|
||||
|
||||
- **Task Automation**: AI agents can carry out repetitive tasks such as data entry, scheduling, and payroll processing without human intervention, greatly reducing the time and resources spent on these activities.
|
||||
- **Improved Efficiency**: By quickly processing large datasets and performing analyses that would take humans significantly longer, AI agents enhance operational efficiency. This allows teams to focus on strategic tasks that require higher-level thinking.
|
||||
- **Enhanced Decision-Making**: AI agents can analyze trends and patterns in data, provide insights, and even suggest actions, helping stakeholders make informed decisions based on factual data rather than intuition alone.
|
||||
|
||||
## 3. Popular AI Agent Frameworks
|
||||
Several frameworks have emerged to facilitate the development of AI agents, each with its own unique features and capabilities. Some of the most popular frameworks include:
|
||||
|
||||
- **Autogen**: A framework designed to streamline the development of AI agents through automation of code generation.
|
||||
- **Semantic Kernel**: Focuses on natural language processing and understanding, enabling agents to comprehend user intentions better.
|
||||
- **Promptflow**: Provides tools for developers to create conversational agents that can navigate complex interactions seamlessly.
|
||||
- **Langchain**: Specializes in leveraging various APIs to ensure agents can access and utilize external data effectively.
|
||||
- **CrewAI**: Aimed at collaborative environments, CrewAI strengthens teamwork by facilitating communication through AI-driven insights.
|
||||
- **MemGPT**: Combines memory-optimized architectures with generative capabilities, allowing for more personalized interactions with users.
|
||||
|
||||
These frameworks empower developers to build versatile and intelligent agents that can engage users, perform advanced analytics, and execute various tasks aligned with organizational goals.
|
||||
|
||||
## 4. AI Agents in Human Resources
|
||||
AI agents are revolutionizing HR practices by automating and optimizing key functions:
|
||||
|
||||
- **Recruiting**: AI agents can screen resumes, schedule interviews, and even conduct initial assessments, thus accelerating the hiring process while minimizing biases.
|
||||
- **Succession Planning**: AI systems analyze employee performance data and potential, helping organizations identify future leaders and plan appropriate training.
|
||||
- **Employee Engagement**: Chatbots powered by AI can facilitate feedback loops between employees and management, promoting an open culture and addressing concerns promptly.
|
||||
|
||||
As AI continues to evolve, HR departments leveraging these agents can realize substantial improvements in both efficiency and employee satisfaction.
|
||||
|
||||
## 5. AI Agents in Finance
|
||||
The finance sector is seeing extensive integration of AI agents that enhance financial practices:
|
||||
|
||||
- **Expense Tracking**: Automated systems manage and monitor expenses, flagging anomalies and offering recommendations based on spending patterns.
|
||||
- **Risk Assessment**: AI models assess credit risk and uncover potential fraud by analyzing transaction data and behavioral patterns.
|
||||
- **Investment Decisions**: AI agents provide stock predictions and analytics based on historical data and current market conditions, empowering investors with informative insights.
|
||||
|
||||
The incorporation of AI agents into finance is fostering a more responsive and risk-aware financial landscape.
|
||||
|
||||
## 6. Market Trends and Investments
|
||||
The growth of AI agents has attracted significant investment, especially amidst the rising popularity of chatbots and generative AI technologies. Companies and entrepreneurs are eager to explore the potential of these systems, recognizing their ability to streamline operations and improve customer engagement.
|
||||
|
||||
Conversely, corporations like Microsoft are taking strides to integrate AI agents into their product offerings, with enhancements to their Copilot 365 applications. This strategic move emphasizes the importance of AI literacy in the modern workplace and indicates the stabilizing of AI agents as essential business tools.
|
||||
|
||||
## 7. Future Predictions and Implications
|
||||
Experts predict that AI agents will transform essential aspects of work life. As we look toward the future, several anticipated changes include:
|
||||
|
||||
- Enhanced integration of AI agents across all business functions, creating interconnected systems that leverage data from various departmental silos for comprehensive decision-making.
|
||||
- Continued advancement of AI technologies, resulting in smarter, more adaptable agents capable of learning and evolving from user interactions.
|
||||
- Increased regulatory scrutiny to ensure ethical use, especially concerning data privacy and employee surveillance as AI agents become more prevalent.
|
||||
|
||||
To stay competitive and harness the full potential of AI agents, organizations must remain vigilant about latest developments in AI technology and consider continuous learning and adaptation in their strategic planning.
|
||||
|
||||
## 8. Conclusion
|
||||
The emergence of AI agents is undeniably reshaping the workplace landscape in 5. With their ability to automate tasks, enhance efficiency, and improve decision-making, AI agents are critical in driving operational success. Organizations must embrace and adapt to AI developments to thrive in an increasingly digital business environment.
|
||||
## Implications
|
||||
…
|
||||
```
|
||||
|
||||
</CodeGroup>
|
||||
|
||||
Your actual file will be longer and reflect live search results.
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
## 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** — `ResearchCrew` runs one task with one agent: the researcher uses **Serper** to search the web, then writes the structured report.
|
||||
3. **Artifact** — The task’s `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).
|
||||
|
||||
<Check>
|
||||
Congratulations!
|
||||
|
||||
You have successfully set up your crew project and are ready to start building your own agentic workflows!
|
||||
|
||||
You now have an end-to-end Flow with an agent crew and a saved report — a solid base to add more steps, crews, or tools.
|
||||
</Check>
|
||||
|
||||
### Note on Consistency in Naming
|
||||
### Naming consistency
|
||||
|
||||
The names you use in your YAML files (`agents.yaml` and `tasks.yaml`) should match the method names in your Python code.
|
||||
For example, you can reference the agent for specific tasks from `tasks.yaml` file.
|
||||
This naming consistency allows CrewAI to automatically link your configurations with your code; otherwise, your task won't recognize the reference properly.
|
||||
YAML keys (`researcher`, `research_task`) must match the method names on your `@CrewBase` class. See [Crews](/en/concepts/crews) for the full decorator pattern.
|
||||
|
||||
#### Example References
|
||||
## Deploying
|
||||
|
||||
<Tip>
|
||||
Note how we use the same name for the agent in the `agents.yaml`
|
||||
(`email_summarizer`) file as the method name in the `crew.py`
|
||||
(`email_summarizer`) file.
|
||||
</Tip>
|
||||
Push your Flow to **[CrewAI AMP](https://app.crewai.com)** once it runs locally and your project is in a **GitHub** repository. From the project root:
|
||||
|
||||
```yaml agents.yaml
|
||||
email_summarizer:
|
||||
role: >
|
||||
Email Summarizer
|
||||
goal: >
|
||||
Summarize emails into a concise and clear summary
|
||||
backstory: >
|
||||
You will create a 5 bullet point summary of the report
|
||||
llm: provider/model-id # Add your choice of model here
|
||||
<CodeGroup>
|
||||
```bash Authenticate
|
||||
crewai login
|
||||
```
|
||||
|
||||
<Tip>
|
||||
Note how we use the same name for the task in the `tasks.yaml`
|
||||
(`email_summarizer_task`) file as the method name in the `crew.py`
|
||||
(`email_summarizer_task`) file.
|
||||
</Tip>
|
||||
|
||||
```yaml tasks.yaml
|
||||
email_summarizer_task:
|
||||
description: >
|
||||
Summarize the email into a 5 bullet point summary
|
||||
expected_output: >
|
||||
A 5 bullet point summary of the email
|
||||
agent: email_summarizer
|
||||
context:
|
||||
- reporting_task
|
||||
- research_task
|
||||
```bash Create deployment
|
||||
crewai deploy create
|
||||
```
|
||||
|
||||
## Deploying Your Crew
|
||||
```bash Check status & logs
|
||||
crewai deploy status
|
||||
crewai deploy logs
|
||||
```
|
||||
|
||||
The easiest way to deploy your crew to production is through [CrewAI AMP](http://app.crewai.com).
|
||||
```bash Ship updates after you change code
|
||||
crewai deploy push
|
||||
```
|
||||
|
||||
Watch this video tutorial for a step-by-step demonstration of deploying your crew to [CrewAI AMP](http://app.crewai.com) using the CLI.
|
||||
```bash List or remove deployments
|
||||
crewai deploy list
|
||||
crewai deploy remove <deployment_id>
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
<iframe
|
||||
className="w-full aspect-video rounded-xl"
|
||||
src="https://www.youtube.com/embed/3EqSV-CYDZA"
|
||||
title="CrewAI Deployment Guide"
|
||||
frameBorder="0"
|
||||
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
|
||||
allowFullScreen
|
||||
></iframe>
|
||||
<Tip>
|
||||
The first deploy usually takes **around 1 minute**. Full prerequisites and the web UI flow are in [Deploy to AMP](/en/enterprise/guides/deploy-to-amp).
|
||||
</Tip>
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Deploy on Enterprise" icon="rocket" href="http://app.crewai.com">
|
||||
Get started with CrewAI AMP and deploy your crew in a production environment
|
||||
with just a few clicks.
|
||||
<Card title="Deploy guide" icon="book" href="/en/enterprise/guides/deploy-to-amp">
|
||||
Step-by-step AMP deployment (CLI and dashboard).
|
||||
</Card>
|
||||
<Card
|
||||
title="Join the Community"
|
||||
icon="comments"
|
||||
href="https://community.crewai.com"
|
||||
>
|
||||
Join our open source community to discuss ideas, share your projects, and
|
||||
connect with other CrewAI developers.
|
||||
Discuss ideas, share projects, and connect with other CrewAI developers.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
@@ -7,6 +7,10 @@ mode: "wide"
|
||||
|
||||
# `CodeInterpreterTool`
|
||||
|
||||
<Warning>
|
||||
**Deprecated:** `CodeInterpreterTool` has been removed from `crewai-tools`. The `allow_code_execution` and `code_execution_mode` parameters on `Agent` are also deprecated. Use a dedicated sandbox service — [E2B](https://e2b.dev) or [Modal](https://modal.com) — for secure, isolated code execution.
|
||||
</Warning>
|
||||
|
||||
## Description
|
||||
|
||||
The `CodeInterpreterTool` enables CrewAI agents to execute Python 3 code that they generate autonomously. This functionality is particularly valuable as it allows agents to create code, execute it, obtain the results, and utilize that information to inform subsequent decisions and actions.
|
||||
|
||||
@@ -75,4 +75,20 @@ tool = CSVSearchTool(
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
## Security
|
||||
|
||||
### Path Validation
|
||||
|
||||
File paths provided to this tool are validated against the current working directory. Paths that resolve outside the working directory are rejected with a `ValueError`.
|
||||
|
||||
To allow paths outside the working directory (for example, in tests or trusted pipelines), set the environment variable:
|
||||
|
||||
```shell
|
||||
CREWAI_TOOLS_ALLOW_UNSAFE_PATHS=true
|
||||
```
|
||||
|
||||
### URL Validation
|
||||
|
||||
URL inputs are validated: `file://` URIs and requests targeting private or reserved IP ranges are blocked to prevent server-side request forgery (SSRF) attacks.
|
||||
```
|
||||
@@ -67,4 +67,16 @@ tool = DirectorySearchTool(
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
## Security
|
||||
|
||||
### Path Validation
|
||||
|
||||
Directory paths provided to this tool are validated against the current working directory. Paths that resolve outside the working directory are rejected with a `ValueError`.
|
||||
|
||||
To allow paths outside the working directory (for example, in tests or trusted pipelines), set the environment variable:
|
||||
|
||||
```shell
|
||||
CREWAI_TOOLS_ALLOW_UNSAFE_PATHS=true
|
||||
```
|
||||
```
|
||||
@@ -74,3 +74,19 @@ tool = JSONSearchTool(
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
## Security
|
||||
|
||||
### Path Validation
|
||||
|
||||
File paths provided to this tool are validated against the current working directory. Paths that resolve outside the working directory are rejected with a `ValueError`.
|
||||
|
||||
To allow paths outside the working directory (for example, in tests or trusted pipelines), set the environment variable:
|
||||
|
||||
```shell
|
||||
CREWAI_TOOLS_ALLOW_UNSAFE_PATHS=true
|
||||
```
|
||||
|
||||
### URL Validation
|
||||
|
||||
URL inputs are validated: `file://` URIs and requests targeting private or reserved IP ranges are blocked to prevent server-side request forgery (SSRF) attacks.
|
||||
|
||||
@@ -105,4 +105,20 @@ tool = PDFSearchTool(
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
## Security
|
||||
|
||||
### Path Validation
|
||||
|
||||
File paths provided to this tool are validated against the current working directory. Paths that resolve outside the working directory are rejected with a `ValueError`.
|
||||
|
||||
To allow paths outside the working directory (for example, in tests or trusted pipelines), set the environment variable:
|
||||
|
||||
```shell
|
||||
CREWAI_TOOLS_ALLOW_UNSAFE_PATHS=true
|
||||
```
|
||||
|
||||
### URL Validation
|
||||
|
||||
URL inputs are validated: `file://` URIs and requests targeting private or reserved IP ranges are blocked to prevent server-side request forgery (SSRF) attacks.
|
||||
```
|
||||
@@ -4,6 +4,110 @@ description: "CrewAI의 제품 업데이트, 개선 사항 및 버그 수정"
|
||||
icon: "clock"
|
||||
mode: "wide"
|
||||
---
|
||||
<Update label="2026년 4월 7일">
|
||||
## v1.14.0
|
||||
|
||||
[GitHub 릴리스 보기](https://github.com/crewAIInc/crewAI/releases/tag/1.14.0)
|
||||
|
||||
## 변경 사항
|
||||
|
||||
### 기능
|
||||
- 체크포인트 목록/정보 CLI 명령 추가
|
||||
- 추적을 구분하기 위한 guardrail_type 및 이름 추가
|
||||
- 체크포인트 저장을 위한 SqliteProvider 추가
|
||||
- 자동 체크포인트 생성을 위한 CheckpointConfig 추가
|
||||
- 런타임 상태 체크포인트, 이벤트 시스템 및 실행기 리팩토링 구현
|
||||
|
||||
### 버그 수정
|
||||
- SSRF 및 경로 탐색 보호 추가
|
||||
- RAG 도구에 경로 및 URL 유효성 검사 추가
|
||||
- 토큰 절약을 위해 메모리 직렬화에서 임베딩 벡터 제외
|
||||
- 흐름 템플릿에 쓰기 전에 출력 디렉토리가 존재하는지 확인
|
||||
- CVE-2026-35030 문제를 해결하기 위해 litellm을 >=1.83.0으로 업데이트
|
||||
- 아랍어 페이지 렌더링을 유발하는 SEO 인덱싱 필드 제거
|
||||
|
||||
### 문서
|
||||
- v1.14.0에 대한 변경 로그 및 버전 업데이트
|
||||
- 명확성을 개선하기 위해 빠른 시작 및 설치 가이드 업데이트
|
||||
- 저장소 제공자 섹션 추가, JsonProvider 내보내기
|
||||
- AMP 교육 탭 가이드 추가
|
||||
|
||||
### 리팩토링
|
||||
- 체크포인트 API 정리
|
||||
- CodeInterpreterTool 제거 및 코드 실행 매개변수 사용 중단
|
||||
|
||||
## 기여자
|
||||
|
||||
@alex-clawd, @github-actions[bot], @greysonlalonde, @iris-clawd, @joaomdmoura, @lorenzejay, @lucasgomide
|
||||
|
||||
</Update>
|
||||
|
||||
<Update label="2026년 4월 7일">
|
||||
## v1.14.0a4
|
||||
|
||||
[GitHub 릴리스 보기](https://github.com/crewAIInc/crewAI/releases/tag/1.14.0a4)
|
||||
|
||||
## 변경 사항
|
||||
|
||||
### 기능
|
||||
- 추적을 구분하기 위해 guardrail_type 및 이름 추가
|
||||
- 체크포인트 저장을 위한 SqliteProvider 추가
|
||||
- 자동 체크포인트 생성을 위한 CheckpointConfig 추가
|
||||
- 런타임 상태 체크포인트, 이벤트 시스템 및 실행기 리팩토링 구현
|
||||
|
||||
### 버그 수정
|
||||
- 토큰 절약을 위해 메모리 직렬화에서 임베딩 벡터 제외
|
||||
- CVE-2026-35030 문제를 해결하기 위해 litellm을 >=1.83.0으로 업데이트
|
||||
|
||||
### 문서
|
||||
- 명확성을 개선하기 위해 빠른 시작 및 설치 가이드 업데이트
|
||||
- 저장소 제공자 섹션 추가 및 JsonProvider 내보내기
|
||||
|
||||
### 성능
|
||||
- 체크포인트 데이터 열에 JSONB 사용
|
||||
|
||||
### 리팩토링
|
||||
- CodeInterpreterTool 제거 및 코드 실행 매개변수 사용 중단
|
||||
|
||||
## 기여자
|
||||
|
||||
@alex-clawd, @github-actions[bot], @greysonlalonde, @joaomdmoura, @lorenzejay, @lucasgomide
|
||||
|
||||
</Update>
|
||||
|
||||
<Update label="2026년 4월 6일">
|
||||
## v1.14.0a3
|
||||
|
||||
[GitHub 릴리스 보기](https://github.com/crewAIInc/crewAI/releases/tag/1.14.0a3)
|
||||
|
||||
## 변경 사항
|
||||
|
||||
### 문서
|
||||
- v1.14.0a2의 변경 로그 및 버전 업데이트
|
||||
|
||||
## 기여자
|
||||
|
||||
@joaomdmoura
|
||||
|
||||
</Update>
|
||||
|
||||
<Update label="2026년 4월 6일">
|
||||
## v1.14.0a2
|
||||
|
||||
[GitHub 릴리스 보기](https://github.com/crewAIInc/crewAI/releases/tag/1.14.0a2)
|
||||
|
||||
## 릴리스 1.14.0a2
|
||||
|
||||
### 지침:
|
||||
- 모든 섹션 제목과 설명을 자연스럽게 번역합니다.
|
||||
- 마크다운 형식을 그대로 유지합니다 (##, ###, -, 등).
|
||||
- 모든 고유 명사, 코드 식별자, 클래스 이름 및 기술 용어는 변경하지 않습니다.
|
||||
(예: "CrewAI", "LiteAgent", "ChromaDB", "MCP", "@username")
|
||||
- ## 기여자 섹션과 GitHub 사용자 이름은 변경하지 않습니다.
|
||||
- 내용을 추가하거나 제거하지 않고 오직 번역만 합니다.
|
||||
|
||||
</Update>
|
||||
|
||||
<Update label="2026년 4월 2일">
|
||||
## v1.13.0
|
||||
|
||||
|
||||
@@ -291,15 +291,13 @@ multimodal_agent = Agent(
|
||||
- `max_retry_limit`: 오류 발생 시 재시도 횟수
|
||||
|
||||
#### 코드 실행
|
||||
- `allow_code_execution`: 코드를 실행하려면 True여야 합니다
|
||||
- `code_execution_mode`:
|
||||
- `"safe"`: Docker를 사용합니다 (프로덕션에 권장)
|
||||
- `"unsafe"`: 직접 실행 (신뢰할 수 있는 환경에서만 사용)
|
||||
|
||||
<Note>
|
||||
이 옵션은 기본 Docker 이미지를 실행합니다. Docker 이미지를 구성하려면 도구 섹션에 있는 Code Interpreter Tool을 확인하십시오.
|
||||
Code Interpreter Tool을 에이전트의 도구 파라미터로 추가하십시오.
|
||||
</Note>
|
||||
<Warning>
|
||||
`allow_code_execution` 및 `code_execution_mode`는 더 이상 사용되지 않습니다. `CodeInterpreterTool`이 `crewai-tools`에서 제거되었습니다. 안전한 코드 실행을 위해 [E2B](https://e2b.dev) 또는 [Modal](https://modal.com)과 같은 전용 샌드박스 서비스를 사용하세요.
|
||||
</Warning>
|
||||
|
||||
- `allow_code_execution` _(지원 중단)_: 이전에 `CodeInterpreterTool`을 통한 내장 코드 실행을 활성화했습니다.
|
||||
- `code_execution_mode` _(지원 중단)_: 이전에 실행 모드를 제어했습니다 (Docker의 경우 `"safe"`, 직접 실행의 경우 `"unsafe"`).
|
||||
|
||||
#### 고급 기능
|
||||
- `multimodal`: 텍스트와 시각적 콘텐츠 처리를 위한 멀티모달 기능 활성화
|
||||
@@ -627,9 +625,10 @@ asyncio.run(main())
|
||||
## 중요한 고려사항 및 모범 사례
|
||||
|
||||
### 보안 및 코드 실행
|
||||
- `allow_code_execution`을 사용할 때는 사용자 입력에 주의하고 항상 입력 값을 검증하세요
|
||||
- 운영 환경에서는 `code_execution_mode: "safe"`(Docker)를 사용하세요
|
||||
- 무한 루프를 방지하기 위해 적절한 `max_execution_time` 제한을 설정하는 것을 고려하세요
|
||||
|
||||
<Warning>
|
||||
`allow_code_execution` 및 `code_execution_mode`는 더 이상 사용되지 않으며 `CodeInterpreterTool`이 제거되었습니다. 안전한 코드 실행을 위해 [E2B](https://e2b.dev) 또는 [Modal](https://modal.com)과 같은 전용 샌드박스 서비스를 사용하세요.
|
||||
</Warning>
|
||||
|
||||
### 성능 최적화
|
||||
- `respect_context_window: true`를 사용하여 토큰 제한 문제를 방지하세요.
|
||||
|
||||
229
docs/ko/concepts/checkpointing.mdx
Normal file
229
docs/ko/concepts/checkpointing.mdx
Normal file
@@ -0,0 +1,229 @@
|
||||
---
|
||||
title: Checkpointing
|
||||
description: 실행 상태를 자동으로 저장하여 크루, 플로우, 에이전트가 실패 후 재개할 수 있습니다.
|
||||
icon: floppy-disk
|
||||
mode: "wide"
|
||||
---
|
||||
|
||||
<Warning>
|
||||
체크포인팅은 초기 릴리스 단계입니다. API는 향후 버전에서 변경될 수 있습니다.
|
||||
</Warning>
|
||||
|
||||
## 개요
|
||||
|
||||
체크포인팅은 실행 중 자동으로 실행 상태를 저장합니다. 크루, 플로우 또는 에이전트가 실행 도중 실패하면 마지막 체크포인트에서 복원하여 이미 완료된 작업을 다시 실행하지 않고 재개할 수 있습니다.
|
||||
|
||||
## 빠른 시작
|
||||
|
||||
```python
|
||||
from crewai import Crew, CheckpointConfig
|
||||
|
||||
crew = Crew(
|
||||
agents=[...],
|
||||
tasks=[...],
|
||||
checkpoint=True, # 기본값 사용: ./.checkpoints, task_completed 이벤트
|
||||
)
|
||||
result = crew.kickoff()
|
||||
```
|
||||
|
||||
각 태스크가 완료된 후 `./.checkpoints/`에 체크포인트 파일이 기록됩니다.
|
||||
|
||||
## 설정
|
||||
|
||||
`CheckpointConfig`를 사용하여 세부 설정을 제어합니다:
|
||||
|
||||
```python
|
||||
from crewai import Crew, CheckpointConfig
|
||||
|
||||
crew = Crew(
|
||||
agents=[...],
|
||||
tasks=[...],
|
||||
checkpoint=CheckpointConfig(
|
||||
location="./my_checkpoints",
|
||||
on_events=["task_completed", "crew_kickoff_completed"],
|
||||
max_checkpoints=5,
|
||||
),
|
||||
)
|
||||
```
|
||||
|
||||
### CheckpointConfig 필드
|
||||
|
||||
| 필드 | 타입 | 기본값 | 설명 |
|
||||
|:-----|:-----|:-------|:-----|
|
||||
| `location` | `str` | `"./.checkpoints"` | 체크포인트 파일 경로 |
|
||||
| `on_events` | `list[str]` | `["task_completed"]` | 체크포인트를 트리거하는 이벤트 타입 |
|
||||
| `provider` | `BaseProvider` | `JsonProvider()` | 스토리지 백엔드 |
|
||||
| `max_checkpoints` | `int \| None` | `None` | 보관할 최대 파일 수; 오래된 것부터 삭제 |
|
||||
|
||||
### 상속 및 옵트아웃
|
||||
|
||||
Crew, Flow, Agent의 `checkpoint` 필드는 `CheckpointConfig`, `True`, `False`, `None`을 받습니다:
|
||||
|
||||
| 값 | 동작 |
|
||||
|:---|:-----|
|
||||
| `None` (기본값) | 부모에서 상속. 에이전트는 크루의 설정을 상속합니다. |
|
||||
| `True` | 기본값으로 활성화. |
|
||||
| `False` | 명시적 옵트아웃. 부모 상속을 중단합니다. |
|
||||
| `CheckpointConfig(...)` | 사용자 정의 설정. |
|
||||
|
||||
```python
|
||||
crew = Crew(
|
||||
agents=[
|
||||
Agent(role="Researcher", ...), # 크루의 checkpoint 상속
|
||||
Agent(role="Writer", ..., checkpoint=False), # 옵트아웃, 체크포인트 없음
|
||||
],
|
||||
tasks=[...],
|
||||
checkpoint=True,
|
||||
)
|
||||
```
|
||||
|
||||
## 체크포인트에서 재개
|
||||
|
||||
```python
|
||||
# 복원 및 재개
|
||||
crew = Crew.from_checkpoint("./my_checkpoints/20260407T120000_abc123.json")
|
||||
result = crew.kickoff() # 마지막으로 완료된 태스크부터 재개
|
||||
```
|
||||
|
||||
복원된 크루는 이미 완료된 태스크를 건너뛰고 첫 번째 미완료 태스크부터 재개합니다.
|
||||
|
||||
## Crew, Flow, Agent에서 사용 가능
|
||||
|
||||
### Crew
|
||||
|
||||
```python
|
||||
crew = Crew(
|
||||
agents=[researcher, writer],
|
||||
tasks=[research_task, write_task, review_task],
|
||||
checkpoint=CheckpointConfig(location="./crew_cp"),
|
||||
)
|
||||
```
|
||||
|
||||
기본 트리거: `task_completed` (완료된 태스크당 하나의 체크포인트).
|
||||
|
||||
### Flow
|
||||
|
||||
```python
|
||||
from crewai.flow.flow import Flow, start, listen
|
||||
from crewai import CheckpointConfig
|
||||
|
||||
class MyFlow(Flow):
|
||||
@start()
|
||||
def step_one(self):
|
||||
return "data"
|
||||
|
||||
@listen(step_one)
|
||||
def step_two(self, data):
|
||||
return process(data)
|
||||
|
||||
flow = MyFlow(
|
||||
checkpoint=CheckpointConfig(
|
||||
location="./flow_cp",
|
||||
on_events=["method_execution_finished"],
|
||||
),
|
||||
)
|
||||
result = flow.kickoff()
|
||||
|
||||
# 재개
|
||||
flow = MyFlow.from_checkpoint("./flow_cp/20260407T120000_abc123.json")
|
||||
result = flow.kickoff()
|
||||
```
|
||||
|
||||
### Agent
|
||||
|
||||
```python
|
||||
agent = Agent(
|
||||
role="Researcher",
|
||||
goal="Research topics",
|
||||
backstory="Expert researcher",
|
||||
checkpoint=CheckpointConfig(
|
||||
location="./agent_cp",
|
||||
on_events=["lite_agent_execution_completed"],
|
||||
),
|
||||
)
|
||||
result = agent.kickoff(messages=[{"role": "user", "content": "Research AI trends"}])
|
||||
```
|
||||
|
||||
## 스토리지 프로바이더
|
||||
|
||||
CrewAI는 두 가지 체크포인트 스토리지 프로바이더를 제공합니다.
|
||||
|
||||
### JsonProvider (기본값)
|
||||
|
||||
각 체크포인트를 별도의 JSON 파일로 저장합니다.
|
||||
|
||||
```python
|
||||
from crewai import Crew, CheckpointConfig
|
||||
from crewai.state import JsonProvider
|
||||
|
||||
crew = Crew(
|
||||
agents=[...],
|
||||
tasks=[...],
|
||||
checkpoint=CheckpointConfig(
|
||||
location="./my_checkpoints",
|
||||
provider=JsonProvider(),
|
||||
max_checkpoints=5,
|
||||
),
|
||||
)
|
||||
```
|
||||
|
||||
### SqliteProvider
|
||||
|
||||
모든 체크포인트를 단일 SQLite 데이터베이스 파일에 저장합니다.
|
||||
|
||||
```python
|
||||
from crewai import Crew, CheckpointConfig
|
||||
from crewai.state import SqliteProvider
|
||||
|
||||
crew = Crew(
|
||||
agents=[...],
|
||||
tasks=[...],
|
||||
checkpoint=CheckpointConfig(
|
||||
location="./.checkpoints.db",
|
||||
provider=SqliteProvider(),
|
||||
),
|
||||
)
|
||||
```
|
||||
|
||||
|
||||
## 이벤트 타입
|
||||
|
||||
`on_events` 필드는 이벤트 타입 문자열의 조합을 받습니다. 일반적인 선택:
|
||||
|
||||
| 사용 사례 | 이벤트 |
|
||||
|:----------|:-------|
|
||||
| 각 태스크 완료 후 (Crew) | `["task_completed"]` |
|
||||
| 각 플로우 메서드 완료 후 | `["method_execution_finished"]` |
|
||||
| 에이전트 실행 완료 후 | `["agent_execution_completed"]`, `["lite_agent_execution_completed"]` |
|
||||
| 크루 완료 시에만 | `["crew_kickoff_completed"]` |
|
||||
| 모든 LLM 호출 후 | `["llm_call_completed"]` |
|
||||
| 모든 이벤트 | `["*"]` |
|
||||
|
||||
<Warning>
|
||||
`["*"]` 또는 `llm_call_completed`와 같은 고빈도 이벤트를 사용하면 많은 체크포인트 파일이 생성되어 성능에 영향을 줄 수 있습니다. `max_checkpoints`를 사용하여 디스크 사용량을 제한하세요.
|
||||
</Warning>
|
||||
|
||||
## 수동 체크포인팅
|
||||
|
||||
완전한 제어를 위해 자체 이벤트 핸들러를 등록하고 `state.checkpoint()`를 직접 호출할 수 있습니다:
|
||||
|
||||
```python
|
||||
from crewai.events.event_bus import crewai_event_bus
|
||||
from crewai.events.types.llm_events import LLMCallCompletedEvent
|
||||
|
||||
# 동기 핸들러
|
||||
@crewai_event_bus.on(LLMCallCompletedEvent)
|
||||
def on_llm_done(source, event, state):
|
||||
path = state.checkpoint("./my_checkpoints")
|
||||
print(f"체크포인트 저장: {path}")
|
||||
|
||||
# 비동기 핸들러
|
||||
@crewai_event_bus.on(LLMCallCompletedEvent)
|
||||
async def on_llm_done_async(source, event, state):
|
||||
path = await state.acheckpoint("./my_checkpoints")
|
||||
print(f"체크포인트 저장: {path}")
|
||||
```
|
||||
|
||||
`state` 인수는 핸들러가 3개의 매개변수를 받을 때 이벤트 버스가 자동으로 전달하는 `RuntimeState`입니다. [Event Listeners](/ko/concepts/event-listener) 문서에 나열된 모든 이벤트 타입에 핸들러를 등록할 수 있습니다.
|
||||
|
||||
체크포인팅은 best-effort입니다: 체크포인트 기록이 실패하면 오류가 로그에 기록되지만 실행은 중단 없이 계속됩니다.
|
||||
@@ -117,35 +117,23 @@ task = Task(
|
||||
|
||||
### Flow와 함께
|
||||
|
||||
flow의 상태 스키마에 있는 파일 타입 필드(`File`, `ImageFile`, `PDFFile`)는 플랫폼 UI에 대한 신호 역할을 합니다. 배포 시 이러한 필드는 파일 업로드 드롭존으로 렌더링됩니다. 파일은 API에서 `input_files`를 통해서도 전달할 수 있습니다.
|
||||
flow에 파일을 전달하면 자동으로 crew에 상속됩니다:
|
||||
|
||||
```python
|
||||
from crewai.flow.flow import Flow, start
|
||||
from crewai_files import File, ImageFile
|
||||
from pydantic import BaseModel
|
||||
from crewai_files import ImageFile
|
||||
|
||||
class MyState(BaseModel):
|
||||
document: File # Renders as file dropzone in Platform UI
|
||||
cover_image: ImageFile # Image-specific dropzone
|
||||
title: str = ""
|
||||
|
||||
class AnalysisFlow(Flow[MyState]):
|
||||
class AnalysisFlow(Flow):
|
||||
@start()
|
||||
def analyze(self):
|
||||
# Files are automatically populated in state
|
||||
content = self.state.document.read()
|
||||
return self.analysis_crew.kickoff()
|
||||
|
||||
flow = AnalysisFlow()
|
||||
result = flow.kickoff(
|
||||
input_files={"document": File(source="report.pdf")}
|
||||
input_files={"image": ImageFile(source="data.png")}
|
||||
)
|
||||
```
|
||||
|
||||
<Note type="info" title="CrewAI 플랫폼 통합">
|
||||
CrewAI 플랫폼에 배포하면 flow 상태의 `ImageFile`, `PDFFile` 및 기타 파일 타입 필드가 자동으로 파일 업로드 UI를 갖게 됩니다. 사용자는 플랫폼 인터페이스에서 직접 파일을 드래그 앤 드롭할 수 있습니다. 파일은 안전하게 저장되고 프로바이더별 최적화(인라인 base64, 파일 업로드 API 또는 프로바이더에 따른 URL 참조)를 사용하여 에이전트에 전달됩니다. API 사용 예제는 [Flows의 파일 입력](/ko/concepts/flows#파일-입력)을 참조하세요.
|
||||
</Note>
|
||||
|
||||
### 단독 에이전트와 함께
|
||||
|
||||
에이전트 킥오프에 직접 파일을 전달합니다:
|
||||
|
||||
@@ -334,90 +334,6 @@ flow.kickoff()
|
||||
|
||||
CrewAI Flows는 비구조적 및 구조적 상태 관리 옵션을 모두 제공함으로써, 개발자들이 다양한 애플리케이션 요구 사항에 맞춰 유연하면서도 견고한 AI 워크플로를 구축할 수 있도록 지원합니다.
|
||||
|
||||
### 파일 입력
|
||||
|
||||
구조화된 상태를 사용할 때, `crewai-files`의 클래스를 사용하여 파일 타입 필드를 포함할 수 있습니다. flow 상태의 파일 타입 필드는 플랫폼에 대한 신호 역할을 합니다 — Run 탭 UI에서 자동으로 파일 업로드 드롭존으로 렌더링되며, 플랫폼을 통해 파일을 업로드하거나 API에서 `input_files`를 통해 전달할 때 자동으로 채워집니다.
|
||||
|
||||
```python
|
||||
from crewai.flow.flow import Flow, start
|
||||
from crewai_files import File, ImageFile, PDFFile
|
||||
from pydantic import BaseModel
|
||||
|
||||
class MyState(BaseModel):
|
||||
document: File # Renders as file dropzone in Platform
|
||||
title: str = ""
|
||||
|
||||
class MyFlow(Flow[MyState]):
|
||||
@start()
|
||||
def process(self):
|
||||
# File object is automatically populated in state
|
||||
# when uploaded via Platform UI or passed via API
|
||||
content = self.state.document.read()
|
||||
print(f"Processing {self.state.title}: {len(content)} bytes")
|
||||
return content
|
||||
```
|
||||
|
||||
**CrewAI 플랫폼**에 배포하면 파일 타입 필드(`crewai-files`의 `File`, `ImageFile`, `PDFFile`)가 UI에서 자동으로 파일 업로드 드롭존으로 렌더링됩니다. 사용자는 파일을 드래그 앤 드롭할 수 있으며, 해당 파일은 flow의 상태에 자동으로 채워집니다.
|
||||
|
||||
**API를 통한 파일 포함 시작:**
|
||||
|
||||
`/kickoff` 엔드포인트는 요청 형식을 자동으로 감지합니다:
|
||||
- **JSON body** → 일반 kickoff
|
||||
- **multipart/form-data** → 파일 업로드 + kickoff
|
||||
|
||||
API 사용자는 파일 타입 필드에 URL 문자열을 직접 전달할 수도 있습니다 — Pydantic이 자동으로 변환합니다.
|
||||
|
||||
### API 사용법
|
||||
|
||||
#### 옵션 1: Multipart kickoff (권장)
|
||||
|
||||
kickoff 요청과 함께 파일을 직접 전송합니다:
|
||||
|
||||
```bash
|
||||
# With files (multipart) — same endpoint
|
||||
curl -X POST https://your-deployment.crewai.com/kickoff \
|
||||
-H 'Authorization: Bearer YOUR_TOKEN' \
|
||||
-F 'inputs={"company_name": "Einstein"}' \
|
||||
-F 'cover_image=@/path/to/photo.jpg'
|
||||
```
|
||||
|
||||
파일은 자동으로 저장되고 `FileInput` 객체로 변환됩니다. 에이전트는 프로바이더별 최적화(LLM 프로바이더에 따라 인라인 base64, 파일 업로드 API 또는 URL 참조)와 함께 파일을 수신합니다.
|
||||
|
||||
#### 옵션 2: JSON kickoff (파일 없음)
|
||||
|
||||
```bash
|
||||
# Without files (JSON) — same endpoint
|
||||
curl -X POST https://your-deployment.crewai.com/kickoff \
|
||||
-H 'Authorization: Bearer YOUR_TOKEN' \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d '{"inputs": {"company_name": "Einstein"}}'
|
||||
```
|
||||
|
||||
#### 옵션 3: 분리된 업로드 + kickoff
|
||||
|
||||
kickoff 요청과 별도로 파일을 업로드해야 할 때 multipart 업로드의 대안입니다. 먼저 파일을 업로드한 다음 URL로 참조합니다:
|
||||
|
||||
```bash
|
||||
# Step 1: Upload
|
||||
curl -X POST https://your-deployment.crewai.com/files \
|
||||
-H 'Authorization: Bearer YOUR_TOKEN' \
|
||||
-F 'file=@/path/to/photo.jpg' \
|
||||
-F 'field_name=cover_image'
|
||||
# Returns: {"url": "https://...", "field_name": "cover_image"}
|
||||
|
||||
# Step 2: Kickoff with URL
|
||||
curl -X POST https://your-deployment.crewai.com/kickoff \
|
||||
-H 'Authorization: Bearer YOUR_TOKEN' \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d '{"inputs": {"company_name": "Einstein"}, "input_files": {"cover_image": "https://..."}}'
|
||||
```
|
||||
|
||||
`/files` 엔드포인트에 대한 자세한 내용은 플랫폼 API 문서를 참조하세요.
|
||||
|
||||
#### CrewAI 플랫폼에서
|
||||
|
||||
플랫폼 UI를 사용할 때 파일 타입 필드는 자동으로 드래그 앤 드롭 업로드 영역으로 렌더링됩니다. API 호출이 필요 없습니다 — 파일을 드롭하고 실행을 클릭하면 됩니다.
|
||||
|
||||
## 플로우 지속성
|
||||
|
||||
@persist 데코레이터는 CrewAI 플로우에서 자동 상태 지속성을 활성화하여, 플로우 상태를 재시작이나 다른 워크플로우 실행 간에도 유지할 수 있도록 합니다. 이 데코레이터는 클래스 수준이나 메서드 수준 모두에 적용할 수 있어, 상태 지속성을 관리하는 데 유연성을 제공합니다.
|
||||
|
||||
@@ -105,7 +105,7 @@ CLI는 `pyproject.toml`에서 프로젝트 유형을 자동으로 감지하고
|
||||
```
|
||||
|
||||
<Tip>
|
||||
첫 배포는 컨테이너 이미지를 빌드하므로 일반적으로 10~15분 정도 소요됩니다. 이후 배포는 훨씬 빠릅니다.
|
||||
첫 배포는 보통 약 1분 정도 소요됩니다.
|
||||
</Tip>
|
||||
|
||||
</Step>
|
||||
@@ -187,7 +187,7 @@ Crew를 GitHub 저장소에 푸시해야 합니다. 아직 Crew를 만들지 않
|
||||
|
||||
1. "Deploy" 버튼을 클릭하여 배포 프로세스를 시작합니다.
|
||||
2. 진행 바를 통해 진행 상황을 모니터링할 수 있습니다.
|
||||
3. 첫 번째 배포에는 일반적으로 약 10-15분 정도 소요되며, 이후 배포는 더 빠릅니다.
|
||||
3. 첫 번째 배포에는 일반적으로 약 1분 정도 소요됩니다
|
||||
|
||||
<Frame>
|
||||

|
||||
|
||||
@@ -86,60 +86,6 @@ curl -H "Authorization: Bearer YOUR_CREW_TOKEN" https://your-crew-url.crewai.com
|
||||
|
||||
베어러 토큰은 crew의 상세 페이지의 Status 탭에서 확인할 수 있습니다.
|
||||
|
||||
## 파일 업로드
|
||||
|
||||
crew나 flow에 파일 타입 상태 필드(`crewai-files`의 `ImageFile`, `PDFFile`, 또는 `File` 사용)가 포함되어 있으면, 이러한 필드는 Run 탭 UI에서 자동으로 파일 업로드 드롭존으로 렌더링됩니다. 사용자는 파일을 직접 드래그 앤 드롭할 수 있으며, 플랫폼이 저장 및 에이전트 전달을 처리합니다.
|
||||
|
||||
### Multipart Kickoff (권장)
|
||||
|
||||
`multipart/form-data`를 사용하여 kickoff 요청과 함께 파일을 직접 전송합니다:
|
||||
|
||||
```bash
|
||||
curl -X POST https://your-deployment.crewai.com/kickoff \
|
||||
-H 'Authorization: Bearer YOUR_TOKEN' \
|
||||
-F 'inputs={"title": "Report"}' \
|
||||
-F 'document=@/path/to/file.pdf'
|
||||
```
|
||||
|
||||
파일은 자동으로 저장되고 파일 객체로 변환됩니다. 에이전트는 프로바이더별 최적화(LLM 프로바이더에 따라 인라인 base64, 파일 업로드 API 또는 URL 참조)와 함께 파일을 수신합니다.
|
||||
|
||||
### 파일 URL을 포함한 JSON Kickoff
|
||||
|
||||
이미 URL에 호스팅된 파일이 있다면 `input_files`를 통해 전달합니다:
|
||||
|
||||
```bash
|
||||
curl -X POST https://your-deployment.crewai.com/kickoff \
|
||||
-H 'Authorization: Bearer YOUR_TOKEN' \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d '{
|
||||
"inputs": {"title": "Report"},
|
||||
"input_files": {"document": "https://example.com/file.pdf"}
|
||||
}'
|
||||
```
|
||||
|
||||
### 분리된 업로드 + Kickoff
|
||||
|
||||
먼저 파일을 업로드한 다음 URL로 참조합니다:
|
||||
|
||||
```bash
|
||||
# Step 1: Upload
|
||||
curl -X POST https://your-deployment.crewai.com/files \
|
||||
-H 'Authorization: Bearer YOUR_TOKEN' \
|
||||
-F 'file=@/path/to/file.pdf' \
|
||||
-F 'field_name=document'
|
||||
# Returns: {"url": "https://...", "field_name": "document"}
|
||||
|
||||
# Step 2: Kickoff with URL
|
||||
curl -X POST https://your-deployment.crewai.com/kickoff \
|
||||
-H 'Authorization: Bearer YOUR_TOKEN' \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d '{"inputs": {"title": "Report"}, "input_files": {"document": "https://..."}}'
|
||||
```
|
||||
|
||||
<Note type="info">
|
||||
파일 업로드는 crew와 flow 모두에서 동일하게 작동합니다. 상태 스키마에 파일 타입 필드를 정의하면 플랫폼 UI와 API가 자동으로 업로드를 처리합니다.
|
||||
</Note>
|
||||
|
||||
### 크루 상태 확인
|
||||
|
||||
작업을 실행하기 전에 크루가 정상적으로 실행되고 있는지 확인할 수 있습니다:
|
||||
|
||||
@@ -197,9 +197,8 @@ CrewAI는 의존성 관리와 패키지 처리를 위해 `uv`를 사용합니다
|
||||
## 다음 단계
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="첫 번째 Agent 만들기" icon="code" href="/ko/quickstart">
|
||||
빠른 시작 가이드를 따라 CrewAI 에이전트를 처음 만들어보고 직접 경험해
|
||||
보세요.
|
||||
<Card title="퀵스타트: Flow + 에이전트" icon="code" href="/ko/quickstart">
|
||||
Flow를 만들고 에이전트 한 명짜리 crew를 실행해 보고서까지 만드는 방법을 따라 해 보세요.
|
||||
</Card>
|
||||
<Card
|
||||
title="커뮤니티 참여하기"
|
||||
|
||||
@@ -138,9 +138,9 @@ Crews의 기능:
|
||||
<Card
|
||||
title="빠른 시작"
|
||||
icon="bolt"
|
||||
href="ko/quickstart"
|
||||
href="/ko/quickstart"
|
||||
>
|
||||
빠른 시작 가이드를 따라 첫 번째 CrewAI agent를 만들고 직접 경험해 보세요.
|
||||
Flow를 만들고 에이전트 한 명 crew를 실행해 끝까지 보고서를 생성해 보세요.
|
||||
</Card>
|
||||
<Card
|
||||
title="커뮤니티 가입하기"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
title: 퀵스타트
|
||||
description: 5분 이내에 CrewAI로 첫 번째 AI 에이전트를 구축해보세요.
|
||||
description: 몇 분 안에 첫 CrewAI Flow를 만듭니다 — 오케스트레이션, 상태, 그리고 실제 보고서를 만드는 에이전트 crew까지.
|
||||
icon: rocket
|
||||
mode: "wide"
|
||||
---
|
||||
@@ -13,375 +13,266 @@ mode: "wide"
|
||||
|
||||
<iframe src="https://www.loom.com/embed/befb9f68b81f42ad8112bfdd95a780af" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen style={{width: "100%", height: "400px"}}></iframe>
|
||||
|
||||
## 첫 번째 CrewAI Agent 만들기
|
||||
이 가이드에서는 **Flow**를 만들어 연구 주제를 정하고, **에이전트 한 명으로 구성된 crew**(웹 검색을 쓰는 연구원)를 실행한 뒤, 디스크에 **Markdown 보고서**를 남깁니다. Flow는 프로덕션 앱을 구성하는 권장 방식으로, **상태**와 **실행 순서**를 담당하고 **에이전트**는 crew 단계 안에서 실제 작업을 수행합니다.
|
||||
|
||||
이제 주어진 주제나 항목에 대해 `최신 AI 개발 동향`을 `연구`하고 `보고`하는 간단한 crew를 만들어보겠습니다.
|
||||
CrewAI를 아직 설치하지 않았다면 먼저 [설치 가이드](/ko/installation)를 따르세요.
|
||||
|
||||
진행하기 전에 CrewAI 설치를 완료했는지 확인하세요.
|
||||
아직 설치하지 않았다면, [설치 가이드](/ko/installation)를 참고해 설치할 수 있습니다.
|
||||
## 사전 요건
|
||||
|
||||
아래 단계를 따라 Crewing을 시작하세요! 🚣♂️
|
||||
- Python 환경과 CrewAI CLI([설치](/ko/installation) 참고)
|
||||
- 올바른 API 키로 설정한 LLM — [LLM](/ko/concepts/llms#setting-up-your-llm) 참고
|
||||
- 이 튜토리얼의 웹 검색용 [Serper.dev](https://serper.dev/) API 키(`SERPER_API_KEY`)
|
||||
|
||||
## 첫 번째 Flow 만들기
|
||||
|
||||
<Steps>
|
||||
<Step title="crew 생성하기">
|
||||
터미널에서 아래 명령어를 실행하여 새로운 crew 프로젝트를 만드세요.
|
||||
이 작업은 `latest-ai-development`라는 새 디렉터리와 기본 구조를 생성합니다.
|
||||
<Step title="Flow 프로젝트 생성">
|
||||
터미널에서 Flow 프로젝트를 생성합니다(폴더 이름은 밑줄 형식입니다. 예: `latest_ai_flow`).
|
||||
|
||||
<CodeGroup>
|
||||
```shell Terminal
|
||||
crewai create crew latest-ai-development
|
||||
crewai create flow latest-ai-flow
|
||||
cd latest_ai_flow
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
이렇게 하면 `src/latest_ai_flow/` 아래에 Flow 앱이 만들어지고, 다음 단계에서 **단일 에이전트** 연구 crew로 바꿀 시작용 crew가 `crews/content_crew/`에 포함됩니다.
|
||||
</Step>
|
||||
<Step title="새로운 crew 프로젝트로 이동하기">
|
||||
<CodeGroup>
|
||||
```shell Terminal
|
||||
cd latest_ai_development
|
||||
```
|
||||
</CodeGroup>
|
||||
</Step>
|
||||
<Step title="`agents.yaml` 파일 수정하기">
|
||||
<Tip>
|
||||
프로젝트에 맞게 agent를 수정하거나 복사/붙여넣기를 할 수 있습니다.
|
||||
`agents.yaml` 및 `tasks.yaml` 파일에서 `{topic}`과 같은 변수를 사용하면, 이는 `main.py` 파일의 변수 값으로 대체됩니다.
|
||||
</Tip>
|
||||
|
||||
<Step title="`agents.yaml`에 에이전트 하나 설정">
|
||||
`src/latest_ai_flow/crews/content_crew/config/agents.yaml` 내용을 한 명의 연구원만 남기도록 바꿉니다. `{topic}` 같은 변수는 `crew.kickoff(inputs=...)`로 채워집니다.
|
||||
|
||||
```yaml agents.yaml
|
||||
# src/latest_ai_development/config/agents.yaml
|
||||
# src/latest_ai_flow/crews/content_crew/config/agents.yaml
|
||||
researcher:
|
||||
role: >
|
||||
{topic} Senior Data Researcher
|
||||
{topic} 시니어 데이터 리서처
|
||||
goal: >
|
||||
Uncover cutting-edge developments in {topic}
|
||||
{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.
|
||||
당신은 {topic}의 최신 흐름을 찾아내는 데 능숙한 연구원입니다.
|
||||
가장 관련성 높은 정보를 찾아 명확하게 전달합니다.
|
||||
```
|
||||
|
||||
</Step>
|
||||
<Step title="`tasks.yaml` 파일 수정하기">
|
||||
|
||||
<Step title="`tasks.yaml`에 작업 하나 설정">
|
||||
```yaml tasks.yaml
|
||||
# src/latest_ai_development/config/tasks.yaml
|
||||
# src/latest_ai_flow/crews/content_crew/config/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.
|
||||
{topic}에 대해 철저히 조사하세요. 웹 검색으로 최신이고 신뢰할 수 있는 정보를 찾으세요.
|
||||
현재 연도는 2026년입니다.
|
||||
expected_output: >
|
||||
A list with 10 bullet points of the most relevant information about {topic}
|
||||
마크다운 보고서로, 주요 트렌드·주목할 도구나 기업·시사점 등으로 섹션을 나누세요.
|
||||
분량은 약 800~1200단어. 문서 전체를 코드 펜스로 감싸지 마세요.
|
||||
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
|
||||
output_file: report.md
|
||||
output_file: output/report.md
|
||||
```
|
||||
|
||||
</Step>
|
||||
<Step title="`crew.py` 파일 수정하기">
|
||||
```python crew.py
|
||||
# src/latest_ai_development/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
|
||||
|
||||
<Step title="crew 클래스 연결 (`content_crew.py`)">
|
||||
생성된 crew가 YAML을 읽고 연구원에게 `SerperDevTool`을 붙이도록 합니다.
|
||||
|
||||
```python content_crew.py
|
||||
# src/latest_ai_flow/crews/content_crew/content_crew.py
|
||||
from typing import List
|
||||
|
||||
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
|
||||
|
||||
|
||||
@CrewBase
|
||||
class LatestAiDevelopmentCrew():
|
||||
"""LatestAiDevelopment crew"""
|
||||
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]
|
||||
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
|
||||
tools=[SerperDevTool()],
|
||||
)
|
||||
|
||||
@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]
|
||||
output_file='output/report.md' # This is the file that will be contain the final report.
|
||||
config=self.tasks_config["research_task"], # type: ignore[index]
|
||||
)
|
||||
|
||||
@crew
|
||||
def crew(self) -> Crew:
|
||||
"""Creates the LatestAiDevelopment crew"""
|
||||
return Crew(
|
||||
agents=self.agents, # Automatically created by the @agent decorator
|
||||
tasks=self.tasks, # Automatically created by the @task decorator
|
||||
agents=self.agents,
|
||||
tasks=self.tasks,
|
||||
process=Process.sequential,
|
||||
verbose=True,
|
||||
)
|
||||
```
|
||||
|
||||
</Step>
|
||||
<Step title="[선택 사항] crew 실행 전/후 함수 추가">
|
||||
```python crew.py
|
||||
# src/latest_ai_development/crew.py
|
||||
from crewai import Agent, Crew, Process, Task
|
||||
from crewai.project import CrewBase, agent, crew, task, before_kickoff, after_kickoff
|
||||
from crewai_tools import SerperDevTool
|
||||
|
||||
@CrewBase
|
||||
class LatestAiDevelopmentCrew():
|
||||
"""LatestAiDevelopment crew"""
|
||||
<Step title="`main.py`에서 Flow 정의">
|
||||
crew를 Flow에 연결합니다: `@start()` 단계에서 주제를 **상태**에 넣고, `@listen` 단계에서 crew를 실행합니다. 작업의 `output_file`은 그대로 `output/report.md`에 씁니다.
|
||||
|
||||
@before_kickoff
|
||||
def before_kickoff_function(self, inputs):
|
||||
print(f"Before kickoff function with inputs: {inputs}")
|
||||
return inputs # You can return the inputs or modify them as needed
|
||||
|
||||
@after_kickoff
|
||||
def after_kickoff_function(self, result):
|
||||
print(f"After kickoff function with result: {result}")
|
||||
return result # You can return the result or modify it as needed
|
||||
|
||||
# ... remaining code
|
||||
```
|
||||
|
||||
</Step>
|
||||
<Step title="crew에 커스텀 입력값 전달하기">
|
||||
예를 들어, crew에 `topic` 입력값을 넘겨 연구 및 보고서 출력을 맞춤화할 수 있습니다.
|
||||
```python main.py
|
||||
#!/usr/bin/env python
|
||||
# src/latest_ai_development/main.py
|
||||
import sys
|
||||
from latest_ai_development.crew import LatestAiDevelopmentCrew
|
||||
# src/latest_ai_flow/main.py
|
||||
from pydantic import BaseModel
|
||||
|
||||
def run():
|
||||
"""
|
||||
Run the crew.
|
||||
"""
|
||||
inputs = {
|
||||
'topic': 'AI Agents'
|
||||
}
|
||||
LatestAiDevelopmentCrew().crew().kickoff(inputs=inputs)
|
||||
from crewai.flow import Flow, listen, start
|
||||
|
||||
from latest_ai_flow.crews.content_crew.content_crew import ResearchCrew
|
||||
|
||||
|
||||
class ResearchFlowState(BaseModel):
|
||||
topic: str = ""
|
||||
report: str = ""
|
||||
|
||||
|
||||
class LatestAiFlow(Flow[ResearchFlowState]):
|
||||
@start()
|
||||
def prepare_topic(self, crewai_trigger_payload: dict | None = None):
|
||||
if crewai_trigger_payload:
|
||||
self.state.topic = crewai_trigger_payload.get("topic", "AI Agents")
|
||||
else:
|
||||
self.state.topic = "AI Agents"
|
||||
print(f"주제: {self.state.topic}")
|
||||
|
||||
@listen(prepare_topic)
|
||||
def run_research(self):
|
||||
result = ResearchCrew().crew().kickoff(inputs={"topic": self.state.topic})
|
||||
self.state.report = result.raw
|
||||
print("연구 crew 실행 완료.")
|
||||
|
||||
@listen(run_research)
|
||||
def summarize(self):
|
||||
print("보고서 경로: output/report.md")
|
||||
|
||||
|
||||
def kickoff():
|
||||
LatestAiFlow().kickoff()
|
||||
|
||||
|
||||
def plot():
|
||||
LatestAiFlow().plot()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
kickoff()
|
||||
```
|
||||
|
||||
</Step>
|
||||
<Step title="환경 변수 설정">
|
||||
crew를 실행하기 전에 `.env` 파일에 아래 키가 환경 변수로 설정되어 있는지 확인하세요:
|
||||
- [Serper.dev](https://serper.dev/) API 키: `SERPER_API_KEY=YOUR_KEY_HERE`
|
||||
- 사용하려는 모델의 설정, 예: API 키. 다양한 공급자의 모델 설정은
|
||||
[LLM 설정 가이드](/ko/concepts/llms#setting-up-your-llm)를 참고하세요.
|
||||
</Step>
|
||||
<Step title="의존성 잠그고 설치하기">
|
||||
- CLI 명령어로 의존성을 잠그고 설치하세요:
|
||||
<CodeGroup>
|
||||
```shell Terminal
|
||||
crewai install
|
||||
```
|
||||
</CodeGroup>
|
||||
- 추가 설치가 필요한 패키지가 있다면, 아래와 같이 실행하면 됩니다:
|
||||
<CodeGroup>
|
||||
```shell Terminal
|
||||
uv add <package-name>
|
||||
```
|
||||
</CodeGroup>
|
||||
</Step>
|
||||
<Step title="crew 실행하기">
|
||||
- 프로젝트 루트에서 다음 명령어로 crew를 실행하세요:
|
||||
<CodeGroup>
|
||||
```bash Terminal
|
||||
crewai run
|
||||
```
|
||||
</CodeGroup>
|
||||
<Tip>
|
||||
패키지 이름이 `latest_ai_flow`가 아니면 `ResearchCrew` import 경로를 프로젝트 모듈 경로에 맞게 바꾸세요.
|
||||
</Tip>
|
||||
</Step>
|
||||
|
||||
<Step title="엔터프라이즈 대안: Crew Studio에서 생성">
|
||||
CrewAI AMP 사용자는 코드를 작성하지 않고도 동일한 crew를 생성할 수 있습니다:
|
||||
<Step title="환경 변수">
|
||||
프로젝트 루트의 `.env`에 다음을 설정합니다.
|
||||
|
||||
1. CrewAI AMP 계정에 로그인하세요([app.crewai.com](https://app.crewai.com)에서 무료 계정 만들기)
|
||||
2. Crew Studio 열기
|
||||
3. 구현하려는 자동화 내용을 입력하세요
|
||||
4. 미션을 시각적으로 생성하고 순차적으로 연결하세요
|
||||
5. 입력값을 구성하고 "Download Code" 또는 "Deploy"를 클릭하세요
|
||||
|
||||

|
||||
|
||||
<Card title="CrewAI AMP 체험하기" icon="rocket" href="https://app.crewai.com">
|
||||
CrewAI AOP에서 무료 계정을 시작하세요
|
||||
</Card>
|
||||
- `SERPER_API_KEY` — [Serper.dev](https://serper.dev/)에서 발급
|
||||
- 모델 제공자 키 — [LLM 설정](/ko/concepts/llms#setting-up-your-llm) 참고
|
||||
</Step>
|
||||
<Step title="최종 보고서 확인하기">
|
||||
콘솔에서 출력 결과를 확인할 수 있으며 프로젝트 루트에 `report.md` 파일로 최종 보고서가 생성됩니다.
|
||||
|
||||
보고서 예시는 다음과 같습니다:
|
||||
<Step title="설치 및 실행">
|
||||
<CodeGroup>
|
||||
```shell Terminal
|
||||
crewai install
|
||||
crewai run
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
`crewai run`은 프로젝트에 정의된 Flow 진입점을 실행합니다(crew와 동일한 명령이며, `pyproject.toml`의 프로젝트 유형은 `"flow"`입니다).
|
||||
</Step>
|
||||
|
||||
<Step title="결과 확인">
|
||||
Flow와 crew 로그가 출력되어야 합니다. 생성된 보고서는 **`output/report.md`**에서 확인하세요(발췌):
|
||||
|
||||
<CodeGroup>
|
||||
```markdown output/report.md
|
||||
# Comprehensive Report on the Rise and Impact of AI Agents in 2025
|
||||
# 2026년 AI 에이전트: 동향과 전망
|
||||
|
||||
## 1. Introduction to AI Agents
|
||||
In 2025, Artificial Intelligence (AI) agents are at the forefront of innovation across various industries. As intelligent systems that can perform tasks typically requiring human cognition, AI agents are paving the way for significant advancements in operational efficiency, decision-making, and overall productivity within sectors like Human Resources (HR) and Finance. This report aims to detail the rise of AI agents, their frameworks, applications, and potential implications on the workforce.
|
||||
## 요약
|
||||
…
|
||||
|
||||
## 2. Benefits of AI Agents
|
||||
AI agents bring numerous advantages that are transforming traditional work environments. Key benefits include:
|
||||
## 주요 트렌드
|
||||
- **도구 사용과 오케스트레이션** — …
|
||||
- **엔터프라이즈 도입** — …
|
||||
|
||||
- **Task Automation**: AI agents can carry out repetitive tasks such as data entry, scheduling, and payroll processing without human intervention, greatly reducing the time and resources spent on these activities.
|
||||
- **Improved Efficiency**: By quickly processing large datasets and performing analyses that would take humans significantly longer, AI agents enhance operational efficiency. This allows teams to focus on strategic tasks that require higher-level thinking.
|
||||
- **Enhanced Decision-Making**: AI agents can analyze trends and patterns in data, provide insights, and even suggest actions, helping stakeholders make informed decisions based on factual data rather than intuition alone.
|
||||
|
||||
## 3. Popular AI Agent Frameworks
|
||||
Several frameworks have emerged to facilitate the development of AI agents, each with its own unique features and capabilities. Some of the most popular frameworks include:
|
||||
|
||||
- **Autogen**: A framework designed to streamline the development of AI agents through automation of code generation.
|
||||
- **Semantic Kernel**: Focuses on natural language processing and understanding, enabling agents to comprehend user intentions better.
|
||||
- **Promptflow**: Provides tools for developers to create conversational agents that can navigate complex interactions seamlessly.
|
||||
- **Langchain**: Specializes in leveraging various APIs to ensure agents can access and utilize external data effectively.
|
||||
- **CrewAI**: Aimed at collaborative environments, CrewAI strengthens teamwork by facilitating communication through AI-driven insights.
|
||||
- **MemGPT**: Combines memory-optimized architectures with generative capabilities, allowing for more personalized interactions with users.
|
||||
|
||||
These frameworks empower developers to build versatile and intelligent agents that can engage users, perform advanced analytics, and execute various tasks aligned with organizational goals.
|
||||
|
||||
## 4. AI Agents in Human Resources
|
||||
AI agents are revolutionizing HR practices by automating and optimizing key functions:
|
||||
|
||||
- **Recruiting**: AI agents can screen resumes, schedule interviews, and even conduct initial assessments, thus accelerating the hiring process while minimizing biases.
|
||||
- **Succession Planning**: AI systems analyze employee performance data and potential, helping organizations identify future leaders and plan appropriate training.
|
||||
- **Employee Engagement**: Chatbots powered by AI can facilitate feedback loops between employees and management, promoting an open culture and addressing concerns promptly.
|
||||
|
||||
As AI continues to evolve, HR departments leveraging these agents can realize substantial improvements in both efficiency and employee satisfaction.
|
||||
|
||||
## 5. AI Agents in Finance
|
||||
The finance sector is seeing extensive integration of AI agents that enhance financial practices:
|
||||
|
||||
- **Expense Tracking**: Automated systems manage and monitor expenses, flagging anomalies and offering recommendations based on spending patterns.
|
||||
- **Risk Assessment**: AI models assess credit risk and uncover potential fraud by analyzing transaction data and behavioral patterns.
|
||||
- **Investment Decisions**: AI agents provide stock predictions and analytics based on historical data and current market conditions, empowering investors with informative insights.
|
||||
|
||||
The incorporation of AI agents into finance is fostering a more responsive and risk-aware financial landscape.
|
||||
|
||||
## 6. Market Trends and Investments
|
||||
The growth of AI agents has attracted significant investment, especially amidst the rising popularity of chatbots and generative AI technologies. Companies and entrepreneurs are eager to explore the potential of these systems, recognizing their ability to streamline operations and improve customer engagement.
|
||||
|
||||
Conversely, corporations like Microsoft are taking strides to integrate AI agents into their product offerings, with enhancements to their Copilot 365 applications. This strategic move emphasizes the importance of AI literacy in the modern workplace and indicates the stabilizing of AI agents as essential business tools.
|
||||
|
||||
## 7. Future Predictions and Implications
|
||||
Experts predict that AI agents will transform essential aspects of work life. As we look toward the future, several anticipated changes include:
|
||||
|
||||
- Enhanced integration of AI agents across all business functions, creating interconnected systems that leverage data from various departmental silos for comprehensive decision-making.
|
||||
- Continued advancement of AI technologies, resulting in smarter, more adaptable agents capable of learning and evolving from user interactions.
|
||||
- Increased regulatory scrutiny to ensure ethical use, especially concerning data privacy and employee surveillance as AI agents become more prevalent.
|
||||
|
||||
To stay competitive and harness the full potential of AI agents, organizations must remain vigilant about latest developments in AI technology and consider continuous learning and adaptation in their strategic planning.
|
||||
|
||||
## 8. Conclusion
|
||||
The emergence of AI agents is undeniably reshaping the workplace landscape in 5. With their ability to automate tasks, enhance efficiency, and improve decision-making, AI agents are critical in driving operational success. Organizations must embrace and adapt to AI developments to thrive in an increasingly digital business environment.
|
||||
## 시사점
|
||||
…
|
||||
```
|
||||
|
||||
</CodeGroup>
|
||||
|
||||
실제 파일은 더 길고 실시간 검색 결과를 반영합니다.
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
## 한 번에 이해하기
|
||||
|
||||
1. **Flow** — `LatestAiFlow`는 `prepare_topic` → `run_research` → `summarize` 순으로 실행됩니다. 상태(`topic`, `report`)는 Flow에 있습니다.
|
||||
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)를 참고하세요.
|
||||
|
||||
<Check>
|
||||
축하합니다!
|
||||
|
||||
crew 프로젝트 설정이 완료되었으며, 이제 자신만의 agentic workflow 구축을 바로 시작하실 수 있습니다!
|
||||
|
||||
에이전트 crew와 저장된 보고서까지 이어진 Flow를 완성했습니다. 이제 단계·crew·도구를 더해 확장할 수 있습니다.
|
||||
</Check>
|
||||
|
||||
### 명명 일관성에 대한 참고
|
||||
### 이름 일치
|
||||
|
||||
YAML 파일(`agents.yaml` 및 `tasks.yaml`)에서 사용하는 이름은 Python 코드의 메서드 이름과 일치해야 합니다.
|
||||
예를 들어, 특정 task에 대한 agent를 `tasks.yaml` 파일에서 참조할 수 있습니다.
|
||||
이러한 명명 일관성을 지키면 CrewAI가 설정과 코드를 자동으로 연결할 수 있습니다. 그렇지 않으면 task가 참조를 제대로 인식하지 못할 수 있습니다.
|
||||
YAML 키(`researcher`, `research_task`)는 `@CrewBase` 클래스의 메서드 이름과 같아야 합니다. 전체 데코레이터 패턴은 [Crews](/ko/concepts/crews)를 참고하세요.
|
||||
|
||||
#### 예시 참조
|
||||
## 배포
|
||||
|
||||
<Tip>
|
||||
`agents.yaml` (`email_summarizer`) 파일에서 에이전트 이름과 `crew.py`
|
||||
(`email_summarizer`) 파일에서 메서드 이름이 동일하게 사용되는 점에 주목하세요.
|
||||
</Tip>
|
||||
로컬에서 정상 실행되고 프로젝트가 **GitHub** 저장소에 있으면 Flow를 **[CrewAI AMP](https://app.crewai.com)**에 올릴 수 있습니다. 프로젝트 루트에서:
|
||||
|
||||
```yaml agents.yaml
|
||||
email_summarizer:
|
||||
role: >
|
||||
Email Summarizer
|
||||
goal: >
|
||||
Summarize emails into a concise and clear summary
|
||||
backstory: >
|
||||
You will create a 5 bullet point summary of the report
|
||||
llm: provider/model-id # Add your choice of model here
|
||||
<CodeGroup>
|
||||
```bash 인증
|
||||
crewai login
|
||||
```
|
||||
|
||||
<Tip>
|
||||
`tasks.yaml` (`email_summarizer_task`) 파일에서 태스크 이름과 `crew.py`
|
||||
(`email_summarizer_task`) 파일에서 메서드 이름이 동일하게 사용되는 점에
|
||||
주목하세요.
|
||||
</Tip>
|
||||
|
||||
```yaml tasks.yaml
|
||||
email_summarizer_task:
|
||||
description: >
|
||||
Summarize the email into a 5 bullet point summary
|
||||
expected_output: >
|
||||
A 5 bullet point summary of the email
|
||||
agent: email_summarizer
|
||||
context:
|
||||
- reporting_task
|
||||
- research_task
|
||||
```bash 배포 생성
|
||||
crewai deploy create
|
||||
```
|
||||
|
||||
## Crew 배포하기
|
||||
```bash 상태 및 로그
|
||||
crewai deploy status
|
||||
crewai deploy logs
|
||||
```
|
||||
|
||||
production 환경에 crew를 배포하는 가장 쉬운 방법은 [CrewAI AMP](http://app.crewai.com)를 통해서입니다.
|
||||
```bash 코드 변경 후 반영
|
||||
crewai deploy push
|
||||
```
|
||||
|
||||
CLI를 사용하여 [CrewAI AMP](http://app.crewai.com)에 crew를 배포하는 단계별 시연은 이 영상 튜토리얼을 참고하세요.
|
||||
```bash 배포 목록 또는 삭제
|
||||
crewai deploy list
|
||||
crewai deploy remove <deployment_id>
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
<iframe
|
||||
className="w-full aspect-video rounded-xl"
|
||||
src="https://www.youtube.com/embed/3EqSV-CYDZA"
|
||||
title="CrewAI Deployment Guide"
|
||||
frameBorder="0"
|
||||
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
|
||||
allowFullScreen
|
||||
></iframe>
|
||||
<Tip>
|
||||
첫 배포는 보통 **약 1분** 정도 걸립니다. 전체 사전 요건과 웹 UI 절차는 [AMP에 배포](/ko/enterprise/guides/deploy-to-amp)를 참고하세요.
|
||||
</Tip>
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Enterprise에 배포" icon="rocket" href="http://app.crewai.com">
|
||||
CrewAI AOP로 시작하여 몇 번의 클릭만으로 production 환경에 crew를
|
||||
배포하세요.
|
||||
<Card title="배포 가이드" icon="book" href="/ko/enterprise/guides/deploy-to-amp">
|
||||
AMP 배포 단계별 안내(CLI 및 대시보드).
|
||||
</Card>
|
||||
<Card
|
||||
title="커뮤니티 참여하기"
|
||||
title="커뮤니티"
|
||||
icon="comments"
|
||||
href="https://community.crewai.com"
|
||||
>
|
||||
오픈 소스 커뮤니티에 참여하여 아이디어를 나누고, 프로젝트를 공유하며, 다른
|
||||
CrewAI 개발자들과 소통하세요.
|
||||
아이디어를 나누고 프로젝트를 공유하며 다른 CrewAI 개발자와 소통하세요.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
@@ -7,6 +7,10 @@ mode: "wide"
|
||||
|
||||
# `CodeInterpreterTool`
|
||||
|
||||
<Warning>
|
||||
**지원 중단:** `CodeInterpreterTool`이 `crewai-tools`에서 제거되었습니다. `Agent`의 `allow_code_execution` 및 `code_execution_mode` 파라미터도 더 이상 사용되지 않습니다. 안전하고 격리된 코드 실행을 위해 전용 샌드박스 서비스 — [E2B](https://e2b.dev) 또는 [Modal](https://modal.com) — 을 사용하세요.
|
||||
</Warning>
|
||||
|
||||
## 설명
|
||||
|
||||
`CodeInterpreterTool`은 CrewAI 에이전트가 자율적으로 생성한 Python 3 코드를 실행할 수 있도록 합니다. 이 기능은 에이전트가 코드를 생성하고, 실행하며, 결과를 얻고, 그 정보를 활용하여 이후의 결정과 행동에 반영할 수 있다는 점에서 특히 유용합니다.
|
||||
|
||||
@@ -76,3 +76,19 @@ tool = CSVSearchTool(
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
## 보안
|
||||
|
||||
### 경로 유효성 검사
|
||||
|
||||
이 도구에 제공되는 파일 경로는 현재 작업 디렉터리에 대해 검증됩니다. 작업 디렉터리 외부로 확인되는 경로는 `ValueError`로 거부됩니다.
|
||||
|
||||
작업 디렉터리 외부의 경로를 허용하려면 (예: 테스트 또는 신뢰할 수 있는 파이프라인), 다음 환경 변수를 설정하세요:
|
||||
|
||||
```shell
|
||||
CREWAI_TOOLS_ALLOW_UNSAFE_PATHS=true
|
||||
```
|
||||
|
||||
### URL 유효성 검사
|
||||
|
||||
URL 입력도 검증됩니다: `file://` URI와 사설 또는 예약된 IP 범위를 대상으로 하는 요청은 서버 측 요청 위조(SSRF) 공격을 방지하기 위해 차단됩니다.
|
||||
|
||||
@@ -68,3 +68,15 @@ tool = DirectorySearchTool(
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
## 보안
|
||||
|
||||
### 경로 유효성 검사
|
||||
|
||||
이 도구에 제공되는 디렉터리 경로는 현재 작업 디렉터리에 대해 검증됩니다. 작업 디렉터리 외부로 확인되는 경로는 `ValueError`로 거부됩니다.
|
||||
|
||||
작업 디렉터리 외부의 경로를 허용하려면 (예: 테스트 또는 신뢰할 수 있는 파이프라인), 다음 환경 변수를 설정하세요:
|
||||
|
||||
```shell
|
||||
CREWAI_TOOLS_ALLOW_UNSAFE_PATHS=true
|
||||
```
|
||||
|
||||
@@ -71,3 +71,19 @@ tool = JSONSearchTool(
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
## 보안
|
||||
|
||||
### 경로 유효성 검사
|
||||
|
||||
이 도구에 제공되는 파일 경로는 현재 작업 디렉터리에 대해 검증됩니다. 작업 디렉터리 외부로 확인되는 경로는 `ValueError`로 거부됩니다.
|
||||
|
||||
작업 디렉터리 외부의 경로를 허용하려면 (예: 테스트 또는 신뢰할 수 있는 파이프라인), 다음 환경 변수를 설정하세요:
|
||||
|
||||
```shell
|
||||
CREWAI_TOOLS_ALLOW_UNSAFE_PATHS=true
|
||||
```
|
||||
|
||||
### URL 유효성 검사
|
||||
|
||||
URL 입력도 검증됩니다: `file://` URI와 사설 또는 예약된 IP 범위를 대상으로 하는 요청은 서버 측 요청 위조(SSRF) 공격을 방지하기 위해 차단됩니다.
|
||||
|
||||
@@ -102,3 +102,19 @@ tool = PDFSearchTool(
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
## 보안
|
||||
|
||||
### 경로 유효성 검사
|
||||
|
||||
이 도구에 제공되는 파일 경로는 현재 작업 디렉터리에 대해 검증됩니다. 작업 디렉터리 외부로 확인되는 경로는 `ValueError`로 거부됩니다.
|
||||
|
||||
작업 디렉터리 외부의 경로를 허용하려면 (예: 테스트 또는 신뢰할 수 있는 파이프라인), 다음 환경 변수를 설정하세요:
|
||||
|
||||
```shell
|
||||
CREWAI_TOOLS_ALLOW_UNSAFE_PATHS=true
|
||||
```
|
||||
|
||||
### URL 유효성 검사
|
||||
|
||||
URL 입력도 검증됩니다: `file://` URI와 사설 또는 예약된 IP 범위를 대상으로 하는 요청은 서버 측 요청 위조(SSRF) 공격을 방지하기 위해 차단됩니다.
|
||||
|
||||
@@ -4,6 +4,110 @@ description: "Atualizações de produto, melhorias e correções do CrewAI"
|
||||
icon: "clock"
|
||||
mode: "wide"
|
||||
---
|
||||
<Update label="07 abr 2026">
|
||||
## v1.14.0
|
||||
|
||||
[Ver release no GitHub](https://github.com/crewAIInc/crewAI/releases/tag/1.14.0)
|
||||
|
||||
## O que Mudou
|
||||
|
||||
### Recursos
|
||||
- Adicionar comandos CLI de lista/informações de checkpoint
|
||||
- Adicionar guardrail_type e nome para distinguir rastros
|
||||
- Adicionar SqliteProvider para armazenamento de checkpoints
|
||||
- Adicionar CheckpointConfig para checkpointing automático
|
||||
- Implementar checkpointing de estado em tempo de execução, sistema de eventos e refatoração do executor
|
||||
|
||||
### Correções de Bugs
|
||||
- Adicionar proteções contra SSRF e travessia de caminho
|
||||
- Adicionar validação de caminho e URL às ferramentas RAG
|
||||
- Excluir vetores de incorporação da serialização de memória para economizar tokens
|
||||
- Garantir que o diretório de saída exista antes de escrever no modelo de fluxo
|
||||
- Atualizar litellm para >=1.83.0 para resolver CVE-2026-35030
|
||||
- Remover campo de indexação SEO que causava renderização de página em árabe
|
||||
|
||||
### Documentação
|
||||
- Atualizar changelog e versão para v1.14.0
|
||||
- Atualizar guias de início rápido e instalação para maior clareza
|
||||
- Adicionar seção de provedores de armazenamento, exportar JsonProvider
|
||||
- Adicionar guia da aba de Treinamento AMP
|
||||
|
||||
### Refatoração
|
||||
- Limpar API de checkpoint
|
||||
- Remover CodeInterpreterTool e descontinuar parâmetros de execução de código
|
||||
|
||||
## Contribuidores
|
||||
|
||||
@alex-clawd, @github-actions[bot], @greysonlalonde, @iris-clawd, @joaomdmoura, @lorenzejay, @lucasgomide
|
||||
|
||||
</Update>
|
||||
|
||||
<Update label="07 abr 2026">
|
||||
## v1.14.0a4
|
||||
|
||||
[Ver release no GitHub](https://github.com/crewAIInc/crewAI/releases/tag/1.14.0a4)
|
||||
|
||||
## O que Mudou
|
||||
|
||||
### Recursos
|
||||
- Adicionar guardrail_type e nome para distinguir rastros
|
||||
- Adicionar SqliteProvider para armazenamento de checkpoints
|
||||
- Adicionar CheckpointConfig para checkpointing automático
|
||||
- Implementar checkpointing de estado em tempo de execução, sistema de eventos e refatoração do executor
|
||||
|
||||
### Correções de Bugs
|
||||
- Excluir vetores de incorporação da serialização de memória para economizar tokens
|
||||
- Atualizar litellm para >=1.83.0 para resolver CVE-2026-35030
|
||||
|
||||
### Documentação
|
||||
- Atualizar guias de início rápido e instalação para melhor clareza
|
||||
- Adicionar seção de provedores de armazenamento e exportar JsonProvider
|
||||
|
||||
### Desempenho
|
||||
- Usar JSONB para a coluna de dados de checkpoint
|
||||
|
||||
### Refatoração
|
||||
- Remover CodeInterpreterTool e descontinuar parâmetros de execução de código
|
||||
|
||||
## Contribuidores
|
||||
|
||||
@alex-clawd, @github-actions[bot], @greysonlalonde, @joaomdmoura, @lorenzejay, @lucasgomide
|
||||
|
||||
</Update>
|
||||
|
||||
<Update label="06 abr 2026">
|
||||
## v1.14.0a3
|
||||
|
||||
[Ver release no GitHub](https://github.com/crewAIInc/crewAI/releases/tag/1.14.0a3)
|
||||
|
||||
## O que Mudou
|
||||
|
||||
### Documentação
|
||||
- Atualizar changelog e versão para v1.14.0a2
|
||||
|
||||
## Contribuidores
|
||||
|
||||
@joaomdmoura
|
||||
|
||||
</Update>
|
||||
|
||||
<Update label="06 abr 2026">
|
||||
## v1.14.0a2
|
||||
|
||||
[Ver release no GitHub](https://github.com/crewAIInc/crewAI/releases/tag/1.14.0a2)
|
||||
|
||||
## Lançamento 1.14.0a2
|
||||
|
||||
### Instruções:
|
||||
- Traduza todos os cabeçalhos de seção e descrições de forma natural
|
||||
- Mantenha a formatação markdown (##, ###, -, etc.) exatamente como está
|
||||
- Mantenha todos os nomes próprios, identificadores de código, nomes de classes e termos técnicos inalterados
|
||||
(por exemplo, "CrewAI", "LiteAgent", "ChromaDB", "MCP", "@username")
|
||||
- Mantenha a seção ## Contribuidores e os nomes de usuários do GitHub inalterados
|
||||
- Não adicione nem remova nenhum conteúdo, apenas traduza
|
||||
|
||||
</Update>
|
||||
|
||||
<Update label="02 abr 2026">
|
||||
## v1.13.0
|
||||
|
||||
|
||||
@@ -304,17 +304,12 @@ multimodal_agent = Agent(
|
||||
|
||||
#### Execução de Código
|
||||
|
||||
- `allow_code_execution`: Deve ser True para permitir execução de código
|
||||
- `code_execution_mode`:
|
||||
- `"safe"`: Usa Docker (recomendado para produção)
|
||||
- `"unsafe"`: Execução direta (apenas em ambientes confiáveis)
|
||||
<Warning>
|
||||
`allow_code_execution` e `code_execution_mode` estão depreciados. O `CodeInterpreterTool` foi removido do `crewai-tools`. Use um serviço de sandbox dedicado como [E2B](https://e2b.dev) ou [Modal](https://modal.com) para execução segura de código.
|
||||
</Warning>
|
||||
|
||||
<Note>
|
||||
Isso executa uma imagem Docker padrão. Se você deseja configurar a imagem
|
||||
Docker, veja a ferramenta Code Interpreter na seção de ferramentas. Adicione a
|
||||
ferramenta de interpretação de código como um parâmetro em ferramentas no
|
||||
agente.
|
||||
</Note>
|
||||
- `allow_code_execution` _(depreciado)_: Anteriormente habilitava a execução de código embutida via `CodeInterpreterTool`.
|
||||
- `code_execution_mode` _(depreciado)_: Anteriormente controlava o modo de execução (`"safe"` para Docker, `"unsafe"` para execução direta).
|
||||
|
||||
#### Funcionalidades Avançadas
|
||||
|
||||
@@ -565,9 +560,9 @@ agent = Agent(
|
||||
|
||||
### Segurança e Execução de Código
|
||||
|
||||
- Ao usar `allow_code_execution`, seja cauteloso com entradas do usuário e sempre as valide
|
||||
- Use `code_execution_mode: "safe"` (Docker) em ambientes de produção
|
||||
- Considere definir limites adequados de `max_execution_time` para evitar loops infinitos
|
||||
<Warning>
|
||||
`allow_code_execution` e `code_execution_mode` estão depreciados e o `CodeInterpreterTool` foi removido. Use um serviço de sandbox dedicado como [E2B](https://e2b.dev) ou [Modal](https://modal.com) para execução segura de código.
|
||||
</Warning>
|
||||
|
||||
### Otimização de Performance
|
||||
|
||||
|
||||
229
docs/pt-BR/concepts/checkpointing.mdx
Normal file
229
docs/pt-BR/concepts/checkpointing.mdx
Normal file
@@ -0,0 +1,229 @@
|
||||
---
|
||||
title: Checkpointing
|
||||
description: Salve automaticamente o estado de execucao para que crews, flows e agentes possam retomar apos falhas.
|
||||
icon: floppy-disk
|
||||
mode: "wide"
|
||||
---
|
||||
|
||||
<Warning>
|
||||
O checkpointing esta em versao inicial. As APIs podem mudar em versoes futuras.
|
||||
</Warning>
|
||||
|
||||
## Visao Geral
|
||||
|
||||
O checkpointing salva automaticamente o estado de execucao durante uma execucao. Se uma crew, flow ou agente falhar no meio da execucao, voce pode restaurar a partir do ultimo checkpoint e retomar sem reexecutar o trabalho ja concluido.
|
||||
|
||||
## Inicio Rapido
|
||||
|
||||
```python
|
||||
from crewai import Crew, CheckpointConfig
|
||||
|
||||
crew = Crew(
|
||||
agents=[...],
|
||||
tasks=[...],
|
||||
checkpoint=True, # usa padroes: ./.checkpoints, em task_completed
|
||||
)
|
||||
result = crew.kickoff()
|
||||
```
|
||||
|
||||
Os arquivos de checkpoint sao gravados em `./.checkpoints/` apos cada tarefa concluida.
|
||||
|
||||
## Configuracao
|
||||
|
||||
Use `CheckpointConfig` para controle total:
|
||||
|
||||
```python
|
||||
from crewai import Crew, CheckpointConfig
|
||||
|
||||
crew = Crew(
|
||||
agents=[...],
|
||||
tasks=[...],
|
||||
checkpoint=CheckpointConfig(
|
||||
location="./my_checkpoints",
|
||||
on_events=["task_completed", "crew_kickoff_completed"],
|
||||
max_checkpoints=5,
|
||||
),
|
||||
)
|
||||
```
|
||||
|
||||
### Campos do CheckpointConfig
|
||||
|
||||
| Campo | Tipo | Padrao | Descricao |
|
||||
|:------|:-----|:-------|:----------|
|
||||
| `location` | `str` | `"./.checkpoints"` | Caminho para os arquivos de checkpoint |
|
||||
| `on_events` | `list[str]` | `["task_completed"]` | Tipos de evento que acionam um checkpoint |
|
||||
| `provider` | `BaseProvider` | `JsonProvider()` | Backend de armazenamento |
|
||||
| `max_checkpoints` | `int \| None` | `None` | Maximo de arquivos a manter; os mais antigos sao removidos primeiro |
|
||||
|
||||
### Heranca e Desativacao
|
||||
|
||||
O campo `checkpoint` em Crew, Flow e Agent aceita `CheckpointConfig`, `True`, `False` ou `None`:
|
||||
|
||||
| Valor | Comportamento |
|
||||
|:------|:--------------|
|
||||
| `None` (padrao) | Herda do pai. Um agente herda a configuracao da crew. |
|
||||
| `True` | Ativa com padroes. |
|
||||
| `False` | Desativacao explicita. Interrompe a heranca do pai. |
|
||||
| `CheckpointConfig(...)` | Configuracao personalizada. |
|
||||
|
||||
```python
|
||||
crew = Crew(
|
||||
agents=[
|
||||
Agent(role="Researcher", ...), # herda checkpoint da crew
|
||||
Agent(role="Writer", ..., checkpoint=False), # desativado, sem checkpoints
|
||||
],
|
||||
tasks=[...],
|
||||
checkpoint=True,
|
||||
)
|
||||
```
|
||||
|
||||
## Retomando a partir de um Checkpoint
|
||||
|
||||
```python
|
||||
# Restaurar e retomar
|
||||
crew = Crew.from_checkpoint("./my_checkpoints/20260407T120000_abc123.json")
|
||||
result = crew.kickoff() # retoma a partir da ultima tarefa concluida
|
||||
```
|
||||
|
||||
A crew restaurada pula tarefas ja concluidas e retoma a partir da primeira incompleta.
|
||||
|
||||
## Funciona em Crew, Flow e Agent
|
||||
|
||||
### Crew
|
||||
|
||||
```python
|
||||
crew = Crew(
|
||||
agents=[researcher, writer],
|
||||
tasks=[research_task, write_task, review_task],
|
||||
checkpoint=CheckpointConfig(location="./crew_cp"),
|
||||
)
|
||||
```
|
||||
|
||||
Gatilho padrao: `task_completed` (um checkpoint por tarefa finalizada).
|
||||
|
||||
### Flow
|
||||
|
||||
```python
|
||||
from crewai.flow.flow import Flow, start, listen
|
||||
from crewai import CheckpointConfig
|
||||
|
||||
class MyFlow(Flow):
|
||||
@start()
|
||||
def step_one(self):
|
||||
return "data"
|
||||
|
||||
@listen(step_one)
|
||||
def step_two(self, data):
|
||||
return process(data)
|
||||
|
||||
flow = MyFlow(
|
||||
checkpoint=CheckpointConfig(
|
||||
location="./flow_cp",
|
||||
on_events=["method_execution_finished"],
|
||||
),
|
||||
)
|
||||
result = flow.kickoff()
|
||||
|
||||
# Retomar
|
||||
flow = MyFlow.from_checkpoint("./flow_cp/20260407T120000_abc123.json")
|
||||
result = flow.kickoff()
|
||||
```
|
||||
|
||||
### Agent
|
||||
|
||||
```python
|
||||
agent = Agent(
|
||||
role="Researcher",
|
||||
goal="Research topics",
|
||||
backstory="Expert researcher",
|
||||
checkpoint=CheckpointConfig(
|
||||
location="./agent_cp",
|
||||
on_events=["lite_agent_execution_completed"],
|
||||
),
|
||||
)
|
||||
result = agent.kickoff(messages=[{"role": "user", "content": "Research AI trends"}])
|
||||
```
|
||||
|
||||
## Provedores de Armazenamento
|
||||
|
||||
O CrewAI inclui dois provedores de armazenamento para checkpoints.
|
||||
|
||||
### JsonProvider (padrao)
|
||||
|
||||
Grava cada checkpoint como um arquivo JSON separado.
|
||||
|
||||
```python
|
||||
from crewai import Crew, CheckpointConfig
|
||||
from crewai.state import JsonProvider
|
||||
|
||||
crew = Crew(
|
||||
agents=[...],
|
||||
tasks=[...],
|
||||
checkpoint=CheckpointConfig(
|
||||
location="./my_checkpoints",
|
||||
provider=JsonProvider(),
|
||||
max_checkpoints=5,
|
||||
),
|
||||
)
|
||||
```
|
||||
|
||||
### SqliteProvider
|
||||
|
||||
Armazena todos os checkpoints em um unico arquivo SQLite.
|
||||
|
||||
```python
|
||||
from crewai import Crew, CheckpointConfig
|
||||
from crewai.state import SqliteProvider
|
||||
|
||||
crew = Crew(
|
||||
agents=[...],
|
||||
tasks=[...],
|
||||
checkpoint=CheckpointConfig(
|
||||
location="./.checkpoints.db",
|
||||
provider=SqliteProvider(),
|
||||
),
|
||||
)
|
||||
```
|
||||
|
||||
|
||||
## Tipos de Evento
|
||||
|
||||
O campo `on_events` aceita qualquer combinacao de strings de tipo de evento. Escolhas comuns:
|
||||
|
||||
| Caso de Uso | Eventos |
|
||||
|:------------|:--------|
|
||||
| Apos cada tarefa (Crew) | `["task_completed"]` |
|
||||
| Apos cada metodo do flow | `["method_execution_finished"]` |
|
||||
| Apos execucao do agente | `["agent_execution_completed"]`, `["lite_agent_execution_completed"]` |
|
||||
| Apenas na conclusao da crew | `["crew_kickoff_completed"]` |
|
||||
| Apos cada chamada LLM | `["llm_call_completed"]` |
|
||||
| Em tudo | `["*"]` |
|
||||
|
||||
<Warning>
|
||||
Usar `["*"]` ou eventos de alta frequencia como `llm_call_completed` gravara muitos arquivos de checkpoint e pode impactar o desempenho. Use `max_checkpoints` para limitar o uso de disco.
|
||||
</Warning>
|
||||
|
||||
## Checkpointing Manual
|
||||
|
||||
Para controle total, registre seu proprio handler de evento e chame `state.checkpoint()` diretamente:
|
||||
|
||||
```python
|
||||
from crewai.events.event_bus import crewai_event_bus
|
||||
from crewai.events.types.llm_events import LLMCallCompletedEvent
|
||||
|
||||
# Handler sincrono
|
||||
@crewai_event_bus.on(LLMCallCompletedEvent)
|
||||
def on_llm_done(source, event, state):
|
||||
path = state.checkpoint("./my_checkpoints")
|
||||
print(f"Checkpoint salvo: {path}")
|
||||
|
||||
# Handler assincrono
|
||||
@crewai_event_bus.on(LLMCallCompletedEvent)
|
||||
async def on_llm_done_async(source, event, state):
|
||||
path = await state.acheckpoint("./my_checkpoints")
|
||||
print(f"Checkpoint salvo: {path}")
|
||||
```
|
||||
|
||||
O argumento `state` e o `RuntimeState` passado automaticamente pelo barramento de eventos quando seu handler aceita 3 parametros. Voce pode registrar handlers em qualquer tipo de evento listado na documentacao de [Event Listeners](/pt-BR/concepts/event-listener).
|
||||
|
||||
O checkpointing e best-effort: se uma gravacao de checkpoint falhar, o erro e registrado no log, mas a execucao continua sem interrupcao.
|
||||
@@ -117,35 +117,23 @@ task = Task(
|
||||
|
||||
### Com Flows
|
||||
|
||||
Campos tipados como arquivo (`File`, `ImageFile`, `PDFFile`) no esquema de estado do seu flow servem como sinal para a interface da Plataforma. Quando implantado, esses campos são renderizados como zonas de upload de arquivos. Arquivos também podem ser passados via `input_files` na API.
|
||||
Passe arquivos para flows, que automaticamente herdam para crews:
|
||||
|
||||
```python
|
||||
from crewai.flow.flow import Flow, start
|
||||
from crewai_files import File, ImageFile
|
||||
from pydantic import BaseModel
|
||||
from crewai_files import ImageFile
|
||||
|
||||
class MyState(BaseModel):
|
||||
document: File # Renders as file dropzone in Platform UI
|
||||
cover_image: ImageFile # Image-specific dropzone
|
||||
title: str = ""
|
||||
|
||||
class AnalysisFlow(Flow[MyState]):
|
||||
class AnalysisFlow(Flow):
|
||||
@start()
|
||||
def analyze(self):
|
||||
# Files are automatically populated in state
|
||||
content = self.state.document.read()
|
||||
return self.analysis_crew.kickoff()
|
||||
|
||||
flow = AnalysisFlow()
|
||||
result = flow.kickoff(
|
||||
input_files={"document": File(source="report.pdf")}
|
||||
input_files={"image": ImageFile(source="data.png")}
|
||||
)
|
||||
```
|
||||
|
||||
<Note type="info" title="Integração com a Plataforma CrewAI">
|
||||
Quando implantado na Plataforma CrewAI, campos tipados como arquivo como `ImageFile`, `PDFFile` e outros no estado do seu flow recebem automaticamente uma interface de upload de arquivos. Os usuários podem arrastar e soltar arquivos diretamente na interface da Plataforma. Os arquivos são armazenados de forma segura e passados para os agentes usando otimizações específicas do provedor (base64 inline, APIs de upload de arquivo ou referências por URL dependendo do provedor). Para exemplos de uso da API, consulte [Entradas de Arquivos em Flows](/pt-BR/concepts/flows#entradas-de-arquivos).
|
||||
</Note>
|
||||
|
||||
### Com Agentes Standalone
|
||||
|
||||
Passe arquivos diretamente no kickoff do agente:
|
||||
|
||||
@@ -173,90 +173,6 @@ Cada estado nos flows do CrewAI recebe automaticamente um identificador único (
|
||||
|
||||
Ao oferecer as duas opções de gerenciamento de estado, o CrewAI Flows permite que desenvolvedores criem fluxos de IA que sejam ao mesmo tempo flexíveis e robustos, atendendo a uma ampla variedade de requisitos de aplicação.
|
||||
|
||||
### Entradas de Arquivos
|
||||
|
||||
Ao usar estado estruturado, você pode incluir campos tipados como arquivo usando classes do `crewai-files`. Campos tipados como arquivo no estado do seu flow servem como sinal para a Plataforma — eles são renderizados automaticamente como zonas de upload de arquivos na aba Run da interface e são preenchidos quando arquivos são enviados via Plataforma ou passados via `input_files` na API.
|
||||
|
||||
```python
|
||||
from crewai.flow.flow import Flow, start
|
||||
from crewai_files import File, ImageFile, PDFFile
|
||||
from pydantic import BaseModel
|
||||
|
||||
class MyState(BaseModel):
|
||||
document: File # Renders as file dropzone in Platform
|
||||
title: str = ""
|
||||
|
||||
class MyFlow(Flow[MyState]):
|
||||
@start()
|
||||
def process(self):
|
||||
# File object is automatically populated in state
|
||||
# when uploaded via Platform UI or passed via API
|
||||
content = self.state.document.read()
|
||||
print(f"Processing {self.state.title}: {len(content)} bytes")
|
||||
return content
|
||||
```
|
||||
|
||||
Quando implantado na **Plataforma CrewAI**, campos tipados como arquivo (`File`, `ImageFile`, `PDFFile` do `crewai-files`) são renderizados automaticamente como zonas de upload de arquivos na interface. Os usuários podem arrastar e soltar arquivos, que são então preenchidos no estado do seu flow.
|
||||
|
||||
**Iniciando com arquivos via API:**
|
||||
|
||||
O endpoint `/kickoff` detecta automaticamente o formato da requisição:
|
||||
- **Corpo JSON** → kickoff normal
|
||||
- **multipart/form-data** → upload de arquivo + kickoff
|
||||
|
||||
Usuários da API também podem passar strings de URL diretamente para campos tipados como arquivo — o Pydantic as converte automaticamente.
|
||||
|
||||
### Uso da API
|
||||
|
||||
#### Opção 1: Kickoff multipart (recomendado)
|
||||
|
||||
Envie arquivos diretamente com a requisição de kickoff:
|
||||
|
||||
```bash
|
||||
# With files (multipart) — same endpoint
|
||||
curl -X POST https://your-deployment.crewai.com/kickoff \
|
||||
-H 'Authorization: Bearer YOUR_TOKEN' \
|
||||
-F 'inputs={"company_name": "Einstein"}' \
|
||||
-F 'cover_image=@/path/to/photo.jpg'
|
||||
```
|
||||
|
||||
Os arquivos são armazenados automaticamente e convertidos em objetos `FileInput`. O agente recebe o arquivo com otimização específica do provedor (base64 inline, API de upload de arquivo ou referência por URL dependendo do provedor LLM).
|
||||
|
||||
#### Opção 2: Kickoff JSON (sem arquivos)
|
||||
|
||||
```bash
|
||||
# Without files (JSON) — same endpoint
|
||||
curl -X POST https://your-deployment.crewai.com/kickoff \
|
||||
-H 'Authorization: Bearer YOUR_TOKEN' \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d '{"inputs": {"company_name": "Einstein"}}'
|
||||
```
|
||||
|
||||
#### Opção 3: Upload separado + kickoff
|
||||
|
||||
Esta é uma alternativa ao upload multipart quando você precisa fazer upload dos arquivos separadamente da requisição de kickoff. Faça o upload dos arquivos primeiro e depois referencie-os por URL:
|
||||
|
||||
```bash
|
||||
# Step 1: Upload
|
||||
curl -X POST https://your-deployment.crewai.com/files \
|
||||
-H 'Authorization: Bearer YOUR_TOKEN' \
|
||||
-F 'file=@/path/to/photo.jpg' \
|
||||
-F 'field_name=cover_image'
|
||||
# Returns: {"url": "https://...", "field_name": "cover_image"}
|
||||
|
||||
# Step 2: Kickoff with URL
|
||||
curl -X POST https://your-deployment.crewai.com/kickoff \
|
||||
-H 'Authorization: Bearer YOUR_TOKEN' \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d '{"inputs": {"company_name": "Einstein"}, "input_files": {"cover_image": "https://..."}}'
|
||||
```
|
||||
|
||||
Consulte a documentação da API da Plataforma para detalhes completos do endpoint `/files`.
|
||||
|
||||
#### Na Plataforma CrewAI
|
||||
|
||||
Ao usar a interface da Plataforma, campos tipados como arquivo são renderizados automaticamente como zonas de arrastar e soltar para upload. Nenhuma chamada de API é necessária — basta soltar o arquivo e clicar em Executar.
|
||||
|
||||
## Persistência de Flow
|
||||
|
||||
O decorador @persist permite a persistência automática do estado nos flows do CrewAI, garantindo que você mantenha o estado do flow entre reinicializações ou execuções diferentes do workflow. Esse decorador pode ser aplicado tanto ao nível de classe, quanto ao nível de método, oferecendo flexibilidade sobre como gerenciar a persistência do estado.
|
||||
|
||||
@@ -105,7 +105,7 @@ A CLI detecta automaticamente o tipo do seu projeto a partir do `pyproject.toml`
|
||||
```
|
||||
|
||||
<Tip>
|
||||
A primeira implantação normalmente leva de 10 a 15 minutos, pois as imagens dos containers são construídas. As próximas implantações são bem mais rápidas.
|
||||
A primeira implantação normalmente leva cerca de 1 minuto.
|
||||
</Tip>
|
||||
|
||||
</Step>
|
||||
@@ -187,7 +187,7 @@ Você precisa enviar seu crew para um repositório do GitHub. Caso ainda não te
|
||||
|
||||
1. Clique no botão "Deploy" para iniciar o processo de implantação
|
||||
2. Você pode monitorar o progresso pela barra de progresso
|
||||
3. A primeira implantação geralmente demora de 10 a 15 minutos; as próximas serão mais rápidas
|
||||
3. A primeira implantação geralmente demora cerca de 1 minuto
|
||||
|
||||
<Frame>
|
||||

|
||||
|
||||
@@ -86,60 +86,6 @@ curl -H "Authorization: Bearer YOUR_CREW_TOKEN" https://your-crew-url.crewai.com
|
||||
|
||||
Seu bearer token está disponível na aba Status na página de detalhes do seu crew.
|
||||
|
||||
## Upload de Arquivos
|
||||
|
||||
Quando seu crew ou flow inclui campos de estado tipados como arquivo (usando `ImageFile`, `PDFFile` ou `File` do `crewai-files`), esses campos são renderizados automaticamente como zonas de upload de arquivos na aba Run da interface. Os usuários podem arrastar e soltar arquivos diretamente, e a Plataforma gerencia o armazenamento e entrega para seus agentes.
|
||||
|
||||
### Kickoff Multipart (Recomendado)
|
||||
|
||||
Envie arquivos diretamente com a requisição de kickoff usando `multipart/form-data`:
|
||||
|
||||
```bash
|
||||
curl -X POST https://your-deployment.crewai.com/kickoff \
|
||||
-H 'Authorization: Bearer YOUR_TOKEN' \
|
||||
-F 'inputs={"title": "Report"}' \
|
||||
-F 'document=@/path/to/file.pdf'
|
||||
```
|
||||
|
||||
Os arquivos são armazenados automaticamente e convertidos em objetos de arquivo. O agente recebe o arquivo com otimização específica do provedor (base64 inline, API de upload de arquivo ou referência por URL dependendo do provedor LLM).
|
||||
|
||||
### Kickoff JSON com URLs de Arquivos
|
||||
|
||||
Se você já tem arquivos hospedados em URLs, passe-os via `input_files`:
|
||||
|
||||
```bash
|
||||
curl -X POST https://your-deployment.crewai.com/kickoff \
|
||||
-H 'Authorization: Bearer YOUR_TOKEN' \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d '{
|
||||
"inputs": {"title": "Report"},
|
||||
"input_files": {"document": "https://example.com/file.pdf"}
|
||||
}'
|
||||
```
|
||||
|
||||
### Upload Separado + Kickoff
|
||||
|
||||
Faça upload dos arquivos primeiro e depois referencie-os por URL:
|
||||
|
||||
```bash
|
||||
# Step 1: Upload
|
||||
curl -X POST https://your-deployment.crewai.com/files \
|
||||
-H 'Authorization: Bearer YOUR_TOKEN' \
|
||||
-F 'file=@/path/to/file.pdf' \
|
||||
-F 'field_name=document'
|
||||
# Returns: {"url": "https://...", "field_name": "document"}
|
||||
|
||||
# Step 2: Kickoff with URL
|
||||
curl -X POST https://your-deployment.crewai.com/kickoff \
|
||||
-H 'Authorization: Bearer YOUR_TOKEN' \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d '{"inputs": {"title": "Report"}, "input_files": {"document": "https://..."}}'
|
||||
```
|
||||
|
||||
<Note type="info">
|
||||
O upload de arquivos funciona da mesma forma tanto para crews quanto para flows. Defina campos tipados como arquivo no seu esquema de estado, e a interface da Plataforma e a API tratarão os uploads automaticamente.
|
||||
</Note>
|
||||
|
||||
### Verificando o Status do Crew
|
||||
|
||||
Antes de executar operações, você pode verificar se seu crew está funcionando corretamente:
|
||||
|
||||
@@ -200,12 +200,11 @@ Para equipes e organizações, o CrewAI oferece opções de implantação corpor
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card
|
||||
title="Construa Seu Primeiro Agente"
|
||||
title="Início rápido: Flow + agente"
|
||||
icon="code"
|
||||
href="/pt-BR/quickstart"
|
||||
>
|
||||
Siga nosso guia de início rápido para criar seu primeiro agente CrewAI e
|
||||
obter experiência prática.
|
||||
Siga o guia rápido para gerar um Flow, executar um crew com um agente e produzir um relatório.
|
||||
</Card>
|
||||
<Card
|
||||
title="Junte-se à Comunidade"
|
||||
|
||||
@@ -140,7 +140,7 @@ Para qualquer aplicação pronta para produção, **comece com um Flow**.
|
||||
icon="bolt"
|
||||
href="/pt-BR/quickstart"
|
||||
>
|
||||
Siga nosso guia rápido para criar seu primeiro agente CrewAI e colocar a mão na massa.
|
||||
Gere um Flow, execute um crew com um agente e produza um relatório ponta a ponta.
|
||||
</Card>
|
||||
<Card
|
||||
title="Junte-se à Comunidade"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
title: Guia Rápido
|
||||
description: Construa seu primeiro agente de IA com a CrewAI em menos de 5 minutos.
|
||||
description: Crie seu primeiro Flow CrewAI em minutos — orquestração, estado e um crew com um agente que gera um relatório real.
|
||||
icon: rocket
|
||||
mode: "wide"
|
||||
---
|
||||
@@ -13,370 +13,266 @@ Você pode instalar com `npx skills add crewaiinc/skills`
|
||||
|
||||
<iframe src="https://www.loom.com/embed/befb9f68b81f42ad8112bfdd95a780af" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen style={{width: "100%", height: "400px"}}></iframe>
|
||||
|
||||
## Construa seu primeiro Agente CrewAI
|
||||
Neste guia você vai **criar um Flow** que define um tópico de pesquisa, executa um **crew com um agente** (um pesquisador com busca na web) e termina com um **relatório em Markdown** no disco. Flows são a forma recomendada de estruturar apps em produção: eles controlam **estado** e **ordem de execução**, enquanto os **agentes** fazem o trabalho dentro da etapa do crew.
|
||||
|
||||
Vamos criar uma tripulação simples que nos ajudará a `pesquisar` e `relatar` sobre os `últimos avanços em IA` para um determinado tópico ou assunto.
|
||||
Se ainda não instalou o CrewAI, siga primeiro o [guia de instalação](/pt-BR/installation).
|
||||
|
||||
Antes de prosseguir, certifique-se de ter concluído a instalação da CrewAI.
|
||||
Se ainda não instalou, faça isso seguindo o [guia de instalação](/pt-BR/installation).
|
||||
## Pré-requisitos
|
||||
|
||||
Siga os passos abaixo para começar a tripular! 🚣♂️
|
||||
- Ambiente Python e a CLI do CrewAI (veja [instalação](/pt-BR/installation))
|
||||
- Um LLM configurado com as chaves corretas — veja [LLMs](/pt-BR/concepts/llms#setting-up-your-llm)
|
||||
- Uma chave de API do [Serper.dev](https://serper.dev/) (`SERPER_API_KEY`) para busca na web neste tutorial
|
||||
|
||||
## Construa seu primeiro Flow
|
||||
|
||||
<Steps>
|
||||
<Step title="Crie sua tripulação">
|
||||
Crie um novo projeto de tripulação executando o comando abaixo em seu terminal.
|
||||
Isso criará um novo diretório chamado `latest-ai-development` com a estrutura básica para sua tripulação.
|
||||
<Step title="Crie um projeto Flow">
|
||||
No terminal, gere um projeto Flow (o nome da pasta usa sublinhados, ex.: `latest_ai_flow`):
|
||||
|
||||
<CodeGroup>
|
||||
```shell Terminal
|
||||
crewai create crew latest-ai-development
|
||||
crewai create flow latest-ai-flow
|
||||
cd latest_ai_flow
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
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="Navegue até o novo projeto da sua tripulação">
|
||||
<CodeGroup>
|
||||
```shell Terminal
|
||||
cd latest_ai_development
|
||||
```
|
||||
</CodeGroup>
|
||||
</Step>
|
||||
<Step title="Modifique seu arquivo `agents.yaml`">
|
||||
<Tip>
|
||||
Você também pode modificar os agentes conforme necessário para atender ao seu caso de uso ou copiar e colar como está para seu projeto.
|
||||
Qualquer variável interpolada nos seus arquivos `agents.yaml` e `tasks.yaml`, como `{topic}`, será substituída pelo valor da variável no arquivo `main.py`.
|
||||
</Tip>
|
||||
|
||||
<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=...)`.
|
||||
|
||||
```yaml agents.yaml
|
||||
# src/latest_ai_development/config/agents.yaml
|
||||
# src/latest_ai_flow/crews/content_crew/config/agents.yaml
|
||||
researcher:
|
||||
role: >
|
||||
Pesquisador Sênior de Dados em {topic}
|
||||
Pesquisador(a) Sênior de Dados em {topic}
|
||||
goal: >
|
||||
Descobrir os avanços mais recentes em {topic}
|
||||
Descobrir os desenvolvimentos mais recentes em {topic}
|
||||
backstory: >
|
||||
Você é um pesquisador experiente com talento para descobrir os últimos avanços em {topic}. Conhecido por sua habilidade em encontrar as informações mais relevantes e apresentá-las de forma clara e concisa.
|
||||
|
||||
reporting_analyst:
|
||||
role: >
|
||||
Analista de Relatórios em {topic}
|
||||
goal: >
|
||||
Criar relatórios detalhados com base na análise de dados e descobertas de pesquisa em {topic}
|
||||
backstory: >
|
||||
Você é um analista meticuloso com um olhar atento aos detalhes. É conhecido por sua capacidade de transformar dados complexos em relatórios claros e concisos, facilitando o entendimento e a tomada de decisão por parte dos outros.
|
||||
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="Modifique seu arquivo `tasks.yaml`">
|
||||
|
||||
<Step title="Configure uma tarefa em `tasks.yaml`">
|
||||
```yaml tasks.yaml
|
||||
# src/latest_ai_development/config/tasks.yaml
|
||||
# src/latest_ai_flow/crews/content_crew/config/tasks.yaml
|
||||
research_task:
|
||||
description: >
|
||||
Realize uma pesquisa aprofundada sobre {topic}.
|
||||
Certifique-se de encontrar informações interessantes e relevantes considerando que o ano atual é 2025.
|
||||
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: >
|
||||
Uma lista com 10 tópicos dos dados mais relevantes sobre {topic}
|
||||
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
|
||||
|
||||
reporting_task:
|
||||
description: >
|
||||
Revise o contexto obtido e expanda cada tópico em uma seção completa para um relatório.
|
||||
Certifique-se de que o relatório seja detalhado e contenha todas as informações relevantes.
|
||||
expected_output: >
|
||||
Um relatório completo com os principais tópicos, cada um com uma seção detalhada de informações.
|
||||
Formate como markdown sem usar '```'
|
||||
agent: reporting_analyst
|
||||
output_file: report.md
|
||||
output_file: output/report.md
|
||||
```
|
||||
|
||||
</Step>
|
||||
<Step title="Modifique seu arquivo `crew.py`">
|
||||
```python crew.py
|
||||
# src/latest_ai_development/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
|
||||
|
||||
<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 typing import List
|
||||
|
||||
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
|
||||
|
||||
|
||||
@CrewBase
|
||||
class LatestAiDevelopmentCrew():
|
||||
"""LatestAiDevelopment crew"""
|
||||
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]
|
||||
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
|
||||
tools=[SerperDevTool()],
|
||||
)
|
||||
|
||||
@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]
|
||||
output_file='output/report.md' # Este é o arquivo que conterá o relatório final.
|
||||
config=self.tasks_config["research_task"], # type: ignore[index]
|
||||
)
|
||||
|
||||
@crew
|
||||
def crew(self) -> Crew:
|
||||
"""Creates the LatestAiDevelopment crew"""
|
||||
return Crew(
|
||||
agents=self.agents, # Criado automaticamente pelo decorador @agent
|
||||
tasks=self.tasks, # Criado automaticamente pelo decorador @task
|
||||
agents=self.agents,
|
||||
tasks=self.tasks,
|
||||
process=Process.sequential,
|
||||
verbose=True,
|
||||
)
|
||||
```
|
||||
|
||||
</Step>
|
||||
<Step title="[Opcional] Adicione funções de pré e pós execução da tripulação">
|
||||
```python crew.py
|
||||
# src/latest_ai_development/crew.py
|
||||
from crewai import Agent, Crew, Process, Task
|
||||
from crewai.project import CrewBase, agent, crew, task, before_kickoff, after_kickoff
|
||||
from crewai_tools import SerperDevTool
|
||||
|
||||
@CrewBase
|
||||
class LatestAiDevelopmentCrew():
|
||||
"""LatestAiDevelopment crew"""
|
||||
<Step title="Defina o Flow em `main.py`">
|
||||
Conecte o crew a um Flow: um passo `@start()` define o tópico no **estado** e um `@listen` executa o crew. O `output_file` da tarefa continua gravando `output/report.md`.
|
||||
|
||||
@before_kickoff
|
||||
def before_kickoff_function(self, inputs):
|
||||
print(f"Before kickoff function with inputs: {inputs}")
|
||||
return inputs # You can return the inputs or modify them as needed
|
||||
|
||||
@after_kickoff
|
||||
def after_kickoff_function(self, result):
|
||||
print(f"After kickoff function with result: {result}")
|
||||
return result # You can return the result or modify it as needed
|
||||
|
||||
# ... remaining code
|
||||
```
|
||||
|
||||
</Step>
|
||||
<Step title="Fique à vontade para passar entradas personalizadas para sua tripulação">
|
||||
Por exemplo, você pode passar o input `topic` para sua tripulação para personalizar a pesquisa e o relatório.
|
||||
```python main.py
|
||||
#!/usr/bin/env python
|
||||
# src/latest_ai_development/main.py
|
||||
import sys
|
||||
from latest_ai_development.crew import LatestAiDevelopmentCrew
|
||||
# src/latest_ai_flow/main.py
|
||||
from pydantic import BaseModel
|
||||
|
||||
def run():
|
||||
"""
|
||||
Run the crew.
|
||||
"""
|
||||
inputs = {
|
||||
'topic': 'AI Agents'
|
||||
}
|
||||
LatestAiDevelopmentCrew().crew().kickoff(inputs=inputs)
|
||||
from crewai.flow import Flow, listen, start
|
||||
|
||||
from latest_ai_flow.crews.content_crew.content_crew import ResearchCrew
|
||||
|
||||
|
||||
class ResearchFlowState(BaseModel):
|
||||
topic: str = ""
|
||||
report: str = ""
|
||||
|
||||
|
||||
class LatestAiFlow(Flow[ResearchFlowState]):
|
||||
@start()
|
||||
def prepare_topic(self, crewai_trigger_payload: dict | None = None):
|
||||
if crewai_trigger_payload:
|
||||
self.state.topic = crewai_trigger_payload.get("topic", "AI Agents")
|
||||
else:
|
||||
self.state.topic = "AI Agents"
|
||||
print(f"Tópico: {self.state.topic}")
|
||||
|
||||
@listen(prepare_topic)
|
||||
def run_research(self):
|
||||
result = ResearchCrew().crew().kickoff(inputs={"topic": self.state.topic})
|
||||
self.state.report = result.raw
|
||||
print("Crew de pesquisa concluído.")
|
||||
|
||||
@listen(run_research)
|
||||
def summarize(self):
|
||||
print("Relatório em: output/report.md")
|
||||
|
||||
|
||||
def kickoff():
|
||||
LatestAiFlow().kickoff()
|
||||
|
||||
|
||||
def plot():
|
||||
LatestAiFlow().plot()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
kickoff()
|
||||
```
|
||||
|
||||
</Step>
|
||||
<Step title="Defina suas variáveis de ambiente">
|
||||
Antes de executar sua tripulação, certifique-se de ter as seguintes chaves configuradas como variáveis de ambiente no seu arquivo `.env`:
|
||||
- Uma chave da API do [Serper.dev](https://serper.dev/): `SERPER_API_KEY=YOUR_KEY_HERE`
|
||||
- A configuração do modelo de sua escolha, como uma chave de API. Veja o
|
||||
[guia de configuração do LLM](/pt-BR/concepts/llms#setting-up-your-llm) para aprender como configurar modelos de qualquer provedor.
|
||||
</Step>
|
||||
<Step title="Trave e instale as dependências">
|
||||
- Trave e instale as dependências utilizando o comando da CLI:
|
||||
<CodeGroup>
|
||||
```shell Terminal
|
||||
crewai install
|
||||
```
|
||||
</CodeGroup>
|
||||
- Se quiser instalar pacotes adicionais, faça isso executando:
|
||||
<CodeGroup>
|
||||
```shell Terminal
|
||||
uv add <package-name>
|
||||
```
|
||||
</CodeGroup>
|
||||
</Step>
|
||||
<Step title="Execute sua tripulação">
|
||||
- Para executar sua tripulação, rode o seguinte comando na raiz do projeto:
|
||||
<CodeGroup>
|
||||
```bash Terminal
|
||||
crewai run
|
||||
```
|
||||
</CodeGroup>
|
||||
<Tip>
|
||||
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>
|
||||
|
||||
<Step title="Alternativa para Empresas: Crie no Crew Studio">
|
||||
Para usuários do CrewAI AMP, você pode criar a mesma tripulação sem escrever código:
|
||||
<Step title="Variáveis de ambiente">
|
||||
Na raiz do projeto, no arquivo `.env`, defina:
|
||||
|
||||
1. Faça login na sua conta CrewAI AMP (crie uma conta gratuita em [app.crewai.com](https://app.crewai.com))
|
||||
2. Abra o Crew Studio
|
||||
3. Digite qual automação deseja construir
|
||||
4. Crie suas tarefas visualmente e conecte-as em sequência
|
||||
5. Configure seus inputs e clique em "Download Code" ou "Deploy"
|
||||
|
||||

|
||||
|
||||
<Card title="Experimente o CrewAI AMP" icon="rocket" href="https://app.crewai.com">
|
||||
Comece sua conta gratuita no CrewAI AMP
|
||||
</Card>
|
||||
- `SERPER_API_KEY` — obtida em [Serper.dev](https://serper.dev/)
|
||||
- As chaves do provedor de modelo conforme necessário — veja [configuração de LLM](/pt-BR/concepts/llms#setting-up-your-llm)
|
||||
</Step>
|
||||
<Step title="Veja seu relatório final">
|
||||
Você verá a saída no console e o arquivo `report.md` deve ser criado na raiz do seu projeto com o relatório final.
|
||||
|
||||
Veja um exemplo de como o relatório deve ser:
|
||||
<Step title="Instalar e executar">
|
||||
<CodeGroup>
|
||||
```shell Terminal
|
||||
crewai install
|
||||
crewai run
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
O `crewai run` executa o ponto de entrada do Flow definido no projeto (o mesmo comando dos crews; o tipo do projeto é `"flow"` no `pyproject.toml`).
|
||||
</Step>
|
||||
|
||||
<Step title="Confira o resultado">
|
||||
Você deve ver logs do Flow e do crew. Abra **`output/report.md`** para o relatório gerado (trecho):
|
||||
|
||||
<CodeGroup>
|
||||
```markdown output/report.md
|
||||
# Relatório Abrangente sobre a Ascensão e o Impacto dos Agentes de IA em 2025
|
||||
# Agentes de IA em 2026: panorama e tendências
|
||||
|
||||
## 1. Introduction to AI Agents
|
||||
In 2025, Artificial Intelligence (AI) agents are at the forefront of innovation across various industries. As intelligent systems that can perform tasks typically requiring human cognition, AI agents are paving the way for significant advancements in operational efficiency, decision-making, and overall productivity within sectors like Human Resources (HR) and Finance. This report aims to detail the rise of AI agents, their frameworks, applications, and potential implications on the workforce.
|
||||
## Resumo executivo
|
||||
…
|
||||
|
||||
## 2. Benefits of AI Agents
|
||||
AI agents bring numerous advantages that are transforming traditional work environments. Key benefits include:
|
||||
## Principais tendências
|
||||
- **Uso de ferramentas e orquestração** — …
|
||||
- **Adoção empresarial** — …
|
||||
|
||||
- **Task Automation**: AI agents can carry out repetitive tasks such as data entry, scheduling, and payroll processing without human intervention, greatly reducing the time and resources spent on these activities.
|
||||
- **Improved Efficiency**: By quickly processing large datasets and performing analyses that would take humans significantly longer, AI agents enhance operational efficiency. This allows teams to focus on strategic tasks that require higher-level thinking.
|
||||
- **Enhanced Decision-Making**: AI agents can analyze trends and patterns in data, provide insights, and even suggest actions, helping stakeholders make informed decisions based on factual data rather than intuition alone.
|
||||
|
||||
## 3. Popular AI Agent Frameworks
|
||||
Several frameworks have emerged to facilitate the development of AI agents, each with its own unique features and capabilities. Some of the most popular frameworks include:
|
||||
|
||||
- **Autogen**: A framework designed to streamline the development of AI agents through automation of code generation.
|
||||
- **Semantic Kernel**: Focuses on natural language processing and understanding, enabling agents to comprehend user intentions better.
|
||||
- **Promptflow**: Provides tools for developers to create conversational agents that can navigate complex interactions seamlessly.
|
||||
- **Langchain**: Specializes in leveraging various APIs to ensure agents can access and utilize external data effectively.
|
||||
- **CrewAI**: Aimed at collaborative environments, CrewAI strengthens teamwork by facilitating communication through AI-driven insights.
|
||||
- **MemGPT**: Combines memory-optimized architectures with generative capabilities, allowing for more personalized interactions with users.
|
||||
|
||||
These frameworks empower developers to build versatile and intelligent agents that can engage users, perform advanced analytics, and execute various tasks aligned with organizational goals.
|
||||
|
||||
## 4. AI Agents in Human Resources
|
||||
AI agents are revolutionizing HR practices by automating and optimizing key functions:
|
||||
|
||||
- **Recruiting**: AI agents can screen resumes, schedule interviews, and even conduct initial assessments, thus accelerating the hiring process while minimizing biases.
|
||||
- **Succession Planning**: AI systems analyze employee performance data and potential, helping organizations identify future leaders and plan appropriate training.
|
||||
- **Employee Engagement**: Chatbots powered by AI can facilitate feedback loops between employees and management, promoting an open culture and addressing concerns promptly.
|
||||
|
||||
As AI continues to evolve, HR departments leveraging these agents can realize substantial improvements in both efficiency and employee satisfaction.
|
||||
|
||||
## 5. AI Agents in Finance
|
||||
The finance sector is seeing extensive integration of AI agents that enhance financial practices:
|
||||
|
||||
- **Expense Tracking**: Automated systems manage and monitor expenses, flagging anomalies and offering recommendations based on spending patterns.
|
||||
- **Risk Assessment**: AI models assess credit risk and uncover potential fraud by analyzing transaction data and behavioral patterns.
|
||||
- **Investment Decisions**: AI agents provide stock predictions and analytics based on historical data and current market conditions, empowering investors with informative insights.
|
||||
|
||||
The incorporation of AI agents into finance is fostering a more responsive and risk-aware financial landscape.
|
||||
|
||||
## 6. Market Trends and Investments
|
||||
The growth of AI agents has attracted significant investment, especially amidst the rising popularity of chatbots and generative AI technologies. Companies and entrepreneurs are eager to explore the potential of these systems, recognizing their ability to streamline operations and improve customer engagement.
|
||||
|
||||
Conversely, corporations like Microsoft are taking strides to integrate AI agents into their product offerings, with enhancements to their Copilot 365 applications. This strategic move emphasizes the importance of AI literacy in the modern workplace and indicates the stabilizing of AI agents as essential business tools.
|
||||
|
||||
## 7. Future Predictions and Implications
|
||||
Experts predict that AI agents will transform essential aspects of work life. As we look toward the future, several anticipated changes include:
|
||||
|
||||
- Enhanced integration of AI agents across all business functions, creating interconnected systems that leverage data from various departmental silos for comprehensive decision-making.
|
||||
- Continued advancement of AI technologies, resulting in smarter, more adaptable agents capable of learning and evolving from user interactions.
|
||||
- Increased regulatory scrutiny to ensure ethical use, especially concerning data privacy and employee surveillance as AI agents become more prevalent.
|
||||
|
||||
To stay competitive and harness the full potential of AI agents, organizations must remain vigilant about latest developments in AI technology and consider continuous learning and adaptation in their strategic planning.
|
||||
|
||||
## 8. Conclusion
|
||||
The emergence of AI agents is undeniably reshaping the workplace landscape in 5. With their ability to automate tasks, enhance efficiency, and improve decision-making, AI agents are critical in driving operational success. Organizations must embrace and adapt to AI developments to thrive in an increasingly digital business environment.
|
||||
## Implicações
|
||||
…
|
||||
```
|
||||
|
||||
</CodeGroup>
|
||||
|
||||
O arquivo real será mais longo e refletirá resultados de busca ao vivo.
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
## Como isso se encaixa
|
||||
|
||||
1. **Flow** — `LatestAiFlow` executa `prepare_topic`, depois `run_research`, depois `summarize`. O estado (`topic`, `report`) fica no Flow.
|
||||
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).
|
||||
|
||||
<Check>
|
||||
Parabéns!
|
||||
|
||||
Você configurou seu projeto de tripulação com sucesso e está pronto para começar a construir seus próprios fluxos de trabalho baseados em agentes!
|
||||
|
||||
Você tem um Flow ponta a ponta com um crew de agente e um relatório salvo — uma base sólida para novas etapas, crews ou ferramentas.
|
||||
</Check>
|
||||
|
||||
### Observação sobre Consistência nos Nomes
|
||||
### Consistência de nomes
|
||||
|
||||
Os nomes utilizados nos seus arquivos YAML (`agents.yaml` e `tasks.yaml`) devem corresponder aos nomes dos métodos no seu código Python.
|
||||
Por exemplo, você pode referenciar o agente para tarefas específicas a partir do arquivo `tasks.yaml`.
|
||||
Essa consistência de nomes permite que a CrewAI conecte automaticamente suas configurações ao seu código; caso contrário, sua tarefa não reconhecerá a referência corretamente.
|
||||
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.
|
||||
|
||||
#### Exemplos de Referências
|
||||
## Implantação
|
||||
|
||||
<Tip>
|
||||
Observe como usamos o mesmo nome para o agente no arquivo `agents.yaml`
|
||||
(`email_summarizer`) e no método do arquivo `crew.py` (`email_summarizer`).
|
||||
</Tip>
|
||||
Envie seu Flow para o **[CrewAI AMP](https://app.crewai.com)** quando rodar localmente e o projeto estiver em um repositório **GitHub**. Na raiz do projeto:
|
||||
|
||||
```yaml agents.yaml
|
||||
email_summarizer:
|
||||
role: >
|
||||
Email Summarizer
|
||||
goal: >
|
||||
Summarize emails into a concise and clear summary
|
||||
backstory: >
|
||||
You will create a 5 bullet point summary of the report
|
||||
llm: provider/model-id # Add your choice of model here
|
||||
<CodeGroup>
|
||||
```bash Autenticar
|
||||
crewai login
|
||||
```
|
||||
|
||||
<Tip>
|
||||
Observe como usamos o mesmo nome para a tarefa no arquivo `tasks.yaml`
|
||||
(`email_summarizer_task`) e no método no arquivo `crew.py`
|
||||
(`email_summarizer_task`).
|
||||
</Tip>
|
||||
|
||||
```yaml tasks.yaml
|
||||
email_summarizer_task:
|
||||
description: >
|
||||
Summarize the email into a 5 bullet point summary
|
||||
expected_output: >
|
||||
A 5 bullet point summary of the email
|
||||
agent: email_summarizer
|
||||
context:
|
||||
- reporting_task
|
||||
- research_task
|
||||
```bash Criar implantação
|
||||
crewai deploy create
|
||||
```
|
||||
|
||||
## Fazendo o Deploy da Sua Tripulação
|
||||
```bash Status e logs
|
||||
crewai deploy status
|
||||
crewai deploy logs
|
||||
```
|
||||
|
||||
A forma mais fácil de fazer deploy da sua tripulação em produção é através da [CrewAI AMP](http://app.crewai.com).
|
||||
```bash Enviar atualizações após mudanças no código
|
||||
crewai deploy push
|
||||
```
|
||||
|
||||
Assista a este vídeo tutorial para uma demonstração detalhada de como fazer deploy da sua tripulação na [CrewAI AMP](http://app.crewai.com) usando a CLI.
|
||||
```bash Listar ou remover implantações
|
||||
crewai deploy list
|
||||
crewai deploy remove <deployment_id>
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
<iframe
|
||||
className="w-full aspect-video rounded-xl"
|
||||
src="https://www.youtube.com/embed/3EqSV-CYDZA"
|
||||
title="CrewAI Deployment Guide"
|
||||
frameBorder="0"
|
||||
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
|
||||
allowFullScreen
|
||||
></iframe>
|
||||
<Tip>
|
||||
A primeira implantação costuma levar **cerca de 1 minuto**. Pré-requisitos completos e fluxo na interface web estão em [Implantar no AMP](/pt-BR/enterprise/guides/deploy-to-amp).
|
||||
</Tip>
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Deploy no Enterprise" icon="rocket" href="http://app.crewai.com">
|
||||
Comece com o CrewAI AMP e faça o deploy da sua tripulação em ambiente de
|
||||
produção com apenas alguns cliques.
|
||||
<Card title="Guia de implantação" icon="book" href="/pt-BR/enterprise/guides/deploy-to-amp">
|
||||
AMP passo a passo (CLI e painel).
|
||||
</Card>
|
||||
<Card
|
||||
title="Junte-se à Comunidade"
|
||||
title="Comunidade"
|
||||
icon="comments"
|
||||
href="https://community.crewai.com"
|
||||
>
|
||||
Participe da nossa comunidade open source para discutir ideias, compartilhar
|
||||
seus projetos e conectar-se com outros desenvolvedores CrewAI.
|
||||
Troque ideias, compartilhe projetos e conecte-se com outros desenvolvedores CrewAI.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
@@ -7,6 +7,10 @@ mode: "wide"
|
||||
|
||||
# `CodeInterpreterTool`
|
||||
|
||||
<Warning>
|
||||
**Depreciado:** O `CodeInterpreterTool` foi removido do `crewai-tools`. Os parâmetros `allow_code_execution` e `code_execution_mode` do `Agent` também estão depreciados. Use um serviço de sandbox dedicado — [E2B](https://e2b.dev) ou [Modal](https://modal.com) — para execução de código segura e isolada.
|
||||
</Warning>
|
||||
|
||||
## Descrição
|
||||
|
||||
O `CodeInterpreterTool` permite que agentes CrewAI executem códigos Python 3 gerados autonomamente. Essa funcionalidade é particularmente valiosa, pois permite que os agentes criem códigos, os executem, obtenham os resultados e usem essas informações para orientar decisões e ações subsequentes.
|
||||
|
||||
@@ -75,4 +75,20 @@ tool = CSVSearchTool(
|
||||
),
|
||||
)
|
||||
)
|
||||
|
||||
## Segurança
|
||||
|
||||
### Validação de Caminhos
|
||||
|
||||
Os caminhos de arquivo fornecidos a esta ferramenta são validados em relação ao diretório de trabalho atual. Caminhos que resolvem fora do diretório de trabalho são rejeitados com um `ValueError`.
|
||||
|
||||
Para permitir caminhos fora do diretório de trabalho (por exemplo, em testes ou pipelines confiáveis), defina a variável de ambiente:
|
||||
|
||||
```shell
|
||||
CREWAI_TOOLS_ALLOW_UNSAFE_PATHS=true
|
||||
```
|
||||
|
||||
### Validação de URLs
|
||||
|
||||
Entradas de URL também são validadas: URIs `file://` e requisições direcionadas a faixas de IP privadas ou reservadas são bloqueadas para prevenir ataques de falsificação de requisições do lado do servidor (SSRF).
|
||||
```
|
||||
@@ -67,4 +67,16 @@ tool = DirectorySearchTool(
|
||||
},
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
## Segurança
|
||||
|
||||
### Validação de Caminhos
|
||||
|
||||
Os caminhos de diretório fornecidos a esta ferramenta são validados em relação ao diretório de trabalho atual. Caminhos que resolvem fora do diretório de trabalho são rejeitados com um `ValueError`.
|
||||
|
||||
Para permitir caminhos fora do diretório de trabalho (por exemplo, em testes ou pipelines confiáveis), defina a variável de ambiente:
|
||||
|
||||
```shell
|
||||
CREWAI_TOOLS_ALLOW_UNSAFE_PATHS=true
|
||||
```
|
||||
@@ -73,4 +73,20 @@ tool = JSONSearchTool(
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
## Segurança
|
||||
|
||||
### Validação de Caminhos
|
||||
|
||||
Os caminhos de arquivo fornecidos a esta ferramenta são validados em relação ao diretório de trabalho atual. Caminhos que resolvem fora do diretório de trabalho são rejeitados com um `ValueError`.
|
||||
|
||||
Para permitir caminhos fora do diretório de trabalho (por exemplo, em testes ou pipelines confiáveis), defina a variável de ambiente:
|
||||
|
||||
```shell
|
||||
CREWAI_TOOLS_ALLOW_UNSAFE_PATHS=true
|
||||
```
|
||||
|
||||
### Validação de URLs
|
||||
|
||||
Entradas de URL também são validadas: URIs `file://` e requisições direcionadas a faixas de IP privadas ou reservadas são bloqueadas para prevenir ataques de falsificação de requisições do lado do servidor (SSRF).
|
||||
```
|
||||
@@ -101,4 +101,20 @@ tool = PDFSearchTool(
|
||||
},
|
||||
}
|
||||
)
|
||||
```
|
||||
```
|
||||
|
||||
## Segurança
|
||||
|
||||
### Validação de Caminhos
|
||||
|
||||
Os caminhos de arquivo fornecidos a esta ferramenta são validados em relação ao diretório de trabalho atual. Caminhos que resolvem fora do diretório de trabalho são rejeitados com um `ValueError`.
|
||||
|
||||
Para permitir caminhos fora do diretório de trabalho (por exemplo, em testes ou pipelines confiáveis), defina a variável de ambiente:
|
||||
|
||||
```shell
|
||||
CREWAI_TOOLS_ALLOW_UNSAFE_PATHS=true
|
||||
```
|
||||
|
||||
### Validação de URLs
|
||||
|
||||
Entradas de URL também são validadas: URIs `file://` e requisições direcionadas a faixas de IP privadas ou reservadas são bloqueadas para prevenir ataques de falsificação de requisições do lado do servidor (SSRF).
|
||||
@@ -152,4 +152,4 @@ __all__ = [
|
||||
"wrap_file_source",
|
||||
]
|
||||
|
||||
__version__ = "1.13.0"
|
||||
__version__ = "1.14.0"
|
||||
|
||||
@@ -10,8 +10,7 @@ requires-python = ">=3.10, <3.14"
|
||||
dependencies = [
|
||||
"pytube~=15.0.0",
|
||||
"requests~=2.32.5",
|
||||
"docker~=7.1.0",
|
||||
"crewai==1.13.0",
|
||||
"crewai==1.14.0",
|
||||
"tiktoken~=0.8.0",
|
||||
"beautifulsoup4~=4.13.4",
|
||||
"python-docx~=1.2.0",
|
||||
|
||||
@@ -35,9 +35,6 @@ from crewai_tools.tools.browserbase_load_tool.browserbase_load_tool import (
|
||||
from crewai_tools.tools.code_docs_search_tool.code_docs_search_tool import (
|
||||
CodeDocsSearchTool,
|
||||
)
|
||||
from crewai_tools.tools.code_interpreter_tool.code_interpreter_tool import (
|
||||
CodeInterpreterTool,
|
||||
)
|
||||
from crewai_tools.tools.composio_tool.composio_tool import ComposioTool
|
||||
from crewai_tools.tools.contextualai_create_agent_tool.contextual_create_agent_tool import (
|
||||
ContextualAICreateAgentTool,
|
||||
@@ -225,7 +222,6 @@ __all__ = [
|
||||
"BrowserbaseLoadTool",
|
||||
"CSVSearchTool",
|
||||
"CodeDocsSearchTool",
|
||||
"CodeInterpreterTool",
|
||||
"ComposioTool",
|
||||
"ContextualAICreateAgentTool",
|
||||
"ContextualAIParseTool",
|
||||
@@ -309,4 +305,4 @@ __all__ = [
|
||||
"ZapierActionTools",
|
||||
]
|
||||
|
||||
__version__ = "1.13.0"
|
||||
__version__ = "1.14.0"
|
||||
|
||||
@@ -109,7 +109,7 @@ class DataTypes:
|
||||
if isinstance(content, str):
|
||||
try:
|
||||
url = urlparse(content)
|
||||
is_url = bool(url.scheme and url.netloc) or url.scheme == "file"
|
||||
is_url = bool(url.scheme in ("http", "https") and url.netloc)
|
||||
except Exception: # noqa: S110
|
||||
pass
|
||||
|
||||
|
||||
205
lib/crewai-tools/src/crewai_tools/security/safe_path.py
Normal file
205
lib/crewai-tools/src/crewai_tools/security/safe_path.py
Normal file
@@ -0,0 +1,205 @@
|
||||
"""Path and URL validation utilities for crewai-tools.
|
||||
|
||||
Provides validation for file paths and URLs to prevent unauthorized
|
||||
file access and server-side request forgery (SSRF) when tools accept
|
||||
user-controlled or LLM-controlled inputs at runtime.
|
||||
|
||||
Set CREWAI_TOOLS_ALLOW_UNSAFE_PATHS=true to bypass validation (not
|
||||
recommended for production).
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import ipaddress
|
||||
import logging
|
||||
import os
|
||||
import socket
|
||||
from urllib.parse import urlparse
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
_UNSAFE_PATHS_ENV = "CREWAI_TOOLS_ALLOW_UNSAFE_PATHS"
|
||||
|
||||
|
||||
def _is_escape_hatch_enabled() -> bool:
|
||||
"""Check if the unsafe paths escape hatch is enabled."""
|
||||
return os.environ.get(_UNSAFE_PATHS_ENV, "").lower() in ("true", "1", "yes")
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# File path validation
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
def validate_file_path(path: str, base_dir: str | None = None) -> str:
|
||||
"""Validate that a file path is safe to read.
|
||||
|
||||
Resolves symlinks and ``..`` components, then checks that the resolved
|
||||
path falls within *base_dir* (defaults to the current working directory).
|
||||
|
||||
Args:
|
||||
path: The file path to validate.
|
||||
base_dir: Allowed root directory. Defaults to ``os.getcwd()``.
|
||||
|
||||
Returns:
|
||||
The resolved, validated absolute path.
|
||||
|
||||
Raises:
|
||||
ValueError: If the path escapes the allowed directory.
|
||||
"""
|
||||
if _is_escape_hatch_enabled():
|
||||
logger.warning(
|
||||
"%s is enabled — skipping file path validation for: %s",
|
||||
_UNSAFE_PATHS_ENV,
|
||||
path,
|
||||
)
|
||||
return os.path.realpath(path)
|
||||
|
||||
if base_dir is None:
|
||||
base_dir = os.getcwd()
|
||||
|
||||
resolved_base = os.path.realpath(base_dir)
|
||||
resolved_path = os.path.realpath(
|
||||
os.path.join(resolved_base, path) if not os.path.isabs(path) else path
|
||||
)
|
||||
|
||||
# Ensure the resolved path is within the base directory.
|
||||
# When resolved_base already ends with a separator (e.g. the filesystem
|
||||
# root "/"), appending os.sep would double it ("//"), so use the base
|
||||
# as-is in that case.
|
||||
prefix = resolved_base if resolved_base.endswith(os.sep) else resolved_base + os.sep
|
||||
if not resolved_path.startswith(prefix) and resolved_path != resolved_base:
|
||||
raise ValueError(
|
||||
f"Path '{path}' resolves to '{resolved_path}' which is outside "
|
||||
f"the allowed directory '{resolved_base}'. "
|
||||
f"Set {_UNSAFE_PATHS_ENV}=true to bypass this check."
|
||||
)
|
||||
|
||||
return resolved_path
|
||||
|
||||
|
||||
def validate_directory_path(path: str, base_dir: str | None = None) -> str:
|
||||
"""Validate that a directory path is safe to read.
|
||||
|
||||
Same as :func:`validate_file_path` but also checks that the path
|
||||
is an existing directory.
|
||||
|
||||
Args:
|
||||
path: The directory path to validate.
|
||||
base_dir: Allowed root directory. Defaults to ``os.getcwd()``.
|
||||
|
||||
Returns:
|
||||
The resolved, validated absolute path.
|
||||
|
||||
Raises:
|
||||
ValueError: If the path escapes the allowed directory or is not a directory.
|
||||
"""
|
||||
validated = validate_file_path(path, base_dir)
|
||||
if not os.path.isdir(validated):
|
||||
raise ValueError(f"Path '{validated}' is not a directory.")
|
||||
return validated
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# URL validation
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
# Private and reserved IP ranges that should not be accessed
|
||||
_BLOCKED_IPV4_NETWORKS = [
|
||||
ipaddress.ip_network("10.0.0.0/8"),
|
||||
ipaddress.ip_network("172.16.0.0/12"),
|
||||
ipaddress.ip_network("192.168.0.0/16"),
|
||||
ipaddress.ip_network("127.0.0.0/8"),
|
||||
ipaddress.ip_network("169.254.0.0/16"), # Link-local / cloud metadata
|
||||
ipaddress.ip_network("0.0.0.0/32"),
|
||||
]
|
||||
|
||||
_BLOCKED_IPV6_NETWORKS = [
|
||||
ipaddress.ip_network("::1/128"),
|
||||
ipaddress.ip_network("::/128"),
|
||||
ipaddress.ip_network("fc00::/7"), # Unique local addresses
|
||||
ipaddress.ip_network("fe80::/10"), # Link-local IPv6
|
||||
]
|
||||
|
||||
|
||||
def _is_private_or_reserved(ip_str: str) -> bool:
|
||||
"""Check if an IP address is private, reserved, or otherwise unsafe."""
|
||||
try:
|
||||
addr = ipaddress.ip_address(ip_str)
|
||||
# Unwrap IPv4-mapped IPv6 addresses (e.g., ::ffff:127.0.0.1) to IPv4
|
||||
# so they are only checked against IPv4 networks (avoids TypeError when
|
||||
# an IPv4Address is compared against an IPv6Network).
|
||||
if isinstance(addr, ipaddress.IPv6Address) and addr.ipv4_mapped:
|
||||
addr = addr.ipv4_mapped
|
||||
networks = (
|
||||
_BLOCKED_IPV4_NETWORKS
|
||||
if isinstance(addr, ipaddress.IPv4Address)
|
||||
else _BLOCKED_IPV6_NETWORKS
|
||||
)
|
||||
return any(addr in network for network in networks)
|
||||
except ValueError:
|
||||
return True # If we can't parse, block it
|
||||
|
||||
|
||||
def validate_url(url: str) -> str:
|
||||
"""Validate that a URL is safe to fetch.
|
||||
|
||||
Blocks ``file://`` scheme entirely. For ``http``/``https``, resolves
|
||||
DNS and checks that the target IP is not private or reserved (prevents
|
||||
SSRF to internal services and cloud metadata endpoints).
|
||||
|
||||
Args:
|
||||
url: The URL to validate.
|
||||
|
||||
Returns:
|
||||
The validated URL string.
|
||||
|
||||
Raises:
|
||||
ValueError: If the URL uses a blocked scheme or resolves to a
|
||||
private/reserved IP address.
|
||||
"""
|
||||
if _is_escape_hatch_enabled():
|
||||
logger.warning(
|
||||
"%s is enabled — skipping URL validation for: %s",
|
||||
_UNSAFE_PATHS_ENV,
|
||||
url,
|
||||
)
|
||||
return url
|
||||
|
||||
parsed = urlparse(url)
|
||||
|
||||
# Block file:// scheme
|
||||
if parsed.scheme == "file":
|
||||
raise ValueError(
|
||||
f"file:// URLs are not allowed: '{url}'. "
|
||||
f"Use a file path instead, or set {_UNSAFE_PATHS_ENV}=true to bypass."
|
||||
)
|
||||
|
||||
# Only allow http and https
|
||||
if parsed.scheme not in ("http", "https"):
|
||||
raise ValueError(
|
||||
f"URL scheme '{parsed.scheme}' is not allowed. Only http and https are supported."
|
||||
)
|
||||
|
||||
if not parsed.hostname:
|
||||
raise ValueError(f"URL has no hostname: '{url}'")
|
||||
|
||||
# Resolve DNS and check IPs
|
||||
try:
|
||||
addrinfos = socket.getaddrinfo(
|
||||
parsed.hostname, parsed.port or (443 if parsed.scheme == "https" else 80)
|
||||
)
|
||||
except socket.gaierror as exc:
|
||||
raise ValueError(f"Could not resolve hostname: '{parsed.hostname}'") from exc
|
||||
|
||||
for _family, _, _, _, sockaddr in addrinfos:
|
||||
ip_str = str(sockaddr[0])
|
||||
if _is_private_or_reserved(ip_str):
|
||||
raise ValueError(
|
||||
f"URL '{url}' resolves to private/reserved IP {ip_str}. "
|
||||
f"Access to internal networks is not allowed. "
|
||||
f"Set {_UNSAFE_PATHS_ENV}=true to bypass."
|
||||
)
|
||||
|
||||
return url
|
||||
@@ -24,9 +24,6 @@ from crewai_tools.tools.browserbase_load_tool.browserbase_load_tool import (
|
||||
from crewai_tools.tools.code_docs_search_tool.code_docs_search_tool import (
|
||||
CodeDocsSearchTool,
|
||||
)
|
||||
from crewai_tools.tools.code_interpreter_tool.code_interpreter_tool import (
|
||||
CodeInterpreterTool,
|
||||
)
|
||||
from crewai_tools.tools.composio_tool.composio_tool import ComposioTool
|
||||
from crewai_tools.tools.contextualai_create_agent_tool.contextual_create_agent_tool import (
|
||||
ContextualAICreateAgentTool,
|
||||
@@ -210,7 +207,6 @@ __all__ = [
|
||||
"BrowserbaseLoadTool",
|
||||
"CSVSearchTool",
|
||||
"CodeDocsSearchTool",
|
||||
"CodeInterpreterTool",
|
||||
"ComposioTool",
|
||||
"ContextualAICreateAgentTool",
|
||||
"ContextualAIParseTool",
|
||||
|
||||
@@ -7,6 +7,8 @@ from crewai.tools import BaseTool, EnvVar
|
||||
from pydantic import BaseModel, Field
|
||||
import requests
|
||||
|
||||
from crewai_tools.security.safe_path import validate_url
|
||||
|
||||
|
||||
class BrightDataConfig(BaseModel):
|
||||
API_URL: str = "https://api.brightdata.com/request"
|
||||
@@ -134,6 +136,7 @@ class BrightDataWebUnlockerTool(BaseTool):
|
||||
"Content-Type": "application/json",
|
||||
}
|
||||
|
||||
validate_url(url)
|
||||
try:
|
||||
response = requests.post(
|
||||
self.base_url, json=payload, headers=headers, timeout=30
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
FROM python:3.12-alpine
|
||||
|
||||
RUN pip install requests beautifulsoup4
|
||||
|
||||
# Set the working directory
|
||||
WORKDIR /workspace
|
||||
@@ -1,95 +0,0 @@
|
||||
# CodeInterpreterTool
|
||||
|
||||
## Description
|
||||
This tool is used to give the Agent the ability to run code (Python3) from the code generated by the Agent itself. The code is executed in a Docker container for secure isolation.
|
||||
|
||||
It is incredibly useful since it allows the Agent to generate code, run it in an isolated environment, get the result and use it to make decisions.
|
||||
|
||||
## ⚠️ Security Requirements
|
||||
|
||||
**Docker is REQUIRED** for safe code execution. The tool will refuse to execute code without Docker to prevent security vulnerabilities.
|
||||
|
||||
### Why Docker is Required
|
||||
|
||||
Previous versions included a "restricted sandbox" fallback when Docker was unavailable. This has been **removed** due to critical security vulnerabilities:
|
||||
|
||||
- The Python-based sandbox could be escaped via object introspection
|
||||
- Attackers could recover the original `__import__` function and access any module
|
||||
- This allowed arbitrary command execution on the host system
|
||||
|
||||
**Docker provides real process isolation** and is the only secure way to execute untrusted code.
|
||||
|
||||
## Requirements
|
||||
|
||||
- **Docker (REQUIRED)** - Install from [docker.com](https://docs.docker.com/get-docker/)
|
||||
|
||||
## Installation
|
||||
Install the crewai_tools package
|
||||
```shell
|
||||
pip install 'crewai[tools]'
|
||||
```
|
||||
|
||||
## Example
|
||||
|
||||
Remember that when using this tool, the code must be generated by the Agent itself. The code must be Python3 code. It will take some time the first time to run because it needs to build the Docker image.
|
||||
|
||||
### Basic Usage (Docker Container - Recommended)
|
||||
|
||||
```python
|
||||
from crewai_tools import CodeInterpreterTool
|
||||
|
||||
Agent(
|
||||
...
|
||||
tools=[CodeInterpreterTool()],
|
||||
)
|
||||
```
|
||||
|
||||
### Custom Dockerfile
|
||||
|
||||
If you need to pass your own Dockerfile:
|
||||
|
||||
```python
|
||||
from crewai_tools import CodeInterpreterTool
|
||||
|
||||
Agent(
|
||||
...
|
||||
tools=[CodeInterpreterTool(user_dockerfile_path="<Dockerfile_path>")],
|
||||
)
|
||||
```
|
||||
|
||||
### Manual Docker Host Configuration
|
||||
|
||||
If it is difficult to connect to the Docker daemon automatically (especially for macOS users), you can set up the Docker host manually:
|
||||
|
||||
```python
|
||||
from crewai_tools import CodeInterpreterTool
|
||||
|
||||
Agent(
|
||||
...
|
||||
tools=[CodeInterpreterTool(
|
||||
user_docker_base_url="<Docker Host Base Url>",
|
||||
user_dockerfile_path="<Dockerfile_path>"
|
||||
)],
|
||||
)
|
||||
```
|
||||
|
||||
### Unsafe Mode (NOT RECOMMENDED)
|
||||
|
||||
If you absolutely cannot use Docker and **fully trust the code source**, you can use unsafe mode:
|
||||
|
||||
```python
|
||||
from crewai_tools import CodeInterpreterTool
|
||||
|
||||
# WARNING: Only use with fully trusted code!
|
||||
Agent(
|
||||
...
|
||||
tools=[CodeInterpreterTool(unsafe_mode=True)],
|
||||
)
|
||||
```
|
||||
|
||||
**⚠️ SECURITY WARNING:** `unsafe_mode=True` executes code directly on the host without any isolation. Only use this if:
|
||||
- You completely trust the code being executed
|
||||
- You understand the security risks
|
||||
- You cannot install Docker in your environment
|
||||
|
||||
For production use, **always use Docker** (the default mode).
|
||||
@@ -1,424 +0,0 @@
|
||||
"""Code Interpreter Tool for executing Python code in isolated environments.
|
||||
|
||||
This module provides a tool for executing Python code either in a Docker container for
|
||||
safe isolation or directly in a restricted sandbox. It includes mechanisms for blocking
|
||||
potentially unsafe operations and importing restricted modules.
|
||||
"""
|
||||
|
||||
import importlib.util
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
from types import ModuleType
|
||||
from typing import Any, ClassVar, TypedDict
|
||||
|
||||
from crewai.tools import BaseTool
|
||||
from docker import ( # type: ignore[import-untyped]
|
||||
DockerClient,
|
||||
from_env as docker_from_env,
|
||||
)
|
||||
from docker.errors import ImageNotFound, NotFound # type: ignore[import-untyped]
|
||||
from pydantic import BaseModel, Field
|
||||
from typing_extensions import Unpack
|
||||
|
||||
from crewai_tools.printer import Printer
|
||||
|
||||
|
||||
class RunKwargs(TypedDict, total=False):
|
||||
"""Keyword arguments for the _run method."""
|
||||
|
||||
code: str
|
||||
libraries_used: list[str]
|
||||
|
||||
|
||||
class CodeInterpreterSchema(BaseModel):
|
||||
"""Schema for defining inputs to the CodeInterpreterTool.
|
||||
|
||||
This schema defines the required parameters for code execution,
|
||||
including the code to run and any libraries that need to be installed.
|
||||
"""
|
||||
|
||||
code: str = Field(
|
||||
...,
|
||||
description="Python3 code used to be interpreted in the Docker container. ALWAYS PRINT the final result and the output of the code",
|
||||
)
|
||||
|
||||
libraries_used: list[str] = Field(
|
||||
...,
|
||||
description="List of libraries used in the code with proper installing names separated by commas. Example: numpy,pandas,beautifulsoup4",
|
||||
)
|
||||
|
||||
|
||||
class SandboxPython:
|
||||
"""INSECURE: A restricted Python execution environment with known vulnerabilities.
|
||||
|
||||
WARNING: This class does NOT provide real security isolation and is vulnerable to
|
||||
sandbox escape attacks via Python object introspection. Attackers can recover the
|
||||
original __import__ function and bypass all restrictions.
|
||||
|
||||
DO NOT USE for untrusted code execution. Use Docker containers instead.
|
||||
|
||||
This class attempts to restrict access to dangerous modules and built-in functions
|
||||
but provides no real security boundary against a motivated attacker.
|
||||
"""
|
||||
|
||||
BLOCKED_MODULES: ClassVar[set[str]] = {
|
||||
"os",
|
||||
"sys",
|
||||
"subprocess",
|
||||
"shutil",
|
||||
"importlib",
|
||||
"inspect",
|
||||
"tempfile",
|
||||
"sysconfig",
|
||||
"builtins",
|
||||
}
|
||||
|
||||
UNSAFE_BUILTINS: ClassVar[set[str]] = {
|
||||
"exec",
|
||||
"eval",
|
||||
"open",
|
||||
"compile",
|
||||
"input",
|
||||
"globals",
|
||||
"locals",
|
||||
"vars",
|
||||
"help",
|
||||
"dir",
|
||||
}
|
||||
|
||||
@staticmethod
|
||||
def restricted_import(
|
||||
name: str,
|
||||
custom_globals: dict[str, Any] | None = None,
|
||||
custom_locals: dict[str, Any] | None = None,
|
||||
fromlist: list[str] | None = None,
|
||||
level: int = 0,
|
||||
) -> ModuleType:
|
||||
"""A restricted import function that blocks importing of unsafe modules.
|
||||
|
||||
Args:
|
||||
name: The name of the module to import.
|
||||
custom_globals: Global namespace to use.
|
||||
custom_locals: Local namespace to use.
|
||||
fromlist: List of items to import from the module.
|
||||
level: The level value passed to __import__.
|
||||
|
||||
Returns:
|
||||
The imported module if allowed.
|
||||
|
||||
Raises:
|
||||
ImportError: If the module is in the blocked modules list.
|
||||
"""
|
||||
if name in SandboxPython.BLOCKED_MODULES:
|
||||
raise ImportError(f"Importing '{name}' is not allowed.")
|
||||
return __import__(name, custom_globals, custom_locals, fromlist or (), level)
|
||||
|
||||
@staticmethod
|
||||
def safe_builtins() -> dict[str, Any]:
|
||||
"""Creates a dictionary of built-in functions with unsafe ones removed.
|
||||
|
||||
Returns:
|
||||
A dictionary of safe built-in functions and objects.
|
||||
"""
|
||||
import builtins
|
||||
|
||||
safe_builtins = {
|
||||
k: v
|
||||
for k, v in builtins.__dict__.items()
|
||||
if k not in SandboxPython.UNSAFE_BUILTINS
|
||||
}
|
||||
safe_builtins["__import__"] = SandboxPython.restricted_import
|
||||
return safe_builtins
|
||||
|
||||
@staticmethod
|
||||
def exec(code: str, locals_: dict[str, Any]) -> None:
|
||||
"""Executes Python code in a restricted environment.
|
||||
|
||||
Args:
|
||||
code: The Python code to execute as a string.
|
||||
locals_: A dictionary that will be used for local variable storage.
|
||||
"""
|
||||
exec(code, {"__builtins__": SandboxPython.safe_builtins()}, locals_) # noqa: S102
|
||||
|
||||
|
||||
class CodeInterpreterTool(BaseTool):
|
||||
"""A tool for executing Python code in isolated environments.
|
||||
|
||||
This tool provides functionality to run Python code either in a Docker container
|
||||
for safe isolation or directly in a restricted sandbox. It can handle installing
|
||||
Python packages and executing arbitrary Python code.
|
||||
"""
|
||||
|
||||
name: str = "Code Interpreter"
|
||||
description: str = "Interprets Python3 code strings with a final print statement."
|
||||
args_schema: type[BaseModel] = CodeInterpreterSchema
|
||||
default_image_tag: str = "code-interpreter:latest"
|
||||
code: str | None = None
|
||||
user_dockerfile_path: str | None = None
|
||||
user_docker_base_url: str | None = None
|
||||
unsafe_mode: bool = False
|
||||
|
||||
@staticmethod
|
||||
def _get_installed_package_path() -> str:
|
||||
"""Gets the installation path of the crewai_tools package.
|
||||
|
||||
Returns:
|
||||
The directory path where the package is installed.
|
||||
|
||||
Raises:
|
||||
RuntimeError: If the package cannot be found.
|
||||
"""
|
||||
spec = importlib.util.find_spec("crewai_tools")
|
||||
if spec is None or spec.origin is None:
|
||||
raise RuntimeError("Cannot find crewai_tools package installation path")
|
||||
return os.path.dirname(spec.origin)
|
||||
|
||||
def _verify_docker_image(self) -> None:
|
||||
"""Verifies if the Docker image is available or builds it if necessary.
|
||||
|
||||
Checks if the required Docker image exists. If not, builds it using either a
|
||||
user-provided Dockerfile or the default one included with the package.
|
||||
|
||||
Raises:
|
||||
FileNotFoundError: If the Dockerfile cannot be found.
|
||||
"""
|
||||
client = (
|
||||
docker_from_env()
|
||||
if self.user_docker_base_url is None
|
||||
else DockerClient(base_url=self.user_docker_base_url)
|
||||
)
|
||||
|
||||
try:
|
||||
client.images.get(self.default_image_tag)
|
||||
|
||||
except ImageNotFound:
|
||||
if self.user_dockerfile_path and os.path.exists(self.user_dockerfile_path):
|
||||
dockerfile_path = self.user_dockerfile_path
|
||||
else:
|
||||
package_path = self._get_installed_package_path()
|
||||
dockerfile_path = os.path.join(
|
||||
package_path, "tools/code_interpreter_tool"
|
||||
)
|
||||
if not os.path.exists(dockerfile_path):
|
||||
raise FileNotFoundError(
|
||||
f"Dockerfile not found in {dockerfile_path}"
|
||||
) from None
|
||||
|
||||
client.images.build(
|
||||
path=dockerfile_path,
|
||||
tag=self.default_image_tag,
|
||||
rm=True,
|
||||
)
|
||||
|
||||
def _run(self, **kwargs: Unpack[RunKwargs]) -> str:
|
||||
"""Runs the code interpreter tool with the provided arguments.
|
||||
|
||||
Args:
|
||||
**kwargs: Keyword arguments that should include 'code' and 'libraries_used'.
|
||||
|
||||
Returns:
|
||||
The output of the executed code as a string.
|
||||
"""
|
||||
code: str | None = kwargs.get("code", self.code)
|
||||
libraries_used: list[str] = kwargs.get("libraries_used", [])
|
||||
|
||||
if not code:
|
||||
return "No code provided to execute."
|
||||
|
||||
if self.unsafe_mode:
|
||||
return self.run_code_unsafe(code, libraries_used)
|
||||
return self.run_code_safety(code, libraries_used)
|
||||
|
||||
@staticmethod
|
||||
def _install_libraries(container: Any, libraries: list[str]) -> None:
|
||||
"""Installs required Python libraries in the Docker container.
|
||||
|
||||
Args:
|
||||
container: The Docker container where libraries will be installed.
|
||||
libraries: A list of library names to install using pip.
|
||||
"""
|
||||
for library in libraries:
|
||||
container.exec_run(["pip", "install", library])
|
||||
|
||||
def _init_docker_container(self) -> Any:
|
||||
"""Initializes and returns a Docker container for code execution.
|
||||
|
||||
Stops and removes any existing container with the same name before creating
|
||||
a new one. Maps the current working directory to /workspace in the container.
|
||||
|
||||
Returns:
|
||||
A Docker container object ready for code execution.
|
||||
"""
|
||||
container_name = "code-interpreter"
|
||||
client = docker_from_env()
|
||||
current_path = os.getcwd()
|
||||
|
||||
# Check if the container is already running
|
||||
try:
|
||||
existing_container = client.containers.get(container_name)
|
||||
existing_container.stop()
|
||||
existing_container.remove()
|
||||
except NotFound:
|
||||
pass # Container does not exist, no need to remove
|
||||
|
||||
return client.containers.run(
|
||||
self.default_image_tag,
|
||||
detach=True,
|
||||
tty=True,
|
||||
working_dir="/workspace",
|
||||
name=container_name,
|
||||
volumes={current_path: {"bind": "/workspace", "mode": "rw"}},
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def _check_docker_available() -> bool:
|
||||
"""Checks if Docker is available and running on the system.
|
||||
|
||||
Attempts to run the 'docker info' command to verify Docker availability.
|
||||
Prints appropriate messages if Docker is not installed or not running.
|
||||
|
||||
Returns:
|
||||
True if Docker is available and running, False otherwise.
|
||||
"""
|
||||
|
||||
try:
|
||||
subprocess.run(
|
||||
["docker", "info"], # noqa: S607
|
||||
check=True,
|
||||
stdout=subprocess.DEVNULL,
|
||||
stderr=subprocess.DEVNULL,
|
||||
timeout=1,
|
||||
)
|
||||
return True
|
||||
except (subprocess.CalledProcessError, subprocess.TimeoutExpired):
|
||||
Printer.print(
|
||||
"Docker is installed but not running or inaccessible.",
|
||||
color="bold_purple",
|
||||
)
|
||||
return False
|
||||
except FileNotFoundError:
|
||||
Printer.print("Docker is not installed", color="bold_purple")
|
||||
return False
|
||||
|
||||
def run_code_safety(self, code: str, libraries_used: list[str]) -> str:
|
||||
"""Runs code in the safest available environment.
|
||||
|
||||
Requires Docker to be available for secure code execution. Fails closed
|
||||
if Docker is not available to prevent sandbox escape vulnerabilities.
|
||||
|
||||
Args:
|
||||
code: The Python code to execute as a string.
|
||||
libraries_used: A list of Python library names to install before execution.
|
||||
|
||||
Returns:
|
||||
The output of the executed code as a string.
|
||||
|
||||
Raises:
|
||||
RuntimeError: If Docker is not available, as the restricted sandbox
|
||||
is vulnerable to escape attacks and should not be used
|
||||
for untrusted code execution.
|
||||
"""
|
||||
if self._check_docker_available():
|
||||
return self.run_code_in_docker(code, libraries_used)
|
||||
|
||||
error_msg = (
|
||||
"Docker is required for safe code execution but is not available. "
|
||||
"The restricted sandbox fallback has been removed due to security vulnerabilities "
|
||||
"that allow sandbox escape via Python object introspection. "
|
||||
"Please install Docker (https://docs.docker.com/get-docker/) or use unsafe_mode=True "
|
||||
"if you trust the code source and understand the security risks."
|
||||
)
|
||||
Printer.print(error_msg, color="bold_red")
|
||||
raise RuntimeError(error_msg)
|
||||
|
||||
def run_code_in_docker(self, code: str, libraries_used: list[str]) -> str:
|
||||
"""Runs Python code in a Docker container for safe isolation.
|
||||
|
||||
Creates a Docker container, installs the required libraries, executes the code,
|
||||
and then cleans up by stopping and removing the container.
|
||||
|
||||
Args:
|
||||
code: The Python code to execute as a string.
|
||||
libraries_used: A list of Python library names to install before execution.
|
||||
|
||||
Returns:
|
||||
The output of the executed code as a string, or an error message if execution failed.
|
||||
"""
|
||||
Printer.print("Running code in Docker environment", color="bold_blue")
|
||||
self._verify_docker_image()
|
||||
container = self._init_docker_container()
|
||||
self._install_libraries(container, libraries_used)
|
||||
|
||||
exec_result: Any = container.exec_run(["python3", "-c", code])
|
||||
|
||||
container.stop()
|
||||
container.remove()
|
||||
|
||||
if exec_result.exit_code != 0:
|
||||
return f"Something went wrong while running the code: \n{exec_result.output.decode('utf-8')}"
|
||||
return str(exec_result.output.decode("utf-8"))
|
||||
|
||||
@staticmethod
|
||||
def run_code_in_restricted_sandbox(code: str) -> str:
|
||||
"""DEPRECATED AND INSECURE: Runs Python code in a restricted sandbox environment.
|
||||
|
||||
WARNING: This method is vulnerable to sandbox escape attacks via Python object
|
||||
introspection and should NOT be used for untrusted code execution. It has been
|
||||
deprecated and is only kept for backward compatibility with trusted code.
|
||||
|
||||
The "restricted" environment can be bypassed by attackers who can:
|
||||
- Use object graph introspection to recover the original __import__ function
|
||||
- Access any Python module including os, subprocess, sys, etc.
|
||||
- Execute arbitrary commands on the host system
|
||||
|
||||
Use run_code_in_docker() for secure code execution, or run_code_unsafe()
|
||||
if you explicitly acknowledge the security risks.
|
||||
|
||||
Args:
|
||||
code: The Python code to execute as a string.
|
||||
|
||||
Returns:
|
||||
The value of the 'result' variable from the executed code,
|
||||
or an error message if execution failed.
|
||||
"""
|
||||
Printer.print(
|
||||
"WARNING: Running code in INSECURE restricted sandbox (vulnerable to escape attacks)",
|
||||
color="bold_red",
|
||||
)
|
||||
exec_locals: dict[str, Any] = {}
|
||||
try:
|
||||
SandboxPython.exec(code=code, locals_=exec_locals)
|
||||
return exec_locals.get("result", "No result variable found.") # type: ignore[no-any-return]
|
||||
except Exception as e:
|
||||
return f"An error occurred: {e!s}"
|
||||
|
||||
@staticmethod
|
||||
def run_code_unsafe(code: str, libraries_used: list[str]) -> str:
|
||||
"""Runs code directly on the host machine without any safety restrictions.
|
||||
|
||||
WARNING: This mode is unsafe and should only be used in trusted environments
|
||||
with code from trusted sources.
|
||||
|
||||
Args:
|
||||
code: The Python code to execute as a string.
|
||||
libraries_used: A list of Python library names to install before execution.
|
||||
|
||||
Returns:
|
||||
The value of the 'result' variable from the executed code,
|
||||
or an error message if execution failed.
|
||||
"""
|
||||
Printer.print("WARNING: Running code in unsafe mode", color="bold_magenta")
|
||||
# Install libraries on the host machine
|
||||
for library in libraries_used:
|
||||
subprocess.run( # noqa: S603
|
||||
[sys.executable, "-m", "pip", "install", library], check=False
|
||||
)
|
||||
|
||||
# Execute the code
|
||||
try:
|
||||
exec_locals: dict[str, Any] = {}
|
||||
exec(code, {}, exec_locals) # noqa: S102
|
||||
return exec_locals.get("result", "No result variable found.") # type: ignore[no-any-return]
|
||||
except Exception as e:
|
||||
return f"An error occurred: {e!s}"
|
||||
@@ -3,6 +3,8 @@ from typing import Any
|
||||
from crewai.tools import BaseTool
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
from crewai_tools.security.safe_path import validate_file_path
|
||||
|
||||
|
||||
class ContextualAICreateAgentSchema(BaseModel):
|
||||
"""Schema for contextual create agent tool."""
|
||||
@@ -47,6 +49,7 @@ class ContextualAICreateAgentTool(BaseTool):
|
||||
document_paths: list[str],
|
||||
) -> str:
|
||||
"""Create a complete RAG pipeline with documents."""
|
||||
resolved_paths = [validate_file_path(doc_path) for doc_path in document_paths]
|
||||
try:
|
||||
import os
|
||||
|
||||
@@ -56,7 +59,7 @@ class ContextualAICreateAgentTool(BaseTool):
|
||||
|
||||
# Upload documents
|
||||
document_ids = []
|
||||
for doc_path in document_paths:
|
||||
for doc_path in resolved_paths:
|
||||
if not os.path.exists(doc_path):
|
||||
raise FileNotFoundError(f"Document not found: {doc_path}")
|
||||
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
from crewai.tools import BaseTool
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
from crewai_tools.security.safe_path import validate_file_path
|
||||
|
||||
|
||||
class ContextualAIParseSchema(BaseModel):
|
||||
"""Schema for contextual parse tool."""
|
||||
@@ -45,6 +47,7 @@ class ContextualAIParseTool(BaseTool):
|
||||
"""Parse a document using Contextual AI's parser."""
|
||||
if output_types is None:
|
||||
output_types = ["markdown-per-page"]
|
||||
file_path = validate_file_path(file_path)
|
||||
try:
|
||||
import json
|
||||
import os
|
||||
|
||||
@@ -4,6 +4,8 @@ from typing import Any
|
||||
from crewai.tools import BaseTool
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
from crewai_tools.security.safe_path import validate_directory_path
|
||||
|
||||
|
||||
class FixedDirectoryReadToolSchema(BaseModel):
|
||||
"""Input for DirectoryReadTool."""
|
||||
@@ -39,6 +41,7 @@ class DirectoryReadTool(BaseTool):
|
||||
if directory is None:
|
||||
raise ValueError("Directory must be provided.")
|
||||
|
||||
directory = validate_directory_path(directory)
|
||||
if directory[-1] == "/":
|
||||
directory = directory[:-1]
|
||||
files_list = [
|
||||
|
||||
@@ -3,6 +3,7 @@ from typing import Any
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
from crewai_tools.rag.data_types import DataType
|
||||
from crewai_tools.security.safe_path import validate_directory_path
|
||||
from crewai_tools.tools.rag.rag_tool import RagTool
|
||||
|
||||
|
||||
@@ -37,6 +38,7 @@ class DirectorySearchTool(RagTool):
|
||||
self._generate_description()
|
||||
|
||||
def add(self, directory: str) -> None: # type: ignore[override]
|
||||
directory = validate_directory_path(directory)
|
||||
super().add(directory, data_type=DataType.DIRECTORY)
|
||||
|
||||
def _run( # type: ignore[override]
|
||||
|
||||
@@ -3,6 +3,8 @@ from typing import Any
|
||||
from crewai.tools import BaseTool
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
from crewai_tools.security.safe_path import validate_file_path
|
||||
|
||||
|
||||
class FileReadToolSchema(BaseModel):
|
||||
"""Input for FileReadTool."""
|
||||
@@ -76,6 +78,7 @@ class FileReadTool(BaseTool):
|
||||
if file_path is None:
|
||||
return "Error: No file path provided. Please provide a file path either in the constructor or as an argument."
|
||||
|
||||
file_path = validate_file_path(file_path)
|
||||
try:
|
||||
with open(file_path, "r") as file:
|
||||
if start_line == 1 and line_count is None:
|
||||
|
||||
@@ -5,6 +5,8 @@ import zipfile
|
||||
from crewai.tools import BaseTool
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
from crewai_tools.security.safe_path import validate_file_path
|
||||
|
||||
|
||||
class FileCompressorToolInput(BaseModel):
|
||||
"""Input schema for FileCompressorTool."""
|
||||
@@ -40,12 +42,15 @@ class FileCompressorTool(BaseTool):
|
||||
overwrite: bool = False,
|
||||
format: str = "zip",
|
||||
) -> str:
|
||||
input_path = validate_file_path(input_path)
|
||||
if not os.path.exists(input_path):
|
||||
return f"Input path '{input_path}' does not exist."
|
||||
|
||||
if not output_path:
|
||||
output_path = self._generate_output_path(input_path, format)
|
||||
|
||||
output_path = validate_file_path(output_path)
|
||||
|
||||
format_extension = {
|
||||
"zip": ".zip",
|
||||
"tar": ".tar",
|
||||
|
||||
@@ -5,6 +5,8 @@ from typing import Any
|
||||
from crewai.tools import BaseTool, EnvVar
|
||||
from pydantic import BaseModel, ConfigDict, Field, PrivateAttr
|
||||
|
||||
from crewai_tools.security.safe_path import validate_url
|
||||
|
||||
|
||||
try:
|
||||
from firecrawl import FirecrawlApp # type: ignore[import-untyped]
|
||||
@@ -106,6 +108,7 @@ class FirecrawlCrawlWebsiteTool(BaseTool):
|
||||
if not self._firecrawl:
|
||||
raise RuntimeError("FirecrawlApp not properly initialized")
|
||||
|
||||
url = validate_url(url)
|
||||
return self._firecrawl.crawl(url=url, poll_interval=2, **self.config)
|
||||
|
||||
|
||||
|
||||
@@ -5,6 +5,8 @@ from typing import Any
|
||||
from crewai.tools import BaseTool, EnvVar
|
||||
from pydantic import BaseModel, ConfigDict, Field, PrivateAttr
|
||||
|
||||
from crewai_tools.security.safe_path import validate_url
|
||||
|
||||
|
||||
try:
|
||||
from firecrawl import FirecrawlApp # type: ignore[import-untyped]
|
||||
@@ -106,6 +108,7 @@ class FirecrawlScrapeWebsiteTool(BaseTool):
|
||||
if not self._firecrawl:
|
||||
raise RuntimeError("FirecrawlApp not properly initialized")
|
||||
|
||||
url = validate_url(url)
|
||||
return self._firecrawl.scrape(url=url, **self.config)
|
||||
|
||||
|
||||
|
||||
@@ -4,6 +4,8 @@ from typing import Any, Literal
|
||||
from crewai.tools import BaseTool, EnvVar
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
from crewai_tools.security.safe_path import validate_url
|
||||
|
||||
|
||||
class HyperbrowserLoadToolSchema(BaseModel):
|
||||
url: str = Field(description="Website URL")
|
||||
@@ -119,6 +121,7 @@ class HyperbrowserLoadTool(BaseTool):
|
||||
) from e
|
||||
|
||||
params = self._prepare_params(params)
|
||||
url = validate_url(url)
|
||||
|
||||
if operation == "scrape":
|
||||
scrape_params = StartScrapeJobParams(url=url, **params)
|
||||
|
||||
@@ -4,6 +4,8 @@ from crewai.tools import BaseTool
|
||||
from pydantic import BaseModel, Field
|
||||
import requests
|
||||
|
||||
from crewai_tools.security.safe_path import validate_url
|
||||
|
||||
|
||||
class JinaScrapeWebsiteToolInput(BaseModel):
|
||||
"""Input schema for JinaScrapeWebsiteTool."""
|
||||
@@ -45,6 +47,7 @@ class JinaScrapeWebsiteTool(BaseTool):
|
||||
"Website URL must be provided either during initialization or execution"
|
||||
)
|
||||
|
||||
url = validate_url(url)
|
||||
response = requests.get(
|
||||
f"https://r.jina.ai/{url}", headers=self.headers, timeout=15
|
||||
)
|
||||
|
||||
@@ -11,6 +11,8 @@ from crewai.tools.base_tool import BaseTool
|
||||
from crewai.utilities.types import LLMMessage
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
from crewai_tools.security.safe_path import validate_file_path
|
||||
|
||||
|
||||
class OCRToolSchema(BaseModel):
|
||||
"""Input schema for Optical Character Recognition Tool.
|
||||
@@ -98,5 +100,6 @@ class OCRTool(BaseTool):
|
||||
Returns:
|
||||
str: Base64-encoded image data as a UTF-8 string.
|
||||
"""
|
||||
image_path = validate_file_path(image_path)
|
||||
with open(image_path, "rb") as image_file:
|
||||
return base64.b64encode(image_file.read()).decode()
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
from abc import ABC, abstractmethod
|
||||
import os
|
||||
from typing import Any, Literal, cast
|
||||
|
||||
from crewai.rag.core.base_embeddings_callable import EmbeddingFunction
|
||||
@@ -246,7 +247,94 @@ class RagTool(BaseTool):
|
||||
# Auto-detect type from extension
|
||||
rag_tool.add("path/to/document.pdf") # auto-detects PDF
|
||||
"""
|
||||
self.adapter.add(*args, **kwargs)
|
||||
# Validate file paths and URLs before adding to prevent
|
||||
# unauthorized file reads and SSRF.
|
||||
from urllib.parse import urlparse
|
||||
|
||||
from crewai_tools.security.safe_path import validate_file_path, validate_url
|
||||
|
||||
def _check_url(value: str, label: str) -> None:
|
||||
try:
|
||||
validate_url(value)
|
||||
except ValueError as e:
|
||||
raise ValueError(f"Blocked unsafe {label}: {e}") from e
|
||||
|
||||
def _check_path(value: str, label: str) -> str:
|
||||
try:
|
||||
return validate_file_path(value)
|
||||
except ValueError as e:
|
||||
raise ValueError(f"Blocked unsafe {label}: {e}") from e
|
||||
|
||||
validated_args: list[ContentItem] = []
|
||||
for arg in args:
|
||||
source_ref = (
|
||||
str(arg.get("source", arg.get("content", "")))
|
||||
if isinstance(arg, dict)
|
||||
else str(arg)
|
||||
)
|
||||
|
||||
# Check if it's a URL — only catch urlparse-specific errors here;
|
||||
# validate_url's ValueError must propagate so it is never silently bypassed.
|
||||
try:
|
||||
parsed = urlparse(source_ref)
|
||||
except (ValueError, AttributeError):
|
||||
parsed = None
|
||||
|
||||
if parsed is not None and parsed.scheme in ("http", "https", "file"):
|
||||
try:
|
||||
validate_url(source_ref)
|
||||
except ValueError as e:
|
||||
raise ValueError(f"Blocked unsafe URL: {e}") from e
|
||||
validated_args.append(arg)
|
||||
continue
|
||||
|
||||
# Check if it looks like a file path (not a plain text string).
|
||||
# Check both os.sep (backslash on Windows) and "/" so that
|
||||
# forward-slash paths like "sub/file.txt" are caught on all platforms.
|
||||
if (
|
||||
os.path.sep in source_ref
|
||||
or "/" in source_ref
|
||||
or source_ref.startswith(".")
|
||||
or os.path.isabs(source_ref)
|
||||
):
|
||||
try:
|
||||
resolved_ref = validate_file_path(source_ref)
|
||||
except ValueError as e:
|
||||
raise ValueError(f"Blocked unsafe file path: {e}") from e
|
||||
# Use the resolved path to prevent symlink TOCTOU
|
||||
if isinstance(arg, dict):
|
||||
arg = {**arg}
|
||||
if "source" in arg:
|
||||
arg["source"] = resolved_ref
|
||||
elif "content" in arg:
|
||||
arg["content"] = resolved_ref
|
||||
else:
|
||||
arg = resolved_ref
|
||||
|
||||
validated_args.append(arg)
|
||||
|
||||
# Validate keyword path/URL arguments — these are equally user-controlled
|
||||
# and must not bypass the checks applied to positional args.
|
||||
if "path" in kwargs and kwargs.get("path") is not None:
|
||||
kwargs["path"] = _check_path(str(kwargs["path"]), "path")
|
||||
if "file_path" in kwargs and kwargs.get("file_path") is not None:
|
||||
kwargs["file_path"] = _check_path(str(kwargs["file_path"]), "file_path")
|
||||
|
||||
if "directory_path" in kwargs and kwargs.get("directory_path") is not None:
|
||||
kwargs["directory_path"] = _check_path(
|
||||
str(kwargs["directory_path"]), "directory_path"
|
||||
)
|
||||
|
||||
if "url" in kwargs and kwargs.get("url") is not None:
|
||||
_check_url(str(kwargs["url"]), "url")
|
||||
if "website" in kwargs and kwargs.get("website") is not None:
|
||||
_check_url(str(kwargs["website"]), "website")
|
||||
if "github_url" in kwargs and kwargs.get("github_url") is not None:
|
||||
_check_url(str(kwargs["github_url"]), "github_url")
|
||||
if "youtube_url" in kwargs and kwargs.get("youtube_url") is not None:
|
||||
_check_url(str(kwargs["youtube_url"]), "youtube_url")
|
||||
|
||||
self.adapter.add(*validated_args, **kwargs)
|
||||
|
||||
def _run(
|
||||
self,
|
||||
|
||||
@@ -5,6 +5,8 @@ from crewai.tools import BaseTool
|
||||
from pydantic import BaseModel, Field
|
||||
import requests
|
||||
|
||||
from crewai_tools.security.safe_path import validate_url
|
||||
|
||||
|
||||
try:
|
||||
from bs4 import BeautifulSoup
|
||||
@@ -81,6 +83,7 @@ class ScrapeElementFromWebsiteTool(BaseTool):
|
||||
if website_url is None or css_element is None:
|
||||
raise ValueError("Both website_url and css_element must be provided.")
|
||||
|
||||
website_url = validate_url(website_url)
|
||||
page = requests.get(
|
||||
website_url,
|
||||
headers=self.headers,
|
||||
|
||||
@@ -5,6 +5,8 @@ from typing import Any
|
||||
from pydantic import Field
|
||||
import requests
|
||||
|
||||
from crewai_tools.security.safe_path import validate_url
|
||||
|
||||
|
||||
try:
|
||||
from bs4 import BeautifulSoup
|
||||
@@ -73,6 +75,7 @@ class ScrapeWebsiteTool(BaseTool):
|
||||
if website_url is None:
|
||||
raise ValueError("Website URL must be provided.")
|
||||
|
||||
website_url = validate_url(website_url)
|
||||
page = requests.get(
|
||||
website_url,
|
||||
timeout=15,
|
||||
|
||||
@@ -5,6 +5,8 @@ from typing import Any, Literal
|
||||
from crewai.tools import BaseTool, EnvVar
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
from crewai_tools.security.safe_path import validate_url
|
||||
|
||||
|
||||
logger = logging.getLogger(__file__)
|
||||
|
||||
@@ -72,6 +74,7 @@ class ScrapflyScrapeWebsiteTool(BaseTool):
|
||||
) -> str | None:
|
||||
from scrapfly import ScrapeConfig
|
||||
|
||||
url = validate_url(url)
|
||||
scrape_config = scrape_config if scrape_config is not None else {}
|
||||
try:
|
||||
response = self.scrapfly.scrape( # type: ignore[union-attr]
|
||||
|
||||
@@ -5,6 +5,8 @@ from crewai.tools import BaseTool, EnvVar
|
||||
from pydantic import BaseModel, Field
|
||||
import requests
|
||||
|
||||
from crewai_tools.security.safe_path import validate_url
|
||||
|
||||
|
||||
class SerperScrapeWebsiteInput(BaseModel):
|
||||
"""Input schema for SerperScrapeWebsite."""
|
||||
@@ -42,6 +44,7 @@ class SerperScrapeWebsiteTool(BaseTool):
|
||||
Returns:
|
||||
Scraped website content as a string
|
||||
"""
|
||||
validate_url(url)
|
||||
try:
|
||||
# Serper API endpoint
|
||||
api_url = "https://scrape.serper.dev"
|
||||
|
||||
@@ -5,6 +5,7 @@ from crewai.tools import EnvVar
|
||||
from pydantic import BaseModel, Field
|
||||
import requests
|
||||
|
||||
from crewai_tools.security.safe_path import validate_url
|
||||
from crewai_tools.tools.rag.rag_tool import RagTool
|
||||
|
||||
|
||||
@@ -48,6 +49,7 @@ class SerplyWebpageToMarkdownTool(RagTool):
|
||||
if self.proxy_location and not self.headers.get("X-Proxy-Location"):
|
||||
self.headers["X-Proxy-Location"] = self.proxy_location
|
||||
|
||||
validate_url(url)
|
||||
data = {"url": url, "method": "GET", "response_type": "markdown"}
|
||||
response = requests.request(
|
||||
"POST",
|
||||
|
||||
@@ -7,6 +7,8 @@ from crewai.tools import BaseTool, EnvVar
|
||||
from crewai.utilities.types import LLMMessage
|
||||
from pydantic import BaseModel, Field, PrivateAttr, field_validator
|
||||
|
||||
from crewai_tools.security.safe_path import validate_file_path
|
||||
|
||||
|
||||
class ImagePromptSchema(BaseModel):
|
||||
"""Input for Vision Tool."""
|
||||
@@ -135,5 +137,6 @@ class VisionTool(BaseTool):
|
||||
Returns:
|
||||
Base64-encoded image data
|
||||
"""
|
||||
image_path = validate_file_path(image_path)
|
||||
with open(image_path, "rb") as image_file:
|
||||
return base64.b64encode(image_file.read()).decode()
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user