Compare commits
105 Commits
devin/1779
...
flow-scrip
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
386a1650da | ||
|
|
7bb9bc7e1a | ||
|
|
ee4f853270 | ||
|
|
ebbc0998ef | ||
|
|
06ada68083 | ||
|
|
4eb90ffbf3 | ||
|
|
a6cf52ec7e | ||
|
|
9d44d0a5e5 | ||
|
|
e9d568dc69 | ||
|
|
fe2c236601 | ||
|
|
53c2284484 | ||
|
|
a5cc6f6d0e | ||
|
|
bb477f8a91 | ||
|
|
d80719df81 | ||
|
|
6ad821b157 | ||
|
|
2444895ca4 | ||
|
|
bf291a7a55 | ||
|
|
64438cba37 | ||
|
|
887adafd2c | ||
|
|
d3fc0d31f8 | ||
|
|
373dca3d04 | ||
|
|
21fa8e32d9 | ||
|
|
f18c03cd8f | ||
|
|
50b9c02272 | ||
|
|
c55334be5f | ||
|
|
05a2ba9ca4 | ||
|
|
fbafe1f0d3 | ||
|
|
5267c059f5 | ||
|
|
243c9edc1c | ||
|
|
68910b70c0 | ||
|
|
299782765c | ||
|
|
a1f44eb272 | ||
|
|
036b032ab6 | ||
|
|
f88ae54f96 | ||
|
|
b6e5d632c1 | ||
|
|
0d971e5bc5 | ||
|
|
b3f175b56f | ||
|
|
f523a7d029 | ||
|
|
f214ff4b7b | ||
|
|
a9e7c3a44f | ||
|
|
da8fe8c715 | ||
|
|
ce42994ae3 | ||
|
|
820c3905e3 | ||
|
|
703ffe67ee | ||
|
|
8919026326 | ||
|
|
988927006c | ||
|
|
48c1987fcf | ||
|
|
af62b7b583 | ||
|
|
1b14e162e9 | ||
|
|
e570534f15 | ||
|
|
913a3abead | ||
|
|
17cfbdf95f | ||
|
|
8cd51fc67e | ||
|
|
3723f0db76 | ||
|
|
cab3319af9 | ||
|
|
906cd9769d | ||
|
|
14ce97d787 | ||
|
|
f3a15a4f07 | ||
|
|
75dad212a2 | ||
|
|
aed69237d4 | ||
|
|
051fa0c1cb | ||
|
|
73d20fb0c3 | ||
|
|
d09e3f4544 | ||
|
|
1357491f0d | ||
|
|
ea88904d35 | ||
|
|
be3cf62b63 | ||
|
|
68cdd44520 | ||
|
|
7676b0937c | ||
|
|
ee707028db | ||
|
|
770d1b284f | ||
|
|
b047c96756 | ||
|
|
d37af0d404 | ||
|
|
c81b4fe11e | ||
|
|
a9cb7867bb | ||
|
|
383ae66b55 | ||
|
|
774fd871a8 | ||
|
|
4a0769d97c | ||
|
|
fee5b3e395 | ||
|
|
3010f1286f | ||
|
|
e53a676c04 | ||
|
|
1aba9fe415 | ||
|
|
4dafb05735 | ||
|
|
5cdc420c50 | ||
|
|
fca21b155c | ||
|
|
0486b85aa3 | ||
|
|
ed91100a0f | ||
|
|
2148c7ed77 | ||
|
|
8890e0d645 | ||
|
|
4a6a072fc8 | ||
|
|
d52106b3c7 | ||
|
|
4b190ae6b4 | ||
|
|
2e36f06732 | ||
|
|
a1033e4bfe | ||
|
|
90a37c94c1 | ||
|
|
c5ea415cda | ||
|
|
1bac7d3afb | ||
|
|
3a52919a35 | ||
|
|
07569f04ee | ||
|
|
952c84c195 | ||
|
|
840ba89900 | ||
|
|
fd10c64148 | ||
|
|
77a61274dc | ||
|
|
32f5e74449 | ||
|
|
bad64b1ee6 | ||
|
|
867df0f633 |
8
.github/workflows/vulnerability-scan.yml
vendored
@@ -64,6 +64,7 @@ jobs:
|
||||
--ignore-vuln PYSEC-2025-197 \
|
||||
--ignore-vuln PYSEC-2025-210 \
|
||||
--ignore-vuln PYSEC-2026-139 \
|
||||
--ignore-vuln GHSA-rrmf-rvhw-rf47 \
|
||||
--ignore-vuln PYSEC-2025-211 \
|
||||
--ignore-vuln PYSEC-2025-212 \
|
||||
--ignore-vuln PYSEC-2025-213 \
|
||||
@@ -71,7 +72,8 @@ jobs:
|
||||
--ignore-vuln PYSEC-2025-215 \
|
||||
--ignore-vuln PYSEC-2025-216 \
|
||||
--ignore-vuln PYSEC-2025-217 \
|
||||
--ignore-vuln PYSEC-2025-218
|
||||
--ignore-vuln PYSEC-2025-218 \
|
||||
--ignore-vuln GHSA-f4j7-r4q5-qw2c
|
||||
# Ignored CVEs:
|
||||
# PYSEC-2024-277 - joblib 1.5.3: disputed; NumpyArrayWrapper only used with trusted caches
|
||||
# PYSEC-2026-89 - markdown 3.10.2: DoS via malformed HTML; fix 3.8.1 — already past, advisory range is stale
|
||||
@@ -80,7 +82,11 @@ jobs:
|
||||
# PYSEC-2025-183 - pyjwt 2.12.1: disputed weak-encryption claim; key length is application-chosen
|
||||
# PYSEC-2025-189..197 - torch 2.11.0: memory-corruption/DoS in functions only reachable via untrusted models; no fix available
|
||||
# PYSEC-2025-210, PYSEC-2026-139 - torch 2.11.0: profiler/deserialization issues; no fix available
|
||||
# GHSA-rrmf-rvhw-rf47 - torch 2.11.0 (CVE-2025-3000, alias of PYSEC-2025-194): memory corruption in torch.jit.script, CVSS 1.9, local-only; affected <=2.12.0, no fix available. pip-audit reports it under the GHSA id so the PYSEC ignore above does not catch it.
|
||||
# PYSEC-2025-211..218 - transformers 5.5.4: deserialization/code injection via malicious model checkpoints; no fix available
|
||||
# GHSA-f4j7-r4q5-qw2c - chromadb 1.1.1 (CVE-2026-45829): pre-auth RCE via /api/v2/tenants/{tenant}/databases/{db}/collections when trust_remote_code=true.
|
||||
# Advisory: vulnerable >=1.0.0,<=1.5.9, firstPatchedVersion=none. We only use chromadb.PersistentClient (lib/crewai/src/crewai/rag/chromadb/factory.py)
|
||||
# and chromadb.utils.embedding_functions; the chromadb HTTP server is never started, so the vulnerable route is not exposed.
|
||||
continue-on-error: true
|
||||
|
||||
- name: Display results
|
||||
|
||||
2
.gitignore
vendored
@@ -31,3 +31,5 @@ chromadb-*.lock
|
||||
blogs/*
|
||||
secrets/*
|
||||
UNKNOWN.egg-info/
|
||||
demos/*
|
||||
.crewai/*
|
||||
|
||||
@@ -28,7 +28,35 @@ repos:
|
||||
hooks:
|
||||
- id: pip-audit
|
||||
name: pip-audit
|
||||
entry: bash -c 'source .venv/bin/activate && uv run pip-audit --skip-editable --ignore-vuln CVE-2026-3219' --
|
||||
# Keep this ignore list in sync with .github/workflows/vulnerability-scan.yml.
|
||||
entry: >-
|
||||
bash -c 'source .venv/bin/activate && uv run pip-audit --skip-editable
|
||||
--ignore-vuln PYSEC-2024-277
|
||||
--ignore-vuln PYSEC-2026-89
|
||||
--ignore-vuln PYSEC-2026-97
|
||||
--ignore-vuln PYSEC-2025-148
|
||||
--ignore-vuln PYSEC-2025-183
|
||||
--ignore-vuln PYSEC-2025-189
|
||||
--ignore-vuln PYSEC-2025-190
|
||||
--ignore-vuln PYSEC-2025-191
|
||||
--ignore-vuln PYSEC-2025-192
|
||||
--ignore-vuln PYSEC-2025-193
|
||||
--ignore-vuln PYSEC-2025-194
|
||||
--ignore-vuln PYSEC-2025-195
|
||||
--ignore-vuln PYSEC-2025-196
|
||||
--ignore-vuln PYSEC-2025-197
|
||||
--ignore-vuln PYSEC-2025-210
|
||||
--ignore-vuln PYSEC-2026-139
|
||||
--ignore-vuln GHSA-rrmf-rvhw-rf47
|
||||
--ignore-vuln PYSEC-2025-211
|
||||
--ignore-vuln PYSEC-2025-212
|
||||
--ignore-vuln PYSEC-2025-213
|
||||
--ignore-vuln PYSEC-2025-214
|
||||
--ignore-vuln PYSEC-2025-215
|
||||
--ignore-vuln PYSEC-2025-216
|
||||
--ignore-vuln PYSEC-2025-217
|
||||
--ignore-vuln PYSEC-2025-218
|
||||
--ignore-vuln GHSA-f4j7-r4q5-qw2c' --
|
||||
language: system
|
||||
pass_filenames: false
|
||||
stages: [pre-push, manual]
|
||||
|
||||
131
conftest.py
@@ -5,12 +5,105 @@ from collections.abc import Generator
|
||||
import gzip
|
||||
import os
|
||||
from pathlib import Path
|
||||
import re
|
||||
import tempfile
|
||||
from typing import Any
|
||||
|
||||
from dotenv import load_dotenv
|
||||
import pytest
|
||||
from vcr.request import Request # type: ignore[import-untyped]
|
||||
|
||||
|
||||
def _patch_vcrpy_aiohttp_compat() -> None:
|
||||
"""Keep vcrpy's aiohttp stub working under aiohttp 3.14.0.
|
||||
|
||||
aiohttp 3.14.0 (pulled in to fix GHSA-jg22-mg44-37j8 and GHSA-hg6j-4rv6-33pg):
|
||||
* removed ``aiohttp.streams.AsyncStreamReaderMixin`` (folded into ``StreamReader``),
|
||||
which vcrpy's ``MockStream`` still subclasses -- vcr's patch machinery then raises
|
||||
``AttributeError`` at collection time; and
|
||||
* added a required ``stream_writer`` keyword-only arg to ``ClientResponse.__init__``,
|
||||
which vcrpy's ``MockClientResponse`` does not pass -- raising ``TypeError`` at
|
||||
cassette playback.
|
||||
|
||||
Restore the mixin, then rebuild ``MockClientResponse``'s ``super().__init__`` call from
|
||||
the live ``ClientResponse`` signature (defaulting every required keyword-only arg to
|
||||
``None``, mirroring vcrpy's original call) so it also survives future aiohttp additions.
|
||||
"""
|
||||
import asyncio
|
||||
import inspect
|
||||
|
||||
from aiohttp import streams
|
||||
from aiohttp.client_reqrep import ClientResponse
|
||||
|
||||
if not hasattr(streams, "AsyncStreamReaderMixin"):
|
||||
|
||||
class AsyncStreamReaderMixin:
|
||||
__slots__ = ()
|
||||
|
||||
def __aiter__(self) -> streams.AsyncStreamIterator[bytes]:
|
||||
return streams.AsyncStreamIterator(self.readline) # type: ignore[attr-defined]
|
||||
|
||||
def iter_chunked(self, n: int) -> streams.AsyncStreamIterator[bytes]:
|
||||
return streams.AsyncStreamIterator(lambda: self.read(n)) # type: ignore[attr-defined]
|
||||
|
||||
def iter_any(self) -> streams.AsyncStreamIterator[bytes]:
|
||||
return streams.AsyncStreamIterator(self.readany) # type: ignore[attr-defined]
|
||||
|
||||
def iter_chunks(self) -> streams.ChunkTupleAsyncStreamIterator:
|
||||
return streams.ChunkTupleAsyncStreamIterator(self) # type: ignore[arg-type]
|
||||
|
||||
streams.AsyncStreamReaderMixin = AsyncStreamReaderMixin # type: ignore[attr-defined]
|
||||
|
||||
# Importing the stub builds MockStream/MockClientResponse, so it must run after the
|
||||
# mixin is restored above.
|
||||
import vcr.stubs.aiohttp_stubs as aiohttp_stubs # type: ignore[import-untyped]
|
||||
|
||||
if getattr(aiohttp_stubs.MockClientResponse, "_crewai_aiohttp_patched", False):
|
||||
return
|
||||
|
||||
keyword_only = [
|
||||
name
|
||||
for name, param in inspect.signature(ClientResponse.__init__).parameters.items()
|
||||
if param.kind is inspect.Parameter.KEYWORD_ONLY
|
||||
]
|
||||
|
||||
class _NullStreamWriter:
|
||||
# aiohttp 3.14.0 reads stream_writer.output_size in the "request already
|
||||
# sent" branch (writer is None), so None is not enough -- supply a stub.
|
||||
output_size = 0
|
||||
|
||||
fallback_loop: list[asyncio.AbstractEventLoop] = []
|
||||
|
||||
def _resolve_loop() -> asyncio.AbstractEventLoop:
|
||||
# MockClientResponse is normally built inside aiohttp's running loop, so
|
||||
# prefer that. In a sync context there is no running loop; avoid
|
||||
# asyncio.get_event_loop(), which on 3.12+ emits a DeprecationWarning
|
||||
# (and can RuntimeError) when no current loop is set. Use one cached
|
||||
# loop instead -- the mock only stores it and calls loop.get_debug().
|
||||
try:
|
||||
return asyncio.get_running_loop()
|
||||
except RuntimeError:
|
||||
if not fallback_loop:
|
||||
fallback_loop.append(asyncio.new_event_loop())
|
||||
return fallback_loop[0]
|
||||
|
||||
def _mock_client_response_init(
|
||||
self: Any, method: str, url: Any, request_info: Any = None
|
||||
) -> None:
|
||||
kwargs: dict[str, Any] = dict.fromkeys(keyword_only)
|
||||
kwargs["request_info"] = request_info
|
||||
if "loop" in kwargs:
|
||||
kwargs["loop"] = _resolve_loop()
|
||||
if "stream_writer" in kwargs:
|
||||
kwargs["stream_writer"] = _NullStreamWriter()
|
||||
ClientResponse.__init__(self, method, url, **kwargs)
|
||||
|
||||
aiohttp_stubs.MockClientResponse.__init__ = _mock_client_response_init
|
||||
aiohttp_stubs.MockClientResponse._crewai_aiohttp_patched = True
|
||||
|
||||
|
||||
_patch_vcrpy_aiohttp_compat()
|
||||
|
||||
from vcr.request import Request # type: ignore[import-untyped] # noqa: E402
|
||||
|
||||
|
||||
try:
|
||||
@@ -20,8 +113,25 @@ except ModuleNotFoundError:
|
||||
|
||||
|
||||
env_test_path = Path(__file__).parent / ".env.test"
|
||||
load_dotenv(env_test_path, override=True)
|
||||
load_dotenv(override=True)
|
||||
|
||||
load_dotenv(env_test_path, override=False)
|
||||
load_dotenv(override=False)
|
||||
|
||||
BEDROCK_HOST_PLACEHOLDER = "bedrock-runtime.vcr.amazonaws.com"
|
||||
_BEDROCK_HOST_RE = re.compile(r"^bedrock-runtime\.[a-z0-9-]+\.amazonaws\.com$")
|
||||
|
||||
|
||||
def _normalize_bedrock_host(host: str) -> str:
|
||||
if _BEDROCK_HOST_RE.match(host):
|
||||
return BEDROCK_HOST_PLACEHOLDER
|
||||
return host
|
||||
|
||||
|
||||
def bedrock_host_matcher(r1: Request, r2: Request) -> bool: # type: ignore[no-any-unimported]
|
||||
"""Match Bedrock requests across AWS regions (CI uses us-east-1, local may use us-west-2)."""
|
||||
return _normalize_bedrock_host(r1.host or "") == _normalize_bedrock_host(
|
||||
r2.host or ""
|
||||
)
|
||||
|
||||
|
||||
def _patched_make_vcr_request(httpx_request: Any, **kwargs: Any) -> Any:
|
||||
@@ -188,6 +298,7 @@ HEADERS_TO_FILTER = {
|
||||
"anthropic-ratelimit-tokens-remaining": "ANTHROPIC-RATELIMIT-TOKENS-REMAINING-XXX",
|
||||
"anthropic-ratelimit-tokens-reset": "ANTHROPIC-RATELIMIT-TOKENS-RESET-XXX",
|
||||
"x-amz-date": "X-AMZ-DATE-XXX",
|
||||
"x-amz-security-token": "X-AMZ-SECURITY-TOKEN-XXX",
|
||||
"amz-sdk-invocation-id": "AMZ-SDK-INVOCATION-ID-XXX",
|
||||
"accept-encoding": "ACCEPT-ENCODING-XXX",
|
||||
"x-amzn-requestid": "X-AMZN-REQUESTID-XXX",
|
||||
@@ -212,6 +323,10 @@ def _filter_request_headers(request: Request) -> Request: # type: ignore[no-any
|
||||
placeholder_host = "fake-azure-endpoint.openai.azure.com"
|
||||
request.uri = request.uri.replace(original_host, placeholder_host)
|
||||
|
||||
# Normalize Bedrock regional endpoints so cassettes work in any AWS region.
|
||||
if request.host and _BEDROCK_HOST_RE.match(request.host):
|
||||
request.uri = request.uri.replace(request.host, BEDROCK_HOST_PLACEHOLDER)
|
||||
|
||||
return request
|
||||
|
||||
|
||||
@@ -229,6 +344,11 @@ def _filter_response_headers(response: dict[str, Any]) -> dict[str, Any] | None:
|
||||
if body == "" or body == b"" or content_length == ["0"]:
|
||||
return None
|
||||
|
||||
status_code = response.get("status", {}).get("code")
|
||||
if isinstance(status_code, int) and status_code >= 400:
|
||||
# Avoid persisting auth/model errors when re-recording without valid AWS creds.
|
||||
return None
|
||||
|
||||
for encoding_header in ["Content-Encoding", "content-encoding"]:
|
||||
if encoding_header in headers:
|
||||
encoding = headers.pop(encoding_header)
|
||||
@@ -279,6 +399,11 @@ def vcr_cassette_dir(request: Any) -> str:
|
||||
return str(cassette_dir)
|
||||
|
||||
|
||||
def pytest_recording_configure(vcr: Any, config: Any) -> None:
|
||||
"""Register custom VCR matchers for each test cassette session."""
|
||||
vcr.register_matcher("bedrock_host", bedrock_host_matcher)
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def vcr_config(vcr_cassette_dir: str) -> dict[str, Any]:
|
||||
"""Configure VCR with organized cassette storage."""
|
||||
|
||||
@@ -4,6 +4,281 @@ description: "تحديثات المنتج والتحسينات وإصلاحات
|
||||
icon: "clock"
|
||||
mode: "wide"
|
||||
---
|
||||
<Update label="11 يونيو 2026">
|
||||
## v1.14.7
|
||||
|
||||
[عرض الإصدار على GitHub](https://github.com/crewAIInc/crewAI/releases/tag/1.14.7)
|
||||
|
||||
## ما الذي تغير
|
||||
|
||||
### الميزات
|
||||
- إضافة واجهات خلفية افتراضية قابلة للتوصيل للذاكرة، والمعرفة، وrag، وflow.
|
||||
- عرض السبب الحقيقي للإنهاء، ومعلمات العينة، وresponse.id في أحداث LLM.
|
||||
- تصنيف مشغلات DSL كزخارف واعية للمسار.
|
||||
- إضافة واجهة برمجة تطبيقات الدردشة لتدفقات المحادثة.
|
||||
- جعل واجهة القفل قابلة للتجاوز.
|
||||
- بناء FlowDefinition من بيانات التعريف الخاصة بـ Flow DSL.
|
||||
- إضافة مزود LLM من Snowflake Cortex الأصلي.
|
||||
- إضافة دعم لملفات الوكلاء المدربين من crew.
|
||||
|
||||
### إصلاحات الأخطاء
|
||||
- إصلاح نقطة التحقق لإعادة بناء BaseLLM مخصص كـ LLM ملموس عند الاستعادة.
|
||||
- تقييد الاستعادة على علامة لمنع اللقطات الحية من إعادة التشغيل كاستئناف.
|
||||
- تحديد حالة وقت التشغيل لكل تشغيل للحد من النمو وعزل التشغيل المتزامن.
|
||||
- إصلاح إعدادات التتبع على crewai-login.
|
||||
- احترام suppress_flow_events لأحداث تنفيذ الطريقة.
|
||||
- استعادة [project.scripts] في حزمة crewai لتثبيت أداة uv.
|
||||
- حل مشكلات CVE الخاصة بـ pip-audit لـ aiohttp وdocling وdocling-core.
|
||||
- إصلاح إدخال الملفات الذي لا يعمل بشكل موثوق.
|
||||
- إصلاح تاريخ نتائج أدوات Snowflake Claude غير المكتملة.
|
||||
|
||||
### الوثائق
|
||||
- تحديث سجل التغييرات والإصدار لـ v1.14.7.
|
||||
- تحديث وثائق جامع OpenTelemetry.
|
||||
- تحديث دليل NVIDIA Nemotron LLM.
|
||||
- إضافة دليل تكامل Databricks.
|
||||
- إضافة دليل تكامل Snowflake.
|
||||
|
||||
### الأداء
|
||||
- تحسين سرعة استيراد crewai من خلال تحميل مستندات docling بشكل كسول.
|
||||
|
||||
### إعادة الهيكلة
|
||||
- تبسيط تقييم شروط التدفق ليكون بلا حالة لكل حدث.
|
||||
- فصل منطق المحادثة عن وقت التشغيل وإضافة تعريف المحادثة.
|
||||
- تقسيم `flow.py` إلى DSL، وتعريف، ووقت تشغيل.
|
||||
|
||||
## المساهمون
|
||||
|
||||
@Luzk, @alex-clawd, @devin-ai-integration[bot], @greysonlalonde, @gvieira, @jessemiller, @lorenzejay, @lucasgomide, @mattatcha, @vinibrsl
|
||||
|
||||
</Update>
|
||||
|
||||
<Update label="10 يونيو 2026">
|
||||
## v1.14.7rc2
|
||||
|
||||
[عرض الإصدار على GitHub](https://github.com/crewAIInc/crewAI/releases/tag/1.14.7rc2)
|
||||
|
||||
## ما الذي تغير
|
||||
|
||||
### إصلاحات الأخطاء
|
||||
- استعادة البوابة على علامة لمنع اللقطات الحية من إعادة التشغيل كاستئناف
|
||||
|
||||
### الوثائق
|
||||
- تحديث سجل التغييرات والإصدار لـ v1.14.7rc1
|
||||
|
||||
## المساهمون
|
||||
|
||||
@greysonlalonde
|
||||
|
||||
</Update>
|
||||
|
||||
<Update label="10 يونيو 2026">
|
||||
## v1.14.7rc1
|
||||
|
||||
[عرض الإصدار على GitHub](https://github.com/crewAIInc/crewAI/releases/tag/1.14.7rc1)
|
||||
|
||||
## ما الذي تغير
|
||||
|
||||
### الميزات
|
||||
- إضافة `reset_runtime_state` لإطلاق حالة الحافلة المتراكمة
|
||||
- التعامل مع دعم كل من الموجهات المخصصة
|
||||
- فصل منطق المحادثة عن وقت التشغيل وإضافة `conversational_definition`
|
||||
|
||||
### إصلاحات الأخطاء
|
||||
- إصلاح نطاق حالة وقت التشغيل لكل تشغيل للحد من النمو وعزل التشغيلات المتزامنة
|
||||
- إصلاح إعدادات القياس عن بُعد على `crewai-login`
|
||||
- إصلاح احترام `suppress_flow_events` لفعاليات تنفيذ الأساليب
|
||||
|
||||
### الوثائق
|
||||
- تحديث صور OpenTelemetry
|
||||
- تحديث الوثائق لتعكس الحالة الجديدة لجمع بيانات OpenTelemetry
|
||||
- تحديث سجل التغييرات والإصدار لـ v1.14.7a4
|
||||
|
||||
### إعادة الهيكلة
|
||||
- تبسيط تقييم شرط التدفق ليكون بلا حالة لكل حدث
|
||||
- تحسين دورة توجيه المحادثة مع تقليل مسار واحد
|
||||
|
||||
## المساهمون
|
||||
|
||||
@greysonlalonde, @lorenzejay, @lucasgomide, @vinibrsl
|
||||
|
||||
</Update>
|
||||
|
||||
<Update label="9 يونيو 2026">
|
||||
## v1.14.7a4
|
||||
|
||||
[عرض الإصدار على GitHub](https://github.com/crewAIInc/crewAI/releases/tag/1.14.7a4)
|
||||
|
||||
## ما الذي تغير
|
||||
|
||||
### الميزات
|
||||
- نقل وقت التشغيل @listen/@router لقراءة من FlowDefinition
|
||||
- إضافة واجهات خلفية افتراضية قابلة للتوصيل للذاكرة، والمعرفة، وrag، وflow
|
||||
|
||||
### الوثائق
|
||||
- تحديث سجل التغييرات والإصدار لـ v1.14.7a3
|
||||
|
||||
## المساهمون
|
||||
|
||||
@greysonlalonde, @mattatcha, @vinibrsl
|
||||
|
||||
</Update>
|
||||
|
||||
<Update label="8 يونيو 2026">
|
||||
## v1.14.7a3
|
||||
|
||||
[عرض الإصدار على GitHub](https://github.com/crewAIInc/crewAI/releases/tag/1.14.7a3)
|
||||
|
||||
## ما الذي تغير
|
||||
|
||||
### إصلاحات الأخطاء
|
||||
- إصلاح تعرض `ask_for_human_input` في `AgentExecutor` التجريبي
|
||||
- حل مشكلات CVEs الخاصة بـ pip-audit لـ `aiohttp`، `docling`، `docling-core`، و `pip`
|
||||
|
||||
### إعادة هيكلة
|
||||
- نقل `@start` لقراءة من `FlowDefinition`
|
||||
|
||||
### الوثائق
|
||||
- تحديث سجل التغييرات والإصدار لـ v1.14.7a2
|
||||
|
||||
## المساهمون
|
||||
|
||||
@greysonlalonde، @lorenzejay، @vinibrsl
|
||||
|
||||
</Update>
|
||||
|
||||
<Update label="5 يونيو 2026">
|
||||
## v1.14.7a2
|
||||
|
||||
[عرض الإصدار على GitHub](https://github.com/crewAIInc/crewAI/releases/tag/1.14.7a2)
|
||||
|
||||
## ما الذي تغير
|
||||
|
||||
### الميزات
|
||||
- إضافة دعم تتبع تدفقات المحادثة.
|
||||
- تحديث وثائق تدفق المحادثة لاستخدام `handle_turn`.
|
||||
- عرض السبب الحقيقي لإنهاء المحادثة، ومعلمات العينة، و`response.id` في أحداث LLM.
|
||||
- تصنيف مشغلات DSL كزخارف واعية بالمسار.
|
||||
- تنفيذ واجهة برمجة التطبيقات للدردشة لتدفقات المحادثة.
|
||||
- جعل قفل الخلفية قابلاً للتجاوز في متجر القفل.
|
||||
- تقسيم أحادي تدفق DSL إلى وحدات زخرفية مركزة.
|
||||
- تسطيح استخدام ذاكرة التخزين المؤقت LiteLLM/أعداد الأسباب الفرعية في `_usage_to_dict`.
|
||||
- بناء `FlowDefinition` من بيانات التعريف الخاصة بتدفق DSL.
|
||||
|
||||
### الوثائق
|
||||
- إضافة دليل NVIDIA Nemotron LLM.
|
||||
- توثيق عمليات نشر المونوريبو.
|
||||
- تحديث سجل التغييرات والإصدار لـ v1.14.7a1.
|
||||
|
||||
## المساهمون
|
||||
|
||||
@alex-clawd, @gvieira, @lorenzejay, @lucasgomide, @mattatcha, @vinibrsl
|
||||
|
||||
</Update>
|
||||
|
||||
<Update label="3 يونيو 2026">
|
||||
## v1.14.7a1
|
||||
|
||||
[عرض الإصدار على GitHub](https://github.com/crewAIInc/crewAI/releases/tag/1.14.7a1)
|
||||
|
||||
## ما الذي تغير
|
||||
|
||||
### الميزات
|
||||
- إضافة دعم ملفات الوكلاء المدربين
|
||||
- إضافة مزود LLM الأصلي لـ Snowflake Cortex
|
||||
- إضافة دليل تكامل Databricks
|
||||
- إضافة دليل تكامل Snowflake
|
||||
|
||||
### إصلاحات الأخطاء
|
||||
- إصلاح CLI عن طريق استعادة `[project.scripts]` في حزمة crewai لتثبيت أداة UV
|
||||
- حل مشكلات موثوقية إدخال الملفات
|
||||
- إصلاح تاريخ نتائج الأدوات غير المكتملة في Snowflake Claude
|
||||
- التعامل مع استدعاءات الأدوات الممثلة كسلاسل لـ Snowflake Claude
|
||||
- إعادة تفعيل مستمعي `or_` متعدد المصادر عبر دورات مدفوعة بالموجه
|
||||
|
||||
### الأداء
|
||||
- تحسين سرعة استيراد crewai عن طريق تحميل استيرادات docling بشكل كسول
|
||||
|
||||
### إعادة هيكلة
|
||||
- تقسيم `flow.py` إلى DSL، تعريف، وتشغيل
|
||||
|
||||
## المساهمون
|
||||
|
||||
@Luzk, @alex-clawd, @devin-ai-integration[bot], @greysonlalonde, @jessemiller, @lorenzejay, @vinibrsl
|
||||
|
||||
</Update>
|
||||
|
||||
<Update label="28 مايو 2026">
|
||||
## v1.14.6
|
||||
|
||||
[عرض الإصدار على GitHub](https://github.com/crewAIInc/crewAI/releases/tag/1.14.6)
|
||||
|
||||
## ما الذي تغير
|
||||
|
||||
### الميزات
|
||||
- تحسين StdioTransport لمنع تسرب متغيرات البيئة
|
||||
- تعزيز تكوين التخطيط ومعالجة الملاحظات
|
||||
- إعلان env_vars على DatabricksQueryTool
|
||||
- إضافة وثائق خطة التحكم في الوكيل
|
||||
|
||||
### إصلاحات الأخطاء
|
||||
- إصلاح تسرب المخرجات المنظمة في حلقات استدعاء الأدوات
|
||||
- حذف ردود الاستدعاء غير القابلة للعودة وحالة المحول في نقطة التحقق
|
||||
- تسلسل الحقول من النوع [BaseModel] كـ JSON schema في نقطة التحقق
|
||||
- تجنب مهمة orphan task_started عند استعادة نطاق الاستئناف
|
||||
- السماح لـ AgentExecutor بالاستعادة من نقطة التحقق
|
||||
- تصحيح خطأ الكتابة من mongodb إلى pymongo في package_dependencies
|
||||
|
||||
### الوثائق
|
||||
- إضافة كتلة تنقل وثائق ACP (بيتا) إلى صفحات خطة التحكم في الوكيل
|
||||
- إزالة المراجع إلى العمليات التوافقية من صفحة العمليات
|
||||
- إعادة هيكلة صفحة نقاط التحقق
|
||||
- توثيق خطوة تثبيت حزمة الإدارة لمرة واحدة
|
||||
- نقل Secrets Manager / Workload Identity من replicated-config
|
||||
- إزالة تعبيرات `{" "}` JSX التي تكسر عرض `<Steps>`
|
||||
|
||||
### إعادة الهيكلة
|
||||
- نقل مستودع المهارات إلى experimental + CREWAI_EXPERIMENTAL gate
|
||||
|
||||
## المساهمون
|
||||
|
||||
@akaKuruma, @alex-clawd, @github-actions[bot], @greysonlalonde, @heitorado, @iris-clawd, @lorenzejay, @lucasgomide, @mattatcha, @thiagomoretto, @vinibrsl
|
||||
|
||||
</Update>
|
||||
|
||||
<Update label="27 مايو 2026">
|
||||
## v1.14.6a2
|
||||
|
||||
[عرض الإصدار على GitHub](https://github.com/crewAIInc/crewAI/releases/tag/1.14.6a2)
|
||||
|
||||
## ما الذي تغير
|
||||
|
||||
### الميزات
|
||||
- تحسين `StdioTransport` لمنع تسرب متغيرات البيئة
|
||||
- تحسين تكوين التخطيط ومعالجة المراقبة
|
||||
- إعلان `env_vars` على `DatabricksQueryTool`
|
||||
- إضافة وثائق خطة التحكم بالوكيل
|
||||
|
||||
### إصلاحات الأخطاء
|
||||
- إصلاح تسرب المخرجات المنظمة في حلقات استدعاء الأدوات
|
||||
- حذف الاستدعاءات غير القابلة للعودة وحالة المحول في نقاط التحقق
|
||||
- تسلسل حقول `type[BaseModel]` كـ JSON schema في نقاط التحقق
|
||||
- تجنب `task_started` اليتيمة عند استعادة نطاق الاستئناف
|
||||
- السماح لـ `AgentExecutor` بالاستعادة من نقطة تحقق
|
||||
- تصحيح خطأ مطبعي في MongoDB إلى `pymongo` في تبعيات الحزمة
|
||||
|
||||
### الوثائق
|
||||
- إعادة هيكلة صفحة نقاط التحقق
|
||||
- توثيق خطوة تثبيت حزمة الإدارة لمرة واحدة
|
||||
- نقل Secrets Manager / Workload Identity من replicated-config
|
||||
- إزالة إدخال Skills Repository من سجل التغييرات
|
||||
|
||||
## المساهمون
|
||||
|
||||
@github-actions[bot], @greysonlalonde, @heitorado, @iris-clawd, @lorenzejay, @lucasgomide, @mattatcha, @thiagomoretto, @vinibrsl
|
||||
|
||||
</Update>
|
||||
|
||||
<Update label="21 مايو 2026">
|
||||
## v1.14.6a1
|
||||
|
||||
@@ -12,7 +287,6 @@ mode: "wide"
|
||||
## ما الذي تغير
|
||||
|
||||
### الميزات
|
||||
- إضافة مستودع المهارات مع التسجيل، التخزين المؤقت، واجهة سطر الأوامر، وتكامل SDK
|
||||
- توليد ملاحظات إصدار مصنفة للمؤسسات
|
||||
|
||||
### إصلاحات الأخطاء
|
||||
|
||||
@@ -70,13 +70,39 @@ mode: "wide"
|
||||
|
||||
## إنشاء الوكلاء
|
||||
|
||||
هناك طريقتان لإنشاء الوكلاء في CrewAI: باستخدام **تهيئة YAML (موصى بها)** أو تعريفهم **مباشرة في الكود**.
|
||||
هناك طريقتان شائعتان لإنشاء الوكلاء في CrewAI: باستخدام **تهيئة JSONC (الموصى بها للـ crews الجديدة)** أو تعريفهم **مباشرة في الكود**.
|
||||
|
||||
### تهيئة YAML (موصى بها)
|
||||
### تهيئة JSONC (موصى بها)
|
||||
|
||||
توفر تهيئة YAML طريقة أنظف وأكثر قابلية للصيانة لتعريف الوكلاء. نوصي بشدة باستخدام هذا النهج في مشاريع CrewAI.
|
||||
المشاريع الجديدة التي تُنشأ عبر `crewai create crew <name>` تستخدم تهيئة JSON-first. يُعرّف كل Agent في `agents/<agent_name>.jsonc`، ويحدد `crew.jsonc` أي Agents تدخل في الـ crew.
|
||||
|
||||
بعد إنشاء مشروع CrewAI كما هو موضح في قسم [التثبيت](/ar/installation)، انتقل إلى ملف `src/latest_ai_development/config/agents.yaml` وعدّل القالب ليتوافق مع متطلباتك.
|
||||
```jsonc agents/researcher.jsonc
|
||||
{
|
||||
"role": "{topic} Senior Data Researcher",
|
||||
"goal": "Uncover cutting-edge developments in {topic}",
|
||||
"backstory": "You find the most relevant information and present it clearly.",
|
||||
"llm": "openai/gpt-4o",
|
||||
"tools": ["SerperDevTool"],
|
||||
"settings": {
|
||||
"verbose": true,
|
||||
"allow_delegation": false
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
استخدم `{placeholder}` داخل `role` أو `goal` أو `backstory`. ضع القيم الافتراضية في `inputs` داخل `crew.jsonc`؛ وسيطلب `crewai run` أي قيم ناقصة. يمكن وضع حقول السلوك مثل `verbose` و `allow_delegation` و `max_iter` و `memory` و `cache` و `planning_config` في المستوى الأعلى أو داخل `settings`.
|
||||
|
||||
<Note>
|
||||
يدعم JSONC التعليقات والفواصل النهائية. إذا وُجد `agents/<name>.jsonc` و `agents/<name>.json` معًا، يستخدم CrewAI ملف JSONC.
|
||||
</Note>
|
||||
|
||||
### تهيئة YAML الكلاسيكية
|
||||
|
||||
المشاريع الكلاسيكية التي تُنشأ عبر `crewai create crew <name> --classic` تستخدم `config/agents.yaml` وفئة `@CrewBase` في `crew.py`.
|
||||
|
||||
تظل تهيئة YAML مدعومة للمشاريع الحالية المبنية بـ Python/YAML وللفِرق التي تفضل تعريف الوكلاء من خلال فئة `@CrewBase`.
|
||||
|
||||
بعد إنشاء مشروع كلاسيكي، انتقل إلى ملف `src/<project_name>/config/agents.yaml` وعدّل القالب ليتوافق مع متطلباتك.
|
||||
|
||||
<Note>
|
||||
ستُستبدل المتغيرات في ملفات YAML (مثل `{topic}`) بقيم من مدخلاتك عند تشغيل الطاقم:
|
||||
@@ -88,7 +114,7 @@ crew.kickoff(inputs={'topic': 'AI Agents'})
|
||||
إليك مثالًا على كيفية تهيئة الوكلاء باستخدام YAML:
|
||||
|
||||
```yaml agents.yaml
|
||||
# src/latest_ai_development/config/agents.yaml
|
||||
# src/<project_name>/config/agents.yaml
|
||||
researcher:
|
||||
role: >
|
||||
{topic} Senior Data Researcher
|
||||
@@ -113,7 +139,7 @@ reporting_analyst:
|
||||
لاستخدام تهيئة YAML في الكود، أنشئ فئة طاقم ترث من `CrewBase`:
|
||||
|
||||
```python Code
|
||||
# src/latest_ai_development/crew.py
|
||||
# src/<project_name>/crew.py
|
||||
from crewai import Agent, Crew, Process
|
||||
from crewai.project import CrewBase, agent, crew
|
||||
from crewai_tools import SerperDevTool
|
||||
|
||||
@@ -5,225 +5,419 @@ icon: floppy-disk
|
||||
mode: "wide"
|
||||
---
|
||||
|
||||
<Warning>
|
||||
الـ Checkpointing في اصدار مبكر. قد تتغير واجهات البرمجة في الاصدارات المستقبلية.
|
||||
</Warning>
|
||||
الـ Checkpointing يحفظ لقطة من حالة التنفيذ أثناء التشغيل بحيث يمكن لطاقم أو تدفق أو وكيل الاستئناف بعد الفشل أو التفرع إلى فرع بديل.
|
||||
|
||||
## نظرة عامة
|
||||
<CardGroup cols={2}>
|
||||
<Card title="الشرح" icon="lightbulb" href="#الشرح">
|
||||
كيف يعمل الـ Checkpointing: الأحداث والتخزين والوراثة.
|
||||
</Card>
|
||||
<Card title="درس تطبيقي" icon="graduation-cap" href="#درس-تطبيقي-استئناف-طاقم-فاشل">
|
||||
دليل 5 دقائق: تشغيل، إيقاف، استئناف.
|
||||
</Card>
|
||||
<Card title="ادلة عملية" icon="screwdriver-wrench" href="#ادلة-عملية">
|
||||
وصفات مركزة على المهام لسير العمل الشائع.
|
||||
</Card>
|
||||
<Card title="المرجع" icon="book" href="#المرجع">
|
||||
`CheckpointConfig` والأحداث والمزودات وسطر الأوامر.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
يقوم الـ Checkpointing بحفظ حالة التنفيذ تلقائيا اثناء التشغيل. اذا فشل طاقم او تدفق او وكيل اثناء التنفيذ، يمكنك الاستعادة من اخر نقطة حفظ والاستئناف دون اعادة تنفيذ العمل المكتمل.
|
||||
## الشرح
|
||||
|
||||
## البداية السريعة
|
||||
### ما هي نقطة الحفظ
|
||||
|
||||
```python
|
||||
from crewai import Crew, CheckpointConfig
|
||||
تلتقط نقطة الحفظ كل ما يحتاجه CrewAI لإعادة إنشاء تشغيل أثناء سيره: الحالة الكاملة للطاقم أو التدفق أو الوكيل — التكوين، وذاكرة الوكلاء ومصادر المعرفة، وتقدم المهام، والمخرجات الوسيطة، والحالة الداخلية والسمات — إلى جانب مدخلات الـ kickoff، وسجل الأحداث حتى تلك النقطة، ومعرف نسب يربط نقطة الحفظ بالتشغيل الذي جاءت منه.
|
||||
|
||||
crew = Crew(
|
||||
agents=[...],
|
||||
tasks=[...],
|
||||
checkpoint=True, # يستخدم الافتراضيات: ./.checkpoints, عند task_completed
|
||||
)
|
||||
result = crew.kickoff()
|
||||
```
|
||||
الاستعادة تعيد بناء تلك الحالة وتستمر. تتخطى المهام المكتملة، وتعاد ترطيب الذاكرة والمعرفة، ويعمل العمل التابع على نفس المخرجات التي أنتجها التشغيل الأصلي. التفرع يجري نفس الاستعادة تحت نسب جديد، بحيث يكتب الفرع الجديد والتشغيل الأصلي نقاط الحفظ جنبا إلى جنب دون أن يطمس أحدهما الآخر.
|
||||
|
||||
تتم كتابة ملفات نقاط الحفظ في `./.checkpoints/` بعد اكتمال كل مهمة.
|
||||
### متى تكتب نقاط الحفظ
|
||||
|
||||
## التكوين
|
||||
الـ Checkpointing مدفوع بالأحداث. يشترك وقت التشغيل في الأحداث التي تحددها عبر `on_events` ويكتب نقطة حفظ عند إطلاق أحدها. الافتراضي `task_completed` ينتج نقطة حفظ لكل مهمة منتهية — توازن معقول بين الدقة واستخدام القرص. الأحداث عالية التردد مثل `llm_call_completed` متاحة للاستعادة الدقيقة لكنها تكتب ملفات أكثر بكثير.
|
||||
|
||||
استخدم `CheckpointConfig` للتحكم الكامل:
|
||||
### التخزين
|
||||
|
||||
```python
|
||||
from crewai import Crew, CheckpointConfig
|
||||
يتضمن CrewAI مزودين:
|
||||
|
||||
crew = Crew(
|
||||
agents=[...],
|
||||
tasks=[...],
|
||||
checkpoint=CheckpointConfig(
|
||||
location="./my_checkpoints",
|
||||
on_events=["task_completed", "crew_kickoff_completed"],
|
||||
max_checkpoints=5,
|
||||
),
|
||||
)
|
||||
```
|
||||
- `JsonProvider` يكتب ملفا لكل نقطة حفظ. قابل للقراءة وسهل التفقد.
|
||||
- `SqliteProvider` يكتب إلى قاعدة بيانات SQLite واحدة. أفضل لنقاط الحفظ عالية التردد.
|
||||
|
||||
### حقول CheckpointConfig
|
||||
كلاهما يحذف أقدم نقاط الحفظ عند تحديد `max_checkpoints`.
|
||||
|
||||
| الحقل | النوع | الافتراضي | الوصف |
|
||||
|:------|:------|:----------|:------|
|
||||
| `location` | `str` | `"./.checkpoints"` | مسار ملفات نقاط الحفظ |
|
||||
| `on_events` | `list[str]` | `["task_completed"]` | انواع الاحداث التي تطلق نقطة حفظ |
|
||||
| `provider` | `BaseProvider` | `JsonProvider()` | واجهة التخزين |
|
||||
| `max_checkpoints` | `int \| None` | `None` | الحد الاقصى للملفات؛ يتم حذف الاقدم اولا |
|
||||
<Note>
|
||||
كتابة نقاط الحفظ بأفضل جهد. فشل نقطة حفظ يسجل لكنه لا يقاطع التشغيل.
|
||||
</Note>
|
||||
|
||||
### الوراثة والانسحاب
|
||||
### نموذج الوراثة
|
||||
|
||||
يقبل حقل `checkpoint` في Crew و Flow و Agent قيم `CheckpointConfig` او `True` او `False` او `None`:
|
||||
`Crew` و`Flow` و`Agent` كلها تقبل وسيط `checkpoint`. يرث الأبناء من الأب ما لم يحددوا قيمتهم الخاصة أو يمرروا `False` للانسحاب. فعل الـ Checkpointing مرة واحدة على الطاقم وتشارك كل الوكلاء، أو استبعد وكيلا واحدا بشكل انتقائي.
|
||||
|
||||
| القيمة | السلوك |
|
||||
|:-------|:-------|
|
||||
| `None` (افتراضي) | يرث من الاصل. الوكيل يرث اعدادات الطاقم. |
|
||||
| `True` | تفعيل بالاعدادات الافتراضية. |
|
||||
| `False` | انسحاب صريح. يوقف الوراثة من الاصل. |
|
||||
| `CheckpointConfig(...)` | اعدادات مخصصة. |
|
||||
## درس تطبيقي: استئناف طاقم فاشل
|
||||
|
||||
```python
|
||||
crew = Crew(
|
||||
agents=[
|
||||
Agent(role="Researcher", ...), # يرث checkpoint من الطاقم
|
||||
Agent(role="Writer", ..., checkpoint=False), # منسحب، بدون نقاط حفظ
|
||||
],
|
||||
tasks=[...],
|
||||
checkpoint=True,
|
||||
)
|
||||
```
|
||||
هذا الدليل يستغرق حوالي 5 دقائق. ستشغل طاقما بمهمتين، توقفه في المنتصف، ثم تستأنف من نقطة الحفظ المحفوظة.
|
||||
|
||||
## الاستئناف من نقطة حفظ
|
||||
<Steps>
|
||||
<Step title="أنشئ الطاقم مع تفعيل الـ Checkpointing">
|
||||
```python
|
||||
from crewai import Agent, Crew, Task
|
||||
|
||||
```python
|
||||
# استعادة واستئناف
|
||||
crew = Crew.from_checkpoint("./my_checkpoints/20260407T120000_abc123.json")
|
||||
result = crew.kickoff() # يستأنف من اخر مهمة مكتملة
|
||||
```
|
||||
researcher = Agent(role="Researcher", goal="Research", backstory="Expert")
|
||||
writer = Agent(role="Writer", goal="Write", backstory="Expert")
|
||||
|
||||
يتخطى الطاقم المستعاد المهام المكتملة ويستأنف من اول مهمة غير مكتملة.
|
||||
crew = Crew(
|
||||
agents=[researcher, writer],
|
||||
tasks=[
|
||||
Task(description="Research AI trends", agent=researcher, expected_output="bullets"),
|
||||
Task(description="Write a summary", agent=writer, expected_output="paragraph"),
|
||||
],
|
||||
checkpoint=True,
|
||||
)
|
||||
```
|
||||
</Step>
|
||||
<Step title="شغله وأوقفه بعد المهمة الأولى">
|
||||
```python
|
||||
result = crew.kickoff()
|
||||
```
|
||||
|
||||
## يعمل على Crew و Flow و Agent
|
||||
اضغط `Ctrl+C` بعد انتهاء المهمة الأولى. في `./.checkpoints/`، الملف بصيغة `<timestamp>_<uuid>.json` هو نقطة الحفظ.
|
||||
</Step>
|
||||
<Step title="استأنف من نقطة الحفظ">
|
||||
```python
|
||||
from crewai import CheckpointConfig
|
||||
|
||||
### Crew
|
||||
result = crew.kickoff(
|
||||
from_checkpoint=CheckpointConfig(
|
||||
restore_from="./.checkpoints/<timestamp>_<uuid>.json",
|
||||
),
|
||||
)
|
||||
```
|
||||
|
||||
```python
|
||||
crew = Crew(
|
||||
agents=[researcher, writer],
|
||||
tasks=[research_task, write_task, review_task],
|
||||
checkpoint=CheckpointConfig(location="./crew_cp"),
|
||||
)
|
||||
```
|
||||
يتم تخطي مهمة البحث، ويعمل الكاتب على مخرجات البحث المحفوظة، وينتهي الطاقم.
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
المشغل الافتراضي: `task_completed` (نقطة حفظ واحدة لكل مهمة مكتملة).
|
||||
## ادلة عملية
|
||||
|
||||
### Flow
|
||||
<AccordionGroup>
|
||||
<Accordion title="تفعيل الـ Checkpointing بالإعدادات الافتراضية" icon="play">
|
||||
```python
|
||||
crew = Crew(agents=[...], tasks=[...], checkpoint=True)
|
||||
```
|
||||
|
||||
```python
|
||||
from crewai.flow.flow import Flow, start, listen
|
||||
from crewai import CheckpointConfig
|
||||
يكتب إلى `./.checkpoints/` عند كل `task_completed`.
|
||||
</Accordion>
|
||||
|
||||
class MyFlow(Flow):
|
||||
@start()
|
||||
def step_one(self):
|
||||
return "data"
|
||||
<Accordion title="تخصيص التخزين والتردد" icon="sliders">
|
||||
```python
|
||||
from crewai import Crew, CheckpointConfig
|
||||
|
||||
@listen(step_one)
|
||||
def step_two(self, data):
|
||||
return process(data)
|
||||
crew = Crew(
|
||||
agents=[...],
|
||||
tasks=[...],
|
||||
checkpoint=CheckpointConfig(
|
||||
location="./my_checkpoints",
|
||||
on_events=["task_completed", "crew_kickoff_completed"],
|
||||
max_checkpoints=5,
|
||||
),
|
||||
)
|
||||
```
|
||||
</Accordion>
|
||||
|
||||
flow = MyFlow(
|
||||
checkpoint=CheckpointConfig(
|
||||
location="./flow_cp",
|
||||
on_events=["method_execution_finished"],
|
||||
),
|
||||
)
|
||||
result = flow.kickoff()
|
||||
<Accordion title="اختيار مزود التخزين" icon="database">
|
||||
<CodeGroup>
|
||||
```python JsonProvider
|
||||
from crewai import Crew, CheckpointConfig
|
||||
from crewai.state import JsonProvider
|
||||
|
||||
# استئناف
|
||||
flow = MyFlow.from_checkpoint("./flow_cp/20260407T120000_abc123.json")
|
||||
result = flow.kickoff()
|
||||
```
|
||||
crew = Crew(
|
||||
agents=[...],
|
||||
tasks=[...],
|
||||
checkpoint=CheckpointConfig(
|
||||
location="./my_checkpoints",
|
||||
provider=JsonProvider(),
|
||||
max_checkpoints=5,
|
||||
),
|
||||
)
|
||||
```
|
||||
```python SqliteProvider
|
||||
from crewai import Crew, CheckpointConfig
|
||||
from crewai.state import SqliteProvider
|
||||
|
||||
### Agent
|
||||
crew = Crew(
|
||||
agents=[...],
|
||||
tasks=[...],
|
||||
checkpoint=CheckpointConfig(
|
||||
location="./.checkpoints.db",
|
||||
provider=SqliteProvider(),
|
||||
max_checkpoints=50,
|
||||
),
|
||||
)
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
```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"}])
|
||||
```
|
||||
<Tip>
|
||||
SQLite يفعل وضع journal WAL للقراءات المتزامنة. يفضل لنقاط الحفظ عالية التردد.
|
||||
</Tip>
|
||||
</Accordion>
|
||||
|
||||
## مزودات التخزين
|
||||
<Accordion title="استبعاد وكيل واحد" icon="user-slash">
|
||||
```python
|
||||
crew = Crew(
|
||||
agents=[
|
||||
Agent(role="Researcher", ...),
|
||||
Agent(role="Writer", ..., checkpoint=False),
|
||||
],
|
||||
tasks=[...],
|
||||
checkpoint=True,
|
||||
)
|
||||
```
|
||||
</Accordion>
|
||||
|
||||
يتضمن CrewAI مزودي تخزين لنقاط الحفظ.
|
||||
<Accordion title="التفرع إلى فرع جديد" icon="code-branch">
|
||||
`fork()` يستعيد نقطة حفظ تحت نسب جديد بحيث لا يتصادم التشغيل الجديد مع الأصلي.
|
||||
|
||||
### JsonProvider (افتراضي)
|
||||
```python
|
||||
config = CheckpointConfig(restore_from="./my_checkpoints/<file>.json")
|
||||
crew = Crew.fork(config, branch="experiment-a")
|
||||
result = crew.kickoff(inputs={"strategy": "aggressive"})
|
||||
```
|
||||
|
||||
يكتب كل نقطة حفظ كملف JSON منفصل.
|
||||
تسمية `branch` اختيارية؛ يتم إنشاء واحدة إذا أغفلت.
|
||||
</Accordion>
|
||||
|
||||
```python
|
||||
from crewai import Crew, CheckpointConfig
|
||||
from crewai.state import JsonProvider
|
||||
<Accordion title="Checkpointing لـ Crew أو Flow أو Agent" icon="cubes">
|
||||
<Tabs>
|
||||
<Tab title="Crew">
|
||||
```python
|
||||
crew = Crew(
|
||||
agents=[researcher, writer],
|
||||
tasks=[research_task, write_task, review_task],
|
||||
checkpoint=CheckpointConfig(location="./crew_cp"),
|
||||
)
|
||||
```
|
||||
|
||||
crew = Crew(
|
||||
agents=[...],
|
||||
tasks=[...],
|
||||
checkpoint=CheckpointConfig(
|
||||
location="./my_checkpoints",
|
||||
provider=JsonProvider(),
|
||||
max_checkpoints=5,
|
||||
),
|
||||
)
|
||||
```
|
||||
المشغل الافتراضي: `task_completed`.
|
||||
</Tab>
|
||||
<Tab title="Flow">
|
||||
```python
|
||||
from crewai.flow.flow import Flow, start, listen
|
||||
from crewai import CheckpointConfig
|
||||
|
||||
### SqliteProvider
|
||||
class MyFlow(Flow):
|
||||
@start()
|
||||
def step_one(self):
|
||||
return "data"
|
||||
|
||||
يخزن جميع نقاط الحفظ في ملف قاعدة بيانات SQLite واحد.
|
||||
@listen(step_one)
|
||||
def step_two(self, data):
|
||||
return process(data)
|
||||
|
||||
```python
|
||||
from crewai import Crew, CheckpointConfig
|
||||
from crewai.state import SqliteProvider
|
||||
flow = MyFlow(
|
||||
checkpoint=CheckpointConfig(
|
||||
location="./flow_cp",
|
||||
on_events=["method_execution_finished"],
|
||||
),
|
||||
)
|
||||
result = flow.kickoff()
|
||||
```
|
||||
</Tab>
|
||||
<Tab title="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"}])
|
||||
```
|
||||
</Tab>
|
||||
</Tabs>
|
||||
</Accordion>
|
||||
|
||||
crew = Crew(
|
||||
agents=[...],
|
||||
tasks=[...],
|
||||
checkpoint=CheckpointConfig(
|
||||
location="./.checkpoints.db",
|
||||
provider=SqliteProvider(),
|
||||
),
|
||||
)
|
||||
```
|
||||
<Accordion title="كتابة نقطة حفظ يدويا" icon="code">
|
||||
سجل معالجا على أي حدث واستدع `state.checkpoint()`.
|
||||
|
||||
<CodeGroup>
|
||||
```python Sync
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING, Any
|
||||
|
||||
from crewai.events.event_bus import crewai_event_bus
|
||||
from crewai.events.types.llm_events import LLMCallCompletedEvent
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from crewai.state.runtime import RuntimeState
|
||||
|
||||
|
||||
## انواع الاحداث
|
||||
@crewai_event_bus.on(LLMCallCompletedEvent)
|
||||
def on_llm_done(source: Any, event: LLMCallCompletedEvent, state: RuntimeState) -> None:
|
||||
path = state.checkpoint("./my_checkpoints")
|
||||
print(f"تم حفظ نقطة الحفظ: {path}")
|
||||
```
|
||||
```python Async
|
||||
from __future__ import annotations
|
||||
|
||||
يقبل حقل `on_events` اي مجموعة من سلاسل انواع الاحداث. الخيارات الشائعة:
|
||||
from typing import TYPE_CHECKING, Any
|
||||
|
||||
| حالة الاستخدام | الاحداث |
|
||||
|:---------------|:--------|
|
||||
| بعد كل مهمة (Crew) | `["task_completed"]` |
|
||||
| بعد كل طريقة في التدفق | `["method_execution_finished"]` |
|
||||
| بعد تنفيذ الوكيل | `["agent_execution_completed"]`, `["lite_agent_execution_completed"]` |
|
||||
| عند اكتمال الطاقم فقط | `["crew_kickoff_completed"]` |
|
||||
| بعد كل استدعاء LLM | `["llm_call_completed"]` |
|
||||
| على كل شيء | `["*"]` |
|
||||
from crewai.events.event_bus import crewai_event_bus
|
||||
from crewai.events.types.llm_events import LLMCallCompletedEvent
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from crewai.state.runtime import RuntimeState
|
||||
|
||||
|
||||
@crewai_event_bus.on(LLMCallCompletedEvent)
|
||||
async def on_llm_done_async(source: Any, event: LLMCallCompletedEvent, state: RuntimeState) -> None:
|
||||
path = await state.acheckpoint("./my_checkpoints")
|
||||
print(f"تم حفظ نقطة الحفظ: {path}")
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
يتم تمرير وسيط `state` تلقائيا عندما يقبل المعالج ثلاثة معاملات. راجع [Event Listeners](/ar/concepts/event-listener) لقائمة الأحداث الكاملة.
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="التصفح والاستئناف والتفرع من سطر الأوامر" icon="terminal">
|
||||
```bash
|
||||
crewai checkpoint
|
||||
crewai checkpoint --location ./my_checkpoints
|
||||
crewai checkpoint --location ./.checkpoints.db
|
||||
```
|
||||
|
||||
<Frame caption="شجرة نقاط الحفظ — الفروع والتفرعات تتداخل تحت أبيها.">
|
||||
<img src="/images/checkpoint-tui-tree.png" alt="Checkpoint TUI tree view" />
|
||||
</Frame>
|
||||
|
||||
اللوحة اليسرى تجمع نقاط الحفظ حسب الفرع؛ التفرعات تتداخل تحت أبيها. اختيار نقطة حفظ يفتح لوحة التفاصيل مع بياناتها الوصفية وحالة الكيان وتقدم المهام. **Resume** يكمل التشغيل؛ **Fork** يبدأ فرعا جديدا.
|
||||
|
||||
<Frame caption="تبويب النظرة العامة — البيانات الوصفية وحالة الكيان وملخص التشغيل.">
|
||||
<img src="/images/checkpoint-tui-detail-overview.png" alt="Checkpoint detail overview tab" />
|
||||
</Frame>
|
||||
|
||||
لوحة التفاصيل تعرض منطقتين قابلتين للتحرير:
|
||||
|
||||
- **Inputs** — مدخلات الـ kickoff الأصلية، معبأة مسبقا وقابلة للتحرير.
|
||||
|
||||
<Frame>
|
||||
<img src="/images/checkpoint-tui-detail-inputs.png" alt="Editable kickoff inputs" />
|
||||
</Frame>
|
||||
|
||||
- **مخرجات المهام** — مخرجات المهام المكتملة. تحرير مخرج والضغط على **Fork** يبطل المهام التابعة لتعاد بالسياق المعدل.
|
||||
|
||||
<Frame>
|
||||
<img src="/images/checkpoint-tui-detail-tasks.png" alt="Editable task outputs" />
|
||||
</Frame>
|
||||
|
||||
<Frame caption="عرض التفرع — تأكيد فرع جديد من نقطة الحفظ المختارة.">
|
||||
<img src="/images/checkpoint-tui-details-fork.png" alt="Fork confirmation panel" />
|
||||
</Frame>
|
||||
|
||||
<Tip>
|
||||
مفيد لاستكشاف "ماذا لو": تفرع، عدل، راقب.
|
||||
</Tip>
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="تفقد نقاط الحفظ بدون TUI" icon="magnifying-glass">
|
||||
```bash
|
||||
crewai checkpoint list ./my_checkpoints
|
||||
crewai checkpoint info ./my_checkpoints/<file>.json
|
||||
crewai checkpoint info ./.checkpoints.db
|
||||
```
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
## المرجع
|
||||
|
||||
### `CheckpointConfig`
|
||||
|
||||
<ParamField path="location" type="str" default='"./.checkpoints"'>
|
||||
وجهة التخزين. مجلد لـ `JsonProvider`، مسار ملف قاعدة بيانات لـ `SqliteProvider`.
|
||||
</ParamField>
|
||||
|
||||
<ParamField path="on_events" type='list[CheckpointEventType | Literal["*"]]' default='["task_completed"]'>
|
||||
أنواع الأحداث التي تطلق نقطة حفظ. `CheckpointEventType` هو `Literal` — مدقق الأنواع يكمل تلقائيا ويرفض القيم غير المدعومة. راجع [أنواع الأحداث](#أنواع-الأحداث) للقائمة الكاملة.
|
||||
</ParamField>
|
||||
|
||||
<ParamField path="provider" type="BaseProvider" default="JsonProvider()">
|
||||
واجهة التخزين. `JsonProvider` أو `SqliteProvider`.
|
||||
</ParamField>
|
||||
|
||||
<ParamField path="max_checkpoints" type="int | None" default="None">
|
||||
الحد الاقصى لنقاط الحفظ المحتفظ بها. الأقدم تحذف بعد كل كتابة.
|
||||
</ParamField>
|
||||
|
||||
<ParamField path="restore_from" type="Path | str | None" default="None">
|
||||
نقطة الحفظ المراد استعادتها عند تمريرها عبر `from_checkpoint`.
|
||||
</ParamField>
|
||||
|
||||
### قيم حقل `checkpoint`
|
||||
|
||||
مقبولة في `Crew` و`Flow` و`Agent`.
|
||||
|
||||
<ParamField path="None" type="افتراضي">
|
||||
يرث من الأب.
|
||||
</ParamField>
|
||||
|
||||
<ParamField path="True" type="bool">
|
||||
تفعيل بالإعدادات الافتراضية.
|
||||
</ParamField>
|
||||
|
||||
<ParamField path="False" type="bool">
|
||||
انسحاب صريح. يوقف الوراثة.
|
||||
</ParamField>
|
||||
|
||||
<ParamField path="CheckpointConfig(...)" type="CheckpointConfig">
|
||||
إعدادات مخصصة.
|
||||
</ParamField>
|
||||
|
||||
### أنواع الأحداث
|
||||
|
||||
يقبل `on_events` أي مجموعة من قيم `CheckpointEventType`. الافتراضي `["task_completed"]` يكتب نقطة حفظ لكل مهمة منتهية، و`["*"]` يطابق جميع الأحداث.
|
||||
|
||||
<Warning>
|
||||
استخدام `["*"]` او احداث عالية التردد مثل `llm_call_completed` سيكتب العديد من ملفات نقاط الحفظ وقد يؤثر على الاداء. استخدم `max_checkpoints` للحد من استخدام المساحة.
|
||||
`["*"]` والأحداث عالية التردد مثل `llm_call_completed` تكتب نقاط حفظ كثيرة وقد تضر بالاداء. استخدمها مع `max_checkpoints`.
|
||||
</Warning>
|
||||
|
||||
## نقاط الحفظ اليدوية
|
||||
<Expandable title="جميع الأحداث المدعومة">
|
||||
|
||||
للتحكم الكامل، سجل معالج الاحداث الخاص بك واستدع `state.checkpoint()` مباشرة:
|
||||
- **Task** — `task_started`, `task_completed`, `task_failed`, `task_evaluation`
|
||||
- **Crew** — `crew_kickoff_started`, `crew_kickoff_completed`, `crew_kickoff_failed`, `crew_train_started`, `crew_train_completed`, `crew_train_failed`, `crew_test_started`, `crew_test_completed`, `crew_test_failed`, `crew_test_result`
|
||||
- **Agent** — `agent_execution_started`, `agent_execution_completed`, `agent_execution_error`, `lite_agent_execution_started`, `lite_agent_execution_completed`, `lite_agent_execution_error`, `agent_evaluation_started`, `agent_evaluation_completed`, `agent_evaluation_failed`
|
||||
- **Flow** — `flow_created`, `flow_started`, `flow_finished`, `flow_paused`, `method_execution_started`, `method_execution_finished`, `method_execution_failed`, `method_execution_paused`, `human_feedback_requested`, `human_feedback_received`, `flow_input_requested`, `flow_input_received`
|
||||
- **LLM** — `llm_call_started`, `llm_call_completed`, `llm_call_failed`, `llm_stream_chunk`, `llm_thinking_chunk`
|
||||
- **LLM Guardrail** — `llm_guardrail_started`, `llm_guardrail_completed`, `llm_guardrail_failed`
|
||||
- **Tool** — `tool_usage_started`, `tool_usage_finished`, `tool_usage_error`, `tool_validate_input_error`, `tool_selection_error`, `tool_execution_error`
|
||||
- **Memory** — `memory_save_started`, `memory_save_completed`, `memory_save_failed`, `memory_query_started`, `memory_query_completed`, `memory_query_failed`, `memory_retrieval_started`, `memory_retrieval_completed`, `memory_retrieval_failed`
|
||||
- **Knowledge** — `knowledge_search_query_started`, `knowledge_search_query_completed`, `knowledge_query_started`, `knowledge_query_completed`, `knowledge_query_failed`, `knowledge_search_query_failed`
|
||||
- **Reasoning** — `agent_reasoning_started`, `agent_reasoning_completed`, `agent_reasoning_failed`
|
||||
- **MCP** — `mcp_connection_started`, `mcp_connection_completed`, `mcp_connection_failed`, `mcp_tool_execution_started`, `mcp_tool_execution_completed`, `mcp_tool_execution_failed`, `mcp_config_fetch_failed`
|
||||
- **Observation** — `step_observation_started`, `step_observation_completed`, `step_observation_failed`, `plan_refinement`, `plan_replan_triggered`, `goal_achieved_early`
|
||||
- **Skill** — `skill_discovery_started`, `skill_discovery_completed`, `skill_loaded`, `skill_activated`, `skill_load_failed`
|
||||
- **Logging** — `agent_logs_started`, `agent_logs_execution`
|
||||
- **A2A** — `a2a_delegation_started`, `a2a_delegation_completed`, `a2a_conversation_started`, `a2a_conversation_completed`, `a2a_message_sent`, `a2a_response_received`, `a2a_polling_started`, `a2a_polling_status`, `a2a_push_notification_registered`, `a2a_push_notification_received`, `a2a_push_notification_sent`, `a2a_push_notification_timeout`, `a2a_streaming_started`, `a2a_streaming_chunk`, `a2a_agent_card_fetched`, `a2a_authentication_failed`, `a2a_artifact_received`, `a2a_connection_error`, `a2a_server_task_started`, `a2a_server_task_completed`, `a2a_server_task_canceled`, `a2a_server_task_failed`, `a2a_parallel_delegation_started`, `a2a_parallel_delegation_completed`, `a2a_transport_negotiated`, `a2a_content_type_negotiated`, `a2a_context_created`, `a2a_context_expired`, `a2a_context_idle`, `a2a_context_completed`, `a2a_context_pruned`
|
||||
- **إشارات النظام** — `SIGTERM`, `SIGINT`, `SIGHUP`, `SIGTSTP`, `SIGCONT`
|
||||
- **حرف بدل** — `"*"` يطابق جميع الأحداث.
|
||||
|
||||
```python
|
||||
from crewai.events.event_bus import crewai_event_bus
|
||||
from crewai.events.types.llm_events import LLMCallCompletedEvent
|
||||
</Expandable>
|
||||
|
||||
# معالج متزامن
|
||||
@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}")
|
||||
```
|
||||
<ParamField path="JsonProvider" type="provider">
|
||||
ملف واحد لكل نقطة حفظ بصيغة `<timestamp>_<uuid>.json` داخل `location`.
|
||||
</ParamField>
|
||||
|
||||
وسيط `state` هو `RuntimeState` الذي يتم تمريره تلقائيا بواسطة ناقل الاحداث عندما يقبل المعالج 3 معاملات. يمكنك تسجيل معالجات على اي نوع حدث مدرج في وثائق [Event Listeners](/ar/concepts/event-listener).
|
||||
<ParamField path="SqliteProvider" type="provider">
|
||||
ملف قاعدة بيانات واحد في `location` مع journaling WAL.
|
||||
</ParamField>
|
||||
|
||||
الـ Checkpointing يعمل بافضل جهد: اذا فشلت كتابة نقطة حفظ، يتم تسجيل الخطأ ولكن التنفيذ يستمر دون انقطاع.
|
||||
### سطر الأوامر
|
||||
|
||||
| الامر | الغرض |
|
||||
|:------|:------|
|
||||
| `crewai checkpoint` | تشغيل TUI؛ كشف التخزين تلقائيا. |
|
||||
| `crewai checkpoint --location <path>` | تشغيل TUI على موقع محدد. |
|
||||
| `crewai checkpoint list <path>` | سرد نقاط الحفظ. |
|
||||
| `crewai checkpoint info <path>` | تفقد ملف نقطة حفظ أو آخر مدخل في قاعدة بيانات SQLite. |
|
||||
|
||||
@@ -52,6 +52,8 @@ crewai create crew my_new_crew
|
||||
crewai create flow my_new_flow
|
||||
```
|
||||
|
||||
افتراضيًا، ينشئ `crewai create crew` مشروعًا JSON-first يحتوي على `crew.jsonc` و `agents/*.jsonc`. استخدم `crewai create crew my_new_crew --classic` فقط إذا أردت البنية القديمة Python/YAML مع `crew.py` و `config/agents.yaml` و `config/tasks.yaml`.
|
||||
|
||||
### 2. الإصدار
|
||||
|
||||
عرض الإصدار المثبت من CrewAI.
|
||||
@@ -142,7 +144,20 @@ crewai chat
|
||||
```
|
||||
|
||||
<Note>
|
||||
مهم: عيّن خاصية `chat_llm` في ملف `crew.py` لتفعيل هذا الأمر.
|
||||
مهم: عيّن خاصية `chat_llm` في تعريف الـ crew لتفعيل هذا الأمر.
|
||||
|
||||
للـ crews بنمط JSON-first، أضفها إلى `crew.jsonc`:
|
||||
|
||||
```jsonc
|
||||
{
|
||||
"name": "My Crew",
|
||||
"agents": ["researcher"],
|
||||
"tasks": [],
|
||||
"chat_llm": "openai/gpt-4o"
|
||||
}
|
||||
```
|
||||
|
||||
للـ crews الكلاسيكية Python/YAML، عيّنها في `crew.py`:
|
||||
|
||||
```python
|
||||
@crew
|
||||
|
||||
@@ -40,11 +40,52 @@ mode: "wide"
|
||||
|
||||
## إنشاء الأطقم
|
||||
|
||||
هناك طريقتان لإنشاء الأطقم في CrewAI: باستخدام **تهيئة YAML (موصى بها)** أو تعريفها **مباشرة في الكود**.
|
||||
هناك طريقتان رئيسيتان لإنشاء الأطقم في CrewAI: باستخدام **تهيئة JSONC (الموصى بها للـ crews الجديدة)** أو تعريفها **مباشرة في الكود** للمشاريع الكلاسيكية والحالات المتقدمة.
|
||||
|
||||
### تهيئة YAML (موصى بها)
|
||||
### تهيئة JSONC (موصى بها)
|
||||
|
||||
توفر تهيئة YAML طريقة أنظف وأكثر قابلية للصيانة لتعريف الأطقم وتتسق مع كيفية تعريف الوكلاء والمهام في مشاريع CrewAI.
|
||||
المشاريع الجديدة التي تُنشأ عبر `crewai create crew <name>` تستخدم `crew.jsonc` لإعدادات الـ crew والمهام، وملفًا منفصلًا لكل Agent داخل `agents/`. يكتشف `crewai run` ملف `crew.jsonc` أو `crew.json`، ويحمّل الـ Agents المشار إليها، ويطلب قيم placeholders الناقصة، ثم يبدأ الـ crew.
|
||||
|
||||
```jsonc crew.jsonc
|
||||
{
|
||||
"name": "Market Research Crew",
|
||||
"agents": ["researcher", "analyst"],
|
||||
"tasks": [
|
||||
{
|
||||
"name": "research",
|
||||
"description": "Research {topic} and collect the most relevant facts.",
|
||||
"expected_output": "Structured research notes about {topic}.",
|
||||
"agent": "researcher"
|
||||
},
|
||||
{
|
||||
"name": "analysis",
|
||||
"description": "Analyze the research and write a concise report.",
|
||||
"expected_output": "A markdown report with findings and recommendations.",
|
||||
"agent": "analyst",
|
||||
"context": ["research"],
|
||||
"output_file": "output/report.md"
|
||||
}
|
||||
],
|
||||
"process": "sequential",
|
||||
"verbose": true,
|
||||
"memory": true,
|
||||
"inputs": {
|
||||
"topic": "AI Agents"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
كل عنصر في `agents` يُحل أولًا إلى `agents/<name>.jsonc` ثم إلى `agents/<name>.json`. للـ crews الهرمية، استخدم `"process": "hierarchical"` مع `manager_llm` أو `manager_agent`.
|
||||
|
||||
<Warning>
|
||||
شغّل مشاريع JSON crew من مصادر تثق بها فقط. أدوات `custom:<name>` ومراجع `{"python": "module.attribute"}` تنفذ كود Python محليًا عند تحميل الـ crew.
|
||||
</Warning>
|
||||
|
||||
### تهيئة YAML الكلاسيكية
|
||||
|
||||
المشاريع الكلاسيكية التي تُنشأ عبر `crewai create crew <name> --classic` تستخدم `crew.py` و `config/agents.yaml` و `config/tasks.yaml` والمزيّنات `@CrewBase` و `@agent` و `@task` و `@crew`.
|
||||
|
||||
تظل هذه الطريقة مدعومة للمشاريع الحالية المبنية بـ Python/YAML وللفِرق التي تحتاج تحكمًا صريحًا عبر decorators.
|
||||
|
||||
```python code
|
||||
from crewai import Agent, Crew, Task, Process
|
||||
|
||||
@@ -226,6 +226,48 @@ counter=2 message='Hello from first_method - updated by second_method'
|
||||
من خلال ضمان إعادة مخرجات الدالة الأخيرة وتوفير الوصول إلى الحالة، تجعل تدفقات CrewAI من السهل دمج نتائج سير عمل الذكاء الاصطناعي في التطبيقات أو الأنظمة الأكبر،
|
||||
مع الحفاظ على الوصول إلى الحالة طوال تنفيذ التدفق.
|
||||
|
||||
## مقاييس استخدام التدفق
|
||||
|
||||
بعد اكتمال تنفيذ التدفق، يمكنك الوصول إلى الخاصية `usage_metrics` لعرض إجمالي استخدام التوكنات عبر **كل استدعاء لنموذج اللغة** يتم خلال التشغيل — بما في ذلك الاستدعاءات من كل فريق (Crew) ينظمه التدفق، والاستدعاءات داخل أدوات الـ Agents، والاستدعاءات المباشرة لـ `LLM.call(...)` من دوال التدفق. هذا هو المكافئ على جانب الـ SDK للإجماليات المعروضة في واجهة CrewAI Enterprise.
|
||||
|
||||
```python Code
|
||||
from crewai import LLM
|
||||
from crewai.flow.flow import Flow, listen, start
|
||||
|
||||
class UsageMetricsFlow(Flow):
|
||||
@start()
|
||||
def run_first_crew(self):
|
||||
self.state.first_result = FirstCrew().crew().kickoff()
|
||||
|
||||
@listen(run_first_crew)
|
||||
def call_llm_directly(self):
|
||||
# استدعاء مباشر لنموذج اللغة — يُحسب أيضًا ضمن flow.usage_metrics
|
||||
llm = LLM(model="openai/gpt-4o-mini")
|
||||
self.state.summary = llm.call("لخّص النقاط الرئيسية.")
|
||||
|
||||
@listen(call_llm_directly)
|
||||
def run_second_crew(self):
|
||||
self.state.second_result = SecondCrew().crew().kickoff()
|
||||
|
||||
flow = UsageMetricsFlow()
|
||||
flow.kickoff()
|
||||
|
||||
print(flow.usage_metrics)
|
||||
# UsageMetrics(total_tokens=8579, prompt_tokens=6210, completion_tokens=2369,
|
||||
# cached_prompt_tokens=0, reasoning_tokens=0,
|
||||
# cache_creation_tokens=0, successful_requests=5)
|
||||
```
|
||||
|
||||
<Note>
|
||||
`flow.usage_metrics` **ليست** نفس `flow.kickoff().token_usage`. هذه الأخيرة
|
||||
ترجع فقط `CrewOutput.token_usage` لـ **آخر** دالة `@listen` أعادت
|
||||
`CrewOutput`، مما يعني أنها تعكس فقط الفريق الأخير وتتجاهل الفرق السابقة
|
||||
وكذلك أي استدعاءات مباشرة لـ `LLM.call(...)`. استخدم `flow.usage_metrics`
|
||||
كلما احتجت إلى الإجمالي **الكامل** للتوكنات لتنفيذ التدفق.
|
||||
</Note>
|
||||
|
||||
كل حقل في [`UsageMetrics`](https://github.com/crewAIInc/crewAI/blob/main/lib/crewai/src/crewai/types/usage_metrics.py) المُعاد هو مجموع جميع استدعاءات نموذج اللغة التي حدثت خلال استدعاء واحد لـ `flow.kickoff()`. تتم إعادة تعيين العدادات عند الاستدعاء التالي لـ `kickoff()` (وفي كل تكرار من `kickoff_for_each`)، لذلك لن تتكرر العدّات عبر التشغيلات المتتالية. يمكن قراءة هذه الخاصية بأمان في أي وقت بعد اكتمال `kickoff()`؛ قراءتها أثناء التنفيذ تُرجع المجموع الجزئي المتراكم حتى تلك اللحظة.
|
||||
|
||||
## إدارة حالة التدفق
|
||||
|
||||
إدارة الحالة بفعالية أمر بالغ الأهمية لبناء سير عمل ذكاء اصطناعي موثوق وقابل للصيانة. توفر تدفقات CrewAI آليات قوية لإدارة الحالة غير المهيكلة والمهيكلة،
|
||||
@@ -788,7 +830,7 @@ if __name__ == "__main__":
|
||||
crewai create flow name_of_flow
|
||||
```
|
||||
|
||||
سيولّد هذا الأمر مشروع CrewAI جديد مع هيكل المجلدات اللازم. يتضمن المشروع المولّد فريق Crew مُعد مسبقًا يُسمى `poem_crew` ويعمل بالفعل. يمكنك استخدام هذا الفريق كقالب بنسخه ولصقه وتعديله لإنشاء فرق أخرى.
|
||||
سيولّد هذا الأمر مشروع CrewAI جديد مع هيكل المجلدات اللازم. يتضمن المشروع المولّد فريق Crew مُعد مسبقًا يُسمى `poem_crew` ويعمل بالفعل. يستخدم الـ embedded crew الابتدائي بنية Python/YAML الكلاسيكية؛ أما crews المستقلة الجديدة التي تُنشأ عبر `crewai create crew` فتستخدم بنية JSON-first.
|
||||
|
||||
### هيكل المجلدات
|
||||
|
||||
@@ -818,7 +860,29 @@ crewai create flow name_of_flow
|
||||
- `config/tasks.yaml`: يحدد المهام للفريق.
|
||||
- `poem_crew.py`: يحتوي على تعريف الفريق، بما في ذلك الـ Agents والمهام والفريق نفسه.
|
||||
|
||||
يمكنك نسخ ولصق وتعديل `poem_crew` لإنشاء فرق أخرى.
|
||||
يمكنك نسخ ولصق وتعديل `poem_crew` لإنشاء crews كلاسيكية مضمّنة أخرى.
|
||||
|
||||
للـ crews المضمّنة بنمط JSON-first، استخدم مجلدًا يحتوي على `crew.jsonc` و `agents/*.jsonc`:
|
||||
|
||||
```text
|
||||
crews/
|
||||
└── research_crew/
|
||||
├── agents/
|
||||
│ └── researcher.jsonc
|
||||
└── crew.jsonc
|
||||
```
|
||||
|
||||
ثم حمّلها من خطوة في Flow:
|
||||
|
||||
```python
|
||||
from pathlib import Path
|
||||
from crewai.project import load_crew
|
||||
|
||||
crew, default_inputs = load_crew(
|
||||
Path(__file__).parent / "crews" / "research_crew" / "crew.jsonc"
|
||||
)
|
||||
result = crew.kickoff(inputs={**default_inputs, "topic": "AI Agents"})
|
||||
```
|
||||
|
||||
### ربط فرق Crew في `main.py`
|
||||
|
||||
|
||||
@@ -107,7 +107,7 @@ mode: "wide"
|
||||
</Tabs>
|
||||
|
||||
<Info>
|
||||
يوفر CrewAI تكاملات SDK أصلية لـ OpenAI و Anthropic و Google (Gemini API) و Azure و AWS Bedrock -- لا حاجة لتثبيت إضافي بخلاف الملحقات الخاصة بالمزود (مثل `uv add "crewai[openai]"`).
|
||||
يوفر CrewAI تكاملات SDK أصلية لـ OpenAI و Anthropic و Google (Gemini API) و Azure و AWS Bedrock و Snowflake Cortex -- لا حاجة لتثبيت إضافي بخلاف الملحقات الخاصة بالمزود (مثل `uv add "crewai[openai]"`).
|
||||
|
||||
جميع المزودين الآخرين مدعومون بواسطة **LiteLLM**. إذا كنت تخطط لاستخدام أي منهم، أضفه كتبعية لمشروعك:
|
||||
```bash
|
||||
@@ -291,6 +291,55 @@ mode: "wide"
|
||||
```
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Snowflake Cortex">
|
||||
يوفر CrewAI تكاملًا أصليًا مع Snowflake Cortex REST API عبر endpoint Chat Completions المتوافق مع OpenAI. تستخدم نماذج `snowflake/...` هذا المسار بدون fallback إلى LiteLLM. يدعم Snowflake Cortex في CrewAI حاليًا Chat Completions فقط، لذلك استخدم وضع `api` الافتراضي ولا تضبط `api="responses"`.
|
||||
|
||||
```toml Code
|
||||
# Required
|
||||
SNOWFLAKE_PAT=<your-programmatic-access-token>
|
||||
SNOWFLAKE_ACCOUNT_URL=https://<account-identifier>.snowflakecomputing.com
|
||||
|
||||
# Alternative account configuration
|
||||
SNOWFLAKE_ACCOUNT=<account-identifier>
|
||||
```
|
||||
|
||||
**الاستخدام الأساسي:**
|
||||
```python Code
|
||||
from crewai import LLM
|
||||
|
||||
llm = LLM(
|
||||
model="snowflake/openai-gpt-4.1",
|
||||
temperature=0.7,
|
||||
max_completion_tokens=1024,
|
||||
)
|
||||
```
|
||||
|
||||
**نماذج Claude على Cortex:**
|
||||
```python Code
|
||||
from crewai import LLM
|
||||
|
||||
llm = LLM(
|
||||
model="snowflake/claude-sonnet-4-5",
|
||||
max_completion_tokens=1024,
|
||||
stream=True,
|
||||
)
|
||||
```
|
||||
|
||||
**متغيرات البيئة المدعومة:**
|
||||
- `SNOWFLAKE_PAT` أو `SNOWFLAKE_TOKEN` أو `SNOWFLAKE_JWT`: الرمز المستخدم كاعتماد Bearer
|
||||
- `SNOWFLAKE_ACCOUNT_URL`: عنوان URL الكامل لحساب Snowflake
|
||||
- `SNOWFLAKE_ACCOUNT` أو `SNOWFLAKE_ACCOUNT_ID` أو `SNOWFLAKE_ACCOUNT_IDENTIFIER`: معرف الحساب المستخدم لبناء URL
|
||||
|
||||
تستخدم طلبات Snowflake REST الدور الافتراضي للمستخدم. تأكد من أن هذا الدور لديه `SNOWFLAKE.CORTEX_USER` أو `SNOWFLAKE.CORTEX_REST_API_USER`. لا يتطلب endpoint Cortex REST Chat Completions معاملات database أو schema أو warehouse أو role صريح.
|
||||
|
||||
**الميزات:**
|
||||
- اختيار provider أصلي باستخدام `model="snowflake/<model-name>"`
|
||||
- Chat Completions مع streaming وبدونه فقط؛ `api="responses"` غير مدعوم
|
||||
- تتبع استخدام الرموز
|
||||
- استدعاء الدوال لنماذج OpenAI و Claude المستضافة في Snowflake
|
||||
- إزالة assistant prefill النهائي غير الصالح تلقائيًا لنماذج Claude في Snowflake
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Anthropic">
|
||||
يوفر CrewAI تكاملًا أصليًا مع Anthropic من خلال Anthropic Python SDK.
|
||||
|
||||
|
||||
@@ -16,7 +16,6 @@ mode: "wide"
|
||||
|
||||
- **تسلسلي**: ينفذ المهام بالتتابع، مما يضمن إكمال المهام بتقدم منظم.
|
||||
- **هرمي**: ينظم المهام في تسلسل إداري هرمي، حيث يتم تفويض المهام وتنفيذها بناءً على سلسلة أوامر منظمة. يجب تحديد نموذج لغة المدير (`manager_llm`) أو وكيل مدير مخصص (`manager_agent`) في الطاقم لتفعيل العملية الهرمية، مما يسهّل إنشاء وإدارة المهام من قبل المدير.
|
||||
- **العملية التوافقية (مخطط لها)**: تهدف إلى اتخاذ القرارات بشكل تعاوني بين الوكلاء حول تنفيذ المهام، وتقدم هذه العملية نهجًا ديمقراطيًا لإدارة المهام داخل CrewAI. وهي مخطط لها للتطوير المستقبلي وغير مطبقة حاليًا في قاعدة الكود.
|
||||
|
||||
## دور العمليات في العمل الجماعي
|
||||
تُمكّن العمليات الوكلاء الأفراد من العمل كوحدة متماسكة، مما يبسّط جهودهم لتحقيق أهداف مشتركة بكفاءة وتناسق.
|
||||
@@ -59,9 +58,9 @@ crew = Crew(
|
||||
|
||||
## فئة Process: نظرة عامة مفصلة
|
||||
|
||||
تم تنفيذ فئة `Process` كتعداد (`Enum`)، مما يضمن أمان الأنواع ويقيّد قيم العملية على الأنواع المحددة (`sequential`، `hierarchical`). العملية التوافقية مخطط لإدراجها مستقبلاً، مما يؤكد التزامنا بالتطوير والابتكار المستمر.
|
||||
تم تنفيذ فئة `Process` كتعداد (`Enum`)، مما يضمن أمان الأنواع ويقيّد قيم العملية على الأنواع المحددة (`sequential`، `hierarchical`).
|
||||
|
||||
## الخلاصة
|
||||
|
||||
التعاون المنظم الذي تسهّله العمليات داخل CrewAI ضروري لتمكين العمل الجماعي المنهجي بين الوكلاء.
|
||||
تم تحديث هذه الوثائق لتعكس أحدث الميزات والتحسينات والتكامل المخطط للعملية التوافقية، مما يضمن وصول المستخدمين إلى أحدث المعلومات وأكثرها شمولاً.
|
||||
تم تحديث هذه الوثائق لتعكس أحدث الميزات والتحسينات، مما يضمن وصول المستخدمين إلى أحدث المعلومات وأكثرها شمولاً.
|
||||
|
||||
@@ -73,13 +73,48 @@ crew = Crew(
|
||||
|
||||
## إنشاء المهام
|
||||
|
||||
هناك طريقتان لإنشاء المهام في CrewAI: باستخدام **إعداد YAML (موصى به)** أو تعريفها **مباشرة في الكود**.
|
||||
هناك طريقتان شائعتان لإنشاء المهام في CrewAI: باستخدام **تهيئة JSONC (الموصى بها للـ crews الجديدة)** أو تعريفها **مباشرة في الكود**.
|
||||
|
||||
### إعداد YAML (موصى به)
|
||||
### تهيئة JSONC (موصى بها)
|
||||
|
||||
يوفر استخدام إعداد YAML طريقة أنظف وأكثر قابلية للصيانة لتعريف المهام. نوصي بشدة باستخدام هذا النهج لتعريف المهام في مشاريع CrewAI.
|
||||
المشاريع الجديدة التي تُنشأ عبر `crewai create crew <name>` تعرّف المهام في `crew.jsonc`.
|
||||
|
||||
بعد إنشاء مشروع CrewAI كما هو موضح في قسم [التثبيت](/ar/installation)، انتقل إلى ملف `src/latest_ai_development/config/tasks.yaml` وعدّل القالب ليتوافق مع متطلبات مهامك المحددة.
|
||||
````jsonc crew.jsonc
|
||||
{
|
||||
"name": "Research Crew",
|
||||
"agents": ["researcher", "reporting_analyst"],
|
||||
"tasks": [
|
||||
{
|
||||
"name": "research_task",
|
||||
"description": "Conduct thorough research about {topic}.",
|
||||
"expected_output": "A list of the most relevant information about {topic}.",
|
||||
"agent": "researcher"
|
||||
},
|
||||
{
|
||||
"name": "reporting_task",
|
||||
"description": "Review the research and expand it into a detailed report.",
|
||||
"expected_output": "A polished markdown report.",
|
||||
"agent": "reporting_analyst",
|
||||
"context": ["research_task"],
|
||||
"markdown": true,
|
||||
"output_file": "report.md"
|
||||
}
|
||||
],
|
||||
"inputs": {
|
||||
"topic": "AI Agents"
|
||||
}
|
||||
}
|
||||
````
|
||||
|
||||
كل مهمة تحتاج إلى `description` و `expected_output`. يجب أن يطابق `agent` اسم Agent مذكورًا في `agents`. يشير `context` إلى أسماء مهام سابقة فقط؛ وترفض الإشارات إلى مهام لاحقة.
|
||||
|
||||
### إعداد YAML الكلاسيكي
|
||||
|
||||
المشاريع الكلاسيكية التي تُنشأ عبر `crewai create crew <name> --classic` تستخدم `config/tasks.yaml` وفئة `@CrewBase` في `crew.py`.
|
||||
|
||||
يظل إعداد YAML مدعومًا للمشاريع الحالية المبنية بـ Python/YAML وللفِرق التي تفضل تعريف المهام من خلال فئة `@CrewBase`.
|
||||
|
||||
بعد إنشاء مشروع كلاسيكي، انتقل إلى ملف `src/<project_name>/config/tasks.yaml` وعدّل القالب ليتوافق مع متطلبات مهامك المحددة.
|
||||
|
||||
<Note>
|
||||
المتغيرات في ملفات YAML (مثل `{topic}`) سيتم استبدالها بالقيم من مدخلاتك عند تشغيل الفريق:
|
||||
@@ -115,7 +150,7 @@ reporting_task:
|
||||
لاستخدام إعداد YAML هذا في كودك، أنشئ فئة فريق ترث من `CrewBase`:
|
||||
|
||||
```python crew.py
|
||||
# src/latest_ai_development/crew.py
|
||||
# src/<project_name>/crew.py
|
||||
|
||||
from crewai import Agent, Crew, Process, Task
|
||||
from crewai.project import CrewBase, agent, crew, task
|
||||
|
||||
112
docs/ar/enterprise/features/agent-control-plane/monitoring.mdx
Normal file
@@ -0,0 +1,112 @@
|
||||
---
|
||||
title: "راقب أتمتاتك"
|
||||
description: "راقب صحة الأسطول واستهلاك LLM وسلوك كل أتمتة من تبويب Automations."
|
||||
sidebarTitle: "المراقبة"
|
||||
icon: "gauge"
|
||||
mode: "wide"
|
||||
---
|
||||
|
||||
<Info>
|
||||
**تنقل وثائق ACP (إصدار تجريبي)**
|
||||
|
||||
- [نظرة عامة](/ar/enterprise/features/agent-control-plane/overview)
|
||||
- **المراقبة** *(أنت هنا)*
|
||||
- [القواعد](/ar/enterprise/features/agent-control-plane/rules)
|
||||
</Info>
|
||||
|
||||
## نظرة عامة
|
||||
|
||||
تبويب **Automations** هو عرض العمليات للقراءة فقط في [Agent Control Plane](/ar/enterprise/features/agent-control-plane/overview). يجمع بين بطاقتَي مقاييس و sankey تفاعلي وجدولين فرعيين — **Automations** و **Consumption** — يمكنك البحث والتصفية والفرز فيهما.
|
||||
|
||||
<Frame>
|
||||

|
||||
</Frame>
|
||||
|
||||
تحترم جميع المخططات والجداول مُحدّد **آخر 24 ساعة / الأسبوع الماضي / آخر 30 يوماً** في أعلى اليمين. تقارن قيم الفرق النافذة المختارة بالنافذة السابقة بنفس الطول.
|
||||
|
||||
<Note>
|
||||
تعرض الصفوف بيانات فقط لعمليات النشر على **crewAI v1.13 أو أحدث** — تظهر عمليات النشر الأقدم في لافتة *"We've detected N other automations that we can't display"* أسفل sankey ولا تساهم بأي مقاييس حتى يتم تحديثها وإعادة نشرها. راجع [نظرة عامة — المتطلبات](/ar/enterprise/features/agent-control-plane/overview#المتطلبات).
|
||||
</Note>
|
||||
|
||||
## لوحة المعلومات
|
||||
|
||||
يحتوي رأس الصفحة على بطاقتَي مقاييس و sankey تفاعلي. النقر على أي من البطاقتين يبدّل sankey بين وضعَين:
|
||||
|
||||
- **وضع الصحة** — `إجمالي الأتمتات → حِزم الحالة (Critical / Warning / Healthy)`. انقر على حِزمة لتصفية جدول Automations إلى عمليات النشر تلك فقط.
|
||||
- **وضع الاستهلاك** — `مزودو النماذج → الأتمتات → التكلفة الإجمالية`. انقر على مزود لتصفية جدول Consumption إلى ذلك المزود.
|
||||
|
||||
| البطاقة | ما تعرضه |
|
||||
|------|---------------|
|
||||
| **Automations** | الأتمتات `active` (والعدد الإجمالي)، إجمالي `errors` في النافذة، `active executions` الحالية (والإجمالي في النافذة)، مع الفرق مقابل الفترة السابقة. |
|
||||
| **Consumption** | إجمالي `cost` و `tokens used`، مع فرق التكلفة مقابل الفترة السابقة. |
|
||||
|
||||
<Frame>
|
||||

|
||||
</Frame>
|
||||
|
||||
## جدول Automations
|
||||
|
||||
التبويب الفرعي **Automations** هو تفصيل صحة الأسطول لكل deployment. كل صف هو crew أو flow منشور.
|
||||
|
||||
<Frame>
|
||||

|
||||
</Frame>
|
||||
|
||||
| العمود | ما يعرضه |
|
||||
|--------|---------------|
|
||||
| **Automation** | اسم الـ deployment وأي وسوم مُسنَدة إليه (مثل `production`، `financial`). |
|
||||
| **Last execution** | الوقت المنقضي منذ آخر تنفيذ. |
|
||||
| **Health Status Breakdown** | شريط مكدّس بنسب `Critical` / `Warning` / `Healthy` لعمليات التنفيذ في النافذة. |
|
||||
| **Executions with Errors** | إجمالي عمليات التنفيذ الفاشلة في النافذة. |
|
||||
| **PII detection applied** | `Yes` إذا كان هناك تكوين PII لكل deployment أو [قاعدة PII](/ar/enterprise/features/agent-control-plane/rules) مطابِقة نشطة. |
|
||||
| **Executions** | إجمالي عمليات التنفيذ في النافذة. |
|
||||
| **Last updated** | متى أُعيد نشر الـ deployment آخر مرة. |
|
||||
| **Crew Version** | إصدار `crewai` الذي يُبلِّغ عنه الـ deployment. يشير أيقونة المعلومات بجانب الإصدارات الأقل من `1.13` إلى صفوف لا يمكنها المساهمة بالمقاييس. |
|
||||
|
||||
ابحث بالاسم، صفِّ حسب `Status` (`Healthy` / `Warning` / `Critical`)، وافرز بأي رأس عمود. انقر على اسم الـ deployment لفتح **لوحة الأتمتة**.
|
||||
|
||||
## جدول Consumption
|
||||
|
||||
التبويب الفرعي **Consumption** هو تفصيل إنفاق LLM واستخدام الرموز لكل deployment.
|
||||
|
||||
<Frame>
|
||||

|
||||
</Frame>
|
||||
|
||||
| العمود | ما يعرضه |
|
||||
|--------|---------------|
|
||||
| **Automation** | اسم الـ deployment. |
|
||||
| **Last execution** | الوقت المنقضي منذ آخر تنفيذ. |
|
||||
| **Tokens used** | صف واحد لكل مزود LLM تستخدمه هذه الأتمتة، مع الفرق مقابل الفترة السابقة. |
|
||||
| **Cost** | التكلفة لكل مزود LLM، مع الفرق مقابل الفترة السابقة. |
|
||||
| **Total cost** | المجموع عبر جميع المزودين، مع الفرق. |
|
||||
| **Executions** | إجمالي عمليات التنفيذ في النافذة. |
|
||||
| **Last updated** | متى أُعيد نشر الـ deployment آخر مرة. |
|
||||
| **Crew Version** | إصدار `crewai` الذي يُبلِّغ عنه الـ deployment. |
|
||||
|
||||
صفِّ حسب **LLM provider** وافرز حسب `Cost` أو `Executions` أو `Last run`.
|
||||
|
||||
<Info>
|
||||
**عادة ما تعني الخلايا الفارغة (`—` أو `$0.00`) أن الـ deployment أدنى من crewAI v1.13.** في اللقطة أعلاه، تظهر *Automation F* (`1.7.0`) و *Automation I* (`1.12.2`) فارغة في الرموز والتكلفة — لا تزال عمليات التنفيذ تعمل، لكنها لا تُصدِر التليمتري على مستوى المزود الذي يُغذِّي هذا الجدول. حدّث هذه الـ crews وأعد نشرها لبدء جمع بيانات الاستهلاك.
|
||||
</Info>
|
||||
|
||||
## ذو صلة
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Agent Control Plane — نظرة عامة" icon="book-open" href="/ar/enterprise/features/agent-control-plane/overview">
|
||||
ما هو ACP، المتطلبات، مستويات الخطط، و RBAC.
|
||||
</Card>
|
||||
<Card title="Agent Control Plane — القواعد" icon="shield-check" href="/ar/enterprise/features/agent-control-plane/rules">
|
||||
طبّق قواعد PII Redaction على مستوى المؤسسة عبر العديد من الأتمتات.
|
||||
</Card>
|
||||
<Card title="Traces" icon="timeline" href="/ar/enterprise/features/traces">
|
||||
تعمّق في تنفيذ واحد لرؤية تفكير الوكيل واستدعاءات الأدوات واستخدام الرموز.
|
||||
</Card>
|
||||
<Card title="النشر إلى AMP" icon="rocket" href="/ar/enterprise/guides/deploy-to-amp">
|
||||
انشر crew على إصدار crewAI يدعم Agent Control Plane.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
<Card title="تحتاج مساعدة؟" icon="headset" href="mailto:support@crewai.com">
|
||||
تواصل مع فريق الدعم للمساعدة في تفسير المقاييس داخل Agent Control Plane.
|
||||
</Card>
|
||||
82
docs/ar/enterprise/features/agent-control-plane/overview.mdx
Normal file
@@ -0,0 +1,82 @@
|
||||
---
|
||||
title: نظرة عامة على Agent Control Plane
|
||||
description: "مركز عمليات موحّد للأتمتات الجارية — صحة الأسطول واستهلاك LLM والسياسات على مستوى المؤسسة في مكان واحد."
|
||||
sidebarTitle: نظرة عامة
|
||||
icon: "book-open"
|
||||
---
|
||||
|
||||
<Info>
|
||||
**تنقل وثائق ACP (إصدار تجريبي)**
|
||||
|
||||
- **نظرة عامة** *(أنت هنا)*
|
||||
- [المراقبة](/ar/enterprise/features/agent-control-plane/monitoring)
|
||||
- [القواعد](/ar/enterprise/features/agent-control-plane/rules)
|
||||
</Info>
|
||||
|
||||
## نظرة عامة
|
||||
|
||||
**Agent Control Plane** (ACP) هو مركز العمليات لكل ما يعمل لديك على CrewAI AMP. إنها شاشة واحدة — مقسّمة إلى تبويبَي **Automations** و **Rules** — تمنح فريقك القدرة على:
|
||||
|
||||
- مراقبة **حالة (الصحة)** كل أتمتة حيّة (crew أو flow) بتفصيل `Critical` / `Warning` / `Healthy` وعدد عمليات التنفيذ.
|
||||
- تتبع **استهلاك LLM** — الرموز (tokens) والتكلفة — لكل أتمتة ولكل مزود ولكل نموذج، مع الفرق مقابل الفترة السابقة.
|
||||
- التعمّق في أي أتمتة منفردة أو مزود نماذج لرؤية المخططات الزمنية وتفصيل البيانات لكل مزود.
|
||||
- تطبيق **قواعد (Rules)** على مستوى المؤسسة (اليوم: PII Redaction) عبر العديد من الأتمتات دفعة واحدة بدلاً من تعديل كل deployment على حدة.
|
||||
|
||||
<Frame>
|
||||

|
||||
</Frame>
|
||||
|
||||
<Note>
|
||||
Agent Control Plane مُوسوم حالياً بـ **Beta** في CrewAI Platform.
|
||||
</Note>
|
||||
|
||||
يجيب التبويبان عن سؤالَين مختلفَين:
|
||||
|
||||
- **Automations** — *"كيف يتصرف أسطولي الآن، وكم يكلّفني؟"* راجع [المراقبة](/ar/enterprise/features/agent-control-plane/monitoring).
|
||||
- **Rules** — *"كيف أفرض سياسة (مثل PII redaction) عبر العديد من عمليات النشر دون إعادة نشر كل واحدة؟"* راجع [القواعد](/ar/enterprise/features/agent-control-plane/rules).
|
||||
|
||||
## المتطلبات
|
||||
|
||||
<Warning>
|
||||
يُشترط **crewAI v1.13 أو أحدث** ليتمكن أي أتمتة من تعبئة أي بيانات على هذه الصفحة — تمر بيانات الصحة وعمليات التنفيذ والأخطاء والرموز والتكلفة عبر التليمتري الذي تم تفعيله في `crewai==1.13`. تظهر عمليات النشر الأقدم في لافتة *"We've detected N other automations that we can't display"* ولا تساهم بأي صفوف حتى يتم تحديثها وإعادة نشرها.
|
||||
</Warning>
|
||||
|
||||
<Warning>
|
||||
يُشترط **خطة Enterprise أو Ultra** لإنشاء أو تعديل [القواعد](/ar/enterprise/features/agent-control-plane/rules). يمكن للمؤسسات على الخطط الأدنى فتح تبويب Rules وعرض القواعد الموجودة، ولكن يُعرض المحرر للقراءة فقط مع شارة قفل "Enterprise" والتنبيه *"PII Redaction rules require an Enterprise plan."*. المراقبة (تبويب Automations) متاحة في جميع الخطط حيث يكون هذا الميزة مفعّلة.
|
||||
</Warning>
|
||||
|
||||
- يجب أن تكون ميزة **Agent Control Plane** مفعّلة لمؤسستك. إن لم ترها في الشريط الجانبي، اطلب من مالك الحساب تفعيلها.
|
||||
- داخل ACP، يحكم [RBAC](/ar/enterprise/features/rbac) الوصول: `read` للعرض في لوحة المعلومات والقواعد، و`manage` لإنشاء وتعديل وتشغيل/إيقاف وحذف القواعد.
|
||||
- يمكن ضبط نطاق جميع المخططات والجداول إلى **آخر 24 ساعة** أو **الأسبوع الماضي** أو **آخر 30 يوماً** عبر مُحدّد الوقت في أعلى اليمين. تقارن قيم الفرق (`↑ 8 vs yesterday`, `↓ $20.57 vs yesterday` وغيرها) النافذة المختارة بالنافذة السابقة بنفس الطول.
|
||||
|
||||
## ما يمكنك فعله هنا
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="المراقبة" icon="gauge" href="/ar/enterprise/features/agent-control-plane/monitoring">
|
||||
راقب صحة الأسطول وإنفاق LLM عبر بطاقات المقاييس و sankey التفاعلي وجداول لكل أتمتة ولوحات جانبية للتعمق في أي أتمتة أو مزود.
|
||||
</Card>
|
||||
<Card title="القواعد" icon="shield-check" href="/ar/enterprise/features/agent-control-plane/rules">
|
||||
طبّق سياسات PII Redaction على مستوى المؤسسة بنطاق محدد بالأدوات والوسوم. تسري التغييرات في التنفيذ التالي — دون الحاجة لإعادة نشر.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
## ذو صلة
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Traces" icon="timeline" href="/ar/enterprise/features/traces">
|
||||
تعمّق في تنفيذ واحد لرؤية تفكير الوكيل واستدعاءات الأدوات واستخدام الرموز.
|
||||
</Card>
|
||||
<Card title="RBAC" icon="users" href="/ar/enterprise/features/rbac">
|
||||
أدِر من يمكنه قراءة Agent Control Plane ومن يمكنه تعديل القواعد.
|
||||
</Card>
|
||||
<Card title="PII Redaction للـ Traces" icon="lock" href="/ar/enterprise/features/pii-trace-redactions">
|
||||
كتالوج الكيانات وضبط PII لكل deployment التي تستند إليها القواعد.
|
||||
</Card>
|
||||
<Card title="النشر إلى AMP" icon="rocket" href="/ar/enterprise/guides/deploy-to-amp">
|
||||
انشر crew على إصدار crewAI يدعم Agent Control Plane.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
<Card title="تحتاج مساعدة؟" icon="headset" href="mailto:support@crewai.com">
|
||||
تواصل مع فريق الدعم للمساعدة في تفسير المقاييس أو تصميم القواعد.
|
||||
</Card>
|
||||
122
docs/ar/enterprise/features/agent-control-plane/rules.mdx
Normal file
@@ -0,0 +1,122 @@
|
||||
---
|
||||
title: "إعداد القواعد"
|
||||
description: "طبّق سياسات على مستوى المؤسسة عبر العديد من الأتمتات من مكان واحد."
|
||||
sidebarTitle: "القواعد"
|
||||
icon: "shield-check"
|
||||
mode: "wide"
|
||||
---
|
||||
|
||||
<Info>
|
||||
**تنقل وثائق ACP (إصدار تجريبي)**
|
||||
|
||||
- [نظرة عامة](/ar/enterprise/features/agent-control-plane/overview)
|
||||
- [المراقبة](/ar/enterprise/features/agent-control-plane/monitoring)
|
||||
- **القواعد** *(أنت هنا)*
|
||||
</Info>
|
||||
|
||||
## نظرة عامة
|
||||
|
||||
تتيح لك القواعد تطبيق سياسات — اليوم: **PII Redaction** — عبر العديد من الأتمتات دفعة واحدة، بدلاً من ضبط كل deployment على حدة. افتح تبويب **Rules** في [Agent Control Plane](/ar/enterprise/features/agent-control-plane/overview) لإدارتها.
|
||||
|
||||
<Frame>
|
||||

|
||||
</Frame>
|
||||
|
||||
تعرض كل بطاقة قاعدة الاسم والوصف و**النطاق (scope)** الذي تنطبق عليه القاعدة (الأدوات والوسوم المختارة) وعدد **الأتمتات المُفعَّلة** — عمليات النشر التي تطابق النطاق حالياً. يقوم المُفتاح على اليمين بتشغيل القاعدة أو إيقافها دون حذفها.
|
||||
|
||||
## المتطلبات
|
||||
|
||||
<Warning>
|
||||
يُشترط **خطة Enterprise أو Ultra** لإنشاء أو تعديل قواعد PII Redaction. يمكن للمؤسسات على الخطط الأدنى فتح تبويب Rules وعرض القواعد الموجودة، ولكن يُعرض المحرر للقراءة فقط مع شارة قفل "Enterprise" والتنبيه *"PII Redaction rules require an Enterprise plan."* — تواصل مع مالك حسابك أو المبيعات للترقية.
|
||||
</Warning>
|
||||
|
||||
- يجب أن تكون ميزة **Agent Control Plane** مفعّلة لمؤسستك. راجع [نظرة عامة — المتطلبات](/ar/enterprise/features/agent-control-plane/overview#المتطلبات).
|
||||
- تحتاج إلى صلاحية `manage` ضمن [RBAC](/ar/enterprise/features/rbac) على Agent Control Plane لإنشاء وتعديل وتشغيل/إيقاف وحذف القواعد. صلاحية `read` كافية لعرضها.
|
||||
- تُسجَّل جميع تغييرات القواعد بإصدارات للتدقيق.
|
||||
|
||||
## أنواع القواعد المتاحة
|
||||
|
||||
| النوع | ما تفعله |
|
||||
|------|---------------|
|
||||
| **PII Redaction** | تطبّق PII redaction على عمليات التنفيذ لكل أتمتة مطابِقة، باستخدام نفس كتالوج الكيانات و recognizers المخصصة الموثَّقة في [PII Redaction للـ Traces](/ar/enterprise/features/pii-trace-redactions). |
|
||||
|
||||
سيتم إضافة أنواع قواعد أخرى مع الوقت.
|
||||
|
||||
## إنشاء قاعدة
|
||||
|
||||
<Frame>
|
||||
<img src="/images/enterprise/acp-rules-edit-side-panel.png" alt="لوحة تعديل قاعدة جانبية بالشروط ونوع قناع PII" width="450" />
|
||||
</Frame>
|
||||
|
||||
<Steps>
|
||||
<Step title="افتح المحرر">
|
||||
انقر على **+ Create new** في أعلى يمين تبويب Rules، أو على **View Details** في بطاقة قاعدة موجودة.
|
||||
</Step>
|
||||
|
||||
<Step title="سَمِّ القاعدة وصِفها">
|
||||
أعطِ القاعدة اسماً واضحاً (مثل *Mask PII (CC)*) ووصفاً يشرح متى تنطبق. يظهر كلاهما على بطاقة القاعدة وفي مودال Engaged Automations.
|
||||
</Step>
|
||||
|
||||
<Step title="اختر النوع">
|
||||
اليوم **PII Redaction** فقط متاحة.
|
||||
</Step>
|
||||
|
||||
<Step title="حدّد الشروط">
|
||||
تحدد الشروط الأتمتات التي تنخرط معها القاعدة. كلاهما اختياري ويستخدم دلالات **مساواة المجموعات (set-equality)**:
|
||||
|
||||
- **Tools** — تنخرط فقط الأتمتات التي تتطابق مجموعة أدواتها **تطابقاً تامّاً** مع الأدوات المختارة. اختر من تطبيقات Studio و MCPs والأدوات مفتوحة المصدر وأدوات سجل Tool Repository.
|
||||
- **Automations** — تنخرط فقط الأتمتات التي تتطابق مجموعة وسومها **تطابقاً تامّاً** مع الوسوم المختارة.
|
||||
|
||||
ترك مُحدِّد فارغ يعني "بدون تصفية على هذا البعد". ترك كليهما فارغَين يعني أن القاعدة تنطبق على **كل** أتمتة في المؤسسة.
|
||||
</Step>
|
||||
|
||||
<Step title="اضبط جدول PII Mask Type">
|
||||
حدّد كل نوع كيان تريد تغطيته واختر **Mask** (يستبدل بتسمية الكيان مثل `<CREDIT_CARD>`) أو **Redact** (يحذف النص المطابِق بالكامل). راجع [PII Redaction للـ Traces](/ar/enterprise/features/pii-trace-redactions) للاطلاع على كتالوج الكيانات الكامل وكيفية إضافة recognizers مخصصة على مستوى المؤسسة.
|
||||
</Step>
|
||||
|
||||
<Step title="احفظ">
|
||||
تنطبق القاعدة على عمليات التنفيذ **المستقبلية** لكل أتمتة مُفعَّلة بمجرد الحفظ. لا حاجة لإعادة النشر.
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
## الأتمتات المُفعَّلة
|
||||
|
||||
انقر على **Engaged N automations** في أي بطاقة قاعدة لرؤية أي عمليات النشر تطابقها القاعدة حالياً بالضبط، إلى جانب آخر تنفيذ لكل منها.
|
||||
|
||||
<Frame>
|
||||

|
||||
</Frame>
|
||||
|
||||
هذه هي أسرع طريقة للتحقق من نطاق قاعدة قبل تمكينها — على سبيل المثال، للتأكد من أن قاعدة محدَّدة بنطاق وسم `production` لا تطابق عن طريق الخطأ deployment تجريبي.
|
||||
|
||||
## قواعد على مستوى المؤسسة مقابل إعدادات لكل deployment
|
||||
|
||||
يمكن ضبط PII Redaction في مكانين:
|
||||
|
||||
- **لكل deployment** — ضمن **Settings → PII Protection** على كل deployment على حدة ([الدليل](/ar/enterprise/features/pii-trace-redactions))
|
||||
- **على مستوى المؤسسة** — كقاعدة في هذه الصفحة
|
||||
|
||||
عندما يتطابق نطاق قاعدة مُفعَّلة على مستوى المؤسسة مع deployment، يُجاوز تكوين الكيانات الخاص بالقاعدة **إعدادات PII المملوكة من قبل الـ deployment** لعمليات تنفيذ ذلك الـ deployment — تصبح القاعدة المصدر الوحيد للحقيقة طالما هي مرتبطة. عطّل القاعدة أو فُكَّ ارتباطها (أو غيِّر نطاقها بحيث لا تتطابق بعد الآن) ويعود الـ deployment إلى إعدادات PII Protection الخاصة به.
|
||||
|
||||
فضّل القواعد على مستوى المؤسسة عندما تريد فرض سياسة متسقة عبر العديد من عمليات النشر؛ احتفظ بالضبط لكل deployment للاستثناءات الفردية.
|
||||
|
||||
## ذو صلة
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Agent Control Plane — نظرة عامة" icon="book-open" href="/ar/enterprise/features/agent-control-plane/overview">
|
||||
ما هو ACP، المتطلبات، مستويات الخطط، و RBAC.
|
||||
</Card>
|
||||
<Card title="Agent Control Plane — المراقبة" icon="gauge" href="/ar/enterprise/features/agent-control-plane/monitoring">
|
||||
راقب الأتمتات واستهلاك LLM عبر أسطولك.
|
||||
</Card>
|
||||
<Card title="PII Redaction للـ Traces" icon="lock" href="/ar/enterprise/features/pii-trace-redactions">
|
||||
كتالوج الكيانات، recognizers المخصصة، والضبط لكل deployment.
|
||||
</Card>
|
||||
<Card title="RBAC" icon="users" href="/ar/enterprise/features/rbac">
|
||||
أدِر من يمكنه إنشاء أو تعديل القواعد.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
<Card title="تحتاج مساعدة؟" icon="headset" href="mailto:support@crewai.com">
|
||||
تواصل مع فريق الدعم للمساعدة في تصميم قواعد لمؤسستك.
|
||||
</Card>
|
||||
@@ -26,10 +26,10 @@ icon: "arrows-rotate"
|
||||
|
||||
## الخطوة 1 — هيكلة طاقم التحقق
|
||||
|
||||
أنشئ مشروع طاقم جديد. يُهيكل CrewAI CLI البنية:
|
||||
أنشئ مشروع crew كلاسيكيًا لأن هذا المثال يربط أداة Python عبر `crew.py`:
|
||||
|
||||
```bash
|
||||
crewai create crew rotation_verifier --skip_provider
|
||||
crewai create crew rotation_verifier --classic --skip_provider
|
||||
cd rotation_verifier
|
||||
```
|
||||
|
||||
|
||||
@@ -24,15 +24,39 @@ mode: "wide"
|
||||
|
||||
1. في CrewAI AMP، انتقل إلى **Settings** > **OpenTelemetry Collectors**.
|
||||
2. انقر على **Add Collector**.
|
||||
3. اختر نوع التكامل — **OpenTelemetry Traces** أو **OpenTelemetry Logs**.
|
||||
4. هيّئ الاتصال:
|
||||
- **Endpoint** — نقطة نهاية OTLP لمجمّعك (مثل `https://otel-collector.example.com:4317`).
|
||||
- **Service Name** — اسم لتعريف هذه الخدمة في منصة المراقبة.
|
||||
- **Custom Headers** *(اختياري)* — أضف رؤوس المصادقة أو التوجيه كأزواج مفتاح-قيمة.
|
||||
- **Certificate** *(اختياري)* — قدم شهادة TLS إذا كان مجمّعك يتطلبها.
|
||||
5. انقر على **Save**.
|
||||
3. اختر تكاملاً:
|
||||
- **OpenTelemetry Traces** و**OpenTelemetry Logs** — صدّر إلى أي مجمّع أو واجهة خلفية متوافقة مع OTLP.
|
||||
- **Datadog** — أرسل التتبعات مباشرة إلى استقبال OTLP الخاص بـ Datadog، دون الحاجة إلى مجمّع منفصل أو Datadog Agent.
|
||||
4. هيّئ الاتصال. تعتمد الحقول على التكامل الذي اخترته:
|
||||
|
||||
<Frame></Frame>
|
||||
<Tabs>
|
||||
<Tab title="OpenTelemetry Traces / Logs">
|
||||
إن **OpenTelemetry Traces** و**OpenTelemetry Logs** تكاملان منفصلان يتشاركان نفس الحقول — اختر التكامل المطابق للإشارة التي تريد تصديرها.
|
||||
|
||||
- **Endpoint** — نقطة نهاية OTLP لمجمّعك (مثل `https://otel-collector.example.com:4317`).
|
||||
- **Service Name** — اسم لتعريف هذه الخدمة في منصة المراقبة.
|
||||
- **Custom Headers** *(اختياري)* — أضف رؤوس المصادقة أو التوجيه كأزواج مفتاح-قيمة.
|
||||
- **Certificate** *(اختياري)* — قدم شهادة TLS إذا كان مجمّعك يتطلبها.
|
||||
|
||||
<Frame></Frame>
|
||||
</Tab>
|
||||
<Tab title="Datadog">
|
||||
- **Datadog Site Domain** — مضيف OTLP لموقع Datadog الخاص بك فقط، دون بروتوكول أو مسار. يقوم CrewAI ببناء نقطة نهاية HTTPS OTLP الكاملة نيابةً عنك. استخدم المضيف المطابق لـ [موقع Datadog](https://docs.datadoghq.com/getting_started/site/) الخاص بك:
|
||||
- `otlp.datadoghq.com` (US1)
|
||||
- `otlp.us3.datadoghq.com` (US3)
|
||||
- `otlp.us5.datadoghq.com` (US5)
|
||||
- `otlp.datadoghq.eu` (EU1)
|
||||
- `otlp.ap1.datadoghq.com` (AP1)
|
||||
- **API Key** — مفتاح واجهة برمجة تطبيقات Datadog الخاص بك. راجع [كيفية إنشاء واحد](https://docs.datadoghq.com/account_management/api-app-keys/#api-keys).
|
||||
|
||||
يصدّر تكامل Datadog **التتبعات**.
|
||||
|
||||
<Frame></Frame>
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
5. *(اختياري)* انقر على **Test Connection** للتحقق من قدرة CrewAI على الوصول إلى نقطة النهاية باستخدام بيانات الاعتماد التي قدمتها.
|
||||
6. انقر على **Save**.
|
||||
|
||||
<Tip>
|
||||
يمكنك إضافة مجمّعات متعددة — على سبيل المثال، واحد للتتبعات وآخر للسجلات، أو الإرسال إلى واجهات خلفية مختلفة لأغراض مختلفة.
|
||||
|
||||
@@ -164,6 +164,12 @@ crewai deploy remove <deployment_id>
|
||||

|
||||
</Frame>
|
||||
|
||||
<Tip>
|
||||
إذا كان Crew أو Flow داخل مجلد فرعي في monorepo، فوسّع **Advanced**
|
||||
وعيّن دليل عمل قبل النشر. راجع
|
||||
[النشر من Monorepo](/ar/enterprise/guides/monorepo-deployments).
|
||||
</Tip>
|
||||
|
||||
</Step>
|
||||
|
||||
<Step title="تعيين متغيرات البيئة">
|
||||
@@ -368,17 +374,17 @@ git push
|
||||
|
||||
**الحل**: تحقق من أن مشروعك يتطابق مع البنية المتوقعة:
|
||||
|
||||
- **كل من الطواقم والتدفقات**: يجب أن تكون نقطة الدخول في `src/project_name/main.py`
|
||||
- **الطواقم**: تستخدم دالة `run()` كنقطة دخول
|
||||
- **التدفقات**: تستخدم دالة `kickoff()` كنقطة دخول
|
||||
- **JSON-first Crews**: أبقِ `crew.jsonc` أو `crew.json` و `agents/` في جذر المشروع
|
||||
- **Crews كلاسيكية**: استخدم `src/project_name/main.py` مع دالة دخول `run()`
|
||||
- **Flows**: استخدم `src/project_name/main.py` مع دالة دخول `kickoff()`
|
||||
|
||||
راجع [التحضير للنشر](/ar/enterprise/guides/prepare-for-deployment) لمخططات البنية المفصلة.
|
||||
|
||||
#### مُزخرف CrewBase مفقود
|
||||
#### مُزخرف CrewBase مفقود في crew كلاسيكية
|
||||
|
||||
**العرض**: أخطاء "Crew not found" أو "Config not found" أو أخطاء تهيئة الوكيل/المهمة
|
||||
|
||||
**الحل**: تأكد من أن **جميع** فئات الطاقم تستخدم مُزخرف `@CrewBase`:
|
||||
**الحل**: في crews الكلاسيكية Python/YAML، تأكد من أن جميع فئات الـ crew تستخدم مُزخرف `@CrewBase`. لا تحتاج crews بنمط JSON-first إلى هذا المزخرف.
|
||||
|
||||
```python
|
||||
from crewai.project import CrewBase, agent, crew, task
|
||||
@@ -398,8 +404,8 @@ class YourCrew():
|
||||
```
|
||||
|
||||
<Info>
|
||||
ينطبق هذا على الطواقم المستقلة والطواقم المضمنة داخل مشاريع التدفق.
|
||||
كل فئة طاقم تحتاج المُزخرف.
|
||||
ينطبق هذا على فئات crew الكلاسيكية المكتوبة في Python، بما في ذلك crews الكلاسيكية المضمنة داخل مشاريع Flow.
|
||||
يتم التحقق من crews بنمط JSON-first من `crew.jsonc` و `agents/` بدلاً من ذلك.
|
||||
</Info>
|
||||
|
||||
#### نوع pyproject.toml غير صحيح
|
||||
@@ -436,8 +442,8 @@ type = "flow"
|
||||
**الحل**:
|
||||
1. تحقق من سجلات التنفيذ في لوحة تحكم AMP (علامة تبويب Traces)
|
||||
2. تحقق من أن جميع الأدوات لديها مفاتيح API المطلوبة مُهيأة
|
||||
3. تأكد من صحة تهيئات الوكلاء في `agents.yaml`
|
||||
4. تحقق من تهيئات المهام في `tasks.yaml` بحثاً عن أخطاء الصياغة
|
||||
3. في crews بنمط JSON-first، تحقق من `crew.jsonc` والملفات المشار إليها داخل `agents/`
|
||||
4. في crews الكلاسيكية، تأكد من صحة `agents.yaml` و `tasks.yaml`
|
||||
|
||||
<Card title="تحتاج مساعدة؟" icon="headset" href="mailto:support@crewai.com">
|
||||
تواصل مع فريق الدعم للمساعدة في مشاكل النشر أو أسئلة حول
|
||||
|
||||
224
docs/ar/enterprise/guides/monorepo-deployments.mdx
Normal file
@@ -0,0 +1,224 @@
|
||||
---
|
||||
title: "النشر من Monorepo"
|
||||
description: "انشر Crew أو Flow من مجلد فرعي داخل مستودع أكبر"
|
||||
icon: "folder-tree"
|
||||
mode: "wide"
|
||||
---
|
||||
|
||||
<Note>
|
||||
استخدم دليل عمل عندما يكون Crew أو Flow داخل مستودع أكبر. يتحقق CrewAI AMP
|
||||
من الأتمتة ويبنيها ويشغلها من ذلك المجلد الفرعي بدلاً من جذر المستودع.
|
||||
</Note>
|
||||
|
||||
## متى تستخدم ذلك
|
||||
|
||||
يكون النشر من monorepo مفيداً عندما يحتوي مستودع واحد على عدة أتمتات أو حزم
|
||||
مشتركة أو كود تطبيقات آخر:
|
||||
|
||||
```text
|
||||
company-ai/
|
||||
|-- uv.lock
|
||||
|-- packages/
|
||||
| `-- shared_tools/
|
||||
`-- crews/
|
||||
|-- support_agent/
|
||||
| |-- pyproject.toml
|
||||
| |-- crew.jsonc
|
||||
| `-- agents/
|
||||
| `-- support_agent.jsonc
|
||||
`-- research_flow/
|
||||
|-- pyproject.toml
|
||||
`-- src/
|
||||
`-- research_flow/
|
||||
`-- main.py
|
||||
```
|
||||
|
||||
لنشر `support_agent`، اضبط دليل العمل على:
|
||||
|
||||
```text
|
||||
crews/support_agent
|
||||
```
|
||||
|
||||
لا يزال AMP يجلب المستودع كاملاً أو يرفعه، لكنه يتعامل مع المجلد المحدد كجذر
|
||||
مشروع الأتمتة.
|
||||
|
||||
## ما الذي يتحكم به دليل العمل
|
||||
|
||||
عند تعيين دليل عمل، يستخدم AMP ذلك المجلد من أجل:
|
||||
|
||||
- التحقق من المشروع، بما في ذلك `pyproject.toml` وملفات crew JSON وأي نقطة دخول كلاسيكية لـ Crew أو Flow
|
||||
- تثبيت الاعتماديات باستخدام `uv`
|
||||
- دليل العمل للعملية قيد التشغيل
|
||||
- متغير البيئة `CREW_ROOT_DIR`
|
||||
|
||||
ترك الحقل فارغاً يحافظ على السلوك الحالي ويستخدم جذر المستودع.
|
||||
|
||||
## المصادر المدعومة
|
||||
|
||||
يمكنك تعيين دليل عمل عند إنشاء نشر من:
|
||||
|
||||
- مستودع GitHub متصل
|
||||
- مستودع Git مكوّن في AMP
|
||||
- رفع ملف ZIP
|
||||
|
||||
<Info>
|
||||
اضبط أدلة العمل من واجهة AMP على الويب. لا يطلب تدفق CLI
|
||||
`crewai deploy create` هذا الحقل.
|
||||
</Info>
|
||||
|
||||
يمكنك أيضاً إضافة دليل العمل أو تغييره في نشر موجود من صفحة **Settings** الخاصة
|
||||
بالنشر. يسري التغيير في النشر التالي.
|
||||
|
||||
<Warning>
|
||||
لا يمكن استخدام أدلة العمل وauto-deploy معاً. إذا كان للنشر دليل عمل، يتم
|
||||
تعطيل auto-deploy لذلك النشر. أوقف auto-deploy قبل تعيين دليل عمل.
|
||||
</Warning>
|
||||
|
||||
## إعداد نشر جديد
|
||||
|
||||
<Steps>
|
||||
<Step title="افتح Deploy from Code">
|
||||
في CrewAI AMP، أنشئ نشراً جديداً واختر المصدر: GitHub أو Git Repository أو
|
||||
رفع ZIP.
|
||||
</Step>
|
||||
|
||||
<Step title="اختر المستودع أو الفرع أو ملف ZIP">
|
||||
اختر المستودع والفرع اللذين يحتويان على monorepo، أو ارفع ملف ZIP يحتوي
|
||||
جذره على محتويات monorepo.
|
||||
</Step>
|
||||
|
||||
<Step title="افتح الإعدادات المتقدمة">
|
||||
وسّع قسم **Advanced** في نموذج النشر.
|
||||
</Step>
|
||||
|
||||
<Step title="أدخل دليل العمل">
|
||||
أدخل المسار من جذر المستودع إلى مشروع Crew أو Flow:
|
||||
|
||||
```text
|
||||
crews/support_agent
|
||||
```
|
||||
|
||||
لا تضف شرطة مائلة في البداية.
|
||||
</Step>
|
||||
|
||||
<Step title="انشر">
|
||||
أضف أي متغيرات بيئة مطلوبة، ثم ابدأ النشر.
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
## إعداد نشر موجود
|
||||
|
||||
<Steps>
|
||||
<Step title="افتح إعدادات النشر">
|
||||
انتقل إلى الأتمتة في AMP وافتح **Settings**.
|
||||
</Step>
|
||||
|
||||
<Step title="أوقف auto-deploy إذا لزم الأمر">
|
||||
إذا كان auto-deploy مفعلاً، أوقفه أولاً. لا يكون حقل دليل العمل متاحاً
|
||||
أثناء تشغيل auto-deploy.
|
||||
</Step>
|
||||
|
||||
<Step title="عيّن دليل العمل">
|
||||
في **Basic settings**، أدخل مسار المجلد الفرعي، مثل:
|
||||
|
||||
```text
|
||||
crews/support_agent
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="أعد النشر">
|
||||
احفظ الإعداد وأعد نشر الأتمتة. سيتم استخدام دليل العمل الجديد في النشر
|
||||
التالي.
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
## قواعد المسار
|
||||
|
||||
يجب أن يكون دليل العمل مساراً نسبياً داخل جذر المستودع أو ZIP.
|
||||
|
||||
| القاعدة | المثال |
|
||||
|---------|--------|
|
||||
| استخدم مساراً نسبياً | `crews/support_agent` |
|
||||
| لا تبدأ بـ `/` | `/crews/support_agent` غير صالح |
|
||||
| لا تستخدم مقاطع المسار `.` أو `..` | `crews/../support_agent` غير صالح |
|
||||
| استخدم الأحرف والأرقام والشرطات والشرطات السفلية والنقاط والشرطات المائلة فقط | `crews/support agent` غير صالح |
|
||||
| اجعل المسار 255 حرفاً أو أقل | يتم رفض المسارات الأطول |
|
||||
|
||||
يزيل AMP المسافات البيضاء في البداية والنهاية، ويضغط الشرطات المائلة المتكررة،
|
||||
ويزيل الشرطة المائلة النهائية. تستخدم القيمة الفارغة جذر المستودع.
|
||||
|
||||
## ملفات القفل وUV Workspaces
|
||||
|
||||
يجب أن يحتوي المجلد المحدد على `pyproject.toml` وملفات المشروع المناسبة لنوع
|
||||
الأتمتة:
|
||||
|
||||
- crew بنمط JSON-first: ملف `crew.jsonc` أو `crew.json` مع مجلد `agents/`
|
||||
- Crew كلاسيكي أو Flow: مجلد `src/` مع نقطة دخول Python المتوقعة
|
||||
|
||||
يمكن أن يوجد ملف `uv.lock` أو `poetry.lock` إما في المجلد المحدد أو في جذر
|
||||
المستودع.
|
||||
|
||||
يدعم هذا تخطيطي ملفات القفل الشائعين:
|
||||
|
||||
<Tabs>
|
||||
<Tab title="ملف قفل المشروع">
|
||||
```text
|
||||
company-ai/
|
||||
`-- crews/
|
||||
`-- support_agent/
|
||||
|-- pyproject.toml
|
||||
|-- uv.lock
|
||||
|-- crew.jsonc
|
||||
`-- agents/
|
||||
`-- support_agent.jsonc
|
||||
```
|
||||
</Tab>
|
||||
|
||||
<Tab title="ملف قفل workspace">
|
||||
```text
|
||||
company-ai/
|
||||
|-- uv.lock
|
||||
|-- packages/
|
||||
| `-- shared_tools/
|
||||
`-- crews/
|
||||
`-- support_agent/
|
||||
|-- pyproject.toml
|
||||
|-- crew.jsonc
|
||||
`-- agents/
|
||||
`-- support_agent.jsonc
|
||||
```
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
<Tip>
|
||||
إذا كانت الأتمتة تستورد حزماً مشتركة من مكان آخر في monorepo، فصرّح بهذه
|
||||
الحزم في `pyproject.toml` باستخدام إعدادات UV workspace أو path أو source.
|
||||
يشغل AMP الأتمتة من المجلد المحدد، لذلك يجب تثبيت الكود المشترك كاعتمادية
|
||||
بدلاً من الاعتماد على وجود جذر المستودع في Python path.
|
||||
</Tip>
|
||||
|
||||
## استكشاف الأخطاء وإصلاحها
|
||||
|
||||
### لم يتم العثور على دليل العمل
|
||||
|
||||
تحقق من أن المسار نسبي إلى جذر المستودع أو ZIP. بالنسبة لرفع ZIP، يجب أن
|
||||
تتضمن محتويات ZIP مسار دليل العمل تماماً كما أدخلته.
|
||||
|
||||
### pyproject.toml مفقود
|
||||
|
||||
يجب أن يشير دليل العمل إلى مجلد مشروع Crew أو Flow، وليس فقط إلى مجلد أب
|
||||
يحتوي على عدة مشاريع.
|
||||
|
||||
### uv.lock أو poetry.lock مفقود
|
||||
|
||||
اعمل commit لملف قفل إما في مجلد المشروع المحدد أو في جذر المستودع. بالنسبة
|
||||
إلى UV workspaces، يتم دعم إبقاء `uv.lock` في جذر workspace.
|
||||
|
||||
### Auto-Deploy غير متاح
|
||||
|
||||
يتم تعطيل auto-deploy أثناء تعيين دليل عمل. استخدم إعادة النشر اليدوية أو شغّل
|
||||
إعادة النشر من CI/CD باستخدام AMP API.
|
||||
|
||||
<Card title="النشر على AMP" icon="rocket" href="/ar/enterprise/guides/deploy-to-amp">
|
||||
تابع دليل النشر بعد اختيار دليل عمل monorepo.
|
||||
</Card>
|
||||
@@ -24,7 +24,7 @@ mode: "wide"
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="مشاريع الطاقم" icon="users">
|
||||
فرق وكلاء ذكاء اصطناعي مستقلة مع `crew.py` يحدد الوكلاء والمهام. الأفضل للمهام المركزة والتعاونية.
|
||||
فرق وكلاء ذكاء اصطناعي مستقلة. الـ crews الجديدة تستخدم بنية JSON-first مع `crew.jsonc` و `agents/`؛ ويمكن للـ crews الكلاسيكية الاستمرار في استخدام `crew.py`.
|
||||
</Card>
|
||||
<Card title="مشاريع التدفق" icon="diagram-project">
|
||||
سير عمل مُنسّق مع طواقم مضمنة في مجلد `crews/`. الأفضل للعمليات المعقدة متعددة المراحل.
|
||||
@@ -33,19 +33,19 @@ mode: "wide"
|
||||
|
||||
| الجانب | الطاقم | التدفق |
|
||||
|--------|--------|--------|
|
||||
| **بنية المشروع** | `src/project_name/` مع `crew.py` | `src/project_name/` مع مجلد `crews/` |
|
||||
| **موقع المنطق الرئيسي** | `src/project_name/crew.py` | `src/project_name/main.py` (فئة Flow) |
|
||||
| **دالة نقطة الدخول** | `run()` في `main.py` | `kickoff()` في `main.py` |
|
||||
| **بنية المشروع** | جذر المشروع مع `crew.jsonc` و `agents/` | `src/project_name/` مع مجلد `crews/` |
|
||||
| **موقع المنطق الرئيسي** | `crew.jsonc` (كلاسيكي: `src/project_name/crew.py`) | `src/project_name/main.py` (فئة Flow) |
|
||||
| **دالة نقطة الدخول** | تُحمّل من `crew.jsonc` (كلاسيكي: `run()` في `main.py`) | `kickoff()` في `main.py` |
|
||||
| **نوع pyproject.toml** | `type = "crew"` | `type = "flow"` |
|
||||
| **أمر CLI للإنشاء** | `crewai create crew name` | `crewai create flow name` |
|
||||
| **موقع التهيئة** | `src/project_name/config/` | `src/project_name/crews/crew_name/config/` |
|
||||
| **موقع التهيئة** | `crew.jsonc` و `agents/` و `tools/` اختياريًا | `src/project_name/crews/crew_name/config/` أو مجلدات crew JSON مضمنة |
|
||||
| **يمكن أن يحتوي طواقم أخرى** | لا | نعم (في مجلد `crews/`) |
|
||||
|
||||
## مرجع بنية المشروع
|
||||
|
||||
### بنية مشروع الطاقم
|
||||
|
||||
عند تشغيل `crewai create crew my_crew`، تحصل على هذه البنية:
|
||||
عند تشغيل `crewai create crew my_crew`، تحصل على بنية JSON-first:
|
||||
|
||||
```
|
||||
my_crew/
|
||||
@@ -54,24 +54,25 @@ my_crew/
|
||||
├── README.md
|
||||
├── .env
|
||||
├── uv.lock # REQUIRED for deployment
|
||||
└── src/
|
||||
└── my_crew/
|
||||
├── __init__.py
|
||||
├── main.py # Entry point with run() function
|
||||
├── crew.py # Crew class with @CrewBase decorator
|
||||
├── tools/
|
||||
│ ├── custom_tool.py
|
||||
│ └── __init__.py
|
||||
└── config/
|
||||
├── agents.yaml # Agent definitions
|
||||
└── tasks.yaml # Task definitions
|
||||
├── crew.jsonc # إعدادات الـ crew والمهام والعملية والمدخلات
|
||||
├── agents/
|
||||
│ └── researcher.jsonc # تعريفات الـ Agents
|
||||
├── tools/ # أدوات custom:<name> اختيارية
|
||||
├── knowledge/
|
||||
└── skills/
|
||||
```
|
||||
|
||||
<Warning>
|
||||
بنية `src/project_name/` المتداخلة ضرورية للطواقم.
|
||||
وضع الملفات في المستوى الخاطئ سيسبب فشل النشر.
|
||||
في crews بنمط JSON-first، أبقِ `crew.jsonc` و `agents/` و `tools/` و `knowledge/` و `skills/`
|
||||
في جذر المشروع. وضعها داخل `src/` يمنع `crewai run` والتحقق قبل النشر من العثور على تعريف الـ crew.
|
||||
</Warning>
|
||||
|
||||
<Info>
|
||||
المشاريع الكلاسيكية التي تُنشأ عبر `crewai create crew my_crew --classic` تستخدم البنية القديمة
|
||||
`src/project_name/crew.py` و `src/project_name/config/agents.yaml` و
|
||||
`src/project_name/config/tasks.yaml`. تظل هذه البنية مدعومة للـ crews المكتوبة في Python مع decorators.
|
||||
</Info>
|
||||
|
||||
### بنية مشروع التدفق
|
||||
|
||||
عند تشغيل `crewai create flow my_flow`، تحصل على هذه البنية:
|
||||
@@ -100,9 +101,9 @@ my_flow/
|
||||
```
|
||||
|
||||
<Info>
|
||||
كلا الطواقم والتدفقات تستخدم بنية `src/project_name/`.
|
||||
الفرق الرئيسي أن التدفقات لها مجلد `crews/` للطواقم المضمنة،
|
||||
بينما الطواقم لها `crew.py` مباشرة في مجلد المشروع.
|
||||
الـ crews المستقلة بنمط JSON-first تستخدم ملفات JSON في جذر المشروع. أما Flows فتظل تستخدم
|
||||
`src/project_name/` ويمكن أن تحتوي crews مضمنة كلاسيكية أو مجلدات crew JSON يتم تحميلها عبر
|
||||
`crewai.project.load_crew`.
|
||||
</Info>
|
||||
|
||||
## قائمة فحص ما قبل النشر
|
||||
@@ -154,60 +155,89 @@ git commit -m "Add uv.lock for deployment"
|
||||
git push
|
||||
```
|
||||
|
||||
### 3. التحقق من استخدام مُزخرف CrewBase
|
||||
### 3. التحقق من تعريف الـ Crew
|
||||
|
||||
**يجب أن تستخدم كل فئة طاقم مُزخرف `@CrewBase`.** ينطبق هذا على:
|
||||
<Tabs>
|
||||
<Tab title="JSON-first Crews">
|
||||
يجب أن تحتوي crews بنمط JSON-first على `crew.jsonc` أو `crew.json` في جذر المشروع.
|
||||
يجب أن يشير مصفوفة `agents` إلى ملفات داخل `agents/`، ويجب أن تشير كل task إلى اسم Agent صحيح.
|
||||
|
||||
- مشاريع الطاقم المستقلة
|
||||
- الطواقم المضمنة داخل مشاريع التدفق
|
||||
```jsonc crew.jsonc
|
||||
{
|
||||
"name": "Research Crew",
|
||||
"agents": ["researcher"],
|
||||
"tasks": [
|
||||
{
|
||||
"name": "research_task",
|
||||
"description": "Research {topic}.",
|
||||
"expected_output": "A concise report.",
|
||||
"agent": "researcher"
|
||||
}
|
||||
],
|
||||
"inputs": {
|
||||
"topic": "AI Agents"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```python
|
||||
from crewai import Agent, Crew, Process, Task
|
||||
from crewai.project import CrewBase, agent, crew, task
|
||||
from crewai.agents.agent_builder.base_agent import BaseAgent
|
||||
from typing import List
|
||||
تُشار الأدوات المخصصة بصيغة `"custom:<name>"` ويجب تنفيذها في
|
||||
`tools/<name>.py` كصنف يرث من `BaseTool`.
|
||||
</Tab>
|
||||
<Tab title="Crews كلاسيكية Python/YAML">
|
||||
يجب أن تستخدم الـ crews الكلاسيكية وPython crews المضمنة داخل Flows مزخرف `@CrewBase`.
|
||||
|
||||
@CrewBase # This decorator is REQUIRED
|
||||
class MyCrew():
|
||||
"""My crew description"""
|
||||
```python
|
||||
from crewai import Agent, Crew, Process, Task
|
||||
from crewai.project import CrewBase, agent, crew, task
|
||||
from crewai.agents.agent_builder.base_agent import BaseAgent
|
||||
from typing import List
|
||||
|
||||
agents: List[BaseAgent]
|
||||
tasks: List[Task]
|
||||
@CrewBase
|
||||
class MyCrew():
|
||||
"""My crew description"""
|
||||
|
||||
@agent
|
||||
def my_agent(self) -> Agent:
|
||||
return Agent(
|
||||
config=self.agents_config['my_agent'], # type: ignore[index]
|
||||
verbose=True
|
||||
)
|
||||
agents: List[BaseAgent]
|
||||
tasks: List[Task]
|
||||
|
||||
@task
|
||||
def my_task(self) -> Task:
|
||||
return Task(
|
||||
config=self.tasks_config['my_task'] # type: ignore[index]
|
||||
)
|
||||
@agent
|
||||
def my_agent(self) -> Agent:
|
||||
return Agent(
|
||||
config=self.agents_config['my_agent'], # type: ignore[index]
|
||||
verbose=True
|
||||
)
|
||||
|
||||
@crew
|
||||
def crew(self) -> Crew:
|
||||
return Crew(
|
||||
agents=self.agents,
|
||||
tasks=self.tasks,
|
||||
process=Process.sequential,
|
||||
verbose=True,
|
||||
)
|
||||
```
|
||||
@task
|
||||
def my_task(self) -> Task:
|
||||
return Task(
|
||||
config=self.tasks_config['my_task'] # type: ignore[index]
|
||||
)
|
||||
|
||||
<Warning>
|
||||
إذا نسيت مُزخرف `@CrewBase`، سيفشل النشر بأخطاء حول
|
||||
تهيئات الوكلاء أو المهام المفقودة.
|
||||
</Warning>
|
||||
@crew
|
||||
def crew(self) -> Crew:
|
||||
return Crew(
|
||||
agents=self.agents,
|
||||
tasks=self.tasks,
|
||||
process=Process.sequential,
|
||||
verbose=True,
|
||||
)
|
||||
```
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
### 4. التحقق من نقاط دخول المشروع
|
||||
|
||||
كل من الطواقم والتدفقات لها نقطة دخول في `src/project_name/main.py`:
|
||||
لا تحتاج crews المستقلة بنمط JSON-first إلى ملف `src/project_name/main.py` مكتوب يدويًا؛
|
||||
يقوم `crewai run` وتغليف النشر بتحميل `crew.jsonc` مباشرة. تستخدم crews الكلاسيكية وFlows نقاط دخول Python:
|
||||
|
||||
<Tabs>
|
||||
<Tab title="للطواقم">
|
||||
<Tab title="JSON-first Crews">
|
||||
شغّل محليًا من جذر المشروع:
|
||||
|
||||
```bash
|
||||
crewai run
|
||||
```
|
||||
</Tab>
|
||||
<Tab title="Crews كلاسيكية">
|
||||
تستخدم نقطة الدخول دالة `run()`:
|
||||
|
||||
```python
|
||||
@@ -278,16 +308,17 @@ grep -A2 "\[tool.crewai\]" pyproject.toml
|
||||
# 2. Verify uv.lock exists
|
||||
ls -la uv.lock || echo "ERROR: uv.lock missing! Run 'uv lock'"
|
||||
|
||||
# 3. Verify src/ structure exists
|
||||
ls -la src/*/main.py 2>/dev/null || echo "No main.py found in src/"
|
||||
# 3. For JSON-first crews, verify crew.jsonc and agents/
|
||||
([ -f crew.jsonc ] || [ -f crew.json ]) || echo "No crew.jsonc or crew.json found"
|
||||
test -d agents || echo "No agents/ directory found"
|
||||
|
||||
# 4. For Crews - verify crew.py exists
|
||||
# 4. For classic Crews - verify crew.py exists
|
||||
ls -la src/*/crew.py 2>/dev/null || echo "No crew.py (expected for Crews)"
|
||||
|
||||
# 5. For Flows - verify crews/ folder exists
|
||||
ls -la src/*/crews/ 2>/dev/null || echo "No crews/ folder (expected for Flows)"
|
||||
|
||||
# 6. Check for CrewBase usage
|
||||
# 6. For classic Python crews - check for CrewBase usage
|
||||
grep -r "@CrewBase" . --include="*.py"
|
||||
```
|
||||
|
||||
@@ -297,8 +328,9 @@ grep -r "@CrewBase" . --include="*.py"
|
||||
|-------|-------|---------|
|
||||
| `uv.lock` مفقود | فشل البناء أثناء حل الاعتماديات | شغّل `uv lock` وارفعه |
|
||||
| `type` خاطئ في pyproject.toml | نجاح البناء لكن فشل وقت التشغيل | غيّر إلى النوع الصحيح |
|
||||
| مُزخرف `@CrewBase` مفقود | أخطاء "Config not found" | أضف المُزخرف لجميع فئات الطاقم |
|
||||
| ملفات في الجذر بدل `src/` | نقطة الدخول غير موجودة | انقلها إلى `src/project_name/` |
|
||||
| `crew.jsonc` أو `agents/` مفقود في crew بنمط JSON-first | لا يمكن العثور على تعريف الـ crew | أبقِ `crew.jsonc` و `agents/` في جذر المشروع |
|
||||
| مُزخرف `@CrewBase` مفقود في crew كلاسيكية | أخطاء "Config not found" | أضف المُزخرف لجميع فئات الـ crew الكلاسيكية |
|
||||
| ملفات كلاسيكية في الجذر بدل `src/` | نقطة الدخول غير موجودة | انقل ملفات Python الكلاسيكية إلى `src/project_name/` |
|
||||
| `run()` أو `kickoff()` مفقودة | لا يمكن بدء الأتمتة | أضف دالة الدخول الصحيحة |
|
||||
|
||||
## الخطوات التالية
|
||||
|
||||
123
docs/ar/enterprise/integrations/databricks.mdx
Normal file
@@ -0,0 +1,123 @@
|
||||
---
|
||||
title: تكامل Databricks
|
||||
description: "اربط وكلاء CrewAI بـ Databricks Genie وSQL وUnity Catalog Functions وVector Search عبر خوادم MCP المُدارة من Databricks."
|
||||
icon: "layer-group"
|
||||
mode: "wide"
|
||||
---
|
||||
|
||||
## نظرة عامة
|
||||
|
||||
اربط وكلاء CrewAI مباشرةً بمساحة عمل Databricks الخاصة بك عبر [خوادم MCP المُدارة من Databricks](https://docs.databricks.com/aws/en/generative-ai/mcp/managed-mcp). يتيح تكامل Databricks لوكلائك طرح أسئلة بلغة طبيعية باستخدام **Genie**، وتنفيذ **SQL** خاضع للحوكمة، واستدعاء **Unity Catalog Functions**، واسترجاع المستندات باستخدام **Vector Search** — كل ذلك دون كتابة أو استضافة أي كود موصِّل، مع تطبيق أذونات Unity Catalog في كل استدعاء.
|
||||
|
||||
في الخلفية، يُعدّ تكامل Databricks غلافًا مُدارًا حول دعم [خوادم MCP المخصصة](/ar/enterprise/guides/custom-mcp-server) في CrewAI. تكشف Databricks عن كل قدرة كنقطة نهاية [Model Context Protocol](https://modelcontextprotocol.io/) خاصة بها، ويتصل بها CrewAI بأمان نيابةً عنك. ولأن كل خادم يُضاف بشكل منفصل، يمكنك تفعيل القدرات التي تحتاجها فرقك (crews) بالضبط.
|
||||
|
||||
## القدرات الرئيسية
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Genie" icon="comments">
|
||||
اطرح أسئلة بلغة طبيعية واحصل على إجابات مستندة إلى بياناتك باستخدام [Genie](https://docs.databricks.com/aws/en/genie/)، الذي يستعلم من Genie Spaces وUnity Catalog ويوفّر روابط تعود إلى واجهة Databricks.
|
||||
</Card>
|
||||
<Card title="Databricks SQL" icon="database">
|
||||
نفّذ SQL خاضعًا للحوكمة على مستودعات Databricks لديك للاستعلام عن البيانات وتحويلها وإنشاء خطوط أنابيب البيانات مباشرةً من وكلائك.
|
||||
</Card>
|
||||
<Card title="Unity Catalog Functions" icon="function">
|
||||
استدعِ [دوال Unity Catalog](https://docs.databricks.com/aws/en/udf/unity-catalog) لتنفيذ SQL مُعرّف مسبقًا ومنطق أعمال مخصّص كأدوات قابلة لإعادة الاستخدام وخاضعة للحوكمة.
|
||||
</Card>
|
||||
<Card title="Vector Search" icon="magnifying-glass">
|
||||
استرجع المستندات ذات الصلة لسير عمل RAG والمعرفة من فهارس [Mosaic AI Vector Search](https://docs.databricks.com/aws/en/generative-ai/vector-search) باستخدام التشابه الدلالي.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
تعمل جميع الخوادم خلف Unity AI Gateway وتطبّق ضوابط الوصول في Unity Catalog، بحيث لا يرى وكلاؤك سوى البيانات والأدوات المصرَّح لهم باستخدامها.
|
||||
|
||||
## المتطلبات المسبقة
|
||||
|
||||
قبل استخدام تكامل Databricks، تأكّد من توفّر ما يلي:
|
||||
|
||||
- حساب [CrewAI AMP](https://app.crewai.com) باشتراك نشط
|
||||
- مساحة عمل Databricks تحتوي على القدرات التي تريد كشفها (Genie Spaces، مستودعات SQL، دوال Unity Catalog، أو فهارس Vector Search)
|
||||
- [امتيازات Unity Catalog](https://docs.databricks.com/aws/en/data-governance/unity-catalog) المناسبة على الكائنات الأساسية
|
||||
- اسم مضيف مساحة عمل Databricks الخاص بك (مثال: `your-workspace.cloud.databricks.com`)
|
||||
|
||||
## خوادم MCP المُدارة من Databricks
|
||||
|
||||
تنشر Databricks خادم MCP مُدارًا منفصلًا لكل قدرة. يكشف CrewAI عنها كاتصالات فردية، يُهيَّأ كل منها باستخدام مضيف مساحة العمل ومعرّفات Unity Catalog ذات الصلة. تتبع نقاط النهاية الأنماط التالية:
|
||||
|
||||
| الخادم | الوظيفة | نمط عنوان MCP |
|
||||
|--------|---------|---------------|
|
||||
| **Genie** | أسئلة وأجوبة بلغة طبيعية على Genie Space | `https://<workspace-hostname>/api/2.0/mcp/genie/{genie_space_id}` |
|
||||
| **Databricks SQL** | تنفيذ SQL على مستودعاتك | `https://<workspace-hostname>/api/2.0/mcp/sql` |
|
||||
| **Unity Catalog Functions** | تشغيل دوال UC المسجّلة | `https://<workspace-hostname>/api/2.0/mcp/functions/{catalog}/{schema}` |
|
||||
| **Vector Search** | الاستعلام من فهرس Vector Search | `https://<workspace-hostname>/api/2.0/mcp/vector-search/{catalog}/{schema}` |
|
||||
|
||||
<Note>
|
||||
لا حاجة لإنشاء عناوين URL هذه يدويًا — يُنشئ CrewAI كل نقطة نهاية من مضيف مساحة العمل والمعرّفات (Genie Space ID، أو catalog/schema) التي تقدّمها عند تهيئة الاتصال. للاطّلاع على المواصفات الكاملة وأحدث تفاصيل نقاط النهاية، راجع [وثائق MCP المُدارة من Databricks](https://docs.databricks.com/aws/en/generative-ai/mcp/managed-mcp).
|
||||
</Note>
|
||||
|
||||
## ربط Databricks في CrewAI AMP
|
||||
|
||||
<Frame>
|
||||
<img src="/images/enterprise/databricks-configure.png" alt="تهيئة خادم MCP مُدار من Databricks في CrewAI AMP" />
|
||||
</Frame>
|
||||
|
||||
تظهر كل قدرة من قدرات Databricks — **Databricks Genie** و**Databricks SQL** و**Databricks Unity Catalog Functions** و**Databricks Vector Search** — كخادم MCP خاص بها ضمن مجموعة Databricks في صفحة **Tools & Integrations**. هيّئ ما تحتاجه:
|
||||
|
||||
<Steps>
|
||||
<Step title="افتح Tools & Integrations">
|
||||
انتقل إلى **Tools & Integrations** في الشريط الجانبي الأيسر في CrewAI AMP وحدِّد مجموعة **Databricks** في قائمة Connections. سترى خوادم Genie وSQL وUnity Catalog Functions وVector Search مُدرجة أسفلها.
|
||||
</Step>
|
||||
|
||||
<Step title="هيّئ خادمًا">
|
||||
انقر على **Configure** بجوار القدرة التي تريد تفعيلها وقدّم تفاصيل الاتصال الخاصة بها:
|
||||
|
||||
- **Workspace Host** — اسم مضيف مساحة عمل Databricks الخاص بك (مثال: `my-workspace.cloud.databricks.com`).
|
||||
- **Genie** — **Genie Space ID** المراد الاستعلام عنه.
|
||||
- **Unity Catalog Functions** — الـ **catalog** والـ **schema** اللذان يحتويان على دوالك.
|
||||
- **Vector Search** — الـ **catalog** والـ **schema** اللذان يحتويان على الفهرس.
|
||||
- **Databricks SQL** — لا توجد معرّفات إضافية؛ تُنفَّذ الاستعلامات على مستودعات SQL في مساحة عملك.
|
||||
</Step>
|
||||
|
||||
<Step title="اختر طريقة المصادقة">
|
||||
اختر كيف يصادق CrewAI على Databricks. يُوصى باستخدام **OAuth**.
|
||||
|
||||
- **Use OAuth** — اتصل بأمان باستخدام OAuth 2.0. يصادق كل مستخدم على حدة، وتُصدر Databricks رموزًا (tokens) محدّدة النطاق للقدرة (`genie` أو `sql` أو `unity-catalog` أو `vector-search`). يتولّى CrewAI تدفّق التفويض ويُجدّد الرموز تلقائيًا.
|
||||
- **Use personal access token** — صادِق باستخدام [رمز وصول شخصي من Databricks](https://docs.databricks.com/aws/en/dev-tools/auth/pat). استخدم هوية بأقل الامتيازات للحدّ من التعرّض.
|
||||
</Step>
|
||||
|
||||
<Step title="صادِق">
|
||||
أكمل المصادقة. بمجرد الاتصال، تصبح أدوات الخادم متاحة لفرقك. كرّر العملية لأي قدرات Databricks أخرى تريد تفعيلها.
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
<Tip>
|
||||
لأن كل قدرة هي اتصال منفصل، يمكنك المزج والمطابقة — على سبيل المثال، فعّل Genie وVector Search لفريق بحث، مع حجز SQL وUnity Catalog Functions لفريق هندسة البيانات. تتيح لك إعدادات الرؤية (Visibility) التحكّم في أعضاء الفريق الذين يمكنهم استخدام كل منها.
|
||||
</Tip>
|
||||
|
||||
## استخدام أدوات Databricks في فرقك
|
||||
|
||||
بمجرد الاتصال، تظهر الأدوات التي يكشفها كل خادم MCP جنبًا إلى جنب مع الاتصالات المدمجة في صفحة **Tools & Integrations**. يمكنك:
|
||||
|
||||
- **إسناد الأدوات إلى الوكلاء** في فرقك تمامًا مثل أي أداة أخرى في CrewAI.
|
||||
- **إدارة الرؤية** للتحكّم في أعضاء الفريق الذين يمكنهم استخدام كل اتصال.
|
||||
- **تعديل أو إزالة** أي اتصال في أي وقت من قائمة Connections.
|
||||
|
||||
يمكن لوكلائك الآن طلب إجابات مستندة من Genie، وتنفيذ SQL على مستودعاتك، واستدعاء دوال Unity Catalog، والبحث في فهارس Vector Search — مع تدفّق النتائج تلقائيًا إلى استدلالهم.
|
||||
|
||||
<Warning>
|
||||
تطبّق Databricks الحوكمة عبر Unity Catalog وUnity AI Gateway: لا يمكن للمستخدم اكتشاف الأدوات واستدعاؤها إلا تلك المصرَّح بها لهوية مساحة عمله. إذا فشل استدعاء أداة، فتأكّد من أن المستخدم المتصل (أو هوية الرمز) يمتلك امتيازات Unity Catalog المطلوبة على Genie Space أو المستودع أو الدالة أو الفهرس. تُنفَّذ بعض استعلامات Genie وSQL بشكل غير متزامن وقد تستغرق لحظة لإرجاع النتائج.
|
||||
</Warning>
|
||||
|
||||
## مزيد من المعلومات
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="خوادم MCP المُدارة من Databricks" icon="layer-group" href="https://docs.databricks.com/aws/en/generative-ai/mcp/managed-mcp">
|
||||
وثائق Databricks الرسمية لخوادم MCP المُدارة Genie وSQL وUnity Catalog Functions وVector Search.
|
||||
</Card>
|
||||
<Card title="خوادم MCP المخصصة في CrewAI" icon="plug" href="/ar/enterprise/guides/custom-mcp-server">
|
||||
تعرّف على كيفية اتصال CrewAI بأي خادم MCP، وهو الأساس الذي يُبنى عليه تكامل Databricks.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
<Card title="بحاجة إلى مساعدة؟" icon="headset" href="mailto:support@crewai.com">
|
||||
تواصل مع فريق الدعم للحصول على المساعدة في تهيئة تكامل Databricks أو في حل المشكلات.
|
||||
</Card>
|
||||
@@ -17,15 +17,62 @@ mode: "wide"
|
||||
- حساب Salesforce بالصلاحيات المناسبة
|
||||
- ربط حساب Salesforce الخاص بك عبر [صفحة التكاملات](https://app.crewai.com/integrations)
|
||||
|
||||
<Note>
|
||||
يتطلب Salesforce **تثبيتًا واحدًا يقوم به مسؤول النظام (admin)** لحزمة
|
||||
CrewAI في مؤسستك قبل أن يتمكن أي مستخدم من الاتصال. هذا متطلب من منصة
|
||||
Salesforce لجميع التكاملات المعتمدة على ExternalClientApp اعتبارًا من
|
||||
إصدار Spring '26 — وليس خطوة خاصة بـ CrewAI. تدليلك خطوة Connect
|
||||
Salesforce في CrewAI AMP خلال هذه العملية عند المحاولة الأولى.
|
||||
</Note>
|
||||
|
||||
## إعداد تكامل Salesforce
|
||||
|
||||
### 1. ربط حساب Salesforce الخاص بك
|
||||
|
||||
1. انتقل إلى [تكاملات CrewAI AMP](https://app.crewai.com/crewai_plus/connectors)
|
||||
2. ابحث عن **Salesforce** في قسم تكاملات المصادقة
|
||||
3. انقر على **Connect** وأكمل عملية OAuth
|
||||
4. امنح الصلاحيات اللازمة لإدارة CRM والمبيعات
|
||||
5. انسخ رمز المؤسسة من [إعدادات التكامل](https://app.crewai.com/crewai_plus/settings/integrations)
|
||||
1. انتقل إلى [تكاملات CrewAI AMP](https://app.crewai.com/crewai_plus/unified_tools).
|
||||
2. ابحث عن **Salesforce** في قسم تكاملات المصادقة.
|
||||
3. انقر على **Connect**.
|
||||
|
||||
ما يحدث بعد ذلك يعتمد على ما إذا كان مسؤول Salesforce في مؤسستك قد ثبّت
|
||||
حزمة CrewAI بالفعل:
|
||||
|
||||
- **الحزمة مثبتة بالفعل:** سيتم نقلك مباشرة إلى شاشة موافقة OAuth في
|
||||
Salesforce — اعتمدها وسيكتمل الاتصال.
|
||||
- **الحزمة غير مثبتة بعد:** سترى صفحة **Install CrewAI in Salesforce**.
|
||||
اتبع خطوات التثبيت لمرة واحدة أدناه، ثم عُد إلى CrewAI AMP وانقر على
|
||||
**Connect** مرة أخرى.
|
||||
|
||||
4. امنح الصلاحيات اللازمة لإدارة CRM والمبيعات.
|
||||
5. انسخ رمز المؤسسة من [إعدادات التكامل](https://app.crewai.com/crewai_plus/settings/integrations).
|
||||
|
||||
#### تثبيت لمرة واحدة بواسطة المسؤول (مسؤول Salesforce فقط)
|
||||
|
||||
عند أول نقرة على **Connect Salesforce** من أي مستخدم في مؤسستك، تقوم CrewAI
|
||||
بإعادة توجيهك إلى صفحة تثبيت تُشير إلى حزمة CrewAI المُدارة. يحتاج مسؤول
|
||||
Salesforce إلى تثبيتها مرة واحدة فقط لكامل المؤسسة.
|
||||
|
||||
1. في صفحة التثبيت داخل CrewAI، انقر على **Install in Salesforce**. (يمكنك
|
||||
أيضًا مشاركة عنوان URL لتلك الصفحة مع المسؤول — رابط التثبيت يعمل لأي
|
||||
شخص يفتحه.)
|
||||
2. سجّل الدخول إلى Salesforce بصلاحيات مسؤول. لبيئات Sandbox، استبدل
|
||||
`login.salesforce.com` بـ `test.salesforce.com` في الرابط قبل فتحه.
|
||||
3. اختر **Install for All Users**، ووافق على إشعار تطبيقات الجهات
|
||||
الخارجية، ثم انقر **Install**.
|
||||
4. من Setup في Salesforce، ابحث عن **External Client App Manager** ←
|
||||
**CrewAI App** ← افتح علامة التبويب **Policies** ← **Edit**، واضبط
|
||||
القيم التالية:
|
||||
- **Permitted Users:** All users may self-authorize
|
||||
- **IP Relaxation:** Relax IP restrictions
|
||||
- **Refresh Token Policy:** Refresh token is valid until revoked
|
||||
5. احفظ التغييرات.
|
||||
6. عُد إلى CrewAI AMP وانقر على **Connect Salesforce** مرة أخرى. سيكتمل
|
||||
OAuth هذه المرة.
|
||||
|
||||
<Note>
|
||||
**لست مسؤول Salesforce؟** أعِد توجيه عنوان URL لصفحة التثبيت (أو رابط
|
||||
التثبيت نفسه) إلى مسؤول Salesforce لديكم واطلب منه إكمال الخطوات أعلاه.
|
||||
بمجرد انتهائه، عُد إلى CrewAI AMP وانقر على **Connect** مرة أخرى.
|
||||
</Note>
|
||||
|
||||
### 2. تثبيت الحزمة المطلوبة
|
||||
|
||||
|
||||
134
docs/ar/enterprise/integrations/snowflake.mdx
Normal file
@@ -0,0 +1,134 @@
|
||||
---
|
||||
title: تكامل Snowflake
|
||||
description: "ربط وكلاء CrewAI بـ Snowflake Cortex Analyst و Cortex Search وتنفيذ SQL من خلال خادم MCP المُدار من Snowflake."
|
||||
icon: "snowflake"
|
||||
mode: "wide"
|
||||
---
|
||||
|
||||
## نظرة عامة
|
||||
|
||||
اربط وكلاء CrewAI مباشرة ببيانات Snowflake الخاصة بك من خلال [خادم MCP المُدار من Snowflake](https://docs.snowflake.com/en/user-guide/snowflake-cortex/cortex-agents-mcp). يتيح تكامل Snowflake لوكلائك الاستعلام عن البيانات المنظمة باستخدام **Cortex Analyst**، والبحث في البيانات غير المنظمة باستخدام **Cortex Search**، وتنفيذ SQL مُدار على مستودعات البيانات الخاصة بك — كل ذلك دون كتابة أو استضافة أي كود للموصّل.
|
||||
|
||||
داخلياً، تكامل Snowflake هو غلاف مُدار حول دعم [Custom MCP Server](/ar/enterprise/guides/custom-mcp-server) في CrewAI. يكشف Snowflake عن قدرات Cortex AI الخاصة به من خلال نقطة نهاية [Model Context Protocol](https://modelcontextprotocol.io/)، ويتصل CrewAI بها بشكل آمن نيابةً عنك. أي أداة تكشفها على جانب Snowflake — Cortex Analyst أو Cortex Search أو تنفيذ SQL أو Cortex Agents أو أدواتك المخصصة — تصبح متاحة لطواقمك.
|
||||
|
||||
## القدرات الرئيسية
|
||||
|
||||
<CardGroup cols={3}>
|
||||
<Card title="Cortex Analyst" icon="chart-bar">
|
||||
اطرح أسئلة بلغة طبيعية ودع [Cortex Analyst](https://docs.snowflake.com/en/user-guide/snowflake-cortex/cortex-analyst) يولّد وينفذ SQL على بياناتك **المنظمة** باستخدام نماذج دلالية غنية.
|
||||
</Card>
|
||||
<Card title="Cortex Search" icon="magnifying-glass">
|
||||
استرجع البيانات **غير المنظمة** ذات الصلة لسير عمل RAG والمعرفة باستخدام [Cortex Search](https://docs.snowflake.com/en/user-guide/snowflake-cortex/cortex-search/cortex-search-overview)، خدمة البحث المُدارة بالكامل من Snowflake.
|
||||
</Card>
|
||||
<Card title="تنفيذ SQL" icon="database">
|
||||
نفّذ استعلامات SQL مُدارة مباشرة على مستودعات Snowflake الخاصة بك، مع وضع القراءة فقط القابل للتكوين، والمهلات الزمنية، واختيار المستودع.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
نظراً لأن التكامل يكشف عن أي أدوات ينشرها خادم MCP الخاص بك، يمكنك أيضاً كشف **Cortex Agents** و**الأدوات المخصصة** (الدوال المعرّفة من المستخدم والإجراءات المخزّنة) لوكلاء CrewAI.
|
||||
|
||||
## المتطلبات الأساسية
|
||||
|
||||
قبل استخدام تكامل Snowflake، تأكد من توفر ما يلي:
|
||||
|
||||
- حساب [CrewAI AMP](https://app.crewai.com) مع اشتراك فعّال
|
||||
- حساب Snowflake مع إمكانية الوصول إلى ميزات Cortex AI
|
||||
- [خادم MCP مُدار من Snowflake](https://docs.snowflake.com/en/user-guide/snowflake-cortex/cortex-agents-mcp) مُكوّن بالأدوات التي تريد كشفها
|
||||
- صلاحيات Snowflake المناسبة (USAGE/SELECT) على خادم MCP والكائنات الأساسية
|
||||
|
||||
## إعداد خادم Snowflake MCP
|
||||
|
||||
يعمل خادم MCP المُدار من Snowflake داخل حساب Snowflake الخاص بك ويحدد الأدوات المتاحة للعملاء الخارجيين مثل CrewAI. أنشئ واحداً باستخدام أمر [`CREATE MCP SERVER`](https://docs.snowflake.com/en/sql-reference/sql/create-mcp-server)، مع سرد خدمات Cortex Search وعروض Cortex Analyst الدلالية وأدوات SQL التي تريد كشفها.
|
||||
|
||||
```sql
|
||||
CREATE MCP SERVER my_mcp_server
|
||||
FROM SPECIFICATION $$
|
||||
tools:
|
||||
- name: "sales_analyst"
|
||||
type: "CORTEX_ANALYST"
|
||||
identifier: "MY_DATABASE.MY_SCHEMA.sales_semantic_view"
|
||||
description: "Answer questions about sales metrics"
|
||||
- name: "docs_search"
|
||||
type: "CORTEX_SEARCH_SERVICE_QUERY"
|
||||
identifier: "MY_DATABASE.MY_SCHEMA.support_docs_search"
|
||||
description: "Search internal support documentation"
|
||||
- name: "run_sql"
|
||||
type: "SQL_EXECUTION"
|
||||
description: "Execute read-only SQL queries"
|
||||
$$;
|
||||
```
|
||||
|
||||
<Note>
|
||||
تتبع نقطة نهاية MCP التنسيق `https://<account_URL>/api/v2/databases/{database}/schemas/{schema}/mcp-servers/{name}`. يبني CrewAI هذا العنوان تلقائياً من **عنوان URL للحساب** و**قاعدة البيانات** و**المخطط** و**اسم خادم MCP** الذي تقدمه عند تكوين التكامل.
|
||||
</Note>
|
||||
|
||||
للمواصفات الكاملة — بما في ذلك Cortex Agents والأدوات المخصصة وحدود حجم الاستجابة وخيارات الحوكمة — راجع [وثائق خادم MCP المُدار من Snowflake](https://docs.snowflake.com/en/user-guide/snowflake-cortex/cortex-agents-mcp).
|
||||
|
||||
## ربط Snowflake في CrewAI AMP
|
||||
|
||||
<Frame>
|
||||
<img src="/images/enterprise/snowflake-configure.png" alt="تكوين تكامل Snowflake في CrewAI AMP" />
|
||||
</Frame>
|
||||
|
||||
<Steps>
|
||||
<Step title="فتح الأدوات والتكاملات">
|
||||
انتقل إلى **الأدوات والتكاملات** في الشريط الجانبي الأيسر لـ CrewAI AMP، وابحث عن **Snowflake** في قائمة التطبيقات، وافتح لوحة التكوين الخاصة به.
|
||||
</Step>
|
||||
|
||||
<Step title="تقديم تفاصيل الاتصال">
|
||||
املأ حقول الاتصال التي يستخدمها CrewAI للوصول إلى خادم Snowflake MCP الخاص بك:
|
||||
|
||||
| الحقل | مطلوب | الوصف |
|
||||
|-------|-------|-------|
|
||||
| **الاسم** | نعم | اسم وصفي لهذا الاتصال (القيمة الافتراضية `Snowflake`). |
|
||||
| **الوصف** | لا | ملخص اختياري لما يوفره هذا الاتصال. |
|
||||
| **عنوان URL للحساب** | نعم | عنوان URL لحساب Snowflake الخاص بك، مثل `xy12345.us-east-1.snowflakecomputing.com`. |
|
||||
| **قاعدة البيانات** | نعم | قاعدة البيانات التي تحتوي على خادم MCP الخاص بك (مثل `MY_DATABASE`). |
|
||||
| **المخطط** | نعم | المخطط الذي يحتوي على خادم MCP الخاص بك (مثل `MY_SCHEMA`). |
|
||||
| **اسم خادم MCP** | نعم | اسم كائن خادم MCP الذي أنشأته في Snowflake (مثل `MY_MCP_SERVER`). |
|
||||
</Step>
|
||||
|
||||
<Step title="اختيار طريقة المصادقة">
|
||||
اختر كيفية مصادقة CrewAI مع Snowflake. يُوصى باستخدام **OAuth**.
|
||||
|
||||
- **استخدام OAuth** — اتصل بشكل آمن باستخدام OAuth 2.0 للمصادقة القائمة على الرموز دون مشاركة بيانات الاعتماد الخاصة بك. يتعامل CrewAI مع تدفق التفويض الكامل ويجدد الرموز تلقائياً. انسخ **عنوان URI لإعادة التوجيه** المعروض في النموذج (`https://oauth.crewai.com/oauth/add`) وسجّله كعنوان URI لإعادة التوجيه المعتمد في [تكامل أمان OAuth](https://docs.snowflake.com/en/user-guide/oauth-custom) في Snowflake.
|
||||
- **استخدام رمز وصول شخصي** — المصادقة باستخدام [رمز وصول برمجي](https://docs.snowflake.com/en/user-guide/programmatic-access-tokens) مُنشأ من إعدادات حساب Snowflake الخاص بك. قم بتعيين دور بأقل صلاحيات للرمز للحد من التعرض.
|
||||
</Step>
|
||||
|
||||
<Step title="المصادقة">
|
||||
انقر على **المصادقة**. بالنسبة لـ OAuth، ستتم إعادة توجيهك إلى Snowflake لتفويض الوصول. بمجرد المصادقة، يظهر خادم Snowflake في قائمة الاتصالات وتصبح أدواته متاحة لطواقمك.
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
<Tip>
|
||||
مع OAuth، يتم مصادقة كل مستخدم بشكل فردي وتُنفّذ الاستعلامات بدور `DEFAULT_ROLE` الخاص به في Snowflake. تأكد من أن المستخدمين المتصلين لديهم دور ومستودع افتراضي محدد (`ALTER USER <username> SET DEFAULT_ROLE = '<role>' DEFAULT_WAREHOUSE = '<warehouse>'`) حتى تتوفر موارد الحوسبة لأدوات Cortex Analyst و SQL.
|
||||
</Tip>
|
||||
|
||||
## استخدام أدوات Snowflake في طواقمك
|
||||
|
||||
بمجرد الاتصال، تظهر الأدوات التي يكشفها خادم MCP الخاص بك إلى جانب الاتصالات المدمجة في صفحة **الأدوات والتكاملات**. يمكنك:
|
||||
|
||||
- **تعيين الأدوات للوكلاء** في طواقمك تماماً مثل أي أداة CrewAI أخرى.
|
||||
- **إدارة الرؤية** للتحكم في أعضاء الفريق الذين يمكنهم استخدام الاتصال.
|
||||
- **تعديل أو إزالة** الاتصال في أي وقت من قائمة الاتصالات.
|
||||
|
||||
يمكن لوكلائك الآن سؤال Cortex Analyst عن المقاييس، وتشغيل Cortex Search على مستنداتك، وتنفيذ SQL — مع تدفق النتائج تلقائياً إلى استدلالهم.
|
||||
|
||||
<Warning>
|
||||
يفرض Snowflake الحوكمة على خادم MCP: يحدد التحكم في الوصول القائم على الأدوار الأدوات التي يمكن للمستخدم اكتشافها واستدعاؤها، وتنطبق حدود على حجم الاستجابة وعدد الأدوات (بحد أقصى 50 لكل خادم) وعمق التكرار. إذا فشل استدعاء أداة، تأكد من أن دور المستخدم المتصل لديه الصلاحيات المطلوبة على خادم MCP والكائنات الأساسية.
|
||||
</Warning>
|
||||
|
||||
## معرفة المزيد
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="خادم MCP المُدار من Snowflake" icon="snowflake" href="https://docs.snowflake.com/en/user-guide/snowflake-cortex/cortex-agents-mcp">
|
||||
الوثائق الرسمية من Snowflake لإنشاء وإدارة خادم MCP.
|
||||
</Card>
|
||||
<Card title="خوادم Custom MCP في CrewAI" icon="plug" href="/ar/enterprise/guides/custom-mcp-server">
|
||||
تعرّف على كيفية اتصال CrewAI بأي خادم MCP، الأساس الذي يبني عليه تكامل Snowflake.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
<Card title="تحتاج مساعدة؟" icon="headset" href="mailto:support@crewai.com">
|
||||
تواصل مع فريق الدعم للحصول على المساعدة في تكامل Snowflake أو استكشاف الأخطاء وإصلاحها.
|
||||
</Card>
|
||||
@@ -161,6 +161,18 @@ crew = Crew(
|
||||
)
|
||||
```
|
||||
|
||||
<Note>
|
||||
يُحتفظ بـ `agent.i18n` للتوافق مع الإصدارات السابقة فقط، وقد تم إهماله. لتخصيص المطالبات أثناء التشغيل، مرّر `prompt_file` إلى `Crew`. وللوصول البرمجي المباشر إلى شرائح المطالبات، استخدم أداة i18n مباشرة:
|
||||
</Note>
|
||||
|
||||
```python
|
||||
from crewai.utilities.i18n import get_i18n
|
||||
|
||||
i18n = get_i18n("custom_prompts.json")
|
||||
format_slice = i18n.slice("format")
|
||||
tool_prompt = i18n.tools("ask_question")
|
||||
```
|
||||
|
||||
#### الخيار 3: تعطيل مطالبات النظام لنماذج o1
|
||||
```python
|
||||
agent = Agent(
|
||||
@@ -208,6 +220,8 @@ agent = Agent(
|
||||
|
||||
يدمج CrewAI بعد ذلك تخصيصاتك مع الإعدادات الافتراضية، فلا تحتاج لإعادة تعريف كل مطالبة. إليك الطريقة:
|
||||
|
||||
بالنسبة للكود الذي يحتاج إلى قراءة شرائح المطالبات مباشرة، استخدم `crewai.utilities.i18n.get_i18n()` مع ملف المطالبات نفسه بدلًا من قراءة `agent.i18n`.
|
||||
|
||||
### مثال: تخصيص أساسي للمطالبات
|
||||
|
||||
أنشئ ملف `custom_prompts.json` بالمطالبات التي تريد تعديلها. تأكد من إدراج جميع المطالبات عالية المستوى التي يجب أن يحتويها، وليس فقط تغييراتك:
|
||||
|
||||
@@ -43,7 +43,7 @@ CrewAI مُصمَّم أصلاً للعمل مع الذكاء الاصطناعي
|
||||
|
||||
| المهارة | متى تُستخدم |
|
||||
|---------|-------------|
|
||||
| `getting-started` | مشاريع جديدة، الاختيار بين `LLM.call()` / `Agent` / `Crew` / `Flow`، ربط `crew.py` / `main.py` |
|
||||
| `getting-started` | مشاريع جديدة، الاختيار بين `LLM.call()` / `Agent` / `Crew` / `Flow`، ربط `crew.jsonc` / `main.py` |
|
||||
| `design-agent` | ضبط الوكلاء — الدور، الهدف، الخلفية، الأدوات، نماذج اللغة، الذاكرة، الحدود الآمنة |
|
||||
| `design-task` | وصف المهام، التبعيات، المخرجات المنظمة (`output_pydantic`، `output_json`)، المراجعة البشرية |
|
||||
| `ask-docs` | الاستعلام من [خادم CrewAI docs MCP](https://docs.crewai.com/mcp) للحصول على تفاصيل واجهة البرمجة الحالية |
|
||||
@@ -64,7 +64,7 @@ CrewAI مُصمَّم أصلاً للعمل مع الذكاء الاصطناعي
|
||||
<Step title="يحصل وكيلك فوراً على خبرة CrewAI">
|
||||
تعلّم الحزمة وكيلك:
|
||||
- **Flows** — تطبيقات ذات حالة، خطوات، وتشغيل crews
|
||||
- **Crews والوكلاء** — أنماط YAML أولاً، الأدوار، المهام، التفويض
|
||||
- **Crews والوكلاء** — أنماط JSON-first (`crew.jsonc` و `agents/*.jsonc`)، الأدوار، المهام، التفويض
|
||||
- **الأدوات والتكاملات** — البحث، واجهات API، خوادم MCP، وأدوات CrewAI الشائعة
|
||||
- **هيكل المشروع** — هياكل CLI واتفاقيات المستودع
|
||||
- **أنماط محدثة** — يتماشى مع وثائق CrewAI الحالية وأفضل الممارسات
|
||||
|
||||
@@ -1,321 +1,140 @@
|
||||
---
|
||||
title: ابنِ أول Crew لك
|
||||
description: دليل تفصيلي لإنشاء فريق AI تعاوني يعمل معًا لحل المشكلات المعقدة.
|
||||
title: ابنِ أول Crew
|
||||
description: دليل خطوة بخطوة لإنشاء فريق AI تعاوني باستخدام تهيئة JSON-first.
|
||||
icon: users-gear
|
||||
mode: "wide"
|
||||
---
|
||||
|
||||
## إطلاق قوة الذكاء الاصطناعي التعاوني
|
||||
## بناء Crew للبحث
|
||||
|
||||
تخيل أن لديك فريقًا من Agents الذكاء الاصطناعي المتخصصة تعمل معًا بسلاسة لحل مشكلات معقدة، كل منها يساهم بمهاراته الفريدة لتحقيق هدف مشترك. هذه هي قوة CrewAI - إطار عمل يمكّنك من إنشاء أنظمة ذكاء اصطناعي تعاونية يمكنها إنجاز مهام تفوق بكثير ما يمكن لـ AI واحد تحقيقه بمفرده.
|
||||
في هذا الدليل ستنشئ crew من Agentين: واحد للبحث وآخر لكتابة تقرير markdown. مشاريع الـ crew الجديدة هي JSON-first: تُعرّف الـ Agents في `agents/*.jsonc`، وتُعرّف المهام وإعدادات الـ crew في `crew.jsonc`، ويحمّل `crewai run` هذا التعريف مباشرة.
|
||||
|
||||
في هذا الدليل، سنمشي عبر إنشاء Crew بحث يساعدنا في البحث والتحليل حول موضوع ما، ثم إنشاء تقرير شامل. يوضح هذا المثال العملي كيف يمكن لـ Agents الذكاء الاصطناعي التعاون لإنجاز مهام معقدة، لكنه مجرد البداية لما هو ممكن مع CrewAI.
|
||||
### المتطلبات
|
||||
|
||||
### ما ستبنيه وتتعلمه
|
||||
1. تثبيت CrewAI من [دليل التثبيت](/ar/installation)
|
||||
2. إعداد مفتاح LLM من [دليل LLMs](/ar/concepts/llms#setting-up-your-llm)
|
||||
3. مفتاح [Serper.dev](https://serper.dev/) إذا أردت استخدام البحث على الويب
|
||||
|
||||
بنهاية هذا الدليل، ستكون قد:
|
||||
|
||||
1. **أنشأت فريق بحث AI متخصص** بأدوار ومسؤوليات مميزة
|
||||
2. **نسّقت التعاون** بين عدة Agents ذكاء اصطناعي
|
||||
3. **أتممت سير عمل معقد** يتضمن جمع المعلومات والتحليل وإنشاء التقارير
|
||||
4. **بنيت مهارات أساسية** يمكنك تطبيقها على مشاريع أكثر طموحًا
|
||||
|
||||
### المتطلبات المسبقة
|
||||
|
||||
قبل البدء، تأكد من:
|
||||
|
||||
1. تثبيت CrewAI باتباع [دليل التثبيت](/ar/installation)
|
||||
2. إعداد مفتاح API لنموذج LLM في بيئتك، باتباع [دليل إعداد LLM](/ar/concepts/llms#setting-up-your-llm)
|
||||
3. فهم أساسي لـ Python
|
||||
|
||||
## الخطوة 1: إنشاء مشروع CrewAI جديد
|
||||
|
||||
أولاً، لننشئ مشروع CrewAI جديد باستخدام CLI. سينشئ هذا الأمر هيكل مشروع كامل بجميع الملفات الضرورية.
|
||||
## الخطوة 1: إنشاء Crew جديدة
|
||||
|
||||
```bash
|
||||
crewai create crew research_crew
|
||||
cd research_crew
|
||||
```
|
||||
|
||||
سينتج هيكل مشروع بالبنية الأساسية المطلوبة لـ Crew. ينشئ CLI تلقائيًا:
|
||||
البنية الناتجة:
|
||||
|
||||
- مجلد مشروع بالملفات اللازمة
|
||||
- ملفات تهيئة للـ Agents والمهام
|
||||
- تطبيق Crew أساسي
|
||||
- سكريبت رئيسي لتشغيل الـ Crew
|
||||
|
||||
<Frame caption="نظرة عامة على إطار عمل CrewAI">
|
||||
<img src="/images/crews.png" alt="نظرة عامة على إطار عمل CrewAI" />
|
||||
</Frame>
|
||||
|
||||
## الخطوة 2: استكشاف هيكل المشروع
|
||||
|
||||
لنخصص لحظة لفهم هيكل المشروع الذي أنشأه CLI.
|
||||
|
||||
```
|
||||
```text
|
||||
research_crew/
|
||||
├── .gitignore
|
||||
├── .env
|
||||
├── agents/
|
||||
│ └── researcher.jsonc
|
||||
├── crew.jsonc
|
||||
├── knowledge/
|
||||
├── pyproject.toml
|
||||
├── README.md
|
||||
├── .env
|
||||
└── src/
|
||||
└── research_crew/
|
||||
├── __init__.py
|
||||
├── main.py
|
||||
├── crew.py
|
||||
├── tools/
|
||||
│ ├── custom_tool.py
|
||||
│ └── __init__.py
|
||||
└── config/
|
||||
├── agents.yaml
|
||||
└── tasks.yaml
|
||||
├── skills/
|
||||
└── tools/
|
||||
```
|
||||
|
||||
يتبع هذا الهيكل أفضل الممارسات لمشاريع Python ويسهّل تنظيم الكود. فصل ملفات التهيئة (YAML) عن كود التنفيذ (Python) يسهّل تعديل سلوك Crew دون تغيير الكود الأساسي.
|
||||
<Tip>
|
||||
إذا احتجت إلى البنية القديمة التي تحتوي على `crew.py` و `config/agents.yaml` و `config/tasks.yaml`، استخدم `crewai create crew research_crew --classic`.
|
||||
</Tip>
|
||||
|
||||
## الخطوة 3: تهيئة الـ Agents
|
||||
## الخطوة 2: تعريف الـ Agents
|
||||
|
||||
الآن يأتي الجزء الممتع - تعريف Agents الذكاء الاصطناعي! في CrewAI، الـ Agents هي كيانات متخصصة بأدوار وأهداف وخلفيات محددة تشكّل سلوكها.
|
||||
عدّل ملف `agents/researcher.jsonc` الذي أنشأه القالب، ثم أضف `agents/analyst.jsonc`. يجب أن تطابق أسماء الملفات الأسماء المشار إليها في `crew.jsonc`.
|
||||
|
||||
لـ Crew البحث لدينا، سننشئ Agent اثنين:
|
||||
1. **باحث** يتفوق في إيجاد وتنظيم المعلومات
|
||||
2. **محلل** يمكنه تفسير نتائج البحث وإنشاء تقارير ثاقبة
|
||||
|
||||
لنعدّل ملف `agents.yaml`. تأكد من تعيين `llm` للمزود الذي تستخدمه.
|
||||
|
||||
```yaml
|
||||
# src/research_crew/config/agents.yaml
|
||||
researcher:
|
||||
role: >
|
||||
Senior Research Specialist for {topic}
|
||||
goal: >
|
||||
Find comprehensive and accurate information about {topic}
|
||||
with a focus on recent developments and key insights
|
||||
backstory: >
|
||||
You are an experienced research specialist with a talent for
|
||||
finding relevant information from various sources. You excel at
|
||||
organizing information in a clear and structured manner, making
|
||||
complex topics accessible to others.
|
||||
llm: provider/model-id # e.g. openai/gpt-4o, google/gemini-2.0-flash, anthropic/claude...
|
||||
|
||||
analyst:
|
||||
role: >
|
||||
Data Analyst and Report Writer for {topic}
|
||||
goal: >
|
||||
Analyze research findings and create a comprehensive, well-structured
|
||||
report that presents insights in a clear and engaging way
|
||||
backstory: >
|
||||
You are a skilled analyst with a background in data interpretation
|
||||
and technical writing. You have a talent for identifying patterns
|
||||
and extracting meaningful insights from research data, then
|
||||
communicating those insights effectively through well-crafted reports.
|
||||
llm: provider/model-id # e.g. openai/gpt-4o, google/gemini-2.0-flash, anthropic/claude...
|
||||
```jsonc agents/researcher.jsonc
|
||||
{
|
||||
"role": "Senior Research Specialist for {topic}",
|
||||
"goal": "Find comprehensive and accurate information about {topic}, with a focus on recent developments and key insights.",
|
||||
"backstory": "You are an experienced research specialist who organizes complex information into clear, useful notes.",
|
||||
// استبدله بالنموذج الذي تستخدمه، مثل "openai/gpt-4o".
|
||||
"llm": "provider/model-id",
|
||||
"tools": ["SerperDevTool"],
|
||||
"settings": {
|
||||
"verbose": true,
|
||||
"allow_delegation": false
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
لاحظ كيف أن لكل Agent دور وهدف وخلفية مميزة. هذه العناصر ليست وصفية فحسب - بل تشكّل بنشاط كيف يتعامل الـ Agent مع مهامه.
|
||||
|
||||
## الخطوة 4: تعريف المهام
|
||||
|
||||
مع تعريف الـ Agents، نحتاج الآن لمنحهم مهام محددة. لنعدّل ملف `tasks.yaml`:
|
||||
|
||||
```yaml
|
||||
# src/research_crew/config/tasks.yaml
|
||||
research_task:
|
||||
description: >
|
||||
Conduct thorough research on {topic}. Focus on:
|
||||
1. Key concepts and definitions
|
||||
2. Historical development and recent trends
|
||||
3. Major challenges and opportunities
|
||||
4. Notable applications or case studies
|
||||
5. Future outlook and potential developments
|
||||
|
||||
Make sure to organize your findings in a structured format with clear sections.
|
||||
expected_output: >
|
||||
A comprehensive research document with well-organized sections covering
|
||||
all the requested aspects of {topic}. Include specific facts, figures,
|
||||
and examples where relevant.
|
||||
agent: researcher
|
||||
|
||||
analysis_task:
|
||||
description: >
|
||||
Analyze the research findings and create a comprehensive report on {topic}.
|
||||
Your report should:
|
||||
1. Begin with an executive summary
|
||||
2. Include all key information from the research
|
||||
3. Provide insightful analysis of trends and patterns
|
||||
4. Offer recommendations or future considerations
|
||||
5. Be formatted in a professional, easy-to-read style with clear headings
|
||||
expected_output: >
|
||||
A polished, professional report on {topic} that presents the research
|
||||
findings with added analysis and insights. The report should be well-structured
|
||||
with an executive summary, main sections, and conclusion.
|
||||
agent: analyst
|
||||
context:
|
||||
- research_task
|
||||
output_file: output/report.md
|
||||
```jsonc agents/analyst.jsonc
|
||||
{
|
||||
"role": "Report Analyst for {topic}",
|
||||
"goal": "Turn research findings into a clear, well-structured report.",
|
||||
"backstory": "You are a careful analyst with strong technical writing skills and a talent for extracting useful insights.",
|
||||
// استبدله بالنموذج الذي تستخدمه، مثل "openai/gpt-4o".
|
||||
"llm": "provider/model-id",
|
||||
"settings": {
|
||||
"verbose": true,
|
||||
"allow_delegation": false
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
لاحظ حقل `context` في مهمة التحليل - هذه ميزة قوية تتيح للمحلل الوصول إلى مخرجات مهمة البحث.
|
||||
استبدل `provider/model-id` بالنموذج الذي تستخدمه، مثل `openai/gpt-4o` أو `anthropic/claude-sonnet-4-6` أو `gemini/gemini-2.0-flash-001`.
|
||||
|
||||
## الخطوة 5: تهيئة الـ Crew
|
||||
## الخطوة 3: تعريف المهام وإعدادات الـ Crew
|
||||
|
||||
الآن حان الوقت لجمع كل شيء معًا. لنعدّل ملف `crew.py`:
|
||||
استبدل `crew.jsonc` بما يلي:
|
||||
|
||||
```python
|
||||
# src/research_crew/crew.py
|
||||
from crewai import Agent, Crew, Process, Task
|
||||
from crewai.project import CrewBase, agent, crew, task
|
||||
from crewai_tools import SerperDevTool
|
||||
from crewai.agents.agent_builder.base_agent import BaseAgent
|
||||
from typing import List
|
||||
|
||||
@CrewBase
|
||||
class ResearchCrew():
|
||||
"""Research crew for comprehensive topic analysis and reporting"""
|
||||
|
||||
agents: List[BaseAgent]
|
||||
tasks: List[Task]
|
||||
|
||||
@agent
|
||||
def researcher(self) -> Agent:
|
||||
return Agent(
|
||||
config=self.agents_config['researcher'], # type: ignore[index]
|
||||
verbose=True,
|
||||
tools=[SerperDevTool()]
|
||||
)
|
||||
|
||||
@agent
|
||||
def analyst(self) -> Agent:
|
||||
return Agent(
|
||||
config=self.agents_config['analyst'], # type: ignore[index]
|
||||
verbose=True
|
||||
)
|
||||
|
||||
@task
|
||||
def research_task(self) -> Task:
|
||||
return Task(
|
||||
config=self.tasks_config['research_task'] # type: ignore[index]
|
||||
)
|
||||
|
||||
@task
|
||||
def analysis_task(self) -> Task:
|
||||
return Task(
|
||||
config=self.tasks_config['analysis_task'], # type: ignore[index]
|
||||
output_file='output/report.md'
|
||||
)
|
||||
|
||||
@crew
|
||||
def crew(self) -> Crew:
|
||||
"""Creates the research crew"""
|
||||
return Crew(
|
||||
agents=self.agents,
|
||||
tasks=self.tasks,
|
||||
process=Process.sequential,
|
||||
verbose=True,
|
||||
)
|
||||
```
|
||||
|
||||
## الخطوة 6: إعداد السكريبت الرئيسي
|
||||
|
||||
```python
|
||||
#!/usr/bin/env python
|
||||
# src/research_crew/main.py
|
||||
import os
|
||||
from research_crew.crew import ResearchCrew
|
||||
|
||||
# Create output directory if it doesn't exist
|
||||
os.makedirs('output', exist_ok=True)
|
||||
|
||||
def run():
|
||||
"""
|
||||
Run the research crew.
|
||||
"""
|
||||
inputs = {
|
||||
'topic': 'Artificial Intelligence in Healthcare'
|
||||
```jsonc crew.jsonc
|
||||
{
|
||||
"name": "Research Crew",
|
||||
"agents": ["researcher", "analyst"],
|
||||
"tasks": [
|
||||
{
|
||||
"name": "research_task",
|
||||
"description": "Conduct thorough research on {topic}. Focus on key concepts, recent developments, major challenges, notable applications, and future outlook.",
|
||||
"expected_output": "A comprehensive research document with organized sections, specific facts, and useful examples about {topic}.",
|
||||
"agent": "researcher"
|
||||
},
|
||||
{
|
||||
"name": "analysis_task",
|
||||
"description": "Analyze the research findings and create a polished report on {topic}. Include an executive summary, key insights, trend analysis, and recommendations.",
|
||||
"expected_output": "A professional markdown report with clear headings, a concise summary, main findings, and recommendations.",
|
||||
"agent": "analyst",
|
||||
"context": ["research_task"],
|
||||
"output_file": "output/report.md",
|
||||
"markdown": true
|
||||
}
|
||||
|
||||
# Create and run the crew
|
||||
result = ResearchCrew().crew().kickoff(inputs=inputs)
|
||||
|
||||
# Print the result
|
||||
print("\n\n=== FINAL REPORT ===\n\n")
|
||||
print(result.raw)
|
||||
|
||||
print("\n\nReport has been saved to output/report.md")
|
||||
|
||||
if __name__ == "__main__":
|
||||
run()
|
||||
],
|
||||
"process": "sequential",
|
||||
"verbose": true,
|
||||
"memory": true,
|
||||
"inputs": {
|
||||
"topic": "Artificial Intelligence in Healthcare"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## الخطوة 7: إعداد متغيرات البيئة
|
||||
يشير `context` إلى أسماء مهام سابقة، لذلك يحصل analyst على مخرجات مهمة البحث. يوفر `inputs` قيمة افتراضية لـ `{topic}`. إذا حذفت القيمة الافتراضية، سيطلبها `crewai run`.
|
||||
|
||||
أنشئ ملف `.env` في جذر مشروعك بمفاتيح API:
|
||||
## الخطوة 4: متغيرات البيئة
|
||||
|
||||
عدّل `.env`:
|
||||
|
||||
```sh
|
||||
SERPER_API_KEY=your_serper_api_key
|
||||
# Add your provider's API key here too.
|
||||
# أضف مفتاح مزود النموذج أيضًا.
|
||||
```
|
||||
|
||||
راجع [دليل إعداد LLM](/ar/concepts/llms#setting-up-your-llm) لتفاصيل تهيئة المزود المفضل لديك. يمكنك الحصول على مفتاح Serper API من [Serper.dev](https://serper.dev/).
|
||||
|
||||
## الخطوة 8: تثبيت التبعيات
|
||||
## الخطوة 5: التثبيت والتشغيل
|
||||
|
||||
```bash
|
||||
crewai install
|
||||
```
|
||||
|
||||
## الخطوة 9: تشغيل الـ Crew
|
||||
|
||||
الآن اللحظة المثيرة - حان وقت تشغيل Crew ومشاهدة التعاون بين الـ AI!
|
||||
|
||||
```bash
|
||||
crewai run
|
||||
```
|
||||
|
||||
عند تشغيل هذا الأمر، سترى Crew يعمل. سيجمع الباحث معلومات حول الموضوع المحدد، ثم سينشئ المحلل تقريرًا شاملاً بناءً على ذلك البحث.
|
||||
بعد انتهاء التشغيل، افتح `output/report.md`.
|
||||
|
||||
## الخطوة 10: مراجعة المخرجات
|
||||
|
||||
بمجرد إتمام Crew عمله، ستجد التقرير النهائي في ملف `output/report.md`. سيتضمن التقرير:
|
||||
|
||||
1. ملخص تنفيذي
|
||||
2. معلومات مفصلة عن الموضوع
|
||||
3. تحليل ورؤى
|
||||
4. توصيات أو اعتبارات مستقبلية
|
||||
|
||||
## استكشاف أوامر CLI الأخرى
|
||||
|
||||
يوفر CrewAI عدة أوامر CLI مفيدة للعمل مع Crews:
|
||||
|
||||
```bash
|
||||
# View all available commands
|
||||
crewai --help
|
||||
|
||||
# Run the crew
|
||||
crewai run
|
||||
|
||||
# Test the crew
|
||||
crewai test
|
||||
|
||||
# Reset crew memories
|
||||
crewai reset-memories
|
||||
|
||||
# Replay from a specific task
|
||||
crewai replay -t <task_id>
|
||||
```
|
||||
|
||||
## ما بعد أول Crew: فن الممكن
|
||||
|
||||
ما بنيته في هذا الدليل مجرد البداية. يمكنك توسيع Crew البحث الأساسي بإضافة Agents متخصصة أخرى وأدوات وقدرات إضافية وسير عمل أكثر تعقيدًا. يمكن تطبيق نفس الأنماط لإنشاء Crews لإنشاء المحتوى وخدمة العملاء وتطوير المنتجات وتحليل البيانات.
|
||||
|
||||
## الخطوات التالية
|
||||
|
||||
1. جرّب تهيئات وشخصيات Agent مختلفة
|
||||
2. جرب هياكل مهام وسير عمل أكثر تعقيدًا
|
||||
3. طبّق أدوات مخصصة لمنح الـ Agents قدرات جديدة
|
||||
4. طبّق Crew على مواضيع أو مجالات مشكلات مختلفة
|
||||
5. استكشف [CrewAI Flows](/ar/guides/flows/first-flow) لسير عمل أكثر تقدمًا مع البرمجة الإجرائية
|
||||
<Warning>
|
||||
شغّل مشاريع JSON crew من مصادر تثق بها فقط. أدوات `custom:<name>` ومراجع `{"python": "module.attribute"}` تنفذ Python محليًا عند تحميل الـ crew.
|
||||
</Warning>
|
||||
|
||||
<Check>
|
||||
تهانينا! لقد بنيت بنجاح أول CrewAI Crew يمكنه البحث والتحليل في أي موضوع تقدمه. هذه التجربة الأساسية أهّلتك بالمهارات لإنشاء أنظمة AI متطورة بشكل متزايد يمكنها معالجة مشكلات معقدة متعددة المراحل من خلال الذكاء التعاوني.
|
||||
أصبحت لديك crew تعمل بأسلوب JSON-first تبحث في موضوع وتكتب تقريرًا.
|
||||
</Check>
|
||||
|
||||
473
docs/ar/guides/flows/conversational-flows.mdx
Normal file
@@ -0,0 +1,473 @@
|
||||
---
|
||||
title: تدفقات المحادثة
|
||||
description: أنشئ تطبيقات دردشة متعددة الجولات مع kickoff لكل جولة وسجل الرسائل وتوجيه النية والتتبع وجسور WebSocket.
|
||||
icon: comments
|
||||
mode: "wide"
|
||||
---
|
||||
|
||||
## نظرة عامة
|
||||
|
||||
تعامل التطبيقات المحادثية مع كل سطر من المستخدم كـ **تشغيل flow جديد** بنفس **معرّف الجلسة**. توفر CrewAI مساعدات لسجل الرسائل وتصنيف النية الاختياري وتأجيل التتبع وجسور الواجهة، إضافة إلى REPL محلي `flow.chat()` للتدفقات المحادثية.
|
||||
|
||||
| المفهوم | التنفيذ |
|
||||
|---------|---------|
|
||||
| معرّف الجلسة | `handle_turn(..., session_id=...)` → `kickoff(inputs={"id": ...})` → `state.id` |
|
||||
| سطر المستخدم | `handle_turn(message)` يضيف الرسالة إلى `state.messages` قبل تشغيل الرسم |
|
||||
| اكتمال الجولة | `FlowFinished` لهذا **التشغيل** فقط؛ تستمر المحادثة في `handle_turn` التالي |
|
||||
| تتبع الجلسة | `ConversationConfig(defer_trace_finalization=True)` + `finalize_session_traces()` |
|
||||
|
||||
## واجهات الجولات
|
||||
|
||||
استخدم **`flow.handle_turn(message, session_id=...)`** لكل رسالة مستخدم من REST أو WebSocket أو الاختبارات أو الواجهات المخصصة. استخدم **`flow.chat()`** عندما تريد حلقة دردشة محلية في الطرفية لـ `Flow` محادثي.
|
||||
|
||||
لا يقبل `Flow.kickoff()` الوسيطين `user_message=` أو `session_id=`. في التدفقات المحادثية، يخزن `handle_turn()` الرسالة المعلقة ويستدعي داخلياً `kickoff(inputs={"id": session_id})`.
|
||||
|
||||
| API | الاستخدام |
|
||||
|-----|-----------|
|
||||
| `handle_turn(message, session_id=...)` | غلاف مريح لجولة واحدة في `Flow` محادثي |
|
||||
| `chat()` | REPL محلي في الطرفية لـ `Flow` محادثي |
|
||||
| `kickoff(inputs={...})` | تشغيل متقدم للـ flow بدون معالجة جولة محادثية |
|
||||
| `ask()` | مطالبة حاجزة **داخل** خطوة واحدة |
|
||||
| `@human_feedback` | الموافقة/الرفض على **مخرجات خطوة** — وليس السطر التالي |
|
||||
| `ChatSession.handle_turn(...)` | طبقة نقل فوق `handle_turn` |
|
||||
|
||||
## بداية سريعة
|
||||
|
||||
```python
|
||||
from uuid import uuid4
|
||||
|
||||
from crewai import Flow
|
||||
from crewai.flow import listen
|
||||
from crewai.experimental.conversational import (
|
||||
ConversationConfig,
|
||||
ConversationState,
|
||||
)
|
||||
|
||||
|
||||
@ConversationConfig(defer_trace_finalization=True)
|
||||
class SupportFlow(Flow[ConversationState]):
|
||||
conversational = True
|
||||
|
||||
def route_turn(self, context):
|
||||
message = (self.state.current_user_message or "").lower()
|
||||
if "طلب" in message or "order" in message:
|
||||
return "order"
|
||||
if "وداع" in message or "goodbye" in message:
|
||||
return "goodbye"
|
||||
return "help"
|
||||
|
||||
@listen("order")
|
||||
def handle_order(self):
|
||||
reply = "طلبك في الطريق."
|
||||
self.append_assistant_message(reply)
|
||||
return reply
|
||||
|
||||
@listen("help")
|
||||
def handle_help(self):
|
||||
reply = "كيف يمكنني المساعدة؟"
|
||||
self.append_assistant_message(reply)
|
||||
return reply
|
||||
|
||||
@listen("goodbye")
|
||||
def handle_goodbye(self):
|
||||
reply = "وداعاً!"
|
||||
self.append_assistant_message(reply)
|
||||
return reply
|
||||
|
||||
|
||||
session_id = str(uuid4())
|
||||
flow = SupportFlow()
|
||||
|
||||
try:
|
||||
flow.handle_turn("أين طلبي؟", session_id=session_id)
|
||||
flow.handle_turn("وماذا عن الإرجاع؟", session_id=session_id)
|
||||
finally:
|
||||
flow.finalize_session_traces()
|
||||
```
|
||||
|
||||
## دورة حياة الجولة
|
||||
|
||||
كل `handle_turn` يشغّل:
|
||||
|
||||
1. **`_configure_conversational_kickoff`** — دمج `session_id` / `user_message` في `inputs` وتطبيق `ConversationalConfig`.
|
||||
2. **استعادة الحالة** — عند وجود `inputs["id"]` و`@persist`.
|
||||
3. **`FlowStarted`** — في أول جولة للجلسة المؤجلة فقط.
|
||||
4. **`prepare_conversational_turn`** — إضافة رسالة المستخدم و`last_user_message` وتصنيف اختياري.
|
||||
5. **تنفيذ الرسم** — `@start` → `@router` → معالجات `@listen`.
|
||||
6. **نهاية التشغيل** — يُتخطى `flow_finished` والتتبع لكل جولة عند التأجيل؛ `Agent.kickoff()` / crews لا تغلق دفعة الأب.
|
||||
|
||||
استدعِ **`append_assistant_message(reply)`** في المعالجات. سطر المستخدم محفوظ عبر `handle_turn` — لا تُضفه مرة أخرى.
|
||||
|
||||
## `ConversationalConfig` (افتراضيات على مستوى الصنف)
|
||||
|
||||
عيّن على صنف `Flow` كـ `conversational_config: ClassVar[ConversationalConfig | None]`.
|
||||
|
||||
| الحقل | الافتراضي | الغرض |
|
||||
|-------|-----------|--------|
|
||||
| `default_intents` | `None` | تسميات outcome للتصنيف التلقائي قبل kickoff |
|
||||
| `intent_llm` | `None` | نموذج التصنيف (مطلوب عند وجود intents) |
|
||||
| `interactive_prompt` | `"You: "` | مطالبة `kickoff(interactive=True)` |
|
||||
| `interactive_timeout` | `None` | مهلة لكل سطر في الوضع التفاعلي |
|
||||
| `exit_commands` | `exit`, `quit` | كلمات إنهاء الوضع التفاعلي |
|
||||
| `defer_trace_finalization` | `True` | إبقاء دفعة trace واحدة مفتوحة بين الجولات |
|
||||
|
||||
يمكن التجاوز لكل kickoff عبر `intents=` و`intent_llm=`.
|
||||
|
||||
## `ChatState` (شكل الحالة الموصى به للحفظ)
|
||||
|
||||
```python
|
||||
from crewai.flow import ChatState
|
||||
|
||||
|
||||
class MyChatState(ChatState):
|
||||
# موروث: id, messages, last_user_message, last_intent, session_ready
|
||||
research_turn_count: int = 0
|
||||
custom_flag: bool = False
|
||||
```
|
||||
|
||||
| الحقل | الدور |
|
||||
|-------|------|
|
||||
| `id` | UUID الجلسة (مثل `session_id` / `inputs["id"]`) |
|
||||
| `messages` | قائمة `{role, content}` لسجل LLM |
|
||||
| `last_user_message` | آخر سطر مستخدم في هذه الجولة |
|
||||
| `last_intent` | تسمية المسار بعد التصنيف (إن وُجد) |
|
||||
| `session_ready` | علم bootstrap لمرة واحدة |
|
||||
|
||||
`ConversationalInputs` هو `TypedDict` لـ `kickoff(inputs={...})`: `id`, `user_message`, `last_intent`.
|
||||
|
||||
## API المحادثة على `Flow`
|
||||
|
||||
### معاملات `kickoff` / `kickoff_async`
|
||||
|
||||
| المعامل | الغرض |
|
||||
|---------|--------|
|
||||
| `user_message` | نص هذه الجولة (أو `{"role": "user", "content": "..."}`) |
|
||||
| `session_id` | UUID المحادثة → `inputs["id"]` / `state.id` |
|
||||
| `intents` | تسميات outcome لـ `classify_intent` قبل kickoff |
|
||||
| `intent_llm` | LLM للتصنيف (مطلوب مع `intents`) |
|
||||
| `interactive` | حلقة CLI عبر `ask()` (للعروض المحلية فقط) |
|
||||
| `interactive_prompt` | مطالبة الوضع التفاعلي |
|
||||
| `interactive_timeout` | مهلة `ask()` لكل سطر |
|
||||
| `exit_commands` | كلمات إنهاء الوضع التفاعلي |
|
||||
| `inputs` | حقول حالة إضافية |
|
||||
| `restore_from_state_id` | استنساخ من flow محفوظ آخر |
|
||||
|
||||
### سمات المثيل
|
||||
|
||||
| السمة | الغرض |
|
||||
|-------|--------|
|
||||
| `conversational_config` | افتراضيات `ConversationalConfig` على مستوى الصنف |
|
||||
| `defer_trace_finalization` | علم المثيل؛ يُضبط تلقائياً من config عند kickoff |
|
||||
| `suppress_flow_events` | يخفي لوحات console؛ **التتبع يُسجّل** |
|
||||
| `stream` | بث؛ مع `ChatSession.handle_turn(..., stream=True)` |
|
||||
|
||||
### طرق وخصائص
|
||||
|
||||
| الاسم | الوصف |
|
||||
|------|--------|
|
||||
| `append_message(role, content, **extra)` | إضافة إلى `state.messages` |
|
||||
| `conversation_messages` | سجل للقراءة فقط لاستدعاءات LLM |
|
||||
| `classify_intent(text, outcomes, *, llm, context=None)` | تعيين outcome |
|
||||
| `receive_user_message(text, *, outcomes=None, llm=None)` | إضافة رسالة مستخدم؛ `last_intent` اختياري |
|
||||
| `finalize_session_traces()` | إصدار `flow_finished` المؤجل وإنهاء دفعة trace |
|
||||
| `_should_defer_trace_finalization()` | هل يُؤجل إنهاء trace لكل جولة |
|
||||
| `input_history` | سجل تدقيق مطالبات وردود `ask()` |
|
||||
|
||||
### مساعدات الوحدة (`crewai.flow.conversation`)
|
||||
|
||||
| الدالة | الوصف |
|
||||
|--------|--------|
|
||||
| `normalize_kickoff_inputs(...)` | دمج kwargs المحادثة في `inputs` |
|
||||
| `get_conversation_messages(flow)` | قراءة الرسائل من الحالة أو المخزن |
|
||||
| `append_message(flow, ...)` | مثل طريقة المثيل |
|
||||
| `prepare_conversational_turn(flow, ...)` | تهيئة الجولة (عادةً kickoff يستدعيها) |
|
||||
| `receive_user_message(flow, ...)` | مثل طريقة المثيل |
|
||||
| `set_state_field(flow, name, value)` | تعيين حقل dict أو Pydantic |
|
||||
| `get_conversational_config(flow)` | قراءة `conversational_config` |
|
||||
| `input_history_to_messages(entries)` | تحويل `input_history` لصيغة رسائل LLM |
|
||||
|
||||
## أنماط توجيه النية
|
||||
|
||||
### أ. تصنيف مسبق عبر `ConversationalConfig` (الأبسط)
|
||||
|
||||
عيّن `default_intents` و`intent_llm`. كل kickoff يصنّف قبل `@router`؛ اقرأ `self.state.last_intent` في `route()`.
|
||||
|
||||
### ب. تصنيف داخل `@router` (مطالبات أغنى)
|
||||
|
||||
عيّن `default_intents=None` ليضيف kickoff الرسالة فقط. في `route()` استدعِ `classify_intent`:
|
||||
|
||||
```python
|
||||
@router(bootstrap)
|
||||
def route(self):
|
||||
intent = self.classify_intent(
|
||||
self._routing_prompt(self.state.last_user_message),
|
||||
("GREETING", "ORDER", "RESEARCH", "GOODBYE"),
|
||||
llm=self.conversational_config.intent_llm or "gpt-4o-mini",
|
||||
)
|
||||
self.state.last_intent = intent
|
||||
return intent
|
||||
```
|
||||
|
||||
للبحث على الويب أو أدوات متعددة الخطوات استخدم **`@listen("RESEARCH")`** مع `Agent.kickoff()` وأدوات — وليس `LLM.call()` فقط.
|
||||
|
||||
## عندما ينتهي الـ flow ويستمر المستخدم
|
||||
|
||||
`FlowFinished` يعني أن **تنفيذ الرسم هذا** اكتمل. تستمر المحادثة بـ `kickoff` آخر ونفس `session_id`. `@persist` يستعيد `messages` والأعلام والسياق.
|
||||
|
||||
**نمط الحفظ:** يُفضّل `@persist` على **خطوة نهائية واحدة** (مثل `finalize`) وليس على صنف `Flow` بالكامل. الحفظ على مستوى الصنف بعد كل method قد يفقد تحديثات المعالجات في نفس الجولة.
|
||||
|
||||
لا تستخدم `@human_feedback` لأسطر المتابعة في الدردشة إلا عند الحاجة لموافقة بشرية على مخرجات خطوة محددة.
|
||||
|
||||
## `Flow` المحادثاتي (تجريبي)
|
||||
|
||||
<Warning>
|
||||
**ميزة تجريبية.** سطح `Flow` المحادثاتي (`conversational = True`،
|
||||
`handle_turn`، `ConversationConfig`، `RouterConfig`،
|
||||
`ConversationState`، الرسم البياني المدمج والمساعدات) يقع تحت
|
||||
`crewai.experimental` وقد يتغير شكله قبل التخرج. ثبّت إصدار CrewAI إذا
|
||||
كنت تعتمد على سلوك محدد، وراقب changelog للتحديثات الكاسرة. الملاحظات
|
||||
والمشاكل مرحب بها.
|
||||
</Warning>
|
||||
|
||||
فعّل الرسم المحادثاتي بتعيين `conversational = True` على صنف فرعي من `Flow`. عندئذٍ يُظهر `Flow` الأساسي رسم `@start` / `@router` / `converse_turn` / `end_conversation` مدمجاً، ويدير `state.messages`، ويُشغّل LLM التوجيه، ويبقي دفعة trace مفتوحة عبر الجولات. أنت تكتب **المسارات المخصصة** فقط؛ والإطار يتولى الباقي.
|
||||
|
||||
استخدمه عندما تريد دردشة متعددة الجولات مع موجّه قائم على LLM ومعالجات لكل مسار دون توصيل دورة الحياة يدوياً. استخدم `Flow[ChatState]` (النمط الأدنى مستوى في الأعلى) عندما تحتاج تحكماً كاملاً.
|
||||
|
||||
### مثال سريع
|
||||
|
||||
```python
|
||||
from crewai import LLM, Flow
|
||||
from crewai.flow import listen
|
||||
from crewai.experimental.conversational import (
|
||||
ConversationConfig,
|
||||
ConversationState,
|
||||
RouterConfig,
|
||||
)
|
||||
|
||||
|
||||
ROUTER_LLM = LLM(model="gpt-4o-mini")
|
||||
|
||||
|
||||
@ConversationConfig(
|
||||
system_prompt="A multi-agent assistant for ordinary chat and tool-backed tasks.",
|
||||
llm=ROUTER_LLM,
|
||||
router=RouterConfig(), # المسارات + الأوصاف تُكتشف تلقائياً من معالجات @listen
|
||||
)
|
||||
class SupportFlow(Flow[ConversationState]):
|
||||
conversational = True
|
||||
|
||||
@listen("INTERNET_SEARCH")
|
||||
def handle_internet_search(self) -> str:
|
||||
"""Fresh web research, current news, real-time lookups."""
|
||||
...
|
||||
self.append_assistant_message(reply)
|
||||
return reply
|
||||
|
||||
@listen("CREWAI_DOCS")
|
||||
def handle_crewai_docs(self) -> str:
|
||||
"""Look up the CrewAI documentation for framework/API questions."""
|
||||
...
|
||||
self.append_assistant_message(reply)
|
||||
return reply
|
||||
|
||||
|
||||
flow = SupportFlow()
|
||||
try:
|
||||
flow.handle_turn("ماذا يمكنك أن تفعل؟") # يوجَّه إلى converse (مدمج)
|
||||
flow.handle_turn("ابحث في الويب عن أخبار الذكاء الاصطناعي.") # يوجَّه إلى INTERNET_SEARCH
|
||||
flow.handle_turn("لخص النتيجة الأولى.") # يعود إلى converse
|
||||
finally:
|
||||
flow.finalize_session_traces()
|
||||
```
|
||||
|
||||
للدردشة المحلية في الطرفية، استخدم `chat()`:
|
||||
|
||||
```python
|
||||
def kickoff() -> None:
|
||||
SupportFlow().chat()
|
||||
```
|
||||
|
||||
يلف `chat()` استدعاءات `handle_turn()` داخل REPL، ويخرج عند `exit` / `quit`، ويتجاهل الأسطر الفارغة افتراضياً، ويستدعي `finalize_session_traces()` عند انتهاء الجلسة.
|
||||
|
||||
### `ConversationConfig`
|
||||
|
||||
مزخرف صنف يُلحق افتراضيات الدردشة على مستوى الصنف.
|
||||
|
||||
| الحقل | الافتراضي | الغرض |
|
||||
|-------|-----------|-------|
|
||||
| `system_prompt` | `slices.conversational_system_prompt` من i18n | رسالة system يستخدمها `converse_turn` المدمج. مرر `""` للتعطيل التام. |
|
||||
| `llm` | `None` | LLM المحادثة (يستخدمه `converse_turn` وكاحتياطي للموجّه). |
|
||||
| `router` | `None` | `RouterConfig` للتوجيه عبر LLM. بدونه، يسقط الـ flow دائماً إلى `converse`. |
|
||||
| `answer_from_history_prompt` | افتراضي الإطار | رسالة system للمسار الاختياري `answer_from_history`. |
|
||||
| `answer_from_history_llm` | `None` | يُفعّل الاختصار `answer_from_history` عند تعيينه. |
|
||||
| `intent_llm` | `None` | LLM لمسار التصنيف المسبق القديم `intents=`/`default_intents`. |
|
||||
| `default_intents` | `None` | تسميات النتائج للتصنيف المسبق القديم. |
|
||||
| `visible_agent_outputs` | `None` | `"all"` أو قائمة بأسماء الـ agents الذين تُرفع مخرجاتهم من `append_agent_result()` إلى رسائل عامة. |
|
||||
| `defer_trace_finalization` | `True` | يبقي دفعة trace واحدة مفتوحة عبر استدعاءات `handle_turn()`. |
|
||||
|
||||
### `RouterConfig` وفهرس المسارات المُولَّد تلقائياً
|
||||
|
||||
```python
|
||||
RouterConfig(
|
||||
prompt="تأطير اختياري للنطاق (سياسة، صوت، شخصية).",
|
||||
response_format=MyRoute, # اختياري؛ يُولَّد تلقائياً عند الإغفال
|
||||
llm=ROUTER_LLM, # يسقط إلى ConversationConfig.llm
|
||||
routes=["INTERNET_SEARCH", "CREWAI_DOCS"], # اختياري؛ يُستنتج من المستمعين
|
||||
route_descriptions={
|
||||
"INTERNET_SEARCH": "تجاوز الـ docstring لهذا المسار فقط.",
|
||||
},
|
||||
default_intent="converse", # يُستخدم عند فشل LLM أو غيابه
|
||||
fallback_intent="converse", # يُستخدم عندما يعيد LLM مساراً غير صالح
|
||||
intent_field="intent",
|
||||
)
|
||||
```
|
||||
|
||||
تُبنى رسالة الموجّه إلى LLM تلقائياً. لكل مسار يختار الإطار وصفاً بهذا الترتيب من الأولوية:
|
||||
|
||||
1. `RouterConfig.route_descriptions[label]` — تجاوز صريح.
|
||||
2. `Flow.builtin_route_descriptions[label]` — نص جاهز من الإطار لـ `converse` و`end` و`answer_from_history` (مصاغ لـ LLM التوجيه).
|
||||
3. أول سطر غير فارغ من docstring معالج `@listen(label)`.
|
||||
4. فارغ (المسار يظهر في الفهرس بلا وصف).
|
||||
|
||||
عملياً، **إضافة مسار جديد = `@listen("X")` + docstring من سطر واحد**:
|
||||
|
||||
```python
|
||||
@listen("INTERNET_SEARCH")
|
||||
def handle_internet_search(self) -> str:
|
||||
"""Fresh web research, current news, real-time lookups."""
|
||||
...
|
||||
```
|
||||
|
||||
…وسيرى LLM التوجيه:
|
||||
|
||||
```
|
||||
Routes:
|
||||
- CREWAI_DOCS: Look up the CrewAI documentation for framework/API questions.
|
||||
- INTERNET_SEARCH: Fresh web research, current news, real-time lookups.
|
||||
- converse: Ordinary chat, follow-ups, summaries, clarifications…
|
||||
- end: User signals the conversation is finished (goodbye, exit, done).
|
||||
```
|
||||
|
||||
`RouterConfig.prompt` مخصص لـ **تأطير النطاق** (شخصية المساعد، قواعد العمل، النبرة). فهرس المسارات يُبنى تلقائياً — لا تُدرج المسارات في `prompt`؛ سيختل التزامن لحظة إضافة معالج جديد.
|
||||
|
||||
### المسارات المدمجة
|
||||
|
||||
| المسار | المعالج | الغرض |
|
||||
|--------|---------|-------|
|
||||
| `converse` | `converse_turn` | معالج الدردشة الافتراضي. يستدعي `ConversationConfig.llm` بـ system prompt + التاريخ القانوني للرسائل. |
|
||||
| `end` | `end_conversation` | يضبط `state.ended = True` ويُصدر رد إنهاء. |
|
||||
| `answer_from_history` | `answer_from_history_turn` | اختياري. يُوجَّه إليه عندما يكون `ConversationConfig.answer_from_history_llm` مُعيَّناً ويمكن الإجابة على الرسالة من التاريخ فقط. |
|
||||
|
||||
يمكنك تجاوز أي من هذه بتعريف معالج بنفس الاسم في الصنف الفرعي.
|
||||
|
||||
### دلالات `handle_turn()`
|
||||
|
||||
`flow.handle_turn(message)` يُشغّل جولة واحدة:
|
||||
|
||||
1. يعيد ضبط تعقّب التنفيذ لكل جولة (`_completed_methods`, `_method_outputs`) ليُعاد تشغيل الرسم — بدون ذلك، استدعاءات `kickoff` المتكررة على نفس النسخة ستُحدث دائرة قصر من الجولة الثانية لأن `Flow.kickoff_async` يعتبر `inputs={"id": ...}` استعادة من نقطة تفتيش.
|
||||
2. يُلحق رسالة المستخدم بـ `state.messages` ويضبط `current_user_message` / `last_user_message`. يُحافَظ على `last_intent` **من الجولة السابقة** كي يستخدمها LLM التوجيه كإشارة.
|
||||
3. يُشغّل `conversation_start` → `route_conversation` → معالج `@listen` المختار.
|
||||
4. يخزّن الموجّه قراره في `state.last_intent` (يكون مرئياً لسياق التوجيه في الجولة التالية).
|
||||
5. إذا أعاد معالجك سلسلة نصية ولم يستدعِ `append_assistant_message`، فإن `handle_turn` يُلحقها نيابةً عنك.
|
||||
|
||||
استدعِ `handle_turn()` لرسائل الدردشة. استدعاء `kickoff(inputs={"id": ...})` مباشرةً يشغل الرسم بدون غلاف الجولة المحادثية.
|
||||
|
||||
### `chat()` للـ REPL المحلي
|
||||
|
||||
`flow.chat()` هو غلاف الطرفية الجاهز فوق `handle_turn()`:
|
||||
|
||||
```python
|
||||
flow = SupportFlow()
|
||||
flow.chat()
|
||||
```
|
||||
|
||||
يتولى الحلقة المحلية الشائعة:
|
||||
|
||||
1. يطلب رسالة من المستخدم.
|
||||
2. يتوقف عند `exit` / `quit` أو `EOFError` أو `KeyboardInterrupt`.
|
||||
3. يستدعي `handle_turn(message, session_id=...)`.
|
||||
4. يطبع نتيجة المساعد.
|
||||
5. ينهي traces الجلسة المؤجلة داخل كتلة `finally`.
|
||||
|
||||
خصص سلوك الطرفية عبر I/O قابل للحقن:
|
||||
|
||||
```python
|
||||
flow.chat(
|
||||
session_id="demo-session",
|
||||
prompt="You: ",
|
||||
assistant_prefix="Assistant: ",
|
||||
exit_commands=("exit", "quit", "bye"),
|
||||
)
|
||||
```
|
||||
|
||||
لتطبيقات الويب والـ workers الخلفية والاختبارات ووسائط النقل المخصصة، استمر في استخدام `handle_turn()` مباشرةً.
|
||||
|
||||
### سلوك موجّه مخصص
|
||||
|
||||
لتشغيل آثار جانبية (إعداد ناقل أحداث، قياس عن بُعد) في كل قرار توجيه، تجاوز `route_turn`:
|
||||
|
||||
```python
|
||||
class SupportFlow(Flow[ConversationState]):
|
||||
conversational = True
|
||||
|
||||
def route_turn(self, context: dict[str, Any]) -> str | None:
|
||||
self.event_bus = MyBus(self)
|
||||
return super().route_turn(context)
|
||||
```
|
||||
|
||||
لتجاوز موجّه LLM واختيار مسار برمجياً، أعد سلسلة نصية من `route_turn`؛ إعادة `None` تسقط إلى `_route_with_config(...)`.
|
||||
|
||||
### `append_assistant_message` و`append_agent_result`
|
||||
|
||||
داخل معالج `@listen(label)`، اختر:
|
||||
|
||||
- `self.append_assistant_message(text)` — يضيف جولة مساعد مرئية للمستخدم إلى `state.messages`. سيراها `converse_turn` في الجولة التالية.
|
||||
- `self.append_agent_result(agent_name, result, visibility="private")` — يسجّل حدثاً منظماً في `state.events` وموضوعاً في `state.agent_threads[agent_name]`. الرؤية العامة تستدعي `append_assistant_message` أيضاً. استخدم النتائج الخاصة للعمل الجانبي الذي يجب ألا يلوث التاريخ القانوني.
|
||||
|
||||
يمكن لـ `ConversationConfig.visible_agent_outputs` رفع النتائج الخاصة لـ agents محددين إلى عامة عالمياً (`"all"` أو قائمة بالأسماء).
|
||||
|
||||
## التتبع عبر الجولات
|
||||
|
||||
مع `defer_trace_finalization=True` (افتراضي في `ConversationalConfig`):
|
||||
|
||||
- **دفعة trace واحدة** لجلسة الدردشة.
|
||||
- **`flow_started`** في الجولة الأولى فقط؛ **`flow_finished`** مرة في `finalize_session_traces()`.
|
||||
- **`kickoff` لكل جولة** لا يطبع "Trace batch finalized".
|
||||
- **العمل المتداخل** (`Agent.kickoff()`, crews, Exa) يُلحق بدفعة **الأب**؛ flow داخلي من `AgentExecutor` لا يغلق دفعة الجلسة مبكراً.
|
||||
|
||||
```python
|
||||
flow.chat(session_id=session_id)
|
||||
```
|
||||
|
||||
`flow.chat()` يستدعي `finalize_session_traces()` نيابةً عنك. عندما تملك الحلقة عبر `handle_turn()` أو `kickoff(...)`، استدعِ `finalize_session_traces()` عند انتهاء الجلسة.
|
||||
|
||||
`suppress_flow_events=True` يخفي لوحات Rich فقط؛ أحداث trace والـ methods تُصدر.
|
||||
|
||||
### دورة حياة trace لـ `Flow` المحادثاتي
|
||||
|
||||
يستخدم [`Flow` المحادثاتي](#flow-المحادثاتي-تجريبي) التجريبي نفس دورة حياة tracing: `defer_trace_finalization` افتراضياً `True`، فيبقي كل `handle_turn()` أثر الجلسة مفتوحاً. أنهِ دوماً عند نهاية الجلسة — لُف حلقتك بـ `try/finally` واستدعِ `flow.finalize_session_traces()` عند الخروج. بدون ذلك، تبقى الدفعة مفتوحة وقد لا تُصدَّر آخر محادثة أبداً.
|
||||
|
||||
## البث
|
||||
|
||||
اضبط `stream = True` على صنف `Flow`. عندئذٍ يُصدر `kickoff(...)` أحداث `assistant_delta` (وما يرتبط بها) عبر ناقل الأحداث القياسي.
|
||||
|
||||
## الاستيراد
|
||||
|
||||
```python
|
||||
from crewai.flow import (
|
||||
ChatState,
|
||||
ConversationalConfig,
|
||||
ConversationalInputs,
|
||||
Flow,
|
||||
listen,
|
||||
persist,
|
||||
router,
|
||||
start,
|
||||
)
|
||||
```
|
||||
|
||||
## مراجع
|
||||
|
||||
- [إتقان إدارة حالة Flow](/ar/guides/flows/mastering-flow-state)
|
||||
- [أنشئ أول Flow](/ar/guides/flows/first-flow)
|
||||
- Demo: `lib/crewai/runner_conversational_flow_simple.py` — REPL بسيط مع `RESEARCH` ووكيل Exa
|
||||
@@ -42,21 +42,26 @@ cd guide_creator_flow
|
||||
|
||||
## الخطوة 2: فهم هيكل المشروع
|
||||
|
||||
يستخدم الـ crew المبدئي المضمّن في مشروع Flow بنية Python/YAML الكلاسيكية. لاستخدام crew بنمط JSON-first داخل Flow، أنشئ `crew.jsonc` و `agents/*.jsonc` داخل مجلد الـ crew وحمّله عبر `crewai.project.load_crew` كما في [Flows](/ar/concepts/flows#building-your-crews).
|
||||
|
||||
```
|
||||
guide_creator_flow/
|
||||
├── .gitignore
|
||||
├── pyproject.toml
|
||||
├── README.md
|
||||
├── .env
|
||||
├── main.py
|
||||
├── crews/
|
||||
│ └── poem_crew/
|
||||
│ ├── config/
|
||||
│ │ ├── agents.yaml
|
||||
│ │ └── tasks.yaml
|
||||
│ └── poem_crew.py
|
||||
└── tools/
|
||||
└── custom_tool.py
|
||||
└── src/
|
||||
└── guide_creator_flow/
|
||||
├── __init__.py
|
||||
├── main.py
|
||||
├── crews/
|
||||
│ └── poem_crew/
|
||||
│ ├── config/
|
||||
│ │ ├── agents.yaml
|
||||
│ │ └── tasks.yaml
|
||||
│ └── poem_crew.py
|
||||
└── tools/
|
||||
└── custom_tool.py
|
||||
```
|
||||
|
||||
يوفر هذا الهيكل فصلاً واضحًا بين مكونات Flow المختلفة. سنعدّل هذا الهيكل لإنشاء Flow منشئ الدليل.
|
||||
@@ -69,139 +74,77 @@ crewai flow add-crew content-crew
|
||||
|
||||
## الخطوة 4: تهيئة Crew كتابة المحتوى
|
||||
|
||||
1. حدّث ملف تهيئة الـ Agents. تذكر تعيين `llm` للمزود الذي تستخدمه.
|
||||
سنهيئ crew كتابة المحتوى باستخدام JSONC. سنعرّف Agent للكتابة وAgent للمراجعة، ثم نحمّل `crew.jsonc` من خطوة Flow.
|
||||
|
||||
```yaml
|
||||
# src/guide_creator_flow/crews/content_crew/config/agents.yaml
|
||||
content_writer:
|
||||
role: >
|
||||
Educational Content Writer
|
||||
goal: >
|
||||
Create engaging, informative content that thoroughly explains the assigned topic
|
||||
and provides valuable insights to the reader
|
||||
backstory: >
|
||||
You are a talented educational writer with expertise in creating clear, engaging
|
||||
content. You have a gift for explaining complex concepts in accessible language
|
||||
and organizing information in a way that helps readers build their understanding.
|
||||
llm: provider/model-id
|
||||
1. أنشئ `src/guide_creator_flow/crews/content_crew/agents/content_writer.jsonc`:
|
||||
|
||||
content_reviewer:
|
||||
role: >
|
||||
Educational Content Reviewer and Editor
|
||||
goal: >
|
||||
Ensure content is accurate, comprehensive, well-structured, and maintains
|
||||
consistency with previously written sections
|
||||
backstory: >
|
||||
You are a meticulous editor with years of experience reviewing educational
|
||||
content. You have an eye for detail, clarity, and coherence.
|
||||
llm: provider/model-id
|
||||
```jsonc
|
||||
{
|
||||
"role": "Educational Content Writer",
|
||||
"goal": "Create engaging, informative content that thoroughly explains the assigned topic and provides valuable insights to the reader.",
|
||||
"backstory": "You are a talented educational writer who explains complex concepts in accessible language and organizes information clearly.",
|
||||
"llm": "provider/model-id",
|
||||
"settings": {
|
||||
"verbose": true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
2. حدّث ملف تهيئة المهام:
|
||||
2. أنشئ `src/guide_creator_flow/crews/content_crew/agents/content_reviewer.jsonc`:
|
||||
|
||||
```yaml
|
||||
# src/guide_creator_flow/crews/content_crew/config/tasks.yaml
|
||||
write_section_task:
|
||||
description: >
|
||||
Write a comprehensive section on the topic: "{section_title}"
|
||||
|
||||
Section description: {section_description}
|
||||
Target audience: {audience_level} level learners
|
||||
|
||||
Your content should:
|
||||
1. Begin with a brief introduction to the section topic
|
||||
2. Explain all key concepts clearly with examples
|
||||
3. Include practical applications or exercises where appropriate
|
||||
4. End with a summary of key points
|
||||
5. Be approximately 500-800 words in length
|
||||
|
||||
Format your content in Markdown with appropriate headings, lists, and emphasis.
|
||||
|
||||
Previously written sections:
|
||||
{previous_sections}
|
||||
expected_output: >
|
||||
A well-structured, comprehensive section in Markdown format that thoroughly
|
||||
explains the topic and is appropriate for the target audience.
|
||||
agent: content_writer
|
||||
|
||||
review_section_task:
|
||||
description: >
|
||||
Review and improve the following section on "{section_title}":
|
||||
|
||||
{draft_content}
|
||||
|
||||
Target audience: {audience_level} level learners
|
||||
|
||||
Previously written sections:
|
||||
{previous_sections}
|
||||
|
||||
Your review should:
|
||||
1. Fix any grammatical or spelling errors
|
||||
2. Improve clarity and readability
|
||||
3. Ensure content is comprehensive and accurate
|
||||
4. Verify consistency with previously written sections
|
||||
5. Enhance the structure and flow
|
||||
6. Add any missing key information
|
||||
expected_output: >
|
||||
An improved, polished version of the section that maintains the original
|
||||
structure but enhances clarity, accuracy, and consistency.
|
||||
agent: content_reviewer
|
||||
context:
|
||||
- write_section_task
|
||||
```jsonc
|
||||
{
|
||||
"role": "Educational Content Reviewer and Editor",
|
||||
"goal": "Ensure content is accurate, comprehensive, well-structured, and consistent with previously written sections.",
|
||||
"backstory": "You are a meticulous editor with an eye for detail, clarity, and coherence.",
|
||||
"llm": "provider/model-id",
|
||||
"settings": {
|
||||
"verbose": true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
3. حدّث ملف تنفيذ Crew:
|
||||
استبدل `provider/model-id` بالنموذج الذي تستخدمه، مثل `openai/gpt-4o` أو `gemini/gemini-2.0-flash-001` أو `anthropic/claude-sonnet-4-6`.
|
||||
|
||||
3. أنشئ `src/guide_creator_flow/crews/content_crew/crew.jsonc`:
|
||||
|
||||
```jsonc
|
||||
{
|
||||
"name": "Content Crew",
|
||||
"agents": ["content_writer", "content_reviewer"],
|
||||
"tasks": [
|
||||
{
|
||||
"name": "write_section_task",
|
||||
"description": "Write a comprehensive section on the topic: \"{section_title}\".\n\nSection description: {section_description}\nTarget audience: {audience_level} level learners\n\nYour content should begin with a brief introduction, explain key concepts clearly with examples, include practical applications where appropriate, end with a summary, and be approximately 500-800 words.\n\nPreviously written sections:\n{previous_sections}",
|
||||
"expected_output": "A well-structured, comprehensive section in Markdown format that thoroughly explains the topic and is appropriate for the target audience.",
|
||||
"agent": "content_writer",
|
||||
"markdown": true
|
||||
},
|
||||
{
|
||||
"name": "review_section_task",
|
||||
"description": "Review and improve this section on \"{section_title}\":\n\n{draft_content}\n\nTarget audience: {audience_level} level learners\nPreviously written sections:\n{previous_sections}\n\nFix errors, improve clarity, verify consistency, enhance structure, and add missing key information.",
|
||||
"expected_output": "An improved, polished version of the section that maintains the original structure but enhances clarity, accuracy, and consistency.",
|
||||
"agent": "content_reviewer",
|
||||
"context": ["write_section_task"],
|
||||
"markdown": true
|
||||
}
|
||||
],
|
||||
"process": "sequential",
|
||||
"verbose": true
|
||||
}
|
||||
```
|
||||
|
||||
4. استبدل `src/guide_creator_flow/crews/content_crew/content_crew.py` بمحمل صغير:
|
||||
|
||||
```python
|
||||
# src/guide_creator_flow/crews/content_crew/content_crew.py
|
||||
from crewai import Agent, Crew, Process, Task
|
||||
from crewai.project import CrewBase, agent, crew, task
|
||||
from crewai.agents.agent_builder.base_agent import BaseAgent
|
||||
from typing import List
|
||||
from pathlib import Path
|
||||
|
||||
@CrewBase
|
||||
class ContentCrew():
|
||||
"""Content writing crew"""
|
||||
from crewai.project import load_crew
|
||||
|
||||
agents: List[BaseAgent]
|
||||
tasks: List[Task]
|
||||
|
||||
@agent
|
||||
def content_writer(self) -> Agent:
|
||||
return Agent(
|
||||
config=self.agents_config['content_writer'], # type: ignore[index]
|
||||
verbose=True
|
||||
)
|
||||
|
||||
@agent
|
||||
def content_reviewer(self) -> Agent:
|
||||
return Agent(
|
||||
config=self.agents_config['content_reviewer'], # type: ignore[index]
|
||||
verbose=True
|
||||
)
|
||||
|
||||
@task
|
||||
def write_section_task(self) -> Task:
|
||||
return Task(
|
||||
config=self.tasks_config['write_section_task'] # type: ignore[index]
|
||||
)
|
||||
|
||||
@task
|
||||
def review_section_task(self) -> Task:
|
||||
return Task(
|
||||
config=self.tasks_config['review_section_task'], # type: ignore[index]
|
||||
context=[self.write_section_task()]
|
||||
)
|
||||
|
||||
@crew
|
||||
def crew(self) -> Crew:
|
||||
"""Creates the content writing crew"""
|
||||
return Crew(
|
||||
agents=self.agents,
|
||||
tasks=self.tasks,
|
||||
process=Process.sequential,
|
||||
verbose=True,
|
||||
)
|
||||
def kickoff_content_crew(inputs: dict):
|
||||
crew, default_inputs = load_crew(Path(__file__).with_name("crew.jsonc"))
|
||||
return crew.kickoff(inputs={**default_inputs, **inputs})
|
||||
```
|
||||
|
||||
## الخطوة 5: إنشاء Flow
|
||||
@@ -272,6 +215,7 @@ crewai flow plot
|
||||
3. استكشف دوال `and_` و`or_` لتنفيذ متوازٍ أكثر تعقيدًا
|
||||
4. اربط Flow بواجهات API خارجية وقواعد بيانات وواجهات مستخدم
|
||||
5. ادمج عدة Crews متخصصة في Flow واحد
|
||||
6. أنشئ تطبيقات دردشة متعددة الجولات مع [تدفقات المحادثة](/ar/guides/flows/conversational-flows) (`kickoff` لكل رسالة، `ChatSession`، تأجيل التتبع)
|
||||
|
||||
<Check>
|
||||
تهانينا! لقد بنيت بنجاح أول CrewAI Flow يجمع بين الكود العادي واستدعاءات LLM المباشرة ومعالجة Crew لإنشاء دليل شامل. هذه المهارات الأساسية تمكّنك من إنشاء تطبيقات AI متطورة بشكل متزايد.
|
||||
|
||||
@@ -20,6 +20,8 @@ mode: "wide"
|
||||
5. **توسيع تطبيقاتك** - دعم سير العمل المعقدة بتنظيم بيانات مناسب
|
||||
6. **تمكين التطبيقات الحوارية** - تخزين والوصول إلى سجل المحادثات للتفاعلات الواعية بالسياق
|
||||
|
||||
للدردشة متعددة الجولات (`kickoff` لكل سطر مستخدم، `ChatState`، توجيه النية، تأجيل التتبع، و`ChatSession`)، راجع [تدفقات المحادثة](/ar/guides/flows/conversational-flows).
|
||||
|
||||
## أساسيات إدارة الحالة
|
||||
|
||||
### نهجان لإدارة الحالة
|
||||
|
||||
@@ -113,7 +113,7 @@ python3 --version
|
||||
|
||||
# إنشاء مشروع CrewAI
|
||||
|
||||
نوصي باستخدام قالب `YAML` لنهج منظم في تعريف الـ Agents والمهام. إليك كيفية البدء:
|
||||
يقوم `crewai create crew` الآن بإنشاء مشروع crew بأسلوب JSON-first. توضع الـ Agents في `agents/*.jsonc`، وتوضع المهام وإعدادات الـ crew في `crew.jsonc`، ويحمّل `crewai run` هذا التعريف مباشرة.
|
||||
|
||||
<Steps>
|
||||
<Step title="إنشاء هيكل المشروع">
|
||||
@@ -126,21 +126,20 @@ python3 --version
|
||||
```
|
||||
my_project/
|
||||
├── .gitignore
|
||||
├── .env
|
||||
├── agents/
|
||||
│ └── researcher.jsonc
|
||||
├── crew.jsonc
|
||||
├── knowledge/
|
||||
├── pyproject.toml
|
||||
├── README.md
|
||||
├── .env
|
||||
└── src/
|
||||
└── my_project/
|
||||
├── __init__.py
|
||||
├── main.py
|
||||
├── crew.py
|
||||
├── tools/
|
||||
│ ├── custom_tool.py
|
||||
│ └── __init__.py
|
||||
└── config/
|
||||
├── agents.yaml
|
||||
└── tasks.yaml
|
||||
├── skills/
|
||||
└── tools/
|
||||
```
|
||||
|
||||
- إذا احتجت إلى البنية القديمة Python/YAML التي تحتوي على `crew.py` و `config/agents.yaml` و `config/tasks.yaml`، شغّل:
|
||||
```shell
|
||||
crewai create crew <your_project_name> --classic
|
||||
```
|
||||
|
||||
</Step>
|
||||
@@ -149,15 +148,15 @@ python3 --version
|
||||
- سيحتوي مشروعك على هذه الملفات الأساسية:
|
||||
| الملف | الغرض |
|
||||
| --- | --- |
|
||||
| `agents.yaml` | تعريف الـ Agents وأدوارهم |
|
||||
| `tasks.yaml` | إعداد مهام الـ Agents وسير العمل |
|
||||
| `crew.jsonc` | إعداد الـ crew وترتيب المهام والعملية وقيم الإدخال الافتراضية |
|
||||
| `agents/*.jsonc` | تعريف دور كل Agent وهدفه و backstory والـ LLM والأدوات والسلوك |
|
||||
| `.env` | تخزين مفاتيح API ومتغيرات البيئة |
|
||||
| `main.py` | نقطة دخول المشروع وتدفق التنفيذ |
|
||||
| `crew.py` | تنسيق وإدارة الـ Crew |
|
||||
| `tools/` | مجلد الأدوات المخصصة |
|
||||
| `knowledge/` | مجلد قاعدة المعرفة |
|
||||
| `tools/` | ملفات Python اختيارية لأدوات `custom:<name>` |
|
||||
| `knowledge/` | ملفات معرفة اختيارية للـ Agents |
|
||||
| `skills/` | ملفات skills اختيارية تطبق على الـ crew |
|
||||
|
||||
- ابدأ بتحرير `agents.yaml` و`tasks.yaml` لتعريف سلوك الـ Crew.
|
||||
- ابدأ بتحرير `crew.jsonc` والملفات داخل `agents/` لتعريف سلوك الـ crew.
|
||||
- استخدم قيم `{placeholder}` في نصوص الـ Agents والمهام، ثم ضع القيم الافتراضية في `inputs` داخل `crew.jsonc`. عند تشغيل `crewai run` ستطلب CLI أي قيم ناقصة.
|
||||
- احتفظ بالمعلومات الحساسة مثل مفاتيح API في `.env`.
|
||||
|
||||
</Step>
|
||||
|
||||
@@ -5,11 +5,15 @@ icon: "at"
|
||||
mode: "wide"
|
||||
---
|
||||
|
||||
يشرح هذا الدليل كيفية استخدام التعليقات التوضيحية للإشارة بشكل صحيح إلى **الوكلاء** و**المهام** والمكونات الأخرى في ملف `crew.py`.
|
||||
يشرح هذا الدليل كيفية استخدام التعليقات التوضيحية للإشارة بشكل صحيح إلى **الوكلاء** و**المهام** والمكونات الأخرى في ملف `crew.py` كلاسيكي.
|
||||
|
||||
<Note>
|
||||
المشاريع الجديدة التي تُنشأ عبر `crewai create crew <name>` هي JSON-first وتستخدم `crew.jsonc` مع `agents/*.jsonc`. استخدم هذا الدليل عند العمل في مشروع كلاسيكي أُنشئ عبر `crewai create crew <name> --classic`، أو عند ترحيل مشروع Python/YAML موجود، أو عندما تحتاج تحكمًا عبر decorators في Python.
|
||||
</Note>
|
||||
|
||||
## مقدمة
|
||||
|
||||
تُستخدم التعليقات التوضيحية في إطار عمل CrewAI لتزيين الفئات والطرق، مما يوفر بيانات وصفية ووظائف للمكونات المختلفة في طاقمك. تساعد هذه التعليقات التوضيحية في تنظيم وهيكلة الكود الخاص بك، مما يجعله أكثر قابلية للقراءة والصيانة.
|
||||
تُستخدم التعليقات التوضيحية في إطار عمل CrewAI لتزيين الفئات والطرق، مما يوفر بيانات وصفية ووظائف للمكونات المختلفة في طاقمك. في مشاريع Python/YAML الكلاسيكية، تنظم الكود الذي يحمّل `config/agents.yaml` و `config/tasks.yaml` ويعيد كائن `Crew`.
|
||||
|
||||
## التعليقات التوضيحية المتاحة
|
||||
|
||||
@@ -113,9 +117,9 @@ def crew(self) -> Crew:
|
||||
|
||||
تُستخدم التعليقة التوضيحية `@crew` لتزيين الطريقة التي تنشئ وتُرجع كائن `Crew`. تجمع هذه الطريقة جميع المكونات (الوكلاء والمهام) في طاقم وظيفي.
|
||||
|
||||
## إعداد YAML
|
||||
## إعداد YAML الكلاسيكي
|
||||
|
||||
تُخزن إعدادات الوكلاء عادةً في ملف YAML. إليك مثالاً على كيفية ظهور ملف `agents.yaml` لوكيل الباحث:
|
||||
في المشاريع الكلاسيكية، تُخزن إعدادات الوكلاء عادةً في ملف YAML. إليك مثالاً على كيفية ظهور ملف `agents.yaml` لوكيل الباحث:
|
||||
|
||||
```yaml
|
||||
researcher:
|
||||
@@ -146,6 +150,6 @@ researcher:
|
||||
- **تسمية متسقة**: استخدم اصطلاحات تسمية واضحة ومتسقة لطرقك. على سبيل المثال، يمكن تسمية طرق الوكلاء بأسماء أدوارهم (مثل researcher، reporting_analyst).
|
||||
- **متغيرات البيئة**: استخدم متغيرات البيئة للمعلومات الحساسة مثل مفاتيح API.
|
||||
- **المرونة**: صمم طاقمك ليكون مرناً بالسماح بإضافة أو إزالة الوكلاء والمهام بسهولة.
|
||||
- **توافق YAML-الكود**: تأكد من أن الأسماء والهياكل في ملفات YAML تتوافق بشكل صحيح مع الطرق المزينة في كود Python الخاص بك.
|
||||
- **توافق YAML-الكود**: في المشاريع الكلاسيكية، تأكد من أن الأسماء والهياكل في ملفات YAML تتوافق بشكل صحيح مع الطرق المزينة في كود Python الخاص بك.
|
||||
|
||||
باتباع هذه الإرشادات واستخدام التعليقات التوضيحية بشكل صحيح، يمكنك إنشاء أطقم منظمة جيداً وسهلة الصيانة باستخدام إطار عمل CrewAI.
|
||||
باتباع هذه الإرشادات واستخدام التعليقات التوضيحية بشكل صحيح، يمكنك الحفاظ على أطقم كلاسيكية منظمة وسهلة الصيانة. للـ crews الجديدة، استخدم بنية JSON-first في [Crews](/ar/concepts/crews).
|
||||
|
||||
@@ -39,84 +39,60 @@ mode: "wide"
|
||||
يُنشئ ذلك تطبيق Flow ضمن `src/latest_ai_flow/`، بما في ذلك طاقمًا أوليًا في `crews/content_crew/` ستستبدله بطاقم بحث **بوكيل واحد** في الخطوات التالية.
|
||||
</Step>
|
||||
|
||||
<Step title="اضبط وكيلًا واحدًا في `agents.yaml`">
|
||||
استبدل محتوى `src/latest_ai_flow/crews/content_crew/config/agents.yaml` بباحث واحد. تُملأ المتغيرات مثل `{topic}` من `crew.kickoff(inputs=...)`.
|
||||
<Step title="اضبط وكيلًا واحدًا في JSONC">
|
||||
أنشئ `src/latest_ai_flow/crews/content_crew/agents/researcher.jsonc` (أنشئ مجلد `agents/` إذا لزم). تُملأ المتغيرات مثل `{topic}` من `crew.kickoff(inputs=...)`.
|
||||
|
||||
```yaml agents.yaml
|
||||
# src/latest_ai_flow/crews/content_crew/config/agents.yaml
|
||||
researcher:
|
||||
role: >
|
||||
باحث بيانات أول في {topic}
|
||||
goal: >
|
||||
اكتشاف أحدث التطورات في {topic}
|
||||
backstory: >
|
||||
أنت باحث مخضرم تكشف أحدث المستجدات في {topic}.
|
||||
تجد المعلومات الأكثر صلة وتعرضها بوضوح.
|
||||
```jsonc agents/researcher.jsonc
|
||||
{
|
||||
"role": "باحث بيانات أول في {topic}",
|
||||
"goal": "اكتشاف أحدث التطورات في {topic}",
|
||||
"backstory": "أنت باحث يجد المعلومات الأكثر صلة ويعرضها بوضوح.",
|
||||
"tools": ["SerperDevTool"],
|
||||
"settings": {
|
||||
"verbose": true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
</Step>
|
||||
|
||||
<Step title="اضبط مهمة واحدة في `tasks.yaml`">
|
||||
```yaml tasks.yaml
|
||||
# src/latest_ai_flow/crews/content_crew/config/tasks.yaml
|
||||
research_task:
|
||||
description: >
|
||||
أجرِ بحثًا معمقًا عن {topic}. استخدم البحث على الويب للعثور على معلومات
|
||||
حديثة وموثوقة. السنة الحالية 2026.
|
||||
expected_output: >
|
||||
تقرير بصيغة Markdown بأقسام واضحة: الاتجاهات الرئيسية، أدوات أو شركات بارزة،
|
||||
والآثار. بين 800 و1200 كلمة تقريبًا. دون إحاطة المستند بأكمله بكتل كود.
|
||||
agent: researcher
|
||||
output_file: output/report.md
|
||||
<Step title="اضبط الـ crew في `crew.jsonc`">
|
||||
أنشئ `src/latest_ai_flow/crews/content_crew/crew.jsonc`:
|
||||
|
||||
```jsonc crew.jsonc
|
||||
{
|
||||
"name": "Research Crew",
|
||||
"agents": ["researcher"],
|
||||
"tasks": [
|
||||
{
|
||||
"name": "research_task",
|
||||
"description": "أجرِ بحثًا معمقًا عن {topic}. استخدم البحث على الويب للعثور على معلومات حديثة وموثوقة.",
|
||||
"expected_output": "تقرير بصيغة Markdown بأقسام واضحة: الاتجاهات الرئيسية، أدوات أو شركات بارزة، والآثار. بين 800 و1200 كلمة تقريبًا. دون إحاطة المستند بأكمله بكتل كود.",
|
||||
"agent": "researcher",
|
||||
"output_file": "output/report.md",
|
||||
"markdown": true
|
||||
}
|
||||
],
|
||||
"process": "sequential",
|
||||
"verbose": true
|
||||
}
|
||||
```
|
||||
|
||||
</Step>
|
||||
|
||||
<Step title="اربط صف الطاقم (`content_crew.py`)">
|
||||
اجعل الطاقم المُولَّد يشير إلى YAML وأرفق `SerperDevTool` بالباحث.
|
||||
<Step title="حمّل crew JSON (`content_crew.py`)">
|
||||
استبدل `content_crew.py` المُولّد بمحمل صغير يحول `crew.jsonc` إلى `Crew`.
|
||||
|
||||
```python content_crew.py
|
||||
# src/latest_ai_flow/crews/content_crew/content_crew.py
|
||||
from typing import List
|
||||
from pathlib import Path
|
||||
|
||||
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
|
||||
from crewai.project import load_crew
|
||||
|
||||
|
||||
@CrewBase
|
||||
class ResearchCrew:
|
||||
"""طاقم بحث بوكيل واحد داخل Flow."""
|
||||
|
||||
agents: List[BaseAgent]
|
||||
tasks: List[Task]
|
||||
|
||||
agents_config = "config/agents.yaml"
|
||||
tasks_config = "config/tasks.yaml"
|
||||
|
||||
@agent
|
||||
def researcher(self) -> Agent:
|
||||
return Agent(
|
||||
config=self.agents_config["researcher"], # type: ignore[index]
|
||||
verbose=True,
|
||||
tools=[SerperDevTool()],
|
||||
)
|
||||
|
||||
@task
|
||||
def research_task(self) -> Task:
|
||||
return Task(
|
||||
config=self.tasks_config["research_task"], # type: ignore[index]
|
||||
)
|
||||
|
||||
@crew
|
||||
def crew(self) -> Crew:
|
||||
return Crew(
|
||||
agents=self.agents,
|
||||
tasks=self.tasks,
|
||||
process=Process.sequential,
|
||||
verbose=True,
|
||||
)
|
||||
def kickoff_content_crew(inputs: dict):
|
||||
crew, default_inputs = load_crew(Path(__file__).with_name("crew.jsonc"))
|
||||
return crew.kickoff(inputs={**default_inputs, **inputs})
|
||||
```
|
||||
|
||||
</Step>
|
||||
@@ -130,7 +106,7 @@ mode: "wide"
|
||||
|
||||
from crewai.flow import Flow, listen, start
|
||||
|
||||
from latest_ai_flow.crews.content_crew.content_crew import ResearchCrew
|
||||
from latest_ai_flow.crews.content_crew.content_crew import kickoff_content_crew
|
||||
|
||||
|
||||
class ResearchFlowState(BaseModel):
|
||||
@@ -149,7 +125,7 @@ mode: "wide"
|
||||
|
||||
@listen(prepare_topic)
|
||||
def run_research(self):
|
||||
result = ResearchCrew().crew().kickoff(inputs={"topic": self.state.topic})
|
||||
result = kickoff_content_crew(inputs={"topic": self.state.topic})
|
||||
self.state.report = result.raw
|
||||
print("اكتمل طاقم البحث.")
|
||||
|
||||
@@ -171,7 +147,7 @@ mode: "wide"
|
||||
```
|
||||
|
||||
<Tip>
|
||||
إذا كان اسم الحزمة ليس `latest_ai_flow`، عدّل استيراد `ResearchCrew` ليطابق مسار الوحدة في مشروعك.
|
||||
إذا كان اسم الحزمة ليس `latest_ai_flow`، عدّل استيراد `kickoff_content_crew` ليطابق مسار الوحدة في مشروعك.
|
||||
</Tip>
|
||||
</Step>
|
||||
|
||||
@@ -198,7 +174,7 @@ mode: "wide"
|
||||
|
||||
<CodeGroup>
|
||||
```markdown output/report.md
|
||||
# وكلاء الذكاء الاصطناعي في 2026: المشهد والاتجاهات
|
||||
# وكلاء الذكاء الاصطناعي: المشهد والاتجاهات الحديثة
|
||||
|
||||
## ملخص تنفيذي
|
||||
…
|
||||
@@ -219,7 +195,7 @@ mode: "wide"
|
||||
## كيف يترابط هذا
|
||||
|
||||
1. **Flow** — يشغّل `LatestAiFlow` أولًا `prepare_topic` ثم `run_research` ثم `summarize`. الحالة (`topic`، `report`) على Flow.
|
||||
2. **الطاقم** — يشغّل `ResearchCrew` مهمة واحدة بوكيل واحد: الباحث يستخدم **Serper** للبحث على الويب ثم يكتب التقرير.
|
||||
2. **الطاقم** — يحمّل `kickoff_content_crew` ملف `crew.jsonc` ويشغّل مهمة واحدة بوكيل واحد: الباحث يستخدم **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).
|
||||
@@ -230,7 +206,10 @@ mode: "wide"
|
||||
|
||||
### اتساق التسمية
|
||||
|
||||
يجب أن تطابق مفاتيح YAML (`researcher`، `research_task`) أسماء الدوال في صف `@CrewBase`. راجع [Crews](/ar/concepts/crews) لنمط الديكورات الكامل.
|
||||
يجب أن تطابق الأسماء في `crew.jsonc` الملفات والمراجع:
|
||||
|
||||
- `agents: ["researcher"]` يحمّل `agents/researcher.jsonc`
|
||||
- `tasks[].agent: "researcher"` يربط المهمة بذلك الـ agent
|
||||
|
||||
## النشر
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ npx skills add crewaiinc/skills
|
||||
## ما يحصل عليه الوكيل
|
||||
|
||||
- **Flows** — تطبيقات ذات حالة وخطوات وkickoffs للـ crew على نمط CrewAI
|
||||
- **Crews والوكلاء** — أنماط YAML أولاً، أدوار، مهام، وتفويض
|
||||
- **Crews والوكلاء** — أنماط JSON-first (`crew.jsonc` و `agents/*.jsonc`)، أدوار، مهام، وتفويض
|
||||
- **الأدوات والتكاملات** — ربط الوكلاء بالبحث وواجهات API وأدوات CrewAI الشائعة
|
||||
- **هيكل المشروع** — مواءمة مع قوالب CLI واتفاقيات المستودع
|
||||
- **أنماط محدثة** — تتبع المهارات وثائق CrewAI والممارسات الموصى بها
|
||||
|
||||
4450
docs/docs.json
@@ -4,6 +4,281 @@ description: "Product updates, improvements, and bug fixes for CrewAI"
|
||||
icon: "clock"
|
||||
mode: "wide"
|
||||
---
|
||||
<Update label="Jun 11, 2026">
|
||||
## v1.14.7
|
||||
|
||||
[View release on GitHub](https://github.com/crewAIInc/crewAI/releases/tag/1.14.7)
|
||||
|
||||
## What's Changed
|
||||
|
||||
### Features
|
||||
- Add pluggable default backends for memory, knowledge, rag, and flow.
|
||||
- Surface real finish_reason, sampling params, and response.id on LLM events.
|
||||
- Type DSL triggers as route-aware decorators.
|
||||
- Add chat API for conversational flows.
|
||||
- Make locking backend overridable.
|
||||
- Build FlowDefinition from Flow DSL metadata.
|
||||
- Add native Snowflake Cortex LLM provider.
|
||||
- Add crew trained agents file support.
|
||||
|
||||
### Bug Fixes
|
||||
- Fix checkpoint to rebuild custom BaseLLM as concrete LLM on restore.
|
||||
- Gate restore on a flag to prevent live snapshots from replaying as resume.
|
||||
- Scope runtime state per run to bound growth and isolate concurrent runs.
|
||||
- Fix telemetry setup on crewai-login.
|
||||
- Respect suppress_flow_events for method-execution events.
|
||||
- Restore [project.scripts] in crewai package for uv tool install.
|
||||
- Resolve pip-audit CVEs for aiohttp, docling, and docling-core.
|
||||
- Fix file input not working reliably.
|
||||
- Fix Snowflake Claude incomplete tool result histories.
|
||||
|
||||
### Documentation
|
||||
- Update changelog and version for v1.14.7.
|
||||
- Update OpenTelemetry collector documentation.
|
||||
- Update NVIDIA Nemotron LLM guide.
|
||||
- Add Databricks integration guide.
|
||||
- Add Snowflake integration guide.
|
||||
|
||||
### Performance
|
||||
- Improve crewai import speed by lazy-loading docling imports.
|
||||
|
||||
### Refactoring
|
||||
- Simplify flow condition evaluation to be stateless per event.
|
||||
- Decouple convo logic from runtime and add a conversational_definition.
|
||||
- Split `flow.py` into DSL, definition, and runtime.
|
||||
|
||||
## Contributors
|
||||
|
||||
@Luzk, @alex-clawd, @devin-ai-integration[bot], @greysonlalonde, @gvieira, @jessemiller, @lorenzejay, @lucasgomide, @mattatcha, @vinibrsl
|
||||
|
||||
</Update>
|
||||
|
||||
<Update label="Jun 10, 2026">
|
||||
## v1.14.7rc2
|
||||
|
||||
[View release on GitHub](https://github.com/crewAIInc/crewAI/releases/tag/1.14.7rc2)
|
||||
|
||||
## What's Changed
|
||||
|
||||
### Bug Fixes
|
||||
- Gate restore on a flag to prevent live snapshots from replaying as resume
|
||||
|
||||
### Documentation
|
||||
- Update changelog and version for v1.14.7rc1
|
||||
|
||||
## Contributors
|
||||
|
||||
@greysonlalonde
|
||||
|
||||
</Update>
|
||||
|
||||
<Update label="Jun 10, 2026">
|
||||
## v1.14.7rc1
|
||||
|
||||
[View release on GitHub](https://github.com/crewAIInc/crewAI/releases/tag/1.14.7rc1)
|
||||
|
||||
## What's Changed
|
||||
|
||||
### Features
|
||||
- Add `reset_runtime_state` to release accumulated bus state
|
||||
- Handle supporting both custom prompts
|
||||
- Decouple conversation logic from runtime and add a `conversational_definition`
|
||||
|
||||
### Bug Fixes
|
||||
- Fix scope of runtime state per run to bound growth and isolate concurrent runs
|
||||
- Fix telemetry setup on `crewai-login`
|
||||
- Fix respect for `suppress_flow_events` for method-execution events
|
||||
|
||||
### Documentation
|
||||
- Update OpenTelemetry images
|
||||
- Update documentation to reflect new state of OpenTelemetry collector
|
||||
- Update changelog and version for v1.14.7a4
|
||||
|
||||
### Refactoring
|
||||
- Simplify flow condition evaluation to be stateless per event
|
||||
- Improve conversation routing cycle with one less route
|
||||
|
||||
## Contributors
|
||||
|
||||
@greysonlalonde, @lorenzejay, @lucasgomide, @vinibrsl
|
||||
|
||||
</Update>
|
||||
|
||||
<Update label="Jun 09, 2026">
|
||||
## v1.14.7a4
|
||||
|
||||
[View release on GitHub](https://github.com/crewAIInc/crewAI/releases/tag/1.14.7a4)
|
||||
|
||||
## What's Changed
|
||||
|
||||
### Features
|
||||
- Migrate @listen/@router runtime to read from FlowDefinition
|
||||
- Add pluggable default backends for memory, knowledge, rag, and flow
|
||||
|
||||
### Documentation
|
||||
- Update changelog and version for v1.14.7a3
|
||||
|
||||
## Contributors
|
||||
|
||||
@greysonlalonde, @mattatcha, @vinibrsl
|
||||
|
||||
</Update>
|
||||
|
||||
<Update label="Jun 08, 2026">
|
||||
## v1.14.7a3
|
||||
|
||||
[View release on GitHub](https://github.com/crewAIInc/crewAI/releases/tag/1.14.7a3)
|
||||
|
||||
## What's Changed
|
||||
|
||||
### Bug Fixes
|
||||
- Fix exposure of `ask_for_human_input` on experimental `AgentExecutor`
|
||||
- Resolve pip-audit CVEs for `aiohttp`, `docling`, `docling-core`, and `pip`
|
||||
|
||||
### Refactoring
|
||||
- Migrate `@start` to read from `FlowDefinition`
|
||||
|
||||
### Documentation
|
||||
- Update changelog and version for v1.14.7a2
|
||||
|
||||
## Contributors
|
||||
|
||||
@greysonlalonde, @lorenzejay, @vinibrsl
|
||||
|
||||
</Update>
|
||||
|
||||
<Update label="Jun 05, 2026">
|
||||
## v1.14.7a2
|
||||
|
||||
[View release on GitHub](https://github.com/crewAIInc/crewAI/releases/tag/1.14.7a2)
|
||||
|
||||
## What's Changed
|
||||
|
||||
### Features
|
||||
- Add conversational flow traces support.
|
||||
- Update conversational flow documentation to utilize `handle_turn`.
|
||||
- Surface real `finish_reason`, sampling parameters, and `response.id` in LLM events.
|
||||
- Type DSL triggers as route-aware decorators.
|
||||
- Implement chat API for conversational flows.
|
||||
- Make locking backend overridable in lock store.
|
||||
- Split flow DSL monolith into focused decorator modules.
|
||||
- Flatten LiteLLM cache/reasoning usage sub-counts in `_usage_to_dict`.
|
||||
- Build `FlowDefinition` from Flow DSL metadata.
|
||||
|
||||
### Documentation
|
||||
- Add NVIDIA Nemotron LLM guide.
|
||||
- Document monorepo deployments.
|
||||
- Update changelog and version for v1.14.7a1.
|
||||
|
||||
## Contributors
|
||||
|
||||
@alex-clawd, @gvieira, @lorenzejay, @lucasgomide, @mattatcha, @vinibrsl
|
||||
|
||||
</Update>
|
||||
|
||||
<Update label="Jun 03, 2026">
|
||||
## v1.14.7a1
|
||||
|
||||
[View release on GitHub](https://github.com/crewAIInc/crewAI/releases/tag/1.14.7a1)
|
||||
|
||||
## What's Changed
|
||||
|
||||
### Features
|
||||
- Add crew trained agents file support
|
||||
- Add native Snowflake Cortex LLM provider
|
||||
- Add Databricks integration guide
|
||||
- Add Snowflake integration guide
|
||||
|
||||
### Bug Fixes
|
||||
- Fix CLI by restoring `[project.scripts]` in crewai package for UV tool install
|
||||
- Resolve file input reliability issues
|
||||
- Fix incomplete tool result histories in Snowflake Claude
|
||||
- Handle stringified tool calls for Snowflake Claude
|
||||
- Re-arm multi-source `or_` listeners across router-driven cycles
|
||||
|
||||
### Performance
|
||||
- Improve crewai import speed by lazy-loading docling imports
|
||||
|
||||
### Refactoring
|
||||
- Split `flow.py` into DSL, definition, and runtime
|
||||
|
||||
## Contributors
|
||||
|
||||
@Luzk, @alex-clawd, @devin-ai-integration[bot], @greysonlalonde, @jessemiller, @lorenzejay, @vinibrsl
|
||||
|
||||
</Update>
|
||||
|
||||
<Update label="May 28, 2026">
|
||||
## v1.14.6
|
||||
|
||||
[View release on GitHub](https://github.com/crewAIInc/crewAI/releases/tag/1.14.6)
|
||||
|
||||
## What's Changed
|
||||
|
||||
### Features
|
||||
- Enhance StdioTransport to prevent environment variable leakage
|
||||
- Enhance planning configuration and observation handling
|
||||
- Declare env_vars on DatabricksQueryTool
|
||||
- Add Agent Control Plane docs
|
||||
|
||||
### Bug Fixes
|
||||
- Fix structured output leaks in tool-calling loops
|
||||
- Drop unroundtrippable callbacks and adapter state in checkpoint
|
||||
- Serialize type[BaseModel] fields as JSON schema in checkpoint
|
||||
- Avoid orphan task_started on resume scope restore
|
||||
- Allow AgentExecutor to restore from checkpoint
|
||||
- Correct mongodb typo to pymongo in package_dependencies
|
||||
|
||||
### Documentation
|
||||
- Add ACP (Beta) docs navigation block to Agent Control Plane pages
|
||||
- Remove consensual process references from processes page
|
||||
- Restructure checkpointing page
|
||||
- Document one-time admin package install step
|
||||
- Migrate Secrets Manager / Workload Identity from replicated-config
|
||||
- Remove `{" "}` JSX expressions breaking `<Steps>` render
|
||||
|
||||
### Refactoring
|
||||
- Move Skills Repository to experimental + CREWAI_EXPERIMENTAL gate
|
||||
|
||||
## Contributors
|
||||
|
||||
@akaKuruma, @alex-clawd, @github-actions[bot], @greysonlalonde, @heitorado, @iris-clawd, @lorenzejay, @lucasgomide, @mattatcha, @thiagomoretto, @vinibrsl
|
||||
|
||||
</Update>
|
||||
|
||||
<Update label="May 27, 2026">
|
||||
## v1.14.6a2
|
||||
|
||||
[View release on GitHub](https://github.com/crewAIInc/crewAI/releases/tag/1.14.6a2)
|
||||
|
||||
## What's Changed
|
||||
|
||||
### Features
|
||||
- Enhance `StdioTransport` to prevent environment variable leakage
|
||||
- Enhance planning configuration and observation handling
|
||||
- Declare `env_vars` on `DatabricksQueryTool`
|
||||
- Add Agent Control Plane documentation
|
||||
|
||||
### Bug Fixes
|
||||
- Fix structured output leaks in tool-calling loops
|
||||
- Drop unroundtrippable callbacks and adapter state in checkpointing
|
||||
- Serialize `type[BaseModel]` fields as JSON schema in checkpointing
|
||||
- Avoid orphan `task_started` on resume scope restore
|
||||
- Allow `AgentExecutor` to restore from checkpoint
|
||||
- Correct MongoDB typo to `pymongo` in package dependencies
|
||||
|
||||
### Documentation
|
||||
- Restructure checkpointing page
|
||||
- Document one-time admin package install step
|
||||
- Migrate Secrets Manager / Workload Identity from replicated-config
|
||||
- Remove Skills Repository entry from changelog
|
||||
|
||||
## Contributors
|
||||
|
||||
@github-actions[bot], @greysonlalonde, @heitorado, @iris-clawd, @lorenzejay, @lucasgomide, @mattatcha, @thiagomoretto, @vinibrsl
|
||||
|
||||
</Update>
|
||||
|
||||
<Update label="May 21, 2026">
|
||||
## v1.14.6a1
|
||||
|
||||
@@ -12,7 +287,6 @@ mode: "wide"
|
||||
## What's Changed
|
||||
|
||||
### Features
|
||||
- Add Skills Repository with registry, cache, CLI, and SDK integration
|
||||
- Generate categorized release notes for enterprise
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
@@ -71,81 +71,65 @@ The Visual Agent Builder enables:
|
||||
|
||||
## Creating Agents
|
||||
|
||||
There are two ways to create agents in CrewAI: using **YAML configuration (recommended)** or defining them **directly in code**.
|
||||
There are two common ways to create agents in CrewAI: using **JSONC project configuration (recommended for new crews)** or defining them **directly in code**.
|
||||
|
||||
### YAML Configuration (Recommended)
|
||||
### JSONC Configuration (Recommended)
|
||||
|
||||
Using YAML configuration provides a cleaner, more maintainable way to define agents. We strongly recommend using this approach in your CrewAI projects.
|
||||
New projects created with `crewai create crew <name>` use JSON-first configuration. Each agent is defined in `agents/<agent_name>.jsonc`, and `crew.jsonc` lists which agents are part of the crew.
|
||||
|
||||
After creating your CrewAI project as outlined in the [Installation](/en/installation) section, navigate to the `src/latest_ai_development/config/agents.yaml` file and modify the template to match your requirements.
|
||||
After creating your CrewAI project as outlined in the [Installation](/en/installation) section, edit the generated files in `agents/`.
|
||||
|
||||
<Note>
|
||||
Variables in your YAML files (like `{topic}`) will be replaced with values from your inputs when running the crew:
|
||||
```python Code
|
||||
crew.kickoff(inputs={'topic': 'AI Agents'})
|
||||
```
|
||||
Use `{placeholder}` values in `role`, `goal`, or `backstory`. Put defaults in `crew.jsonc` under `inputs`; `crewai run` prompts for any missing values.
|
||||
</Note>
|
||||
|
||||
Here's an example of how to configure agents using YAML:
|
||||
Here's an example `agents/researcher.jsonc` file:
|
||||
|
||||
```yaml agents.yaml
|
||||
# src/latest_ai_development/config/agents.yaml
|
||||
researcher:
|
||||
role: >
|
||||
{topic} Senior Data Researcher
|
||||
goal: >
|
||||
Uncover cutting-edge developments in {topic}
|
||||
backstory: >
|
||||
You're a seasoned researcher with a knack for uncovering the latest
|
||||
developments in {topic}. Known for your ability to find the most relevant
|
||||
information and present it in a clear and concise manner.
|
||||
|
||||
reporting_analyst:
|
||||
role: >
|
||||
{topic} Reporting Analyst
|
||||
goal: >
|
||||
Create detailed reports based on {topic} data analysis and research findings
|
||||
backstory: >
|
||||
You're a meticulous analyst with a keen eye for detail. You're known for
|
||||
your ability to turn complex data into clear and concise reports, making
|
||||
it easy for others to understand and act on the information you provide.
|
||||
```jsonc agents/researcher.jsonc
|
||||
{
|
||||
"role": "{topic} Senior Data Researcher",
|
||||
"goal": "Uncover cutting-edge developments in {topic}",
|
||||
"backstory": "You find the most relevant information and present it clearly.",
|
||||
"llm": "openai/gpt-4o",
|
||||
"tools": ["SerperDevTool"],
|
||||
"settings": {
|
||||
"verbose": true,
|
||||
"allow_delegation": false,
|
||||
"max_iter": 20
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
To use this YAML configuration in your code, create a crew class that inherits from `CrewBase`:
|
||||
Then include that agent from `crew.jsonc`:
|
||||
|
||||
```python Code
|
||||
# src/latest_ai_development/crew.py
|
||||
from crewai import Agent, Crew, Process
|
||||
from crewai.project import CrewBase, agent, crew
|
||||
from crewai_tools import SerperDevTool
|
||||
|
||||
@CrewBase
|
||||
class LatestAiDevelopmentCrew():
|
||||
"""LatestAiDevelopment crew"""
|
||||
|
||||
agents_config = "config/agents.yaml"
|
||||
|
||||
@agent
|
||||
def researcher(self) -> Agent:
|
||||
return Agent(
|
||||
config=self.agents_config['researcher'], # type: ignore[index]
|
||||
verbose=True,
|
||||
tools=[SerperDevTool()]
|
||||
)
|
||||
|
||||
@agent
|
||||
def reporting_analyst(self) -> Agent:
|
||||
return Agent(
|
||||
config=self.agents_config['reporting_analyst'], # type: ignore[index]
|
||||
verbose=True
|
||||
)
|
||||
```jsonc crew.jsonc
|
||||
{
|
||||
"name": "Research Crew",
|
||||
"agents": ["researcher"],
|
||||
"tasks": [
|
||||
{
|
||||
"name": "research_task",
|
||||
"description": "Research {topic}",
|
||||
"expected_output": "A concise briefing about {topic}",
|
||||
"agent": "researcher"
|
||||
}
|
||||
],
|
||||
"inputs": {
|
||||
"topic": "AI Agents"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Agent files support any public `Agent` field. Common fields include `role`, `goal`, `backstory`, `llm`, `tools`, `function_calling_llm`, `guardrail`, `step_callback`, and `settings`. Behavior options such as `verbose`, `allow_delegation`, `max_iter`, `max_rpm`, `memory`, `cache`, `planning_config`, and `use_system_prompt` can be placed at the top level or under `settings`; values in `settings` take precedence.
|
||||
|
||||
<Note>
|
||||
The names you use in your YAML files (`agents.yaml`) should match the method
|
||||
names in your Python code.
|
||||
JSONC supports comments and trailing commas. If both `agents/<name>.jsonc` and `agents/<name>.json` exist, CrewAI uses the JSONC file.
|
||||
</Note>
|
||||
|
||||
### Classic YAML Configuration
|
||||
|
||||
Classic projects created with `crewai create crew <name> --classic` use `config/agents.yaml` and a `@CrewBase` class in `crew.py`. This remains supported for teams that want Python decorators or existing YAML projects.
|
||||
|
||||
### Direct Code Definition
|
||||
|
||||
You can create agents directly in code by instantiating the `Agent` class. Here's a comprehensive example showing all available parameters:
|
||||
|
||||
@@ -5,301 +5,419 @@ icon: floppy-disk
|
||||
mode: "wide"
|
||||
---
|
||||
|
||||
<Warning>
|
||||
Checkpointing is in early release. APIs may change in future versions.
|
||||
</Warning>
|
||||
Checkpointing saves a snapshot of execution state during a run so a crew, flow, or agent can resume after a failure or be forked into an alternate branch.
|
||||
|
||||
## Overview
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Explanation" icon="lightbulb" href="#explanation">
|
||||
How checkpointing works: events, storage, and inheritance.
|
||||
</Card>
|
||||
<Card title="Tutorial" icon="graduation-cap" href="#tutorial-resume-a-failing-crew">
|
||||
A 5-minute walkthrough: run, interrupt, resume.
|
||||
</Card>
|
||||
<Card title="How-to guides" icon="screwdriver-wrench" href="#how-to-guides">
|
||||
Task-focused recipes for common workflows.
|
||||
</Card>
|
||||
<Card title="Reference" icon="book" href="#reference">
|
||||
`CheckpointConfig`, events, providers, and CLI.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
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.
|
||||
## Explanation
|
||||
|
||||
## Quick Start
|
||||
### What a checkpoint is
|
||||
|
||||
```python
|
||||
from crewai import Crew, CheckpointConfig
|
||||
A checkpoint captures everything CrewAI needs to recreate a run mid-flight: the full state of the crew, flow, or agent — configuration, agent memory and knowledge sources, task progress, intermediate outputs, internal state and attributes — alongside the kickoff inputs, the event history up to that point, and a lineage ID that ties the checkpoint to the run it came from.
|
||||
|
||||
crew = Crew(
|
||||
agents=[...],
|
||||
tasks=[...],
|
||||
checkpoint=True, # uses defaults: ./.checkpoints, on task_completed
|
||||
)
|
||||
result = crew.kickoff()
|
||||
```
|
||||
Restoring rebuilds that state and continues. Completed tasks are skipped, memory and knowledge are rehydrated, and downstream work runs against the same outputs the original run produced. Forking does the same restore under a new lineage, so the new branch and the original run can write checkpoints side by side without overwriting each other.
|
||||
|
||||
Checkpoint files are written to `./.checkpoints/` after each completed task.
|
||||
### When checkpoints are written
|
||||
|
||||
## Configuration
|
||||
Checkpointing is event-driven. The runtime subscribes to events you select via `on_events` and writes a checkpoint each time one fires. The default `task_completed` produces one checkpoint per finished task — a sensible tradeoff between granularity and disk use. Higher-frequency events like `llm_call_completed` are available for fine-grained recovery but write far more files.
|
||||
|
||||
Use `CheckpointConfig` for full control:
|
||||
### Storage
|
||||
|
||||
```python
|
||||
from crewai import Crew, CheckpointConfig
|
||||
Two providers ship with CrewAI:
|
||||
|
||||
crew = Crew(
|
||||
agents=[...],
|
||||
tasks=[...],
|
||||
checkpoint=CheckpointConfig(
|
||||
location="./my_checkpoints",
|
||||
on_events=["task_completed", "crew_kickoff_completed"],
|
||||
max_checkpoints=5,
|
||||
),
|
||||
)
|
||||
```
|
||||
- `JsonProvider` writes one file per checkpoint. Human-readable and easy to inspect.
|
||||
- `SqliteProvider` writes to a single SQLite database. Better for high-frequency checkpointing.
|
||||
|
||||
### CheckpointConfig Fields
|
||||
Both prune oldest checkpoints when `max_checkpoints` is set.
|
||||
|
||||
| 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. |
|
||||
| `restore_from` | `Path \| str \| None` | `None` | Path to a checkpoint to restore from. Used when passing config via a kickoff method's `from_checkpoint` parameter. |
|
||||
<Note>
|
||||
Auto-checkpoint writes (event-driven) are best-effort: a failed write is logged and the run continues. Manual `state.checkpoint()` and `state.acheckpoint()` calls re-raise on failure.
|
||||
</Note>
|
||||
|
||||
### Inheritance and Opt-Out
|
||||
### Inheritance model
|
||||
|
||||
The `checkpoint` field on Crew, Flow, and Agent accepts `CheckpointConfig`, `True`, `False`, or `None`:
|
||||
`Crew`, `Flow`, and `Agent` all accept a `checkpoint` argument. Children inherit from their parent unless they set their own value or pass `False` to opt out. Enable checkpointing once on the crew and every agent participates, or selectively exclude one agent.
|
||||
|
||||
| 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. |
|
||||
## Tutorial: Resume a failing crew
|
||||
|
||||
```python
|
||||
crew = Crew(
|
||||
agents=[
|
||||
Agent(role="Researcher", ...), # inherits crew's checkpoint
|
||||
Agent(role="Writer", ..., checkpoint=False), # opted out, no checkpoints
|
||||
],
|
||||
tasks=[...],
|
||||
checkpoint=True,
|
||||
)
|
||||
```
|
||||
This walkthrough takes ~5 minutes. You will run a two-task crew, kill it midway, and resume from the saved checkpoint.
|
||||
|
||||
## Resuming from a Checkpoint
|
||||
<Steps>
|
||||
<Step title="Create the crew with checkpointing enabled">
|
||||
```python
|
||||
from crewai import Agent, Crew, Task
|
||||
|
||||
Pass a `CheckpointConfig` with `restore_from` to any kickoff method. The crew restores from that checkpoint, skips completed tasks, and resumes.
|
||||
researcher = Agent(role="Researcher", goal="Research", backstory="Expert")
|
||||
writer = Agent(role="Writer", goal="Write", backstory="Expert")
|
||||
|
||||
```python
|
||||
from crewai import Crew, CheckpointConfig
|
||||
crew = Crew(
|
||||
agents=[researcher, writer],
|
||||
tasks=[
|
||||
Task(description="Research AI trends", agent=researcher, expected_output="bullets"),
|
||||
Task(description="Write a summary", agent=writer, expected_output="paragraph"),
|
||||
],
|
||||
checkpoint=True,
|
||||
)
|
||||
```
|
||||
</Step>
|
||||
<Step title="Run it and interrupt after the first task">
|
||||
```python
|
||||
result = crew.kickoff()
|
||||
```
|
||||
|
||||
crew = Crew(agents=[...], tasks=[...])
|
||||
result = crew.kickoff(
|
||||
from_checkpoint=CheckpointConfig(
|
||||
restore_from="./my_checkpoints/20260407T120000_abc123.json",
|
||||
),
|
||||
)
|
||||
```
|
||||
Press `Ctrl+C` after the first task finishes. Look in `./.checkpoints/` — a file named `<timestamp>_<uuid>.json` is the checkpoint.
|
||||
</Step>
|
||||
<Step title="Resume from the checkpoint">
|
||||
```python
|
||||
from crewai import CheckpointConfig
|
||||
|
||||
Remaining `CheckpointConfig` fields apply to the new run, so checkpointing continues after the restore.
|
||||
result = crew.kickoff(
|
||||
from_checkpoint=CheckpointConfig(
|
||||
restore_from="./.checkpoints/<timestamp>_<uuid>.json",
|
||||
),
|
||||
)
|
||||
```
|
||||
|
||||
You can also use the classmethod directly:
|
||||
The research task is skipped, the writer runs against the saved research output, and the crew finishes.
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
```python
|
||||
config = CheckpointConfig(restore_from="./my_checkpoints/20260407T120000_abc123.json")
|
||||
crew = Crew.from_checkpoint(config)
|
||||
result = crew.kickoff()
|
||||
```
|
||||
## How-to guides
|
||||
|
||||
## Forking from a Checkpoint
|
||||
<AccordionGroup>
|
||||
<Accordion title="Enable checkpointing with defaults" icon="play">
|
||||
```python
|
||||
crew = Crew(agents=[...], tasks=[...], checkpoint=True)
|
||||
```
|
||||
|
||||
`fork()` restores a checkpoint and starts a new execution branch. Useful for exploring alternative paths from the same point.
|
||||
Writes to `./.checkpoints/` on every `task_completed`.
|
||||
</Accordion>
|
||||
|
||||
```python
|
||||
from crewai import Crew, CheckpointConfig
|
||||
<Accordion title="Customize storage and frequency" icon="sliders">
|
||||
```python
|
||||
from crewai import Crew, CheckpointConfig
|
||||
|
||||
config = CheckpointConfig(restore_from="./my_checkpoints/20260407T120000_abc123.json")
|
||||
crew = Crew.fork(config, branch="experiment-a")
|
||||
result = crew.kickoff(inputs={"strategy": "aggressive"})
|
||||
```
|
||||
crew = Crew(
|
||||
agents=[...],
|
||||
tasks=[...],
|
||||
checkpoint=CheckpointConfig(
|
||||
location="./my_checkpoints",
|
||||
on_events=["task_completed", "crew_kickoff_completed"],
|
||||
max_checkpoints=5,
|
||||
),
|
||||
)
|
||||
```
|
||||
</Accordion>
|
||||
|
||||
Each fork gets a unique lineage ID so checkpoints from different branches don't collide. The `branch` label is optional and auto-generated if omitted.
|
||||
<Accordion title="Choose a storage provider" icon="database">
|
||||
<CodeGroup>
|
||||
```python JsonProvider
|
||||
from crewai import Crew, CheckpointConfig
|
||||
from crewai.state import JsonProvider
|
||||
|
||||
## Works on Crew, Flow, and Agent
|
||||
crew = Crew(
|
||||
agents=[...],
|
||||
tasks=[...],
|
||||
checkpoint=CheckpointConfig(
|
||||
location="./my_checkpoints",
|
||||
provider=JsonProvider(),
|
||||
max_checkpoints=5,
|
||||
),
|
||||
)
|
||||
```
|
||||
```python SqliteProvider
|
||||
from crewai import Crew, CheckpointConfig
|
||||
from crewai.state import SqliteProvider
|
||||
|
||||
### Crew
|
||||
crew = Crew(
|
||||
agents=[...],
|
||||
tasks=[...],
|
||||
checkpoint=CheckpointConfig(
|
||||
location="./.checkpoints.db",
|
||||
provider=SqliteProvider(),
|
||||
max_checkpoints=50,
|
||||
),
|
||||
)
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
```python
|
||||
crew = Crew(
|
||||
agents=[researcher, writer],
|
||||
tasks=[research_task, write_task, review_task],
|
||||
checkpoint=CheckpointConfig(location="./crew_cp"),
|
||||
)
|
||||
```
|
||||
<Tip>
|
||||
SQLite enables WAL journal mode for concurrent reads. Prefer it for high-frequency checkpointing.
|
||||
</Tip>
|
||||
</Accordion>
|
||||
|
||||
Default trigger: `task_completed` (one checkpoint per finished task).
|
||||
<Accordion title="Opt one agent out" icon="user-slash">
|
||||
```python
|
||||
crew = Crew(
|
||||
agents=[
|
||||
Agent(role="Researcher", ...),
|
||||
Agent(role="Writer", ..., checkpoint=False),
|
||||
],
|
||||
tasks=[...],
|
||||
checkpoint=True,
|
||||
)
|
||||
```
|
||||
</Accordion>
|
||||
|
||||
### Flow
|
||||
<Accordion title="Fork into a new branch" icon="code-branch">
|
||||
`fork()` restores a checkpoint under a fresh lineage so the new run does not collide with the original.
|
||||
|
||||
```python
|
||||
from crewai.flow.flow import Flow, start, listen
|
||||
from crewai import CheckpointConfig
|
||||
```python
|
||||
config = CheckpointConfig(restore_from="./my_checkpoints/<file>.json")
|
||||
crew = Crew.fork(config, branch="experiment-a")
|
||||
result = crew.kickoff(inputs={"strategy": "aggressive"})
|
||||
```
|
||||
|
||||
class MyFlow(Flow):
|
||||
@start()
|
||||
def step_one(self):
|
||||
return "data"
|
||||
The `branch` label is optional; one is generated if omitted.
|
||||
</Accordion>
|
||||
|
||||
@listen(step_one)
|
||||
def step_two(self, data):
|
||||
return process(data)
|
||||
<Accordion title="Checkpoint a Crew, Flow, or Agent" icon="cubes">
|
||||
<Tabs>
|
||||
<Tab title="Crew">
|
||||
```python
|
||||
crew = Crew(
|
||||
agents=[researcher, writer],
|
||||
tasks=[research_task, write_task, review_task],
|
||||
checkpoint=CheckpointConfig(location="./crew_cp"),
|
||||
)
|
||||
```
|
||||
|
||||
flow = MyFlow(
|
||||
checkpoint=CheckpointConfig(
|
||||
location="./flow_cp",
|
||||
on_events=["method_execution_finished"],
|
||||
),
|
||||
)
|
||||
result = flow.kickoff()
|
||||
Default trigger: `task_completed`.
|
||||
</Tab>
|
||||
<Tab title="Flow">
|
||||
```python
|
||||
from crewai.flow.flow import Flow, start, listen
|
||||
from crewai import CheckpointConfig
|
||||
|
||||
# Resume
|
||||
config = CheckpointConfig(restore_from="./flow_cp/20260407T120000_abc123.json")
|
||||
flow = MyFlow.from_checkpoint(config)
|
||||
result = flow.kickoff()
|
||||
```
|
||||
class MyFlow(Flow):
|
||||
@start()
|
||||
def step_one(self):
|
||||
return "data"
|
||||
|
||||
### Agent
|
||||
@listen(step_one)
|
||||
def step_two(self, data):
|
||||
return process(data)
|
||||
|
||||
```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"}])
|
||||
```
|
||||
flow = MyFlow(
|
||||
checkpoint=CheckpointConfig(
|
||||
location="./flow_cp",
|
||||
on_events=["method_execution_finished"],
|
||||
),
|
||||
)
|
||||
result = flow.kickoff()
|
||||
```
|
||||
</Tab>
|
||||
<Tab title="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"}])
|
||||
```
|
||||
</Tab>
|
||||
</Tabs>
|
||||
</Accordion>
|
||||
|
||||
## Storage Providers
|
||||
<Accordion title="Write a checkpoint manually" icon="code">
|
||||
Register a handler on any event and call `state.checkpoint()`.
|
||||
|
||||
CrewAI ships with two checkpoint storage providers.
|
||||
<CodeGroup>
|
||||
```python Sync
|
||||
from __future__ import annotations
|
||||
|
||||
### JsonProvider (default)
|
||||
from typing import TYPE_CHECKING, Any
|
||||
|
||||
Writes each checkpoint as a separate JSON file. Simple, human-readable, easy to inspect.
|
||||
from crewai.events.event_bus import crewai_event_bus
|
||||
from crewai.events.types.llm_events import LLMCallCompletedEvent
|
||||
|
||||
```python
|
||||
from crewai import Crew, CheckpointConfig
|
||||
from crewai.state import JsonProvider
|
||||
if TYPE_CHECKING:
|
||||
from crewai.state.runtime import RuntimeState
|
||||
|
||||
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.
|
||||
@crewai_event_bus.on(LLMCallCompletedEvent)
|
||||
def on_llm_done(source: Any, event: LLMCallCompletedEvent, state: RuntimeState) -> None:
|
||||
path = state.checkpoint("./my_checkpoints")
|
||||
print(f"Saved checkpoint: {path}")
|
||||
```
|
||||
```python Async
|
||||
from __future__ import annotations
|
||||
|
||||
### SqliteProvider
|
||||
from typing import TYPE_CHECKING, Any
|
||||
|
||||
Stores all checkpoints in a single SQLite database file. Better for high-frequency checkpointing and avoids many small files.
|
||||
from crewai.events.event_bus import crewai_event_bus
|
||||
from crewai.events.types.llm_events import LLMCallCompletedEvent
|
||||
|
||||
```python
|
||||
from crewai import Crew, CheckpointConfig
|
||||
from crewai.state import SqliteProvider
|
||||
if TYPE_CHECKING:
|
||||
from crewai.state.runtime import RuntimeState
|
||||
|
||||
crew = Crew(
|
||||
agents=[...],
|
||||
tasks=[...],
|
||||
checkpoint=CheckpointConfig(
|
||||
location="./.checkpoints.db",
|
||||
provider=SqliteProvider(),
|
||||
max_checkpoints=50,
|
||||
),
|
||||
)
|
||||
```
|
||||
|
||||
WAL journal mode is enabled for concurrent read access.
|
||||
@crewai_event_bus.on(LLMCallCompletedEvent)
|
||||
async def on_llm_done_async(source: Any, event: LLMCallCompletedEvent, state: RuntimeState) -> None:
|
||||
path = await state.acheckpoint("./my_checkpoints")
|
||||
print(f"Saved checkpoint: {path}")
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
## Event Types
|
||||
A `state` argument is supplied automatically when the handler takes three parameters. See [Event Listeners](/en/concepts/event-listener) for the full event catalog.
|
||||
</Accordion>
|
||||
|
||||
The `on_events` field accepts any combination of event type strings. Common choices:
|
||||
<Accordion title="Browse, resume, and fork from the CLI" icon="terminal">
|
||||
```bash
|
||||
crewai checkpoint
|
||||
crewai checkpoint --location ./my_checkpoints
|
||||
crewai checkpoint --location ./.checkpoints.db
|
||||
```
|
||||
|
||||
| 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 | `["*"]` |
|
||||
<Frame caption="Checkpoint tree — branches and forks nest under their parent.">
|
||||
<img src="/images/checkpoint-tui-tree.png" alt="Checkpoint TUI tree view" />
|
||||
</Frame>
|
||||
|
||||
The left panel groups checkpoints by branch; forks nest under their parent. Selecting a checkpoint opens the detail panel with metadata, entity state, and task progress. **Resume** continues the run; **Fork** starts a new branch.
|
||||
|
||||
<Frame caption="Overview tab — metadata, entity state, and run summary.">
|
||||
<img src="/images/checkpoint-tui-detail-overview.png" alt="Checkpoint detail overview tab" />
|
||||
</Frame>
|
||||
|
||||
The detail panel exposes two editable areas:
|
||||
|
||||
- **Inputs** — original kickoff inputs, pre-filled and editable.
|
||||
|
||||
<Frame>
|
||||
<img src="/images/checkpoint-tui-detail-inputs.png" alt="Editable kickoff inputs" />
|
||||
</Frame>
|
||||
|
||||
- **Task outputs** — outputs of completed tasks. Editing an output and hitting **Fork** invalidates downstream tasks so they re-run against the modified context.
|
||||
|
||||
<Frame>
|
||||
<img src="/images/checkpoint-tui-detail-tasks.png" alt="Editable task outputs" />
|
||||
</Frame>
|
||||
|
||||
<Frame caption="Fork view — confirm a new branch from the selected checkpoint.">
|
||||
<img src="/images/checkpoint-tui-details-fork.png" alt="Fork confirmation panel" />
|
||||
</Frame>
|
||||
|
||||
<Tip>
|
||||
Useful for "what if" exploration: fork, tweak, observe.
|
||||
</Tip>
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Inspect checkpoints without the TUI" icon="magnifying-glass">
|
||||
```bash
|
||||
crewai checkpoint list ./my_checkpoints
|
||||
crewai checkpoint info ./my_checkpoints/<file>.json
|
||||
crewai checkpoint info ./.checkpoints.db
|
||||
```
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
## Reference
|
||||
|
||||
### `CheckpointConfig`
|
||||
|
||||
<ParamField path="location" type="str" default='"./.checkpoints"'>
|
||||
Storage destination. A directory for `JsonProvider`, a database file path for `SqliteProvider`.
|
||||
</ParamField>
|
||||
|
||||
<ParamField path="on_events" type='list[CheckpointEventType | Literal["*"]]' default='["task_completed"]'>
|
||||
Event types that trigger a checkpoint. `CheckpointEventType` is a `Literal` — your type checker will autocomplete and reject unsupported values. See [event types](#event-types) for the full list.
|
||||
</ParamField>
|
||||
|
||||
<ParamField path="provider" type="BaseProvider" default="JsonProvider()">
|
||||
Storage backend. Either `JsonProvider` or `SqliteProvider`.
|
||||
</ParamField>
|
||||
|
||||
<ParamField path="max_checkpoints" type="int | None" default="None">
|
||||
Maximum checkpoints to retain. Oldest are pruned after each write.
|
||||
</ParamField>
|
||||
|
||||
<ParamField path="restore_from" type="Path | str | None" default="None">
|
||||
Checkpoint to restore from when passed via `from_checkpoint`.
|
||||
</ParamField>
|
||||
|
||||
### `checkpoint` field values
|
||||
|
||||
Accepted by `Crew`, `Flow`, and `Agent`.
|
||||
|
||||
<ParamField path="None" type="default">
|
||||
Inherit from parent.
|
||||
</ParamField>
|
||||
|
||||
<ParamField path="True" type="bool">
|
||||
Enable with defaults.
|
||||
</ParamField>
|
||||
|
||||
<ParamField path="False" type="bool">
|
||||
Explicit opt-out. Stops inheritance.
|
||||
</ParamField>
|
||||
|
||||
<ParamField path="CheckpointConfig(...)" type="CheckpointConfig">
|
||||
Custom configuration.
|
||||
</ParamField>
|
||||
|
||||
### Event types
|
||||
|
||||
`on_events` accepts any combination of `CheckpointEventType` values. The default `["task_completed"]` writes one checkpoint per finished task; `["*"]` matches every event.
|
||||
|
||||
<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.
|
||||
`["*"]` and high-frequency events like `llm_call_completed` write many checkpoints and can degrade performance. Pair them with `max_checkpoints`.
|
||||
</Warning>
|
||||
|
||||
## Manual Checkpointing
|
||||
<Expandable title="All supported events">
|
||||
|
||||
For full control, register your own event handler and call `state.checkpoint()` directly:
|
||||
- **Task** — `task_started`, `task_completed`, `task_failed`, `task_evaluation`
|
||||
- **Crew** — `crew_kickoff_started`, `crew_kickoff_completed`, `crew_kickoff_failed`, `crew_train_started`, `crew_train_completed`, `crew_train_failed`, `crew_test_started`, `crew_test_completed`, `crew_test_failed`, `crew_test_result`
|
||||
- **Agent** — `agent_execution_started`, `agent_execution_completed`, `agent_execution_error`, `lite_agent_execution_started`, `lite_agent_execution_completed`, `lite_agent_execution_error`, `agent_evaluation_started`, `agent_evaluation_completed`, `agent_evaluation_failed`
|
||||
- **Flow** — `flow_created`, `flow_started`, `flow_finished`, `flow_paused`, `method_execution_started`, `method_execution_finished`, `method_execution_failed`, `method_execution_paused`, `human_feedback_requested`, `human_feedback_received`, `flow_input_requested`, `flow_input_received`
|
||||
- **LLM** — `llm_call_started`, `llm_call_completed`, `llm_call_failed`, `llm_stream_chunk`, `llm_thinking_chunk`
|
||||
- **LLM Guardrail** — `llm_guardrail_started`, `llm_guardrail_completed`, `llm_guardrail_failed`
|
||||
- **Tool** — `tool_usage_started`, `tool_usage_finished`, `tool_usage_error`, `tool_validate_input_error`, `tool_selection_error`, `tool_execution_error`
|
||||
- **Memory** — `memory_save_started`, `memory_save_completed`, `memory_save_failed`, `memory_query_started`, `memory_query_completed`, `memory_query_failed`, `memory_retrieval_started`, `memory_retrieval_completed`, `memory_retrieval_failed`
|
||||
- **Knowledge** — `knowledge_search_query_started`, `knowledge_search_query_completed`, `knowledge_query_started`, `knowledge_query_completed`, `knowledge_query_failed`, `knowledge_search_query_failed`
|
||||
- **Reasoning** — `agent_reasoning_started`, `agent_reasoning_completed`, `agent_reasoning_failed`
|
||||
- **MCP** — `mcp_connection_started`, `mcp_connection_completed`, `mcp_connection_failed`, `mcp_tool_execution_started`, `mcp_tool_execution_completed`, `mcp_tool_execution_failed`, `mcp_config_fetch_failed`
|
||||
- **Observation** — `step_observation_started`, `step_observation_completed`, `step_observation_failed`, `plan_refinement`, `plan_replan_triggered`, `goal_achieved_early`
|
||||
- **Skill** — `skill_discovery_started`, `skill_discovery_completed`, `skill_loaded`, `skill_activated`, `skill_load_failed`
|
||||
- **Logging** — `agent_logs_started`, `agent_logs_execution`
|
||||
- **A2A** — `a2a_delegation_started`, `a2a_delegation_completed`, `a2a_conversation_started`, `a2a_conversation_completed`, `a2a_message_sent`, `a2a_response_received`, `a2a_polling_started`, `a2a_polling_status`, `a2a_push_notification_registered`, `a2a_push_notification_received`, `a2a_push_notification_sent`, `a2a_push_notification_timeout`, `a2a_streaming_started`, `a2a_streaming_chunk`, `a2a_agent_card_fetched`, `a2a_authentication_failed`, `a2a_artifact_received`, `a2a_connection_error`, `a2a_server_task_started`, `a2a_server_task_completed`, `a2a_server_task_canceled`, `a2a_server_task_failed`, `a2a_parallel_delegation_started`, `a2a_parallel_delegation_completed`, `a2a_transport_negotiated`, `a2a_content_type_negotiated`, `a2a_context_created`, `a2a_context_expired`, `a2a_context_idle`, `a2a_context_completed`, `a2a_context_pruned`
|
||||
- **System signals** — `SIGTERM`, `SIGINT`, `SIGHUP`, `SIGTSTP`, `SIGCONT`
|
||||
- **Wildcard** — `"*"` matches every event.
|
||||
|
||||
```python
|
||||
from crewai.events.event_bus import crewai_event_bus
|
||||
from crewai.events.types.llm_events import LLMCallCompletedEvent
|
||||
</Expandable>
|
||||
|
||||
# Sync handler
|
||||
@crewai_event_bus.on(LLMCallCompletedEvent)
|
||||
def on_llm_done(source, event, state):
|
||||
path = state.checkpoint("./my_checkpoints")
|
||||
print(f"Saved checkpoint: {path}")
|
||||
### Storage providers
|
||||
|
||||
# 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}")
|
||||
```
|
||||
<ParamField path="JsonProvider" type="provider">
|
||||
One file per checkpoint, named `<timestamp>_<uuid>.json` inside `location`.
|
||||
</ParamField>
|
||||
|
||||
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.
|
||||
<ParamField path="SqliteProvider" type="provider">
|
||||
Single database file at `location` with WAL journaling.
|
||||
</ParamField>
|
||||
|
||||
Checkpointing is best-effort: if a checkpoint write fails, the error is logged but execution continues uninterrupted.
|
||||
### CLI
|
||||
|
||||
## CLI
|
||||
|
||||
The `crewai checkpoint` command gives you a TUI for browsing, inspecting, resuming, and forking checkpoints. It auto-detects whether your checkpoints are JSON files or a SQLite database.
|
||||
|
||||
```bash
|
||||
# Launch the TUI — auto-detects .checkpoints/ or .checkpoints.db
|
||||
crewai checkpoint
|
||||
|
||||
# Point at a specific location
|
||||
crewai checkpoint --location ./my_checkpoints
|
||||
crewai checkpoint --location ./.checkpoints.db
|
||||
```
|
||||
|
||||
<Frame>
|
||||
<img src="/images/checkpointing.png" alt="Checkpoint TUI" />
|
||||
</Frame>
|
||||
|
||||
The left panel is a tree view. Checkpoints are grouped by branch, and forks nest under the checkpoint they diverged from. Select a checkpoint to see its metadata, entity state, and task progress in the detail panel. Hit **Resume** to pick up where it left off, or **Fork** to start a new branch from that point.
|
||||
|
||||
### Editing inputs and task outputs
|
||||
|
||||
When a checkpoint is selected, the detail panel shows:
|
||||
|
||||
- **Inputs** — if the original kickoff had inputs (e.g. `{topic}`), they appear as editable fields pre-filled with the original values. Change them before resuming or forking.
|
||||
- **Task outputs** — completed tasks show their output in editable text areas. Edit a task's output to change the context that downstream tasks receive. When you modify a task output and hit Fork, all subsequent tasks are invalidated and re-run with the new context.
|
||||
|
||||
This is useful for "what if" exploration — fork from a checkpoint, tweak a task's result, and see how it changes downstream behavior.
|
||||
|
||||
### Subcommands
|
||||
|
||||
```bash
|
||||
# List all checkpoints
|
||||
crewai checkpoint list ./my_checkpoints
|
||||
|
||||
# Inspect a specific checkpoint
|
||||
crewai checkpoint info ./my_checkpoints/20260407T120000_abc123.json
|
||||
|
||||
# Inspect latest in a SQLite database
|
||||
crewai checkpoint info ./.checkpoints.db
|
||||
```
|
||||
| Command | Purpose |
|
||||
|:--------|:--------|
|
||||
| `crewai checkpoint` | Launch the TUI; auto-detect storage. |
|
||||
| `crewai checkpoint --location <path>` | Launch the TUI against a specific location. |
|
||||
| `crewai checkpoint list <path>` | List checkpoints. |
|
||||
| `crewai checkpoint info <path>` | Inspect a checkpoint file or the latest entry in a SQLite database. |
|
||||
|
||||
@@ -52,6 +52,8 @@ crewai create crew my_new_crew
|
||||
crewai create flow my_new_flow
|
||||
```
|
||||
|
||||
By default, `crewai create crew` creates a JSON-first crew project with `crew.jsonc` and `agents/*.jsonc`. Use `crewai create crew my_new_crew --classic` only when you want the older Python/YAML scaffold with `crew.py`, `config/agents.yaml`, and `config/tasks.yaml`.
|
||||
|
||||
### 2. Version
|
||||
|
||||
Show the installed version of CrewAI.
|
||||
@@ -185,7 +187,20 @@ crewai chat
|
||||
Ensure you execute these commands from your CrewAI project's root directory.
|
||||
</Note>
|
||||
<Note>
|
||||
IMPORTANT: Set the `chat_llm` property in your `crew.py` file to enable this command.
|
||||
IMPORTANT: Set the `chat_llm` property in your crew definition to enable this command.
|
||||
|
||||
For JSON-first crews, add it to `crew.jsonc`:
|
||||
|
||||
```jsonc
|
||||
{
|
||||
"name": "My Crew",
|
||||
"agents": ["researcher"],
|
||||
"tasks": [],
|
||||
"chat_llm": "openai/gpt-4o"
|
||||
}
|
||||
```
|
||||
|
||||
For classic Python/YAML crews, set it in `crew.py`:
|
||||
|
||||
```python
|
||||
@crew
|
||||
@@ -336,7 +351,7 @@ Notes:
|
||||
|
||||
### 12. API Keys
|
||||
|
||||
When running `crewai create crew` command, the CLI will show you a list of available LLM providers to choose from, followed by model selection for your chosen provider.
|
||||
When running the `crewai create crew` command, the CLI shows a list of available LLM providers, followed by model selection for your chosen provider. The selected model is saved in the generated `.env` file and each generated agent JSONC file can set its own `llm`.
|
||||
|
||||
Once you've selected an LLM provider and model, you will be prompted for API keys.
|
||||
|
||||
|
||||
@@ -48,108 +48,74 @@ A crew in crewAI represents a collaborative group of agents working together to
|
||||
|
||||
## Creating Crews
|
||||
|
||||
There are two ways to create crews in CrewAI: using **YAML configuration (recommended)** or defining them **directly in code**.
|
||||
There are two common ways to create crews in CrewAI: using **JSONC project configuration (recommended for new crews)** or defining them **directly in code**.
|
||||
|
||||
### YAML Configuration (Recommended)
|
||||
### JSONC Configuration (Recommended)
|
||||
|
||||
Using YAML configuration provides a cleaner, more maintainable way to define crews and is consistent with how agents and tasks are defined in CrewAI projects.
|
||||
New projects created with `crewai create crew <name>` use `crew.jsonc` for crew-level settings and tasks, plus one file per agent in `agents/`.
|
||||
|
||||
After creating your CrewAI project as outlined in the [Installation](/en/installation) section, you can define your crew in a class that inherits from `CrewBase` and uses decorators to define agents, tasks, and the crew itself.
|
||||
`crewai run` automatically detects `crew.jsonc` or `crew.json`, loads the referenced agents, prompts for missing placeholders, and kicks off the crew.
|
||||
|
||||
#### Example Crew Class with Decorators
|
||||
#### Example `crew.jsonc`
|
||||
|
||||
```python code
|
||||
from crewai import Agent, Crew, Task, Process
|
||||
from crewai.project import CrewBase, agent, task, crew, before_kickoff, after_kickoff
|
||||
from crewai.agents.agent_builder.base_agent import BaseAgent
|
||||
from typing import List
|
||||
|
||||
@CrewBase
|
||||
class YourCrewName:
|
||||
"""Description of your crew"""
|
||||
|
||||
agents: List[BaseAgent]
|
||||
tasks: List[Task]
|
||||
|
||||
# Paths to your YAML configuration files
|
||||
# To see an example agent and task defined in YAML, checkout the following:
|
||||
# - Task: https://docs.crewai.com/concepts/tasks#yaml-configuration-recommended
|
||||
# - Agents: https://docs.crewai.com/concepts/agents#yaml-configuration-recommended
|
||||
agents_config = 'config/agents.yaml'
|
||||
tasks_config = 'config/tasks.yaml'
|
||||
|
||||
@before_kickoff
|
||||
def prepare_inputs(self, inputs):
|
||||
# Modify inputs before the crew starts
|
||||
inputs['additional_data'] = "Some extra information"
|
||||
return inputs
|
||||
|
||||
@after_kickoff
|
||||
def process_output(self, output):
|
||||
# Modify output after the crew finishes
|
||||
output.raw += "\nProcessed after kickoff."
|
||||
return output
|
||||
|
||||
@agent
|
||||
def agent_one(self) -> Agent:
|
||||
return Agent(
|
||||
config=self.agents_config['agent_one'], # type: ignore[index]
|
||||
verbose=True
|
||||
)
|
||||
|
||||
@agent
|
||||
def agent_two(self) -> Agent:
|
||||
return Agent(
|
||||
config=self.agents_config['agent_two'], # type: ignore[index]
|
||||
verbose=True
|
||||
)
|
||||
|
||||
@task
|
||||
def task_one(self) -> Task:
|
||||
return Task(
|
||||
config=self.tasks_config['task_one'] # type: ignore[index]
|
||||
)
|
||||
|
||||
@task
|
||||
def task_two(self) -> Task:
|
||||
return Task(
|
||||
config=self.tasks_config['task_two'] # type: ignore[index]
|
||||
)
|
||||
|
||||
@crew
|
||||
def crew(self) -> Crew:
|
||||
return Crew(
|
||||
agents=self.agents, # Automatically collected by the @agent decorator
|
||||
tasks=self.tasks, # Automatically collected by the @task decorator.
|
||||
process=Process.sequential,
|
||||
verbose=True,
|
||||
)
|
||||
```jsonc crew.jsonc
|
||||
{
|
||||
"name": "Market Research Crew",
|
||||
"agents": ["researcher", "analyst"],
|
||||
"tasks": [
|
||||
{
|
||||
"name": "research",
|
||||
"description": "Research {topic} and collect the most relevant facts.",
|
||||
"expected_output": "Structured research notes about {topic}.",
|
||||
"agent": "researcher"
|
||||
},
|
||||
{
|
||||
"name": "analysis",
|
||||
"description": "Analyze the research and write a concise report.",
|
||||
"expected_output": "A markdown report with findings and recommendations.",
|
||||
"agent": "analyst",
|
||||
"context": ["research"],
|
||||
"output_file": "output/report.md"
|
||||
}
|
||||
],
|
||||
"process": "sequential",
|
||||
"verbose": true,
|
||||
"memory": true,
|
||||
"inputs": {
|
||||
"topic": "AI Agents"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
How to run the above code:
|
||||
Each string in `agents` resolves to `agents/<name>.jsonc` first, then `agents/<name>.json`.
|
||||
|
||||
```python code
|
||||
YourCrewName().crew().kickoff(inputs={"any": "input here"})
|
||||
```jsonc agents/researcher.jsonc
|
||||
{
|
||||
"role": "{topic} Senior Researcher",
|
||||
"goal": "Find accurate and current information about {topic}.",
|
||||
"backstory": "You are a careful researcher who cites clear evidence.",
|
||||
"llm": "openai/gpt-4o",
|
||||
"tools": ["SerperDevTool"]
|
||||
}
|
||||
```
|
||||
|
||||
<Note>
|
||||
Tasks will be executed in the order they are defined.
|
||||
Tasks run in the order they appear in `tasks` when `process` is `"sequential"`.
|
||||
</Note>
|
||||
|
||||
The `CrewBase` class, along with these decorators, automates the collection of agents and tasks, reducing the need for manual management.
|
||||
For hierarchical crews, set `"process": "hierarchical"` and provide either `manager_llm` or `manager_agent`. A `manager_agent` can reference an `agents/<name>.jsonc` file that is not included in the top-level `agents` list.
|
||||
|
||||
#### Decorators overview from `annotations.py`
|
||||
JSON crew definitions support crew-level fields such as `process`, `verbose`, `memory`, `cache`, `max_rpm`, `planning`, `planning_llm`, `manager_llm`, `manager_agent`, `function_calling_llm`, `output_log_file`, `stream`, `tracing`, `before_kickoff_callbacks`, and `after_kickoff_callbacks`.
|
||||
|
||||
CrewAI provides several decorators in the `annotations.py` file that are used to mark methods within your crew class for special handling:
|
||||
Python callbacks and custom classes use `{"python": "module.attribute"}`. Custom tools use `"custom:<name>"` and load `tools/<name>.py` at runtime.
|
||||
|
||||
- `@CrewBase`: Marks the class as a crew base class.
|
||||
- `@agent`: Denotes a method that returns an `Agent` object.
|
||||
- `@task`: Denotes a method that returns a `Task` object.
|
||||
- `@crew`: Denotes the method that returns the `Crew` object.
|
||||
- `@before_kickoff`: (Optional) Marks a method to be executed before the crew starts.
|
||||
- `@after_kickoff`: (Optional) Marks a method to be executed after the crew finishes.
|
||||
<Warning>
|
||||
Only run JSON crew projects from sources you trust. `custom:<name>` tools and `{"python": "module.attribute"}` references execute local Python code when the crew loads.
|
||||
</Warning>
|
||||
|
||||
These decorators help in organizing your crew's structure and automatically collecting agents and tasks without manually listing them.
|
||||
### Classic Python/YAML Configuration
|
||||
|
||||
Classic projects created with `crewai create crew <name> --classic` use `crew.py`, `config/agents.yaml`, `config/tasks.yaml`, and the `@CrewBase`, `@agent`, `@task`, and `@crew` decorators. That pattern remains supported and is documented in [Using Annotations](/en/learn/using-annotations).
|
||||
|
||||
### Direct Code Definition (Alternative)
|
||||
|
||||
|
||||
@@ -226,6 +226,49 @@ After the Flow has run, you can access the final state to see the updates made b
|
||||
By ensuring that the final method's output is returned and providing access to the state, CrewAI Flows make it easy to integrate the results of your AI workflows into larger applications or systems,
|
||||
while also maintaining and accessing the state throughout the Flow's execution.
|
||||
|
||||
## Flow Usage Metrics
|
||||
|
||||
After a Flow execution completes, you can access the `usage_metrics` property to view aggregated token usage across **every LLM call** made during the run — including calls from every Crew the Flow orchestrated, calls inside Agent tools, and bare `LLM.call(...)` invocations from Flow methods. This is the SDK-side equivalent of the totals shown in the CrewAI Enterprise UI.
|
||||
|
||||
```python Code
|
||||
from crewai import LLM
|
||||
from crewai.flow.flow import Flow, listen, start
|
||||
|
||||
class UsageMetricsFlow(Flow):
|
||||
@start()
|
||||
def run_first_crew(self):
|
||||
self.state.first_result = FirstCrew().crew().kickoff()
|
||||
|
||||
@listen(run_first_crew)
|
||||
def call_llm_directly(self):
|
||||
# Bare LLM call — still counted by flow.usage_metrics
|
||||
llm = LLM(model="openai/gpt-4o-mini")
|
||||
self.state.summary = llm.call("Summarize the key takeaways.")
|
||||
|
||||
@listen(call_llm_directly)
|
||||
def run_second_crew(self):
|
||||
self.state.second_result = SecondCrew().crew().kickoff()
|
||||
|
||||
flow = UsageMetricsFlow()
|
||||
flow.kickoff()
|
||||
|
||||
print(flow.usage_metrics)
|
||||
# UsageMetrics(total_tokens=8579, prompt_tokens=6210, completion_tokens=2369,
|
||||
# cached_prompt_tokens=0, reasoning_tokens=0,
|
||||
# cache_creation_tokens=0, successful_requests=5)
|
||||
```
|
||||
|
||||
<Note>
|
||||
`flow.usage_metrics` is **not** the same as `flow.kickoff().token_usage`. The
|
||||
latter returns the `CrewOutput.token_usage` of the **last** `@listen` method
|
||||
that returned a `CrewOutput`, which means it only reflects the final Crew and
|
||||
ignores prior Crews and bare `LLM.call(...)` invocations entirely. Use
|
||||
`flow.usage_metrics` whenever you need the **full** token rollup for the Flow
|
||||
execution.
|
||||
</Note>
|
||||
|
||||
Each entry in the returned [`UsageMetrics`](https://github.com/crewAIInc/crewAI/blob/main/lib/crewai/src/crewai/types/usage_metrics.py) is the sum across all LLM calls made within a single `flow.kickoff()` invocation. Counters reset on the next `kickoff()` call (or on each iteration of `kickoff_for_each`), so successive runs don't double-count. The property is safe to read at any point after `kickoff()` completes; reading it during execution returns the partial total accumulated so far.
|
||||
|
||||
## Flow State Management
|
||||
|
||||
Managing state effectively is crucial for building reliable and maintainable AI workflows. CrewAI Flows provides robust mechanisms for both unstructured and structured state management,
|
||||
@@ -788,7 +831,7 @@ You can generate a new CrewAI project that includes all the scaffolding needed t
|
||||
crewai create flow name_of_flow
|
||||
```
|
||||
|
||||
This command will generate a new CrewAI project with the necessary folder structure. The generated project includes a prebuilt crew called `poem_crew` that is already working. You can use this crew as a template by copying, pasting, and editing it to create other crews.
|
||||
This command will generate a new CrewAI project with the necessary folder structure. The generated project includes a prebuilt crew called `poem_crew` that is already working. The starter embedded crew uses the classic Python/YAML layout; new standalone crews created with `crewai create crew` use the JSON-first layout.
|
||||
|
||||
### Folder Structure
|
||||
|
||||
@@ -812,13 +855,35 @@ After running the `crewai create flow name_of_flow` command, you will see a fold
|
||||
|
||||
### Building Your Crews
|
||||
|
||||
In the `crews` folder, you can define multiple crews. Each crew will have its own folder containing configuration files and the crew definition file. For example, the `poem_crew` folder contains:
|
||||
In the `crews` folder, you can define multiple crews. The generated `poem_crew` uses the classic embedded-crew structure:
|
||||
|
||||
- `config/agents.yaml`: Defines the agents for the crew.
|
||||
- `config/tasks.yaml`: Defines the tasks for the crew.
|
||||
- `poem_crew.py`: Contains the crew definition, including agents, tasks, and the crew itself.
|
||||
|
||||
You can copy, paste, and edit the `poem_crew` to create other crews.
|
||||
You can copy, paste, and edit the `poem_crew` to create other classic embedded crews.
|
||||
|
||||
For JSON-first embedded crews, use a folder with `crew.jsonc` and `agents/*.jsonc` instead:
|
||||
|
||||
```text
|
||||
crews/
|
||||
└── research_crew/
|
||||
├── agents/
|
||||
│ └── researcher.jsonc
|
||||
└── crew.jsonc
|
||||
```
|
||||
|
||||
Then load it from a Flow step:
|
||||
|
||||
```python
|
||||
from pathlib import Path
|
||||
from crewai.project import load_crew
|
||||
|
||||
crew, default_inputs = load_crew(
|
||||
Path(__file__).parent / "crews" / "research_crew" / "crew.jsonc"
|
||||
)
|
||||
result = crew.kickoff(inputs={**default_inputs, "topic": "AI Agents"})
|
||||
```
|
||||
|
||||
### Connecting Crews in `main.py`
|
||||
|
||||
|
||||
@@ -107,7 +107,7 @@ There are different places in CrewAI code where you can specify the model to use
|
||||
</Tabs>
|
||||
|
||||
<Info>
|
||||
CrewAI provides native SDK integrations for OpenAI, Anthropic, Google (Gemini API), Azure, and AWS Bedrock — no extra install needed beyond the provider-specific extras (e.g. `uv add "crewai[openai]"`).
|
||||
CrewAI provides native SDK integrations for OpenAI, Anthropic, Google (Gemini API), Azure, AWS Bedrock, and Snowflake Cortex — no extra install needed beyond the provider-specific extras (e.g. `uv add "crewai[openai]"`).
|
||||
|
||||
All other providers are powered by **LiteLLM**. If you plan to use any of them, add it as a dependency to your project:
|
||||
```bash
|
||||
@@ -291,6 +291,55 @@ In this section, you'll find detailed examples that help you select, configure,
|
||||
```
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Snowflake Cortex">
|
||||
CrewAI provides native integration with the Snowflake Cortex REST API through its OpenAI-compatible Chat Completions endpoint. This avoids LiteLLM fallback for `snowflake/...` models. Snowflake Cortex currently supports Chat Completions only in CrewAI, so use the default `api` mode and do not set `api="responses"`.
|
||||
|
||||
```toml Code
|
||||
# Required
|
||||
SNOWFLAKE_PAT=<your-programmatic-access-token>
|
||||
SNOWFLAKE_ACCOUNT_URL=https://<account-identifier>.snowflakecomputing.com
|
||||
|
||||
# Alternative account configuration
|
||||
SNOWFLAKE_ACCOUNT=<account-identifier>
|
||||
```
|
||||
|
||||
**Basic Usage:**
|
||||
```python Code
|
||||
from crewai import LLM
|
||||
|
||||
llm = LLM(
|
||||
model="snowflake/openai-gpt-4.1",
|
||||
temperature=0.7,
|
||||
max_completion_tokens=1024,
|
||||
)
|
||||
```
|
||||
|
||||
**Claude Models on Cortex:**
|
||||
```python Code
|
||||
from crewai import LLM
|
||||
|
||||
llm = LLM(
|
||||
model="snowflake/claude-sonnet-4-5",
|
||||
max_completion_tokens=1024,
|
||||
stream=True,
|
||||
)
|
||||
```
|
||||
|
||||
**Supported Environment Variables:**
|
||||
- `SNOWFLAKE_PAT`, `SNOWFLAKE_TOKEN`, or `SNOWFLAKE_JWT`: token used as the Bearer credential
|
||||
- `SNOWFLAKE_ACCOUNT_URL`: full Snowflake account URL
|
||||
- `SNOWFLAKE_ACCOUNT`, `SNOWFLAKE_ACCOUNT_ID`, or `SNOWFLAKE_ACCOUNT_IDENTIFIER`: account identifier used to build the account URL
|
||||
|
||||
Snowflake REST requests use the user's default Snowflake role. Make sure that role has `SNOWFLAKE.CORTEX_USER` or `SNOWFLAKE.CORTEX_REST_API_USER`. Database, schema, warehouse, and explicit role parameters are not required by the Cortex REST Chat Completions endpoint.
|
||||
|
||||
**Features:**
|
||||
- Native provider selection with `model="snowflake/<model-name>"`
|
||||
- Streaming and non-streaming Chat Completions only; `api="responses"` is not supported
|
||||
- Token usage tracking
|
||||
- Function calling for Snowflake-hosted OpenAI and Claude models
|
||||
- Automatic removal of invalid trailing assistant prefill for Snowflake Claude models
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Anthropic">
|
||||
CrewAI provides native integration with Anthropic through the Anthropic Python SDK.
|
||||
|
||||
@@ -903,6 +952,61 @@ In this section, you'll find detailed examples that help you select, configure,
|
||||
```
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="NVIDIA Nemotron">
|
||||
NVIDIA Nemotron models are designed for demanding agentic workloads, including complex reasoning, long-context analysis, tool use, multilingual tasks, and high-stakes RAG.
|
||||
|
||||
The `NVIDIA-Nemotron-3-Ultra-550B-A55B-NVFP4` model is a frontier-scale open-weight model from NVIDIA with 550B total parameters and 55B active parameters. It uses a LatentMoE architecture that combines Mamba-2, MoE, Attention, and Multi-Token Prediction (MTP), and supports context lengths up to 1M tokens.
|
||||
|
||||
<Info>
|
||||
`NVIDIA-Nemotron-3-Ultra-550B-A55B-NVFP4` is a very large model. NVIDIA lists minimum serving requirements of 4x GB200, 4x B200, 4x GB300, 4x B300, or 8x H100 GPUs. For most CrewAI users, the recommended path is to use NVIDIA NIM or another OpenAI-compatible hosted endpoint rather than running it locally.
|
||||
</Info>
|
||||
|
||||
**Hosted NVIDIA NIM usage:**
|
||||
```toml Code
|
||||
NVIDIA_API_KEY=<your-api-key>
|
||||
```
|
||||
|
||||
```python Code
|
||||
from crewai import LLM
|
||||
|
||||
llm = LLM(
|
||||
model="nvidia_nim/nvidia/nvidia-nemotron-3-ultra-550b-a55b",
|
||||
temperature=0.2,
|
||||
max_tokens=4096,
|
||||
)
|
||||
```
|
||||
|
||||
**Self-hosted OpenAI-compatible endpoint:**
|
||||
```python Code
|
||||
from crewai import LLM
|
||||
|
||||
llm = LLM(
|
||||
model="openai/nvidia-nemotron-3-ultra-550b-a55b-nvfp4",
|
||||
base_url="https://your-nemotron-endpoint.example.com/v1",
|
||||
api_key="your-api-key",
|
||||
temperature=0.2,
|
||||
max_tokens=4096,
|
||||
)
|
||||
```
|
||||
|
||||
**Model details:**
|
||||
|
||||
| Model | Context Window | Best For |
|
||||
|-------|----------------|----------|
|
||||
| `nvidia/NVIDIA-Nemotron-3-Ultra-550B-A55B-NVFP4` | Up to 1M tokens | Frontier reasoning, complex agentic workflows, long-context analysis, tool use, multilingual reasoning, and high-stakes RAG |
|
||||
|
||||
**Supported languages:** English, French, Spanish, Italian, German, Japanese, Korean, Hindi, Brazilian Portuguese, and Chinese.
|
||||
|
||||
**Reasoning mode:** Nemotron 3 Ultra supports configurable reasoning via its chat template using `enable_thinking=True` or `enable_thinking=False`. If you are using a hosted endpoint, check your provider's documentation for how that flag is exposed.
|
||||
|
||||
For model details, license, and deployment guidance, see the [NVIDIA Nemotron 3 Ultra model card](https://huggingface.co/nvidia/NVIDIA-Nemotron-3-Ultra-550B-A55B-NVFP4).
|
||||
|
||||
**Note:** Hosted NVIDIA NIM usage uses LiteLLM. Add it as a dependency to your project:
|
||||
```bash
|
||||
uv add 'crewai[litellm]'
|
||||
```
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Local NVIDIA NIM Deployed using WSL2">
|
||||
|
||||
NVIDIA NIM enables you to run powerful LLMs locally on your Windows machine using WSL2 (Windows Subsystem for Linux).
|
||||
|
||||
@@ -101,7 +101,7 @@ crew = Crew(
|
||||
)
|
||||
```
|
||||
|
||||
When `memory=True`, the crew creates a default `Memory()` and passes the crew's `embedder` configuration through automatically. All agents in the crew share the crew's memory unless an agent has its own.
|
||||
When `memory=True`, the crew creates a default `Memory()` and passes the crew's `embedder` configuration through automatically. All agents in the crew share the crew's memory unless an agent has its own. Without a custom `embedder`, memory uses OpenAI `text-embedding-3-large` embeddings.
|
||||
|
||||
After each task, the crew automatically extracts discrete facts from the task output and stores them. Before each task, the agent recalls relevant context from memory and injects it into the task prompt.
|
||||
|
||||
@@ -515,7 +515,11 @@ memory = Memory(
|
||||
|
||||
## Embedder Configuration
|
||||
|
||||
Memory needs an embedding model to convert text into vectors for semantic search. You can configure this in three ways.
|
||||
Memory needs an embedding model to convert text into vectors for semantic search. By default, `Memory()` uses OpenAI `text-embedding-3-large` embeddings, which produce 3072-dimensional vectors. Set `OPENAI_API_KEY` for the default path, or configure a custom embedder in one of three ways.
|
||||
|
||||
<Warning>
|
||||
Existing local memory stores created with 1536-dimensional embeddings, such as `text-embedding-3-small` or `text-embedding-ada-002`, may not be compatible with the `text-embedding-3-large` default. This applies to both the OpenAI and Azure OpenAI providers — Azure's default embedding model also changed from `text-embedding-ada-002` to `text-embedding-3-large`. If local testing fails with an embedding dimension mismatch, reset memory with `crewai reset-memories -m`, delete the local memory storage directory, or explicitly configure the older embedder model until you migrate.
|
||||
</Warning>
|
||||
|
||||
### Passing to Memory Directly
|
||||
|
||||
@@ -523,7 +527,7 @@ Memory needs an embedding model to convert text into vectors for semantic search
|
||||
from crewai import Memory
|
||||
|
||||
# As a config dict
|
||||
memory = Memory(embedder={"provider": "openai", "config": {"model_name": "text-embedding-3-small"}})
|
||||
memory = Memory(embedder={"provider": "openai", "config": {"model_name": "text-embedding-3-large"}})
|
||||
|
||||
# As a pre-built callable
|
||||
from crewai.rag.embeddings.factory import build_embedder
|
||||
@@ -542,7 +546,7 @@ crew = Crew(
|
||||
agents=[...],
|
||||
tasks=[...],
|
||||
memory=True,
|
||||
embedder={"provider": "openai", "config": {"model_name": "text-embedding-3-small"}},
|
||||
embedder={"provider": "openai", "config": {"model_name": "text-embedding-3-large"}},
|
||||
)
|
||||
```
|
||||
|
||||
@@ -554,7 +558,7 @@ crew = Crew(
|
||||
memory = Memory(embedder={
|
||||
"provider": "openai",
|
||||
"config": {
|
||||
"model_name": "text-embedding-3-small",
|
||||
"model_name": "text-embedding-3-large",
|
||||
# "api_key": "sk-...", # or set OPENAI_API_KEY env var
|
||||
},
|
||||
})
|
||||
@@ -701,9 +705,9 @@ memory = Memory(embedder=my_embedder)
|
||||
|
||||
| Provider | Key | Typical Model | Notes |
|
||||
| :--- | :--- | :--- | :--- |
|
||||
| OpenAI | `openai` | `text-embedding-3-small` | Default. Set `OPENAI_API_KEY`. |
|
||||
| OpenAI | `openai` | `text-embedding-3-large` | Default. Set `OPENAI_API_KEY`. |
|
||||
| Ollama | `ollama` | `mxbai-embed-large` | Local, no API key needed. |
|
||||
| Azure OpenAI | `azure` | `text-embedding-ada-002` | Requires `deployment_id`. |
|
||||
| Azure OpenAI | `azure` | `text-embedding-3-large` | Default model. Requires `deployment_id`. |
|
||||
| Google AI | `google-generativeai` | `gemini-embedding-001` | Set `GOOGLE_API_KEY`. |
|
||||
| Google Vertex | `google-vertex` | `gemini-embedding-001` | Requires `project_id`. |
|
||||
| Cohere | `cohere` | `embed-english-v3.0` | Strong multilingual support. |
|
||||
@@ -836,6 +840,9 @@ class MemoryMonitor(BaseEventListener):
|
||||
**Background save errors in logs?**
|
||||
- Memory saves run in a background thread. Errors are emitted as `MemorySaveFailedEvent` but don't crash the agent. Check logs for the root cause (usually LLM or embedder connection issues).
|
||||
|
||||
**Embedding dimension mismatch?**
|
||||
- Existing local memory stores may have been created with a different embedding model. The default OpenAI memory embedder is now `text-embedding-3-large` (3072 dimensions), while older stores commonly used 1536-dimensional embeddings. For local testing, run `crewai reset-memories -m`, delete the local memory storage directory, or configure the previous embedder model explicitly.
|
||||
|
||||
**Concurrent write conflicts?**
|
||||
- LanceDB operations are serialized with a shared lock and retried automatically on conflict. This handles multiple `Memory` instances pointing at the same database (e.g. agent memory + crew memory). No action needed.
|
||||
|
||||
@@ -862,7 +869,7 @@ All configuration is passed as keyword arguments to `Memory(...)`. Every paramet
|
||||
| :--- | :--- | :--- |
|
||||
| `llm` | `"gpt-4o-mini"` | LLM for analysis (model name or `BaseLLM` instance). |
|
||||
| `storage` | `"lancedb"` | Storage backend (`"lancedb"`, a path string, or a `StorageBackend` instance). |
|
||||
| `embedder` | `None` (OpenAI default) | Embedder (config dict, callable, or `None` for default OpenAI). |
|
||||
| `embedder` | `None` (OpenAI `text-embedding-3-large`) | Embedder (config dict, callable, or `None` for default OpenAI). |
|
||||
| `recency_weight` | `0.3` | Weight for recency in composite score. |
|
||||
| `semantic_weight` | `0.5` | Weight for semantic similarity in composite score. |
|
||||
| `importance_weight` | `0.2` | Weight for importance in composite score. |
|
||||
|
||||
@@ -16,7 +16,6 @@ mode: "wide"
|
||||
|
||||
- **Sequential**: Executes tasks sequentially, ensuring tasks are completed in an orderly progression.
|
||||
- **Hierarchical**: Organizes tasks in a managerial hierarchy, where tasks are delegated and executed based on a structured chain of command. A manager language model (`manager_llm`) or a custom manager agent (`manager_agent`) must be specified in the crew to enable the hierarchical process, facilitating the creation and management of tasks by the manager.
|
||||
- **Consensual Process (Planned)**: Aiming for collaborative decision-making among agents on task execution, this process type introduces a democratic approach to task management within CrewAI. It is planned for future development and is not currently implemented in the codebase.
|
||||
|
||||
## The Role of Processes in Teamwork
|
||||
Processes enable individual agents to operate as a cohesive unit, streamlining their efforts to achieve common objectives with efficiency and coherence.
|
||||
@@ -59,9 +58,9 @@ Emulates a corporate hierarchy, CrewAI allows specifying a custom manager agent
|
||||
|
||||
## Process Class: Detailed Overview
|
||||
|
||||
The `Process` class is implemented as an enumeration (`Enum`), ensuring type safety and restricting process values to the defined types (`sequential`, `hierarchical`). The consensual process is planned for future inclusion, emphasizing our commitment to continuous development and innovation.
|
||||
The `Process` class is implemented as an enumeration (`Enum`), ensuring type safety and restricting process values to the defined types (`sequential`, `hierarchical`).
|
||||
|
||||
## Conclusion
|
||||
|
||||
The structured collaboration facilitated by processes within CrewAI is crucial for enabling systematic teamwork among agents.
|
||||
This documentation has been updated to reflect the latest features, enhancements, and the planned integration of the Consensual Process, ensuring users have access to the most current and comprehensive information.
|
||||
This documentation has been updated to reflect the latest features and enhancements, ensuring users have access to the most current and comprehensive information.
|
||||
@@ -74,104 +74,54 @@ crew = Crew(
|
||||
|
||||
## Creating Tasks
|
||||
|
||||
There are two ways to create tasks in CrewAI: using **YAML configuration (recommended)** or defining them **directly in code**.
|
||||
There are two common ways to create tasks in CrewAI: using **JSONC project configuration (recommended for new crews)** or defining them **directly in code**.
|
||||
|
||||
### YAML Configuration (Recommended)
|
||||
### JSONC Configuration (Recommended)
|
||||
|
||||
Using YAML configuration provides a cleaner, more maintainable way to define tasks. We strongly recommend using this approach to define tasks in your CrewAI projects.
|
||||
New projects created with `crewai create crew <name>` define tasks in `crew.jsonc`. The `agents` array points to files in `agents/`, and the `tasks` array defines the ordered work the crew should run.
|
||||
|
||||
After creating your CrewAI project as outlined in the [Installation](/en/installation) section, navigate to the `src/latest_ai_development/config/tasks.yaml` file and modify the template to match your specific task requirements.
|
||||
After creating your CrewAI project as outlined in the [Installation](/en/installation) section, edit the generated `crew.jsonc`.
|
||||
|
||||
<Note>
|
||||
Variables in your YAML files (like `{topic}`) will be replaced with values from your inputs when running the crew:
|
||||
```python Code
|
||||
crew.kickoff(inputs={'topic': 'AI Agents'})
|
||||
```
|
||||
Use `{placeholder}` values in task `description`, `expected_output`, and `output_file`. Put defaults in the top-level `inputs` object; `crewai run` prompts for any missing values.
|
||||
</Note>
|
||||
|
||||
Here's an example of how to configure tasks using YAML:
|
||||
Here's an example `crew.jsonc` with two ordered tasks:
|
||||
|
||||
````yaml tasks.yaml
|
||||
research_task:
|
||||
description: >
|
||||
Conduct a thorough research about {topic}
|
||||
Make sure you find any interesting and relevant information given
|
||||
the current year is 2025.
|
||||
expected_output: >
|
||||
A list with 10 bullet points of the most relevant information about {topic}
|
||||
agent: researcher
|
||||
|
||||
reporting_task:
|
||||
description: >
|
||||
Review the context you got and expand each topic into a full section for a report.
|
||||
Make sure the report is detailed and contains any and all relevant information.
|
||||
expected_output: >
|
||||
A fully fledge reports with the mains topics, each with a full section of information.
|
||||
Formatted as markdown without '```'
|
||||
agent: reporting_analyst
|
||||
markdown: true
|
||||
output_file: report.md
|
||||
````jsonc crew.jsonc
|
||||
{
|
||||
"name": "Research Crew",
|
||||
"agents": ["researcher", "reporting_analyst"],
|
||||
"tasks": [
|
||||
{
|
||||
"name": "research_task",
|
||||
"description": "Conduct thorough research about {topic}. Include current and relevant information.",
|
||||
"expected_output": "A list of the most relevant information about {topic}.",
|
||||
"agent": "researcher"
|
||||
},
|
||||
{
|
||||
"name": "reporting_task",
|
||||
"description": "Review the research and expand it into a detailed report.",
|
||||
"expected_output": "A polished markdown report without fenced code blocks.",
|
||||
"agent": "reporting_analyst",
|
||||
"context": ["research_task"],
|
||||
"markdown": true,
|
||||
"output_file": "report.md"
|
||||
}
|
||||
],
|
||||
"inputs": {
|
||||
"topic": "AI Agents"
|
||||
}
|
||||
}
|
||||
````
|
||||
|
||||
To use this YAML configuration in your code, create a crew class that inherits from `CrewBase`:
|
||||
Each task must include `description` and `expected_output`. The `agent` value should match an agent name listed in `agents`. `context` is a list of prior task names; forward references are rejected so sequential context stays explicit.
|
||||
|
||||
```python crew.py
|
||||
# src/latest_ai_development/crew.py
|
||||
Task entries support any public `Task` field. Common fields include `name`, `agent`, `context`, `output_file`, `tools`, `human_input`, `async_execution`, `guardrail`, `guardrails`, `guardrail_max_retries`, `markdown`, `input_files`, `output_json`, `output_pydantic`, `response_model`, and `converter_cls`. Use `"type": "ConditionalTask"` with a `condition` field for conditional tasks.
|
||||
|
||||
from crewai import Agent, Crew, Process, Task
|
||||
from crewai.project import CrewBase, agent, crew, task
|
||||
from crewai_tools import SerperDevTool
|
||||
### Classic YAML Configuration
|
||||
|
||||
@CrewBase
|
||||
class LatestAiDevelopmentCrew():
|
||||
"""LatestAiDevelopment crew"""
|
||||
|
||||
@agent
|
||||
def researcher(self) -> Agent:
|
||||
return Agent(
|
||||
config=self.agents_config['researcher'], # type: ignore[index]
|
||||
verbose=True,
|
||||
tools=[SerperDevTool()]
|
||||
)
|
||||
|
||||
@agent
|
||||
def reporting_analyst(self) -> Agent:
|
||||
return Agent(
|
||||
config=self.agents_config['reporting_analyst'], # type: ignore[index]
|
||||
verbose=True
|
||||
)
|
||||
|
||||
@task
|
||||
def research_task(self) -> Task:
|
||||
return Task(
|
||||
config=self.tasks_config['research_task'] # type: ignore[index]
|
||||
)
|
||||
|
||||
@task
|
||||
def reporting_task(self) -> Task:
|
||||
return Task(
|
||||
config=self.tasks_config['reporting_task'] # type: ignore[index]
|
||||
)
|
||||
|
||||
@crew
|
||||
def crew(self) -> Crew:
|
||||
return Crew(
|
||||
agents=[
|
||||
self.researcher(),
|
||||
self.reporting_analyst()
|
||||
],
|
||||
tasks=[
|
||||
self.research_task(),
|
||||
self.reporting_task()
|
||||
],
|
||||
process=Process.sequential
|
||||
)
|
||||
```
|
||||
|
||||
<Note>
|
||||
The names you use in your YAML files (`agents.yaml` and `tasks.yaml`) should
|
||||
match the method names in your Python code.
|
||||
</Note>
|
||||
Classic projects created with `crewai create crew <name> --classic` use `config/tasks.yaml` and a `@CrewBase` class in `crew.py`. This remains supported for existing YAML projects or teams that prefer decorator-based Python wiring.
|
||||
|
||||
### Direct Code Definition (Alternative)
|
||||
|
||||
|
||||
@@ -187,7 +187,7 @@ flowchart TD
|
||||
- **Filename Requirement:** Ensure that the filename ends with `.pkl`. The code will raise a `ValueError` if this condition is not met.
|
||||
- **Error Handling:** The code handles subprocess errors and unexpected exceptions, providing error messages to the user.
|
||||
- Trained guidance is applied at prompt time; it does not modify your Python/YAML agent configuration.
|
||||
- Agents automatically load trained suggestions from a file named `trained_agents_data.pkl` located in the current working directory. If you trained to a different filename, either rename it to `trained_agents_data.pkl` before running, or adjust the loader in code.
|
||||
- Agents automatically load trained suggestions from a file named `trained_agents_data.pkl` located in the current working directory. If you trained to a different filename, pass that path with `Crew(trained_agents_file="my_custom_trained.pkl")`, set `CREWAI_TRAINED_AGENTS_FILE`, or use `crewai run -f my_custom_trained.pkl`.
|
||||
- You can change the output filename when calling `crewai train` with `-f/--filename`. Absolute paths are supported if you want to save outside the CWD.
|
||||
|
||||
It is important to note that the training process may take some time, depending on the complexity of your agents and will also require your feedback on each iteration.
|
||||
|
||||
112
docs/en/enterprise/features/agent-control-plane/monitoring.mdx
Normal file
@@ -0,0 +1,112 @@
|
||||
---
|
||||
title: "Watch your Automations"
|
||||
description: "Watch fleet health, LLM consumption, and per-automation behavior from the Automations tab."
|
||||
sidebarTitle: "Monitoring"
|
||||
icon: "gauge"
|
||||
mode: "wide"
|
||||
---
|
||||
|
||||
<Info>
|
||||
**ACP (Beta) Docs Navigation**
|
||||
|
||||
- [Overview](/en/enterprise/features/agent-control-plane/overview)
|
||||
- **Monitoring** *(you are here)*
|
||||
- [Rules](/en/enterprise/features/agent-control-plane/rules)
|
||||
</Info>
|
||||
|
||||
## Overview
|
||||
|
||||
The **Automations** tab is the read-only operations view of the [Agent Control Plane](/en/enterprise/features/agent-control-plane/overview). It combines two metric cards, an interactive sankey, and two sub-tables — **Automations** and **Consumption** — that you can search, filter, and sort.
|
||||
|
||||
<Frame>
|
||||

|
||||
</Frame>
|
||||
|
||||
All charts and tables respect the **Last 24 hours / Last Week / Last 30 days** selector at the top right. Deltas compare the selected window against the previous one of the same length.
|
||||
|
||||
<Note>
|
||||
Rows only show data for deployments on **crewAI v1.13 or higher** — older deployments appear in the *"We've detected N other automations that we can't display"* banner under the sankey and contribute zero metrics until they're updated and re-deployed. See [Overview — Requirements](/en/enterprise/features/agent-control-plane/overview#requirements).
|
||||
</Note>
|
||||
|
||||
## Dashboard
|
||||
|
||||
The header of the page has two metric cards and an interactive sankey. Clicking either card switches the sankey between two modes:
|
||||
|
||||
- **Health mode** — `Total Automations → status buckets (Critical / Warning / Healthy)`. Click a bucket to filter the Automations table to just those deployments.
|
||||
- **Consumption mode** — `Model Providers → Automations → Total Cost`. Click a provider to filter the Consumption table to that provider.
|
||||
|
||||
| Card | What it shows |
|
||||
|------|---------------|
|
||||
| **Automations** | `active` automations (and total count), total `errors` in the window, currently `active executions` (and total in the window), with a delta vs the previous period. |
|
||||
| **Consumption** | Total `cost` and `tokens used`, with a cost delta vs the previous period. |
|
||||
|
||||
<Frame>
|
||||

|
||||
</Frame>
|
||||
|
||||
## Automations table
|
||||
|
||||
The **Automations** sub-tab is the per-deployment breakdown of fleet health. Each row is one deployed crew or flow.
|
||||
|
||||
<Frame>
|
||||

|
||||
</Frame>
|
||||
|
||||
| Column | What it shows |
|
||||
|--------|---------------|
|
||||
| **Automation** | Deployment name and any tags assigned to it (e.g. `production`, `financial`). |
|
||||
| **Last execution** | Time since the most recent run. |
|
||||
| **Health Status Breakdown** | Stacked bar of `Critical` / `Warning` / `Healthy` percentages for executions in the window. |
|
||||
| **Executions with Errors** | Total failed executions in the window. |
|
||||
| **PII detection applied** | `Yes` if a per-deployment PII config or a matching [PII rule](/en/enterprise/features/agent-control-plane/rules) is active. |
|
||||
| **Executions** | Total executions in the window. |
|
||||
| **Last updated** | When the deployment was last re-deployed. |
|
||||
| **Crew Version** | The `crewai` version reported by the deployment. An info icon next to versions below `1.13` flags rows that can't contribute metrics. |
|
||||
|
||||
Search by name, filter by `Status` (`Healthy` / `Warning` / `Critical`), and sort by any column header. Click a deployment name to open the **Automation panel** (see below).
|
||||
|
||||
## Consumption table
|
||||
|
||||
The **Consumption** sub-tab is the per-deployment breakdown of LLM spend and token usage.
|
||||
|
||||
<Frame>
|
||||

|
||||
</Frame>
|
||||
|
||||
| Column | What it shows |
|
||||
|--------|---------------|
|
||||
| **Automation** | Deployment name. |
|
||||
| **Last execution** | Time since the most recent run. |
|
||||
| **Tokens used** | One row per LLM provider used by this automation, with the delta vs the previous period. |
|
||||
| **Cost** | Cost per LLM provider, with the delta vs the previous period. |
|
||||
| **Total cost** | Sum across all providers, with the delta. |
|
||||
| **Executions** | Total executions in the window. |
|
||||
| **Last updated** | When the deployment was last re-deployed. |
|
||||
| **Crew Version** | The `crewai` version reported by the deployment. |
|
||||
|
||||
Filter by **LLM provider** and sort by `Cost`, `Executions`, or `Last run`.
|
||||
|
||||
<Info>
|
||||
**Empty cells (`—` or `$0.00`) usually mean the deployment is below crewAI v1.13.** In the screenshot above, *Automation F* (`1.7.0`) and *Automation I* (`1.12.2`) show blanks for tokens and cost — their executions still run, but they don't emit the provider-level telemetry that powers this table. Update and re-deploy these crews to start collecting consumption data.
|
||||
</Info>
|
||||
|
||||
## Related
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Agent Control Plane — Overview" icon="book-open" href="/en/enterprise/features/agent-control-plane/overview">
|
||||
What ACP is, requirements, plan tiers, and RBAC.
|
||||
</Card>
|
||||
<Card title="Agent Control Plane — Rules" icon="shield-check" href="/en/enterprise/features/agent-control-plane/rules">
|
||||
Apply organization-wide PII Redaction rules across many automations.
|
||||
</Card>
|
||||
<Card title="Traces" icon="timeline" href="/en/enterprise/features/traces">
|
||||
Drill into a single execution to see agent reasoning, tool calls, and token usage.
|
||||
</Card>
|
||||
<Card title="Deploy to AMP" icon="rocket" href="/en/enterprise/guides/deploy-to-amp">
|
||||
Deploy a crew on a crewAI version that supports the Agent Control Plane.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
<Card title="Need Help?" icon="headset" href="mailto:support@crewai.com">
|
||||
Contact our support team for help interpreting metrics in the Agent Control Plane.
|
||||
</Card>
|
||||
82
docs/en/enterprise/features/agent-control-plane/overview.mdx
Normal file
@@ -0,0 +1,82 @@
|
||||
---
|
||||
title: Agent Control Plane Overview
|
||||
description: "Single operations hub for live automations — fleet health, LLM consumption, and organization-wide policies in one place."
|
||||
sidebarTitle: Overview
|
||||
icon: "book-open"
|
||||
---
|
||||
|
||||
<Info>
|
||||
**ACP (Beta) Docs Navigation**
|
||||
|
||||
- **Overview** *(you are here)*
|
||||
- [Monitoring](/en/enterprise/features/agent-control-plane/monitoring)
|
||||
- [Rules](/en/enterprise/features/agent-control-plane/rules)
|
||||
</Info>
|
||||
|
||||
## Overview
|
||||
|
||||
The **Agent Control Plane** (ACP) is the operations hub for everything you have running on CrewAI AMP. It is a single screen — split into **Automations** and **Rules** tabs — that lets your team:
|
||||
|
||||
- Monitor the **health** of every live automation (crew or flow), with `Critical` / `Warning` / `Healthy` breakdowns and execution counts.
|
||||
- Track **LLM consumption** — tokens and cost — per automation, per provider, and per model, with a delta vs the previous period.
|
||||
- Drill into any single automation or model provider for time-series charts and per-provider breakdowns.
|
||||
- Apply organization-wide **Rules** (today: PII Redaction) across many automations at once instead of editing each deployment individually.
|
||||
|
||||
<Frame>
|
||||

|
||||
</Frame>
|
||||
|
||||
<Note>
|
||||
The Agent Control Plane is currently labeled **Beta** in CrewAI Platform.
|
||||
</Note>
|
||||
|
||||
The two tabs answer two different questions:
|
||||
|
||||
- **Automations** — *"How is my fleet behaving right now, and what is it costing me?"* See [Monitoring](/en/enterprise/features/agent-control-plane/monitoring).
|
||||
- **Rules** — *"How do I enforce a policy (e.g. PII redaction) across many deployments without re-deploying each one?"* See [Rules](/en/enterprise/features/agent-control-plane/rules).
|
||||
|
||||
## Requirements
|
||||
|
||||
<Warning>
|
||||
**crewAI v1.13 or higher** is required for an automation to populate any data on this page — health, executions, errors, tokens, and cost all flow through telemetry that lit up in `crewai==1.13`. Older deployments appear in the *"We've detected N other automations that we can't display"* banner and contribute zero rows until they are updated and re-deployed.
|
||||
</Warning>
|
||||
|
||||
<Warning>
|
||||
**Enterprise Plan or Ultra Plan** is required to create or edit [Rules](/en/enterprise/features/agent-control-plane/rules). Lower-tier organizations can open the Rules tab and view existing rules, but the editor renders read-only with an "Enterprise" lock pill and the alert *"PII Redaction rules require an Enterprise plan."* Monitoring (the Automations tab) is available on all plans where the feature is enabled.
|
||||
</Warning>
|
||||
|
||||
- The **Agent Control Plane** feature must be enabled for your organization. If you don't see it in the sidebar, ask your account owner to request enablement.
|
||||
- Inside ACP, [RBAC](/en/enterprise/features/rbac) governs access: `read` to view the dashboard and rules, `manage` to create, edit, toggle, or delete rules.
|
||||
- All charts and tables can be scoped to the **Last 24 hours**, **Last Week**, or **Last 30 days** using the time selector at the top right. Deltas (`↑ 8 vs yesterday`, `↓ $20.57 vs yesterday`, etc.) compare the selected window against the previous one of the same length.
|
||||
|
||||
## What you can do here
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Monitoring" icon="gauge" href="/en/enterprise/features/agent-control-plane/monitoring">
|
||||
Watch fleet health and LLM spend with metric cards, an interactive sankey, per-automation tables, and drill-down side panels for any automation or provider.
|
||||
</Card>
|
||||
<Card title="Rules" icon="shield-check" href="/en/enterprise/features/agent-control-plane/rules">
|
||||
Apply organization-wide PII Redaction policies scoped by tools and tags. Changes take effect on the next execution — no re-deploy required.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
## Related
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Traces" icon="timeline" href="/en/enterprise/features/traces">
|
||||
Drill into a single execution to see agent reasoning, tool calls, and token usage.
|
||||
</Card>
|
||||
<Card title="RBAC" icon="users" href="/en/enterprise/features/rbac">
|
||||
Manage who can read the Agent Control Plane and who can edit rules.
|
||||
</Card>
|
||||
<Card title="PII Redaction for Traces" icon="lock" href="/en/enterprise/features/pii-trace-redactions">
|
||||
Entity catalog and per-deployment PII configuration referenced by Rules.
|
||||
</Card>
|
||||
<Card title="Deploy to AMP" icon="rocket" href="/en/enterprise/guides/deploy-to-amp">
|
||||
Deploy a crew on a crewAI version that supports the Agent Control Plane.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
<Card title="Need Help?" icon="headset" href="mailto:support@crewai.com">
|
||||
Contact our support team for help interpreting metrics or designing rules.
|
||||
</Card>
|
||||
122
docs/en/enterprise/features/agent-control-plane/rules.mdx
Normal file
@@ -0,0 +1,122 @@
|
||||
---
|
||||
title: "Set up the Rules"
|
||||
description: "Apply organization-wide policies across many automations from a single place."
|
||||
sidebarTitle: "Rules"
|
||||
icon: "shield-check"
|
||||
mode: "wide"
|
||||
---
|
||||
|
||||
<Info>
|
||||
**ACP (Beta) Docs Navigation**
|
||||
|
||||
- [Overview](/en/enterprise/features/agent-control-plane/overview)
|
||||
- [Monitoring](/en/enterprise/features/agent-control-plane/monitoring)
|
||||
- **Rules** *(you are here)*
|
||||
</Info>
|
||||
|
||||
## Overview
|
||||
|
||||
Rules let you apply policies — today: **PII Redaction** — across many automations at once, instead of configuring each deployment individually. Open the **Rules** tab in the [Agent Control Plane](/en/enterprise/features/agent-control-plane/overview) to manage them.
|
||||
|
||||
<Frame>
|
||||

|
||||
</Frame>
|
||||
|
||||
Each rule card shows the name, description, the **scope** the rule applies to (selected tools and tags), and a count of **engaged automations** — deployments that currently match the scope. The toggle on the right enables or disables the rule without deleting it.
|
||||
|
||||
## Requirements
|
||||
|
||||
<Warning>
|
||||
**Enterprise Plan or Ultra Plan** is required to create or edit PII Redaction rules. Lower-tier organizations can still open the Rules tab and view existing rules, but the editor renders read-only with an "Enterprise" lock pill and the alert *"PII Redaction rules require an Enterprise plan."* — contact your account owner or sales to upgrade.
|
||||
</Warning>
|
||||
|
||||
- The **Agent Control Plane** feature must be enabled for your organization. See [Overview — Requirements](/en/enterprise/features/agent-control-plane/overview#requirements).
|
||||
- The `manage` [RBAC permission](/en/enterprise/features/rbac) on Agent Control Plane is required to create, edit, toggle, or delete rules. The `read` permission is enough to view them.
|
||||
- All rule changes are versioned for auditing.
|
||||
|
||||
## Available rule types
|
||||
|
||||
| Type | What it does |
|
||||
|------|---------------|
|
||||
| **PII Redaction** | Applies PII redaction to executions of every matching automation, using the same entity catalog and custom recognizers documented in [PII Redaction for Traces](/en/enterprise/features/pii-trace-redactions). |
|
||||
|
||||
More rule types will be added over time.
|
||||
|
||||
## Creating a rule
|
||||
|
||||
<Frame>
|
||||
<img src="/images/enterprise/acp-rules-edit-side-panel.png" alt="Rule edit side panel with conditions and PII mask type" width="450" />
|
||||
</Frame>
|
||||
|
||||
<Steps>
|
||||
<Step title="Open the editor">
|
||||
Click **+ Create new** at the top-right of the Rules tab, or **View Details** on an existing rule card.
|
||||
</Step>
|
||||
|
||||
<Step title="Name and describe the rule">
|
||||
Give the rule a clear name (e.g. *Mask PII (CC)*) and a description explaining when it applies. Both show up on the rule card and in the Engaged Automations modal.
|
||||
</Step>
|
||||
|
||||
<Step title="Pick the type">
|
||||
Today only **PII Redaction** is available.
|
||||
</Step>
|
||||
|
||||
<Step title="Set the conditions">
|
||||
Conditions decide which automations the rule engages with. Both are optional and use **set-equality** semantics:
|
||||
|
||||
- **Tools** — only automations whose tool set **exactly matches** the selected tools will engage. Picks from Studio apps, MCPs, OSS tools, and Tool Repository registry tools.
|
||||
- **Automations** — only automations whose tag set **exactly matches** the selected tags will engage.
|
||||
|
||||
Leaving a picker empty means "no filter on this dimension". Leaving both empty means the rule applies to **every** automation in the organization.
|
||||
</Step>
|
||||
|
||||
<Step title="Configure the PII Mask Type table">
|
||||
Check each entity type you want covered and choose **Mask** (replaces with the entity label, e.g. `<CREDIT_CARD>`) or **Redact** (removes the matched text entirely). See [PII Redaction for Traces](/en/enterprise/features/pii-trace-redactions) for the full entity catalog and how to add organization-level custom recognizers.
|
||||
</Step>
|
||||
|
||||
<Step title="Save">
|
||||
The rule applies to **future** executions of every engaged automation as soon as you save. No re-deploy is needed.
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
## Engaged automations
|
||||
|
||||
Click **Engaged N automations** on any rule card to see exactly which deployments the rule is currently matching, along with each one's last execution.
|
||||
|
||||
<Frame>
|
||||

|
||||
</Frame>
|
||||
|
||||
This is the fastest way to sanity-check a rule's scope before enabling it — for example, to confirm that a rule scoped to the `production` tag isn't accidentally matching a staging deployment.
|
||||
|
||||
## Org-wide rules vs per-deployment settings
|
||||
|
||||
PII Redaction can be configured in two places:
|
||||
|
||||
- **Per-deployment** — under **Settings → PII Protection** on each individual deployment ([guide](/en/enterprise/features/pii-trace-redactions))
|
||||
- **Org-wide** — as a Rule on this page
|
||||
|
||||
When an enabled org-wide rule's scope matches a deployment, the rule's entity configuration **overrides** the deployment-owned PII settings for that deployment's executions — the rule becomes the single source of truth while it's attached. Disable or detach the rule (or change its scope so it no longer matches) and the deployment falls back to its own PII Protection settings.
|
||||
|
||||
Prefer org-wide rules when you want to enforce a consistent policy across many deployments; reserve per-deployment configuration for one-off exceptions.
|
||||
|
||||
## Related
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Agent Control Plane — Overview" icon="book-open" href="/en/enterprise/features/agent-control-plane/overview">
|
||||
What ACP is, requirements, plan tiers, and RBAC.
|
||||
</Card>
|
||||
<Card title="Agent Control Plane — Monitoring" icon="gauge" href="/en/enterprise/features/agent-control-plane/monitoring">
|
||||
Monitor automations and LLM consumption across your fleet.
|
||||
</Card>
|
||||
<Card title="PII Redaction for Traces" icon="lock" href="/en/enterprise/features/pii-trace-redactions">
|
||||
Entity catalog, custom recognizers, and per-deployment configuration.
|
||||
</Card>
|
||||
<Card title="RBAC" icon="users" href="/en/enterprise/features/rbac">
|
||||
Manage who can create or edit rules.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
<Card title="Need Help?" icon="headset" href="mailto:support@crewai.com">
|
||||
Contact our support team for help designing rules for your organization.
|
||||
</Card>
|
||||
@@ -26,10 +26,10 @@ Before running this verification:
|
||||
|
||||
## Step 1 — Scaffold a Verification Crew
|
||||
|
||||
Create a new crew project. The CrewAI CLI scaffolds the structure:
|
||||
Create a classic crew project because this example wires a Python tool through `crew.py`:
|
||||
|
||||
```bash
|
||||
crewai create crew rotation_verifier --skip_provider
|
||||
crewai create crew rotation_verifier --classic --skip_provider
|
||||
cd rotation_verifier
|
||||
```
|
||||
|
||||
|
||||
@@ -24,15 +24,39 @@ Telemetry data follows the [OpenTelemetry GenAI semantic conventions](https://op
|
||||
|
||||
1. In CrewAI AMP, go to **Settings** > **OpenTelemetry Collectors**.
|
||||
2. Click **Add Collector**.
|
||||
3. Select an integration type — **OpenTelemetry Traces** or **OpenTelemetry Logs**.
|
||||
4. Configure the connection:
|
||||
- **Endpoint** — Your collector's OTLP endpoint (e.g., `https://otel-collector.example.com:4317`).
|
||||
- **Service Name** — A name to identify this service in your observability platform.
|
||||
- **Custom Headers** *(optional)* — Add authentication or routing headers as key-value pairs.
|
||||
- **Certificate** *(optional)* — Provide a TLS certificate if your collector requires one.
|
||||
5. Click **Save**.
|
||||
3. Select an integration:
|
||||
- **OpenTelemetry Traces** and **OpenTelemetry Logs** — export to any OTLP-compatible collector or backend.
|
||||
- **Datadog** — send traces straight to Datadog's OTLP intake, no separate collector or Datadog Agent required.
|
||||
4. Configure the connection. The fields depend on the integration you selected:
|
||||
|
||||
<Frame></Frame>
|
||||
<Tabs>
|
||||
<Tab title="OpenTelemetry Traces / Logs">
|
||||
**OpenTelemetry Traces** and **OpenTelemetry Logs** are separate integrations that share the same fields — pick the one matching the signal you want to export.
|
||||
|
||||
- **Endpoint** — Your collector's OTLP endpoint (e.g., `https://otel-collector.example.com:4317`).
|
||||
- **Service Name** — A name to identify this service in your observability platform.
|
||||
- **Custom Headers** *(optional)* — Add authentication or routing headers as key-value pairs.
|
||||
- **Certificate** *(optional)* — Provide a TLS certificate if your collector requires one.
|
||||
|
||||
<Frame></Frame>
|
||||
</Tab>
|
||||
<Tab title="Datadog">
|
||||
- **Datadog Site Domain** — Your Datadog site's OTLP host only, with no protocol or path. CrewAI builds the full HTTPS OTLP endpoint for you. Use the host that matches your [Datadog site](https://docs.datadoghq.com/getting_started/site/):
|
||||
- `otlp.datadoghq.com` (US1)
|
||||
- `otlp.us3.datadoghq.com` (US3)
|
||||
- `otlp.us5.datadoghq.com` (US5)
|
||||
- `otlp.datadoghq.eu` (EU1)
|
||||
- `otlp.ap1.datadoghq.com` (AP1)
|
||||
- **API Key** — Your Datadog API key. See [how to create one](https://docs.datadoghq.com/account_management/api-app-keys/#api-keys).
|
||||
|
||||
The Datadog integration exports **traces**.
|
||||
|
||||
<Frame></Frame>
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
5. *(optional)* Click **Test Connection** to verify CrewAI can reach the endpoint with the credentials you provided.
|
||||
6. Click **Save**.
|
||||
|
||||
<Tip>
|
||||
You can add multiple collectors — for example, one for traces and another for logs, or send to different backends for different purposes.
|
||||
|
||||
@@ -164,6 +164,12 @@ You need to push your crew to a GitHub repository. If you haven't created a crew
|
||||

|
||||
</Frame>
|
||||
|
||||
<Tip>
|
||||
If your Crew or Flow is inside a monorepo subfolder, expand **Advanced**
|
||||
and set a working directory before deploying. See
|
||||
[Monorepo Deployments](/en/enterprise/guides/monorepo-deployments).
|
||||
</Tip>
|
||||
|
||||
</Step>
|
||||
|
||||
<Step title="Set Environment Variables">
|
||||
@@ -368,17 +374,17 @@ git push
|
||||
|
||||
**Solution**: Verify your project matches the expected structure:
|
||||
|
||||
- **Both Crews and Flows**: Must have entry point at `src/project_name/main.py`
|
||||
- **Crews**: Use a `run()` function as entry point
|
||||
- **Flows**: Use a `kickoff()` function as entry point
|
||||
- **JSON-first Crews**: Keep `crew.jsonc` or `crew.json` and `agents/` at the project root
|
||||
- **Classic Crews**: Use `src/project_name/main.py` with a `run()` entry point
|
||||
- **Flows**: Use `src/project_name/main.py` with a `kickoff()` entry point
|
||||
|
||||
See [Prepare for Deployment](/en/enterprise/guides/prepare-for-deployment) for detailed structure diagrams.
|
||||
|
||||
#### Missing CrewBase Decorator
|
||||
#### Missing CrewBase Decorator in a Classic Crew
|
||||
|
||||
**Symptom**: "Crew not found", "Config not found", or agent/task configuration errors
|
||||
|
||||
**Solution**: Ensure **all** crew classes use the `@CrewBase` decorator:
|
||||
**Solution**: For classic Python/YAML crews, ensure all crew classes use the `@CrewBase` decorator. JSON-first crews do not need this decorator.
|
||||
|
||||
```python
|
||||
from crewai.project import CrewBase, agent, crew, task
|
||||
@@ -398,8 +404,8 @@ class YourCrew():
|
||||
```
|
||||
|
||||
<Info>
|
||||
This applies to standalone Crews AND crews embedded inside Flow projects.
|
||||
Every crew class needs the decorator.
|
||||
This applies to classic Python crew classes, including classic crews embedded inside Flow projects.
|
||||
JSON-first crews are validated from `crew.jsonc` and `agents/` instead.
|
||||
</Info>
|
||||
|
||||
#### Incorrect pyproject.toml Type
|
||||
@@ -436,8 +442,8 @@ type = "flow"
|
||||
**Solution**:
|
||||
1. Check the execution logs in the AMP dashboard (Traces tab)
|
||||
2. Verify all tools have required API keys configured
|
||||
3. Ensure agent configurations in `agents.yaml` are valid
|
||||
4. Check task configurations in `tasks.yaml` for syntax errors
|
||||
3. For JSON-first crews, validate `crew.jsonc` and the referenced files in `agents/`
|
||||
4. For classic crews, ensure `agents.yaml` and `tasks.yaml` are valid
|
||||
|
||||
<Card title="Need Help?" icon="headset" href="mailto:support@crewai.com">
|
||||
Contact our support team for assistance with deployment issues or questions
|
||||
|
||||
229
docs/en/enterprise/guides/monorepo-deployments.mdx
Normal file
@@ -0,0 +1,229 @@
|
||||
---
|
||||
title: "Monorepo Deployments"
|
||||
description: "Deploy a Crew or Flow from a subfolder in a larger repository"
|
||||
icon: "folder-tree"
|
||||
mode: "wide"
|
||||
---
|
||||
|
||||
<Note>
|
||||
Use a working directory when your Crew or Flow lives inside a larger
|
||||
repository. CrewAI AMP validates, builds, tests, and runs the automation from
|
||||
that subfolder instead of the repository root.
|
||||
</Note>
|
||||
|
||||
## When to Use This
|
||||
|
||||
Monorepo deployments are useful when one repository contains multiple
|
||||
automations, shared packages, or other application code:
|
||||
|
||||
```text
|
||||
company-ai/
|
||||
|-- uv.lock
|
||||
|-- packages/
|
||||
| `-- shared_tools/
|
||||
`-- crews/
|
||||
|-- support_agent/
|
||||
| |-- pyproject.toml
|
||||
| |-- crew.jsonc
|
||||
| `-- agents/
|
||||
| `-- support_agent.jsonc
|
||||
`-- research_flow/
|
||||
|-- pyproject.toml
|
||||
`-- src/
|
||||
`-- research_flow/
|
||||
`-- main.py
|
||||
```
|
||||
|
||||
To deploy `support_agent`, set the working directory to:
|
||||
|
||||
```text
|
||||
crews/support_agent
|
||||
```
|
||||
|
||||
AMP still pulls or uploads the whole repository, but it treats the selected
|
||||
folder as the automation project root.
|
||||
|
||||
## What the Working Directory Controls
|
||||
|
||||
When a working directory is set, AMP uses that folder for:
|
||||
|
||||
- Project validation, including `pyproject.toml`, JSON crew files, and any classic Crew or Flow entry point
|
||||
- Dependency installation with `uv`
|
||||
- The running process working directory
|
||||
- The `CREW_ROOT_DIR` environment variable
|
||||
|
||||
Leaving the field empty keeps the existing behavior and uses the repository
|
||||
root.
|
||||
|
||||
## Supported Sources
|
||||
|
||||
You can set a working directory when creating a deployment from:
|
||||
|
||||
- A connected GitHub repository
|
||||
- A Git repository configured in AMP
|
||||
- A ZIP upload
|
||||
|
||||
<Info>
|
||||
Configure working directories in the AMP web interface. The
|
||||
`crewai deploy create` CLI flow does not prompt for this field.
|
||||
</Info>
|
||||
|
||||
You can also add or change the working directory on an existing deployment from
|
||||
the deployment's **Settings** page. The change takes effect on the next deploy.
|
||||
|
||||
<Warning>
|
||||
Working directories and auto-deploy cannot be used together. If a deployment
|
||||
has a working directory, auto-deploy is disabled for that deployment. Turn
|
||||
auto-deploy off before setting a working directory.
|
||||
</Warning>
|
||||
|
||||
## Configure a New Deployment
|
||||
|
||||
<Steps>
|
||||
<Step title="Open Deploy from Code">
|
||||
In CrewAI AMP, create a new deployment and choose your source: GitHub, Git
|
||||
Repository, or ZIP upload.
|
||||
</Step>
|
||||
|
||||
<Step title="Select the repository, branch, or ZIP file">
|
||||
Choose the repository and branch that contain your monorepo, or upload a ZIP
|
||||
file whose root contains the monorepo contents.
|
||||
</Step>
|
||||
|
||||
<Step title="Open Advanced settings">
|
||||
Expand the **Advanced** section in the deploy form.
|
||||
</Step>
|
||||
|
||||
<Step title="Enter the working directory">
|
||||
Enter the path from the repository root to the Crew or Flow project:
|
||||
|
||||
```text
|
||||
crews/support_agent
|
||||
```
|
||||
|
||||
Do not include a leading slash.
|
||||
</Step>
|
||||
|
||||
<Step title="Deploy">
|
||||
Add any required environment variables, then start the deployment.
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
## Configure an Existing Deployment
|
||||
|
||||
<Steps>
|
||||
<Step title="Open the deployment settings">
|
||||
Go to your automation in AMP and open **Settings**.
|
||||
</Step>
|
||||
|
||||
<Step title="Turn off auto-deploy if needed">
|
||||
If auto-deploy is enabled, disable it first. The working directory field is
|
||||
unavailable while auto-deploy is on.
|
||||
</Step>
|
||||
|
||||
<Step title="Set the working directory">
|
||||
In **Basic settings**, enter the subfolder path, such as:
|
||||
|
||||
```text
|
||||
crews/support_agent
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Redeploy">
|
||||
Save the setting and redeploy the automation. The new working directory is
|
||||
used on the next deploy.
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
## Path Rules
|
||||
|
||||
The working directory must be a relative path inside the repository or ZIP root.
|
||||
|
||||
| Rule | Example |
|
||||
|------|---------|
|
||||
| Use a relative path | `crews/support_agent` |
|
||||
| Do not start with `/` | `/crews/support_agent` is invalid |
|
||||
| Do not use `.` or `..` path segments | `crews/../support_agent` is invalid |
|
||||
| Use only letters, numbers, dashes, underscores, dots, and forward slashes | `crews/support agent` is invalid |
|
||||
| Keep the path at 255 characters or fewer | Longer paths are rejected |
|
||||
|
||||
AMP trims leading and trailing whitespace, collapses repeated slashes, and
|
||||
removes trailing slashes. A blank value uses the repository root.
|
||||
|
||||
## Lock Files and UV Workspaces
|
||||
|
||||
The selected folder must contain the automation's `pyproject.toml` and the
|
||||
project files for its type:
|
||||
|
||||
- JSON-first crew: `crew.jsonc` or `crew.json`, plus `agents/`
|
||||
- Classic crew or Flow: `src/` with the expected Python entry point
|
||||
|
||||
A `uv.lock` or `poetry.lock` file can live either in the selected folder or at
|
||||
the repository root.
|
||||
|
||||
This supports both common lock-file layouts:
|
||||
|
||||
<Tabs>
|
||||
<Tab title="Project lock file">
|
||||
```text
|
||||
company-ai/
|
||||
`-- crews/
|
||||
`-- support_agent/
|
||||
|-- pyproject.toml
|
||||
|-- uv.lock
|
||||
|-- crew.jsonc
|
||||
`-- agents/
|
||||
`-- support_agent.jsonc
|
||||
```
|
||||
</Tab>
|
||||
|
||||
<Tab title="Workspace lock file">
|
||||
```text
|
||||
company-ai/
|
||||
|-- uv.lock
|
||||
|-- packages/
|
||||
| `-- shared_tools/
|
||||
`-- crews/
|
||||
`-- support_agent/
|
||||
|-- pyproject.toml
|
||||
|-- crew.jsonc
|
||||
`-- agents/
|
||||
`-- support_agent.jsonc
|
||||
```
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
<Tip>
|
||||
If your automation imports shared packages from elsewhere in the monorepo,
|
||||
declare those packages in `pyproject.toml` using UV workspace, path, or source
|
||||
configuration. AMP runs the automation from the selected folder, so shared
|
||||
code should be installed as a dependency instead of relying on the repository
|
||||
root being on the Python path.
|
||||
</Tip>
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Working Directory Not Found
|
||||
|
||||
Check that the path is relative to the repository or ZIP root. For ZIP uploads,
|
||||
the ZIP contents must include the working directory path exactly as entered.
|
||||
|
||||
### Missing pyproject.toml
|
||||
|
||||
The working directory should point to the Crew or Flow project folder, not just
|
||||
to a parent folder that contains several projects.
|
||||
|
||||
### Missing uv.lock or poetry.lock
|
||||
|
||||
Commit a lock file either in the selected project folder or in the repository
|
||||
root. For UV workspaces, keeping `uv.lock` at the workspace root is supported.
|
||||
|
||||
### Auto-Deploy Is Unavailable
|
||||
|
||||
Auto-deploy is disabled while a working directory is set. Use manual redeploys
|
||||
or trigger redeployments from CI/CD with the AMP API instead.
|
||||
|
||||
<Card title="Deploy to AMP" icon="rocket" href="/en/enterprise/guides/deploy-to-amp">
|
||||
Continue with the deployment guide after choosing your monorepo working
|
||||
directory.
|
||||
</Card>
|
||||
@@ -24,7 +24,7 @@ Understanding which type you're deploying is essential because they have differe
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Crew Projects" icon="users">
|
||||
Standalone AI agent teams with `crew.py` defining agents and tasks. Best for focused, collaborative tasks.
|
||||
Standalone AI agent teams. New crews are JSON-first with `crew.jsonc` and `agents/`; classic crews can still use `crew.py`.
|
||||
</Card>
|
||||
<Card title="Flow Projects" icon="diagram-project">
|
||||
Orchestrated workflows with embedded crews in a `crews/` folder. Best for complex, multi-stage processes.
|
||||
@@ -33,19 +33,19 @@ Understanding which type you're deploying is essential because they have differe
|
||||
|
||||
| Aspect | Crew | Flow |
|
||||
|--------|------|------|
|
||||
| **Project structure** | `src/project_name/` with `crew.py` | `src/project_name/` with `crews/` folder |
|
||||
| **Main logic location** | `src/project_name/crew.py` | `src/project_name/main.py` (Flow class) |
|
||||
| **Entry point function** | `run()` in `main.py` | `kickoff()` in `main.py` |
|
||||
| **Project structure** | Project root with `crew.jsonc` and `agents/` | `src/project_name/` with `crews/` folder |
|
||||
| **Main logic location** | `crew.jsonc` (classic: `src/project_name/crew.py`) | `src/project_name/main.py` (Flow class) |
|
||||
| **Entry point function** | Loaded from `crew.jsonc` (classic: `run()` in `main.py`) | `kickoff()` in `main.py` |
|
||||
| **pyproject.toml type** | `type = "crew"` | `type = "flow"` |
|
||||
| **CLI create command** | `crewai create crew name` | `crewai create flow name` |
|
||||
| **Config location** | `src/project_name/config/` | `src/project_name/crews/crew_name/config/` |
|
||||
| **Config location** | `crew.jsonc`, `agents/`, optional `tools/` | `src/project_name/crews/crew_name/config/` or embedded JSON crew folders |
|
||||
| **Can contain other crews** | No | Yes (in `crews/` folder) |
|
||||
|
||||
## Project Structure Reference
|
||||
|
||||
### Crew Project Structure
|
||||
|
||||
When you run `crewai create crew my_crew`, you get this structure:
|
||||
When you run `crewai create crew my_crew`, you get the JSON-first structure:
|
||||
|
||||
```
|
||||
my_crew/
|
||||
@@ -54,24 +54,27 @@ my_crew/
|
||||
├── README.md
|
||||
├── .env
|
||||
├── uv.lock # REQUIRED for deployment
|
||||
└── src/
|
||||
└── my_crew/
|
||||
├── __init__.py
|
||||
├── main.py # Entry point with run() function
|
||||
├── crew.py # Crew class with @CrewBase decorator
|
||||
├── tools/
|
||||
│ ├── custom_tool.py
|
||||
│ └── __init__.py
|
||||
└── config/
|
||||
├── agents.yaml # Agent definitions
|
||||
└── tasks.yaml # Task definitions
|
||||
├── crew.jsonc # Crew settings, tasks, process, inputs
|
||||
├── agents/
|
||||
│ └── researcher.jsonc # Agent definitions
|
||||
├── tools/ # Optional custom:<name> tools
|
||||
├── knowledge/
|
||||
└── skills/
|
||||
```
|
||||
|
||||
<Warning>
|
||||
The nested `src/project_name/` structure is critical for Crews.
|
||||
Placing files at the wrong level will cause deployment failures.
|
||||
For JSON-first crews, keep `crew.jsonc`, `agents/`, `tools/`, `knowledge/`, and `skills/`
|
||||
at the project root. Placing them under `src/` will prevent `crewai run` and deployment
|
||||
validation from finding the crew definition.
|
||||
</Warning>
|
||||
|
||||
<Info>
|
||||
Classic projects created with `crewai create crew my_crew --classic` use the older
|
||||
`src/project_name/crew.py`, `src/project_name/config/agents.yaml`, and
|
||||
`src/project_name/config/tasks.yaml` layout. That layout remains supported for
|
||||
decorator-based Python crews.
|
||||
</Info>
|
||||
|
||||
### Flow Project Structure
|
||||
|
||||
When you run `crewai create flow my_flow`, you get this structure:
|
||||
@@ -100,9 +103,9 @@ my_flow/
|
||||
```
|
||||
|
||||
<Info>
|
||||
Both Crews and Flows use the `src/project_name/` structure.
|
||||
The key difference is that Flows have a `crews/` folder for embedded crews,
|
||||
while Crews have `crew.py` directly in the project folder.
|
||||
JSON-first standalone crews use project-root JSON files. Flows still use
|
||||
`src/project_name/` and can contain either classic embedded crews or embedded
|
||||
JSON crew folders loaded with `crewai.project.load_crew`.
|
||||
</Info>
|
||||
|
||||
## Pre-Deployment Checklist
|
||||
@@ -154,60 +157,91 @@ git commit -m "Add uv.lock for deployment"
|
||||
git push
|
||||
```
|
||||
|
||||
### 3. Validate CrewBase Decorator Usage
|
||||
### 3. Validate the Crew Definition
|
||||
|
||||
**Every crew class must use the `@CrewBase` decorator.** This applies to:
|
||||
<Tabs>
|
||||
<Tab title="JSON-first Crews">
|
||||
JSON-first crews must have a `crew.jsonc` or `crew.json` file at the project root.
|
||||
The `agents` array must reference files in `agents/`, and each task should reference
|
||||
a valid agent name.
|
||||
|
||||
- Standalone crew projects
|
||||
- Crews embedded inside Flow projects
|
||||
```jsonc crew.jsonc
|
||||
{
|
||||
"name": "Research Crew",
|
||||
"agents": ["researcher"],
|
||||
"tasks": [
|
||||
{
|
||||
"name": "research_task",
|
||||
"description": "Research {topic}.",
|
||||
"expected_output": "A concise report.",
|
||||
"agent": "researcher"
|
||||
}
|
||||
],
|
||||
"inputs": {
|
||||
"topic": "AI Agents"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```python
|
||||
from crewai import Agent, Crew, Process, Task
|
||||
from crewai.project import CrewBase, agent, crew, task
|
||||
from crewai.agents.agent_builder.base_agent import BaseAgent
|
||||
from typing import List
|
||||
Custom tools are referenced as `"custom:<name>"` and must be implemented in
|
||||
`tools/<name>.py` with a `BaseTool` subclass.
|
||||
</Tab>
|
||||
<Tab title="Classic Python/YAML Crews">
|
||||
Classic crews and Python crews embedded in Flows must use the `@CrewBase` decorator.
|
||||
|
||||
@CrewBase # This decorator is REQUIRED
|
||||
class MyCrew():
|
||||
"""My crew description"""
|
||||
```python
|
||||
from crewai import Agent, Crew, Process, Task
|
||||
from crewai.project import CrewBase, agent, crew, task
|
||||
from crewai.agents.agent_builder.base_agent import BaseAgent
|
||||
from typing import List
|
||||
|
||||
agents: List[BaseAgent]
|
||||
tasks: List[Task]
|
||||
@CrewBase
|
||||
class MyCrew():
|
||||
"""My crew description"""
|
||||
|
||||
@agent
|
||||
def my_agent(self) -> Agent:
|
||||
return Agent(
|
||||
config=self.agents_config['my_agent'], # type: ignore[index]
|
||||
verbose=True
|
||||
)
|
||||
agents: List[BaseAgent]
|
||||
tasks: List[Task]
|
||||
|
||||
@task
|
||||
def my_task(self) -> Task:
|
||||
return Task(
|
||||
config=self.tasks_config['my_task'] # type: ignore[index]
|
||||
)
|
||||
@agent
|
||||
def my_agent(self) -> Agent:
|
||||
return Agent(
|
||||
config=self.agents_config['my_agent'], # type: ignore[index]
|
||||
verbose=True
|
||||
)
|
||||
|
||||
@crew
|
||||
def crew(self) -> Crew:
|
||||
return Crew(
|
||||
agents=self.agents,
|
||||
tasks=self.tasks,
|
||||
process=Process.sequential,
|
||||
verbose=True,
|
||||
)
|
||||
```
|
||||
@task
|
||||
def my_task(self) -> Task:
|
||||
return Task(
|
||||
config=self.tasks_config['my_task'] # type: ignore[index]
|
||||
)
|
||||
|
||||
<Warning>
|
||||
If you forget the `@CrewBase` decorator, your deployment will fail with
|
||||
errors about missing agents or tasks configurations.
|
||||
</Warning>
|
||||
@crew
|
||||
def crew(self) -> Crew:
|
||||
return Crew(
|
||||
agents=self.agents,
|
||||
tasks=self.tasks,
|
||||
process=Process.sequential,
|
||||
verbose=True,
|
||||
)
|
||||
```
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
### 4. Check Project Entry Points
|
||||
|
||||
Both Crews and Flows have their entry point in `src/project_name/main.py`:
|
||||
JSON-first standalone crews do not need a hand-written `src/project_name/main.py`; `crewai run`
|
||||
and deployment packaging load `crew.jsonc` directly. Classic crews and Flows use Python entry
|
||||
points:
|
||||
|
||||
<Tabs>
|
||||
<Tab title="For Crews">
|
||||
<Tab title="JSON-first Crews">
|
||||
Run locally from the project root:
|
||||
|
||||
```bash
|
||||
crewai run
|
||||
```
|
||||
</Tab>
|
||||
<Tab title="Classic Crews">
|
||||
The entry point uses a `run()` function:
|
||||
|
||||
```python
|
||||
@@ -278,16 +312,17 @@ grep -A2 "\[tool.crewai\]" pyproject.toml
|
||||
# 2. Verify uv.lock exists
|
||||
ls -la uv.lock || echo "ERROR: uv.lock missing! Run 'uv lock'"
|
||||
|
||||
# 3. Verify src/ structure exists
|
||||
ls -la src/*/main.py 2>/dev/null || echo "No main.py found in src/"
|
||||
# 3. For JSON-first crews, verify crew.jsonc and agents/ exist
|
||||
([ -f crew.jsonc ] || [ -f crew.json ]) || echo "No crew.jsonc or crew.json found"
|
||||
test -d agents || echo "No agents/ directory found"
|
||||
|
||||
# 4. For Crews - verify crew.py exists
|
||||
# 4. For classic Crews - verify crew.py exists
|
||||
ls -la src/*/crew.py 2>/dev/null || echo "No crew.py (expected for Crews)"
|
||||
|
||||
# 5. For Flows - verify crews/ folder exists
|
||||
ls -la src/*/crews/ 2>/dev/null || echo "No crews/ folder (expected for Flows)"
|
||||
|
||||
# 6. Check for CrewBase usage
|
||||
# 6. For classic Python crews - check for CrewBase usage
|
||||
grep -r "@CrewBase" . --include="*.py"
|
||||
```
|
||||
|
||||
@@ -297,8 +332,9 @@ grep -r "@CrewBase" . --include="*.py"
|
||||
|---------|---------|-----|
|
||||
| Missing `uv.lock` | Build fails during dependency resolution | Run `uv lock` and commit |
|
||||
| Wrong `type` in pyproject.toml | Build succeeds but runtime fails | Change to correct type |
|
||||
| Missing `@CrewBase` decorator | "Config not found" errors | Add decorator to all crew classes |
|
||||
| Files at root instead of `src/` | Entry point not found | Move to `src/project_name/` |
|
||||
| Missing `crew.jsonc` or `agents/` in a JSON-first crew | Crew definition not found | Keep `crew.jsonc` and `agents/` at the project root |
|
||||
| Missing `@CrewBase` decorator in a classic crew | "Config not found" errors | Add decorator to all classic crew classes |
|
||||
| Classic files at root instead of `src/` | Entry point not found | Move classic Python files to `src/project_name/` |
|
||||
| Missing `run()` or `kickoff()` | Cannot start automation | Add correct entry function |
|
||||
|
||||
## Next Steps
|
||||
|
||||
123
docs/en/enterprise/integrations/databricks.mdx
Normal file
@@ -0,0 +1,123 @@
|
||||
---
|
||||
title: Databricks Integration
|
||||
description: "Connect CrewAI agents to Databricks Genie, SQL, Unity Catalog Functions, and Vector Search through Databricks managed MCP servers."
|
||||
icon: "layer-group"
|
||||
mode: "wide"
|
||||
---
|
||||
|
||||
## Overview
|
||||
|
||||
Connect your CrewAI agents directly to your Databricks workspace through [Databricks managed MCP servers](https://docs.databricks.com/aws/en/generative-ai/mcp/managed-mcp). The Databricks integration lets your agents ask natural-language questions with **Genie**, run governed **SQL**, call **Unity Catalog Functions**, and retrieve documents with **Vector Search** — all without writing or hosting any connector code, and with Unity Catalog permissions enforced on every call.
|
||||
|
||||
Under the hood, the Databricks integration is a managed wrapper around CrewAI's [Custom MCP Server](/en/enterprise/guides/custom-mcp-server) support. Databricks exposes each capability as its own [Model Context Protocol](https://modelcontextprotocol.io/) endpoint, and CrewAI connects to them securely on your behalf. Because each server is added separately, you can enable exactly the capabilities your crews need.
|
||||
|
||||
## Key Capabilities
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Genie" icon="comments">
|
||||
Ask questions in plain language and get grounded answers from your data with [Genie](https://docs.databricks.com/aws/en/genie/), which queries Genie Spaces and Unity Catalog and links back to the Databricks UI.
|
||||
</Card>
|
||||
<Card title="Databricks SQL" icon="database">
|
||||
Run governed SQL against your Databricks warehouses to query, transform, and author data pipelines directly from your agents.
|
||||
</Card>
|
||||
<Card title="Unity Catalog Functions" icon="function">
|
||||
Invoke [Unity Catalog functions](https://docs.databricks.com/aws/en/udf/unity-catalog) to run predefined SQL and custom business logic as governed, reusable tools.
|
||||
</Card>
|
||||
<Card title="Vector Search" icon="magnifying-glass">
|
||||
Retrieve relevant documents for RAG and knowledge workflows from [Mosaic AI Vector Search](https://docs.databricks.com/aws/en/generative-ai/vector-search) indexes using semantic similarity.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
Every server runs behind the Unity AI Gateway and enforces Unity Catalog access controls, so your agents only ever see the data and tools they're permitted to use.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
Before using the Databricks integration, ensure you have:
|
||||
|
||||
- A [CrewAI AMP](https://app.crewai.com) account with an active subscription
|
||||
- A Databricks workspace with the capabilities you want to expose (Genie Spaces, SQL warehouses, Unity Catalog functions, or Vector Search indexes)
|
||||
- Appropriate [Unity Catalog privileges](https://docs.databricks.com/aws/en/data-governance/unity-catalog) on the underlying objects
|
||||
- Your Databricks workspace hostname (e.g. `your-workspace.cloud.databricks.com`)
|
||||
|
||||
## Databricks Managed MCP Servers
|
||||
|
||||
Databricks publishes a separate managed MCP server for each capability. CrewAI exposes these as individual connections, each configured with your workspace host and the relevant Unity Catalog identifiers. The endpoints follow these patterns:
|
||||
|
||||
| Server | What it does | MCP URL pattern |
|
||||
|--------|--------------|-----------------|
|
||||
| **Genie** | Natural-language Q&A over a Genie Space | `https://<workspace-hostname>/api/2.0/mcp/genie/{genie_space_id}` |
|
||||
| **Databricks SQL** | Execute SQL against your warehouses | `https://<workspace-hostname>/api/2.0/mcp/sql` |
|
||||
| **Unity Catalog Functions** | Run registered UC functions | `https://<workspace-hostname>/api/2.0/mcp/functions/{catalog}/{schema}` |
|
||||
| **Vector Search** | Query a Vector Search index | `https://<workspace-hostname>/api/2.0/mcp/vector-search/{catalog}/{schema}` |
|
||||
|
||||
<Note>
|
||||
You don't construct these URLs by hand — CrewAI builds each endpoint from the workspace host and identifiers (Genie Space ID, or catalog/schema) you provide when configuring the connection. For the full specification and the latest endpoint details, see the [Databricks managed MCP documentation](https://docs.databricks.com/aws/en/generative-ai/mcp/managed-mcp).
|
||||
</Note>
|
||||
|
||||
## Connecting Databricks in CrewAI AMP
|
||||
|
||||
<Frame>
|
||||
<img src="/images/enterprise/databricks-configure.png" alt="Configure a Databricks managed MCP server in CrewAI AMP" />
|
||||
</Frame>
|
||||
|
||||
Each Databricks capability — **Databricks Genie**, **Databricks SQL**, **Databricks Unity Catalog Functions**, and **Databricks Vector Search** — appears as its own MCP server under the Databricks group on the **Tools & Integrations** page. Configure the ones you need:
|
||||
|
||||
<Steps>
|
||||
<Step title="Open Tools & Integrations">
|
||||
Navigate to **Tools & Integrations** in the left sidebar of CrewAI AMP and locate the **Databricks** group in the Connections list. You'll see the Genie, SQL, Unity Catalog Functions, and Vector Search servers listed beneath it.
|
||||
</Step>
|
||||
|
||||
<Step title="Configure a server">
|
||||
Click **Configure** next to the capability you want to enable and provide its connection details:
|
||||
|
||||
- **Workspace Host** — your Databricks workspace hostname (e.g. `my-workspace.cloud.databricks.com`).
|
||||
- **Genie** — the **Genie Space ID** to query.
|
||||
- **Unity Catalog Functions** — the **catalog** and **schema** that contain your functions.
|
||||
- **Vector Search** — the **catalog** and **schema** that contain your index.
|
||||
- **Databricks SQL** — no additional identifiers; queries run against your workspace's SQL warehouses.
|
||||
</Step>
|
||||
|
||||
<Step title="Choose an authentication method">
|
||||
Select how CrewAI authenticates to Databricks. **OAuth** is recommended.
|
||||
|
||||
- **Use OAuth** — Connect securely using OAuth 2.0. Each user authenticates individually, and Databricks issues tokens scoped to the capability (`genie`, `sql`, `unity-catalog`, or `vector-search`). CrewAI handles the authorization flow and refreshes tokens automatically.
|
||||
- **Use personal access token** — Authenticate with a [Databricks personal access token](https://docs.databricks.com/aws/en/dev-tools/auth/pat). Use a least-privileged identity to limit exposure.
|
||||
</Step>
|
||||
|
||||
<Step title="Authenticate">
|
||||
Complete authentication. Once connected, the server's tools become available to your crews. Repeat for any other Databricks capabilities you want to enable.
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
<Tip>
|
||||
Because each capability is a separate connection, you can mix and match — for example, enable Genie and Vector Search for a research crew while reserving SQL and Unity Catalog Functions for a data-engineering crew. Visibility settings let you control which team members can use each one.
|
||||
</Tip>
|
||||
|
||||
## Using Databricks Tools in Your Crews
|
||||
|
||||
Once connected, the tools each MCP server exposes appear alongside built-in connections on the **Tools & Integrations** page. You can:
|
||||
|
||||
- **Assign tools to agents** in your crews just like any other CrewAI tool.
|
||||
- **Manage visibility** to control which team members can use each connection.
|
||||
- **Edit or remove** any connection at any time from the Connections list.
|
||||
|
||||
Your agents can now ask Genie for grounded answers, run SQL against your warehouses, call Unity Catalog functions, and search Vector Search indexes — with results flowing back into their reasoning automatically.
|
||||
|
||||
<Warning>
|
||||
Databricks enforces governance through Unity Catalog and the Unity AI Gateway: a user can only discover and invoke tools their workspace identity is permitted to use. If a tool call fails, confirm the connecting user (or token identity) has the required Unity Catalog privileges on the Genie Space, warehouse, function, or index. Some Genie and SQL queries run asynchronously and may take a moment to return results.
|
||||
</Warning>
|
||||
|
||||
## Learn More
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Databricks Managed MCP Servers" icon="layer-group" href="https://docs.databricks.com/aws/en/generative-ai/mcp/managed-mcp">
|
||||
Official Databricks documentation for the managed Genie, SQL, Unity Catalog Functions, and Vector Search MCP servers.
|
||||
</Card>
|
||||
<Card title="Custom MCP Servers in CrewAI" icon="plug" href="/en/enterprise/guides/custom-mcp-server">
|
||||
Learn how CrewAI connects to any MCP server, the foundation the Databricks integration builds on.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
<Card title="Need Help?" icon="headset" href="mailto:support@crewai.com">
|
||||
Contact our support team for assistance with the Databricks integration or troubleshooting.
|
||||
</Card>
|
||||
@@ -17,15 +17,61 @@ Before using the Salesforce integration, ensure you have:
|
||||
- A Salesforce account with appropriate permissions
|
||||
- Connected your Salesforce account through the [Integrations page](https://app.crewai.com/integrations)
|
||||
|
||||
<Note>
|
||||
Salesforce requires a **one-time admin install** of the CrewAI package in
|
||||
your org before any user can connect. This is a Salesforce platform
|
||||
requirement for all ExternalClientApp-based integrations as of the Spring
|
||||
'26 release — not a CrewAI-specific step. The Connect Salesforce flow in
|
||||
CrewAI AMP walks you through it the first time.
|
||||
</Note>
|
||||
|
||||
## Setting Up Salesforce Integration
|
||||
|
||||
### 1. Connect Your Salesforce Account
|
||||
|
||||
1. Navigate to [CrewAI AMP Integrations](https://app.crewai.com/crewai_plus/connectors)
|
||||
2. Find **Salesforce** in the Authentication Integrations section
|
||||
3. Click **Connect** and complete the OAuth flow
|
||||
4. Grant the necessary permissions for CRM and sales management
|
||||
5. Copy your Enterprise Token from [Integration Settings](https://app.crewai.com/crewai_plus/settings/integrations)
|
||||
1. Navigate to [CrewAI AMP Integrations](https://app.crewai.com/crewai_plus/unified_tools).
|
||||
2. Find **Salesforce** in the Authentication Integrations section.
|
||||
3. Click **Connect**.
|
||||
|
||||
What happens next depends on whether a Salesforce admin in your org has
|
||||
already installed the CrewAI package:
|
||||
|
||||
- **Package already installed:** you're taken straight to the Salesforce
|
||||
OAuth consent screen — approve it and you're connected.
|
||||
- **Package not installed yet:** you'll see an **Install CrewAI in
|
||||
Salesforce** page. Follow the one-time install steps below, then come
|
||||
back to CrewAI AMP and click **Connect** again.
|
||||
|
||||
4. Grant the necessary permissions for CRM and sales management.
|
||||
5. Copy your Enterprise Token from [Integration Settings](https://app.crewai.com/crewai_plus/settings/integrations).
|
||||
|
||||
#### One-time admin install (Salesforce admin only)
|
||||
|
||||
The first time anyone in your org clicks **Connect Salesforce**, CrewAI
|
||||
redirects them to an install page that points at the CrewAI managed package.
|
||||
A Salesforce admin needs to install it once for the whole org.
|
||||
|
||||
1. On the install page in CrewAI, click **Install in Salesforce**. (You can
|
||||
also share the page URL with your admin — the install link works for
|
||||
anyone who opens it.)
|
||||
2. Sign in to Salesforce as an admin. For sandboxes, swap `login.salesforce.com`
|
||||
for `test.salesforce.com` in the URL before opening it.
|
||||
3. Choose **Install for All Users**, acknowledge the third-party app prompt,
|
||||
and click **Install**.
|
||||
4. In Salesforce Setup, search **External Client App Manager** → **CrewAI
|
||||
App** → open the **Policies** tab → **Edit** and set:
|
||||
- **Permitted Users:** All users may self-authorize
|
||||
- **IP Relaxation:** Relax IP restrictions
|
||||
- **Refresh Token Policy:** Refresh token is valid until revoked
|
||||
5. Save.
|
||||
6. Return to CrewAI AMP and click **Connect Salesforce** again. OAuth will
|
||||
complete this time.
|
||||
|
||||
<Note>
|
||||
**Not a Salesforce admin?** Forward the install page URL (or the install
|
||||
link itself) to your Salesforce admin and ask them to complete the steps
|
||||
above. Once they're done, return to CrewAI AMP and click **Connect** again.
|
||||
</Note>
|
||||
|
||||
### 2. Install Required Package
|
||||
|
||||
|
||||
134
docs/en/enterprise/integrations/snowflake.mdx
Normal file
@@ -0,0 +1,134 @@
|
||||
---
|
||||
title: Snowflake Integration
|
||||
description: "Connect CrewAI agents to Snowflake Cortex Analyst, Cortex Search, and SQL execution through the Snowflake-managed MCP server."
|
||||
icon: "snowflake"
|
||||
mode: "wide"
|
||||
---
|
||||
|
||||
## Overview
|
||||
|
||||
Connect your CrewAI agents directly to your Snowflake data through the [Snowflake-managed MCP server](https://docs.snowflake.com/en/user-guide/snowflake-cortex/cortex-agents-mcp). The Snowflake integration lets your agents query structured data with **Cortex Analyst**, search unstructured data with **Cortex Search**, and run governed SQL against your warehouses — all without writing or hosting any connector code.
|
||||
|
||||
Under the hood, the Snowflake integration is a managed wrapper around CrewAI's [Custom MCP Server](/en/enterprise/guides/custom-mcp-server) support. Snowflake exposes its Cortex AI capabilities through a [Model Context Protocol](https://modelcontextprotocol.io/) endpoint, and CrewAI connects to it securely on your behalf. Any tool you expose on the Snowflake side — Cortex Analyst, Cortex Search, SQL execution, Cortex Agents, or your own custom tools — becomes available to your crews.
|
||||
|
||||
## Key Capabilities
|
||||
|
||||
<CardGroup cols={3}>
|
||||
<Card title="Cortex Analyst" icon="chart-bar">
|
||||
Ask questions in natural language and let [Cortex Analyst](https://docs.snowflake.com/en/user-guide/snowflake-cortex/cortex-analyst) generate and run SQL against your **structured** data using rich semantic models.
|
||||
</Card>
|
||||
<Card title="Cortex Search" icon="magnifying-glass">
|
||||
Retrieve relevant **unstructured** data for RAG and knowledge workflows with [Cortex Search](https://docs.snowflake.com/en/user-guide/snowflake-cortex/cortex-search/cortex-search-overview), Snowflake's fully managed search service.
|
||||
</Card>
|
||||
<Card title="SQL Execution" icon="database">
|
||||
Run governed SQL queries directly against your Snowflake warehouses, with configurable read-only mode, timeouts, and warehouse selection.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
Because the integration surfaces whatever tools your MCP server publishes, you can also expose **Cortex Agents** and **custom tools** (user-defined functions and stored procedures) to your CrewAI agents.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
Before using the Snowflake integration, ensure you have:
|
||||
|
||||
- A [CrewAI AMP](https://app.crewai.com) account with an active subscription
|
||||
- A Snowflake account with access to Cortex AI features
|
||||
- A [Snowflake-managed MCP server](https://docs.snowflake.com/en/user-guide/snowflake-cortex/cortex-agents-mcp) configured with the tools you want to expose
|
||||
- Appropriate Snowflake privileges (USAGE/SELECT) on the MCP server and its underlying objects
|
||||
|
||||
## Setting Up the Snowflake MCP Server
|
||||
|
||||
The Snowflake-managed MCP server runs inside your Snowflake account and defines which tools are available to external clients like CrewAI. Create one with the [`CREATE MCP SERVER`](https://docs.snowflake.com/en/sql-reference/sql/create-mcp-server) command, listing the Cortex Search services, Cortex Analyst semantic views, and SQL tools you want to expose.
|
||||
|
||||
```sql
|
||||
CREATE MCP SERVER my_mcp_server
|
||||
FROM SPECIFICATION $$
|
||||
tools:
|
||||
- name: "sales_analyst"
|
||||
type: "CORTEX_ANALYST"
|
||||
identifier: "MY_DATABASE.MY_SCHEMA.sales_semantic_view"
|
||||
description: "Answer questions about sales metrics"
|
||||
- name: "docs_search"
|
||||
type: "CORTEX_SEARCH_SERVICE_QUERY"
|
||||
identifier: "MY_DATABASE.MY_SCHEMA.support_docs_search"
|
||||
description: "Search internal support documentation"
|
||||
- name: "run_sql"
|
||||
type: "SQL_EXECUTION"
|
||||
description: "Execute read-only SQL queries"
|
||||
$$;
|
||||
```
|
||||
|
||||
<Note>
|
||||
The MCP endpoint follows the format `https://<account_URL>/api/v2/databases/{database}/schemas/{schema}/mcp-servers/{name}`. CrewAI builds this URL automatically from the **Account URL**, **Database**, **Schema**, and **MCP Server Name** you provide when configuring the integration.
|
||||
</Note>
|
||||
|
||||
For the complete specification — including Cortex Agents, custom tools, response-size limits, and governance options — see the [Snowflake-managed MCP server documentation](https://docs.snowflake.com/en/user-guide/snowflake-cortex/cortex-agents-mcp).
|
||||
|
||||
## Connecting Snowflake in CrewAI AMP
|
||||
|
||||
<Frame>
|
||||
<img src="/images/enterprise/snowflake-configure.png" alt="Configure Snowflake integration in CrewAI AMP" />
|
||||
</Frame>
|
||||
|
||||
<Steps>
|
||||
<Step title="Open Tools & Integrations">
|
||||
Navigate to **Tools & Integrations** in the left sidebar of CrewAI AMP, find **Snowflake** in the list of applications, and open its configuration panel.
|
||||
</Step>
|
||||
|
||||
<Step title="Provide connection details">
|
||||
Fill in the connection fields that CrewAI uses to reach your Snowflake MCP server:
|
||||
|
||||
| Field | Required | Description |
|
||||
|-------|----------|-------------|
|
||||
| **Name** | Yes | A descriptive name for this connection (defaults to `Snowflake`). |
|
||||
| **Description** | No | An optional summary of what this connection provides. |
|
||||
| **Account URL** | Yes | Your Snowflake account URL, e.g. `xy12345.us-east-1.snowflakecomputing.com`. |
|
||||
| **Database** | Yes | The database that contains your MCP server (e.g. `MY_DATABASE`). |
|
||||
| **Schema** | Yes | The schema that contains your MCP server (e.g. `MY_SCHEMA`). |
|
||||
| **MCP Server Name** | Yes | The name of the MCP server object you created in Snowflake (e.g. `MY_MCP_SERVER`). |
|
||||
</Step>
|
||||
|
||||
<Step title="Choose an authentication method">
|
||||
Select how CrewAI authenticates to Snowflake. **OAuth** is recommended.
|
||||
|
||||
- **Use OAuth** — Connect securely using OAuth 2.0 for token-based authentication without sharing your credentials. CrewAI handles the full authorization flow and refreshes tokens automatically. Copy the **Redirect URI** shown in the form (`https://oauth.crewai.com/oauth/add`) and register it as an authorized redirect URI in your Snowflake [OAuth security integration](https://docs.snowflake.com/en/user-guide/oauth-custom).
|
||||
- **Use personal access token** — Authenticate using a [programmatic access token](https://docs.snowflake.com/en/user-guide/programmatic-access-tokens) generated from your Snowflake account settings. Assign a least-privileged role to the token to limit exposure.
|
||||
</Step>
|
||||
|
||||
<Step title="Authenticate">
|
||||
Click **Authenticate**. For OAuth, you'll be redirected to Snowflake to authorize access. Once authenticated, the Snowflake server appears in your Connections and its tools become available to your crews.
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
<Tip>
|
||||
With OAuth, each user authenticates individually and queries run with their Snowflake `DEFAULT_ROLE`. Make sure connecting users have a default role and warehouse set (`ALTER USER <username> SET DEFAULT_ROLE = '<role>' DEFAULT_WAREHOUSE = '<warehouse>'`) so Cortex Analyst and SQL tools have compute to run on.
|
||||
</Tip>
|
||||
|
||||
## Using Snowflake Tools in Your Crews
|
||||
|
||||
Once connected, the tools your MCP server exposes appear alongside built-in connections on the **Tools & Integrations** page. You can:
|
||||
|
||||
- **Assign tools to agents** in your crews just like any other CrewAI tool.
|
||||
- **Manage visibility** to control which team members can use the connection.
|
||||
- **Edit or remove** the connection at any time from the Connections list.
|
||||
|
||||
Your agents can now ask Cortex Analyst for metrics, run Cortex Search over your documents, and execute SQL — with results flowing back into their reasoning automatically.
|
||||
|
||||
<Warning>
|
||||
Snowflake enforces governance on the MCP server: role-based access control determines which tools a user can discover and invoke, and limits apply to response size, tool count (max 50 per server), and recursion depth. If a tool call fails, confirm the connecting user's role has the required privileges on the MCP server and its underlying objects.
|
||||
</Warning>
|
||||
|
||||
## Learn More
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Snowflake-managed MCP Server" icon="snowflake" href="https://docs.snowflake.com/en/user-guide/snowflake-cortex/cortex-agents-mcp">
|
||||
Official Snowflake documentation for creating and governing the MCP server.
|
||||
</Card>
|
||||
<Card title="Custom MCP Servers in CrewAI" icon="plug" href="/en/enterprise/guides/custom-mcp-server">
|
||||
Learn how CrewAI connects to any MCP server, the foundation the Snowflake integration builds on.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
<Card title="Need Help?" icon="headset" href="mailto:support@crewai.com">
|
||||
Contact our support team for assistance with the Snowflake integration or troubleshooting.
|
||||
</Card>
|
||||
@@ -161,6 +161,18 @@ crew = Crew(
|
||||
)
|
||||
```
|
||||
|
||||
<Note>
|
||||
`agent.i18n` is maintained only for backward compatibility and is deprecated. For runtime prompt customization, pass `prompt_file` to `Crew`. For programmatic access to prompt slices, use the i18n utility directly:
|
||||
</Note>
|
||||
|
||||
```python
|
||||
from crewai.utilities.i18n import get_i18n
|
||||
|
||||
i18n = get_i18n("custom_prompts.json")
|
||||
format_slice = i18n.slice("format")
|
||||
tool_prompt = i18n.tools("ask_question")
|
||||
```
|
||||
|
||||
#### Option 3: Disable System Prompts for o1 Models
|
||||
```python
|
||||
agent = Agent(
|
||||
@@ -208,6 +220,8 @@ One straightforward approach is to create a JSON file for the prompts you want t
|
||||
|
||||
CrewAI then merges your customizations with the defaults, so you don't have to redefine every prompt. Here's how:
|
||||
|
||||
For code that needs to read prompt slices directly, use `crewai.utilities.i18n.get_i18n()` with the same prompt file instead of reading `agent.i18n`.
|
||||
|
||||
### Example: Basic Prompt Customization
|
||||
|
||||
Create a `custom_prompts.json` file with the prompts you want to modify. Ensure you list all top-level prompts it should contain, not just your changes:
|
||||
|
||||
@@ -43,7 +43,7 @@ CrewAI is AI-native. This page brings together everything an AI coding agent nee
|
||||
|
||||
| Skill | When it runs |
|
||||
|-------|--------------|
|
||||
| `getting-started` | Scaffolding new projects, choosing between `LLM.call()` / `Agent` / `Crew` / `Flow`, wiring `crew.py` / `main.py` |
|
||||
| `getting-started` | Scaffolding new projects, choosing between `LLM.call()` / `Agent` / `Crew` / `Flow`, wiring `crew.jsonc` / `main.py` |
|
||||
| `design-agent` | Configuring agents — role, goal, backstory, tools, LLMs, memory, guardrails |
|
||||
| `design-task` | Writing task descriptions, dependencies, structured output (`output_pydantic`, `output_json`), human review |
|
||||
| `ask-docs` | Querying the live [CrewAI docs MCP server](https://docs.crewai.com/mcp) for up-to-date API details |
|
||||
@@ -64,7 +64,7 @@ CrewAI is AI-native. This page brings together everything an AI coding agent nee
|
||||
<Step title="Your agent gets instant CrewAI expertise">
|
||||
The skill pack teaches your agent:
|
||||
- **Flows** — stateful apps, steps, and crew kickoffs
|
||||
- **Crews & Agents** — YAML-first patterns, roles, tasks, delegation
|
||||
- **Crews & Agents** — JSON-first patterns (`crew.jsonc`, `agents/*.jsonc`), roles, tasks, delegation
|
||||
- **Tools & Integrations** — search, APIs, MCP servers, and common CrewAI tools
|
||||
- **Project layout** — CLI scaffolds and repo conventions
|
||||
- **Up-to-date patterns** — tracks current CrewAI docs and best practices
|
||||
|
||||
@@ -172,7 +172,7 @@ Flows are ideal when:
|
||||
|
||||
```python
|
||||
# Example: Customer Support Flow with structured processing
|
||||
from crewai.flow.flow import Flow, listen, router, start
|
||||
from crewai.flow.flow import Flow, listen, or_, router, start
|
||||
from pydantic import BaseModel
|
||||
from typing import List, Dict
|
||||
|
||||
@@ -238,7 +238,7 @@ class CustomerSupportFlow(Flow[SupportTicketState]):
|
||||
|
||||
# Additional category handlers...
|
||||
|
||||
@listen("billing", "account_access", "technical_issue", "feature_request", "other")
|
||||
@listen(or_("billing", "account_access", "technical_issue", "feature_request", "other"))
|
||||
def resolve_ticket(self, resolution_info):
|
||||
# Final resolution step
|
||||
self.state.resolution = f"Issue resolved: {resolution_info}"
|
||||
|
||||
@@ -1,396 +1,162 @@
|
||||
---
|
||||
title: Build Your First Crew
|
||||
description: Step-by-step tutorial to create a collaborative AI team that works together to solve complex problems.
|
||||
description: Step-by-step tutorial to create a collaborative AI team with JSON-first crew configuration.
|
||||
icon: users-gear
|
||||
mode: "wide"
|
||||
---
|
||||
|
||||
## Unleashing the Power of Collaborative AI
|
||||
## Build a Research Crew
|
||||
|
||||
Imagine having a team of specialized AI agents working together seamlessly to solve complex problems, each contributing their unique skills to achieve a common goal. This is the power of CrewAI - a framework that enables you to create collaborative AI systems that can accomplish tasks far beyond what a single AI could achieve alone.
|
||||
|
||||
In this guide, we'll walk through creating a research crew that will help us research and analyze a topic, then create a comprehensive report. This practical example demonstrates how AI agents can collaborate to accomplish complex tasks, but it's just the beginning of what's possible with CrewAI.
|
||||
|
||||
### What You'll Build and Learn
|
||||
|
||||
By the end of this guide, you'll have:
|
||||
|
||||
1. **Created a specialized AI research team** with distinct roles and responsibilities
|
||||
2. **Orchestrated collaboration** between multiple AI agents
|
||||
3. **Automated a complex workflow** that involves gathering information, analysis, and report generation
|
||||
4. **Built foundational skills** that you can apply to more ambitious projects
|
||||
|
||||
While we're building a simple research crew in this guide, the same patterns and techniques can be applied to create much more sophisticated teams for tasks like:
|
||||
|
||||
- Multi-stage content creation with specialized writers, editors, and fact-checkers
|
||||
- Complex customer service systems with tiered support agents
|
||||
- Autonomous business analysts that gather data, create visualizations, and generate insights
|
||||
- Product development teams that ideate, design, and plan implementation
|
||||
|
||||
Let's get started building your first crew!
|
||||
In this guide, you will create a two-agent research crew that gathers information about a topic and writes a markdown report. New crew projects are JSON-first: agents are defined in `agents/*.jsonc`, tasks and crew settings are defined in `crew.jsonc`, and `crewai run` loads the JSON definition directly.
|
||||
|
||||
### Prerequisites
|
||||
|
||||
Before starting, make sure you have:
|
||||
|
||||
1. Installed CrewAI following the [installation guide](/en/installation)
|
||||
2. Set up your LLM API key in your environment, following the [LLM setup
|
||||
guide](/en/concepts/llms#setting-up-your-llm)
|
||||
3. Basic understanding of Python
|
||||
2. Set up your LLM API key following the [LLM setup guide](/en/concepts/llms#setting-up-your-llm)
|
||||
3. A [Serper.dev](https://serper.dev/) API key if you want the researcher to use web search
|
||||
|
||||
## Step 1: Create a New CrewAI Project
|
||||
|
||||
First, let's create a new CrewAI project using the CLI. This command will set up a complete project structure with all the necessary files, allowing you to focus on defining your agents and their tasks rather than setting up boilerplate code.
|
||||
## Step 1: Create a New Crew
|
||||
|
||||
```bash
|
||||
crewai create crew research_crew
|
||||
cd research_crew
|
||||
```
|
||||
|
||||
This will generate a project with the basic structure needed for your crew. The CLI automatically creates:
|
||||
The CLI creates a JSON-first project:
|
||||
|
||||
- A project directory with the necessary files
|
||||
- Configuration files for agents and tasks
|
||||
- A basic crew implementation
|
||||
- A main script to run the crew
|
||||
|
||||
<Frame caption="CrewAI Framework Overview">
|
||||
<img src="/images/crews.png" alt="CrewAI Framework Overview" />
|
||||
</Frame>
|
||||
|
||||
|
||||
## Step 2: Explore the Project Structure
|
||||
|
||||
Let's take a moment to understand the project structure created by the CLI. CrewAI follows best practices for Python projects, making it easy to maintain and extend your code as your crews become more complex.
|
||||
|
||||
```
|
||||
```text
|
||||
research_crew/
|
||||
├── .gitignore
|
||||
├── .env
|
||||
├── agents/
|
||||
│ └── researcher.jsonc
|
||||
├── crew.jsonc
|
||||
├── knowledge/
|
||||
├── pyproject.toml
|
||||
├── README.md
|
||||
├── .env
|
||||
└── src/
|
||||
└── research_crew/
|
||||
├── __init__.py
|
||||
├── main.py
|
||||
├── crew.py
|
||||
├── tools/
|
||||
│ ├── custom_tool.py
|
||||
│ └── __init__.py
|
||||
└── config/
|
||||
├── agents.yaml
|
||||
└── tasks.yaml
|
||||
├── skills/
|
||||
└── tools/
|
||||
```
|
||||
|
||||
This structure follows best practices for Python projects and makes it easy to organize your code. The separation of configuration files (in YAML) from implementation code (in Python) makes it easy to modify your crew's behavior without changing the underlying code.
|
||||
<Tip>
|
||||
Need the older `crew.py`, `config/agents.yaml`, and `config/tasks.yaml` layout? Create it with `crewai create crew research_crew --classic`.
|
||||
</Tip>
|
||||
|
||||
## Step 3: Configure Your Agents
|
||||
## Step 2: Define Your Agents
|
||||
|
||||
Now comes the fun part - defining your AI agents! In CrewAI, agents are specialized entities with specific roles, goals, and backstories that shape their behavior. Think of them as characters in a play, each with their own personality and purpose.
|
||||
Replace the generated `agents/researcher.jsonc` file and add `agents/analyst.jsonc`. The file names are the names you reference from `crew.jsonc`.
|
||||
|
||||
For our research crew, we'll create two agents:
|
||||
1. A **researcher** who excels at finding and organizing information
|
||||
2. An **analyst** who can interpret research findings and create insightful reports
|
||||
|
||||
Let's modify the `agents.yaml` file to define these specialized agents. Be sure
|
||||
to set `llm` to the provider you are using.
|
||||
|
||||
```yaml
|
||||
# src/research_crew/config/agents.yaml
|
||||
researcher:
|
||||
role: >
|
||||
Senior Research Specialist for {topic}
|
||||
goal: >
|
||||
Find comprehensive and accurate information about {topic}
|
||||
with a focus on recent developments and key insights
|
||||
backstory: >
|
||||
You are an experienced research specialist with a talent for
|
||||
finding relevant information from various sources. You excel at
|
||||
organizing information in a clear and structured manner, making
|
||||
complex topics accessible to others.
|
||||
llm: provider/model-id # e.g. openai/gpt-4o, google/gemini-2.0-flash, anthropic/claude...
|
||||
|
||||
analyst:
|
||||
role: >
|
||||
Data Analyst and Report Writer for {topic}
|
||||
goal: >
|
||||
Analyze research findings and create a comprehensive, well-structured
|
||||
report that presents insights in a clear and engaging way
|
||||
backstory: >
|
||||
You are a skilled analyst with a background in data interpretation
|
||||
and technical writing. You have a talent for identifying patterns
|
||||
and extracting meaningful insights from research data, then
|
||||
communicating those insights effectively through well-crafted reports.
|
||||
llm: provider/model-id # e.g. openai/gpt-4o, google/gemini-2.0-flash, anthropic/claude...
|
||||
```jsonc agents/researcher.jsonc
|
||||
{
|
||||
"role": "Senior Research Specialist for {topic}",
|
||||
"goal": "Find comprehensive and accurate information about {topic}, with a focus on recent developments and key insights.",
|
||||
"backstory": "You are an experienced research specialist who organizes complex information into clear, useful notes.",
|
||||
// Replace with your model, for example "openai/gpt-4o".
|
||||
"llm": "provider/model-id",
|
||||
"tools": ["SerperDevTool"],
|
||||
"settings": {
|
||||
"verbose": true,
|
||||
"allow_delegation": false
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Notice how each agent has a distinct role, goal, and backstory. These elements aren't just descriptive - they actively shape how the agent approaches its tasks. By crafting these carefully, you can create agents with specialized skills and perspectives that complement each other.
|
||||
|
||||
## Step 4: Define Your Tasks
|
||||
|
||||
With our agents defined, we now need to give them specific tasks to perform. Tasks in CrewAI represent the concrete work that agents will perform, with detailed instructions and expected outputs.
|
||||
|
||||
For our research crew, we'll define two main tasks:
|
||||
1. A **research task** for gathering comprehensive information
|
||||
2. An **analysis task** for creating an insightful report
|
||||
|
||||
Let's modify the `tasks.yaml` file:
|
||||
|
||||
```yaml
|
||||
# src/research_crew/config/tasks.yaml
|
||||
research_task:
|
||||
description: >
|
||||
Conduct thorough research on {topic}. Focus on:
|
||||
1. Key concepts and definitions
|
||||
2. Historical development and recent trends
|
||||
3. Major challenges and opportunities
|
||||
4. Notable applications or case studies
|
||||
5. Future outlook and potential developments
|
||||
|
||||
Make sure to organize your findings in a structured format with clear sections.
|
||||
expected_output: >
|
||||
A comprehensive research document with well-organized sections covering
|
||||
all the requested aspects of {topic}. Include specific facts, figures,
|
||||
and examples where relevant.
|
||||
agent: researcher
|
||||
|
||||
analysis_task:
|
||||
description: >
|
||||
Analyze the research findings and create a comprehensive report on {topic}.
|
||||
Your report should:
|
||||
1. Begin with an executive summary
|
||||
2. Include all key information from the research
|
||||
3. Provide insightful analysis of trends and patterns
|
||||
4. Offer recommendations or future considerations
|
||||
5. Be formatted in a professional, easy-to-read style with clear headings
|
||||
expected_output: >
|
||||
A polished, professional report on {topic} that presents the research
|
||||
findings with added analysis and insights. The report should be well-structured
|
||||
with an executive summary, main sections, and conclusion.
|
||||
agent: analyst
|
||||
context:
|
||||
- research_task
|
||||
output_file: output/report.md
|
||||
```jsonc agents/analyst.jsonc
|
||||
{
|
||||
"role": "Report Analyst for {topic}",
|
||||
"goal": "Turn research findings into a clear, well-structured report.",
|
||||
"backstory": "You are a careful analyst with strong technical writing skills and a talent for extracting useful insights.",
|
||||
// Replace with your model, for example "openai/gpt-4o".
|
||||
"llm": "provider/model-id",
|
||||
"settings": {
|
||||
"verbose": true,
|
||||
"allow_delegation": false
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Note the `context` field in the analysis task - this is a powerful feature that allows the analyst to access the output of the research task. This creates a workflow where information flows naturally between agents, just as it would in a human team.
|
||||
Replace `provider/model-id` with the model you use, for example `openai/gpt-4o`, `anthropic/claude-sonnet-4-6`, or `gemini/gemini-2.0-flash-001`.
|
||||
|
||||
## Step 5: Configure Your Crew
|
||||
## Step 3: Define Tasks and Crew Settings
|
||||
|
||||
Now it's time to bring everything together by configuring our crew. The crew is the container that orchestrates how agents work together to complete tasks.
|
||||
Replace `crew.jsonc` with:
|
||||
|
||||
Let's modify the `crew.py` file:
|
||||
|
||||
```python
|
||||
# src/research_crew/crew.py
|
||||
from crewai import Agent, Crew, Process, Task
|
||||
from crewai.project import CrewBase, agent, crew, task
|
||||
from crewai_tools import SerperDevTool
|
||||
from crewai.agents.agent_builder.base_agent import BaseAgent
|
||||
from typing import List
|
||||
|
||||
@CrewBase
|
||||
class ResearchCrew():
|
||||
"""Research crew for comprehensive topic analysis and reporting"""
|
||||
|
||||
agents: List[BaseAgent]
|
||||
tasks: List[Task]
|
||||
|
||||
@agent
|
||||
def researcher(self) -> Agent:
|
||||
return Agent(
|
||||
config=self.agents_config['researcher'], # type: ignore[index]
|
||||
verbose=True,
|
||||
tools=[SerperDevTool()]
|
||||
)
|
||||
|
||||
@agent
|
||||
def analyst(self) -> Agent:
|
||||
return Agent(
|
||||
config=self.agents_config['analyst'], # type: ignore[index]
|
||||
verbose=True
|
||||
)
|
||||
|
||||
@task
|
||||
def research_task(self) -> Task:
|
||||
return Task(
|
||||
config=self.tasks_config['research_task'] # type: ignore[index]
|
||||
)
|
||||
|
||||
@task
|
||||
def analysis_task(self) -> Task:
|
||||
return Task(
|
||||
config=self.tasks_config['analysis_task'], # type: ignore[index]
|
||||
output_file='output/report.md'
|
||||
)
|
||||
|
||||
@crew
|
||||
def crew(self) -> Crew:
|
||||
"""Creates the research crew"""
|
||||
return Crew(
|
||||
agents=self.agents,
|
||||
tasks=self.tasks,
|
||||
process=Process.sequential,
|
||||
verbose=True,
|
||||
)
|
||||
```
|
||||
|
||||
In this code, we're:
|
||||
1. Creating the researcher agent and equipping it with the SerperDevTool to search the web
|
||||
2. Creating the analyst agent
|
||||
3. Setting up the research and analysis tasks
|
||||
4. Configuring the crew to run tasks sequentially (the analyst will wait for the researcher to finish)
|
||||
|
||||
This is where the magic happens - with just a few lines of code, we've defined a collaborative AI system where specialized agents work together in a coordinated process.
|
||||
|
||||
## Step 6: Set Up Your Main Script
|
||||
|
||||
Now, let's set up the main script that will run our crew. This is where we provide the specific topic we want our crew to research.
|
||||
|
||||
```python
|
||||
#!/usr/bin/env python
|
||||
# src/research_crew/main.py
|
||||
import os
|
||||
from research_crew.crew import ResearchCrew
|
||||
|
||||
# Create output directory if it doesn't exist
|
||||
os.makedirs('output', exist_ok=True)
|
||||
|
||||
def run():
|
||||
"""
|
||||
Run the research crew.
|
||||
"""
|
||||
inputs = {
|
||||
'topic': 'Artificial Intelligence in Healthcare'
|
||||
```jsonc crew.jsonc
|
||||
{
|
||||
"name": "Research Crew",
|
||||
"agents": ["researcher", "analyst"],
|
||||
"tasks": [
|
||||
{
|
||||
"name": "research_task",
|
||||
"description": "Conduct thorough research on {topic}. Focus on key concepts, recent developments, major challenges, notable applications, and future outlook.",
|
||||
"expected_output": "A comprehensive research document with organized sections, specific facts, and useful examples about {topic}.",
|
||||
"agent": "researcher"
|
||||
},
|
||||
{
|
||||
"name": "analysis_task",
|
||||
"description": "Analyze the research findings and create a polished report on {topic}. Include an executive summary, key insights, trend analysis, and recommendations.",
|
||||
"expected_output": "A professional markdown report with clear headings, a concise summary, main findings, and recommendations.",
|
||||
"agent": "analyst",
|
||||
"context": ["research_task"],
|
||||
"output_file": "output/report.md",
|
||||
"markdown": true
|
||||
}
|
||||
|
||||
# Create and run the crew
|
||||
result = ResearchCrew().crew().kickoff(inputs=inputs)
|
||||
|
||||
# Print the result
|
||||
print("\n\n=== FINAL REPORT ===\n\n")
|
||||
print(result.raw)
|
||||
|
||||
print("\n\nReport has been saved to output/report.md")
|
||||
|
||||
if __name__ == "__main__":
|
||||
run()
|
||||
],
|
||||
"process": "sequential",
|
||||
"verbose": true,
|
||||
"memory": true,
|
||||
"inputs": {
|
||||
"topic": "Artificial Intelligence in Healthcare"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
This script prepares the environment, specifies our research topic, and kicks off the crew's work. The power of CrewAI is evident in how simple this code is - all the complexity of managing multiple AI agents is handled by the framework.
|
||||
`context` points to prior task names, so the analyst receives the research task output. The `inputs` object provides default values for `{topic}`. If you remove a default, `crewai run` prompts for it.
|
||||
|
||||
## Step 7: Set Up Your Environment Variables
|
||||
## Step 4: Set Environment Variables
|
||||
|
||||
Create a `.env` file in your project root with your API keys:
|
||||
Open `.env` and add the keys your model and tools need:
|
||||
|
||||
```sh
|
||||
SERPER_API_KEY=your_serper_api_key
|
||||
# Add your provider's API key here too.
|
||||
# Add your model provider API key here too.
|
||||
```
|
||||
|
||||
See the [LLM Setup guide](/en/concepts/llms#setting-up-your-llm) for details on configuring your provider of choice. You can get a Serper API key from [Serper.dev](https://serper.dev/).
|
||||
See the [LLM setup guide](/en/concepts/llms#setting-up-your-llm) for provider-specific keys.
|
||||
|
||||
## Step 8: Install Dependencies
|
||||
|
||||
Install the required dependencies using the CrewAI CLI:
|
||||
## Step 5: Install and Run
|
||||
|
||||
```bash
|
||||
crewai install
|
||||
```
|
||||
|
||||
This command will:
|
||||
1. Read the dependencies from your project configuration
|
||||
2. Create a virtual environment if needed
|
||||
3. Install all required packages
|
||||
|
||||
## Step 9: Run Your Crew
|
||||
|
||||
Now for the exciting moment - it's time to run your crew and see AI collaboration in action!
|
||||
|
||||
```bash
|
||||
crewai run
|
||||
```
|
||||
|
||||
When you run this command, you'll see your crew spring to life. The researcher will gather information about the specified topic, and the analyst will then create a comprehensive report based on that research. You'll see the agents' thought processes, actions, and outputs in real-time as they work together to complete their tasks.
|
||||
`crewai run` detects `crew.jsonc`, loads the agents from `agents/`, prompts for missing placeholders, and runs the crew. When the run finishes, open `output/report.md`.
|
||||
|
||||
## Step 10: Review the Output
|
||||
## How It Works
|
||||
|
||||
Once the crew completes its work, you'll find the final report in the `output/report.md` file. The report will include:
|
||||
1. `crew.jsonc` defines the crew, task order, process, memory, and runtime inputs.
|
||||
2. `agents/researcher.jsonc` and `agents/analyst.jsonc` define the agents.
|
||||
3. The researcher runs first.
|
||||
4. The analyst runs second with `context: ["research_task"]`.
|
||||
5. The final task writes `output/report.md`.
|
||||
|
||||
1. An executive summary
|
||||
2. Detailed information about the topic
|
||||
3. Analysis and insights
|
||||
4. Recommendations or future considerations
|
||||
## Extending Your Crew
|
||||
|
||||
Take a moment to appreciate what you've accomplished - you've created a system where multiple AI agents collaborated on a complex task, each contributing their specialized skills to produce a result that's greater than what any single agent could achieve alone.
|
||||
You can add:
|
||||
|
||||
## Exploring Other CLI Commands
|
||||
- More agents by creating new `agents/<name>.jsonc` files and listing them in `crew.jsonc`
|
||||
- More tasks by appending objects to the `tasks` array
|
||||
- Built-in tools by adding tool class names such as `"FileReadTool"` or `"SerperDevTool"`
|
||||
- Custom tools with `"custom:<name>"`, which loads `tools/<name>.py`
|
||||
- Hierarchical execution with `"process": "hierarchical"` and a `manager_llm` or `manager_agent`
|
||||
|
||||
CrewAI offers several other useful CLI commands for working with crews:
|
||||
|
||||
```bash
|
||||
# View all available commands
|
||||
crewai --help
|
||||
|
||||
# Run the crew
|
||||
crewai run
|
||||
|
||||
# Test the crew
|
||||
crewai test
|
||||
|
||||
# Reset crew memories
|
||||
crewai reset-memories
|
||||
|
||||
# Replay from a specific task
|
||||
crewai replay -t <task_id>
|
||||
```
|
||||
|
||||
## The Art of the Possible: Beyond Your First Crew
|
||||
|
||||
What you've built in this guide is just the beginning. The skills and patterns you've learned can be applied to create increasingly sophisticated AI systems. Here are some ways you could extend this basic research crew:
|
||||
|
||||
### Expanding Your Crew
|
||||
|
||||
You could add more specialized agents to your crew:
|
||||
- A **fact-checker** to verify research findings
|
||||
- A **data visualizer** to create charts and graphs
|
||||
- A **domain expert** with specialized knowledge in a particular area
|
||||
- A **critic** to identify weaknesses in the analysis
|
||||
|
||||
### Adding Tools and Capabilities
|
||||
|
||||
You could enhance your agents with additional tools:
|
||||
- Web browsing tools for real-time research
|
||||
- CSV/database tools for data analysis
|
||||
- Code execution tools for data processing
|
||||
- API connections to external services
|
||||
|
||||
### Creating More Complex Workflows
|
||||
|
||||
You could implement more sophisticated processes:
|
||||
- Hierarchical processes where manager agents delegate to worker agents
|
||||
- Iterative processes with feedback loops for refinement
|
||||
- Parallel processes where multiple agents work simultaneously
|
||||
- Dynamic processes that adapt based on intermediate results
|
||||
|
||||
### Applying to Different Domains
|
||||
|
||||
The same patterns can be applied to create crews for:
|
||||
- **Content creation**: Writers, editors, fact-checkers, and designers working together
|
||||
- **Customer service**: Triage agents, specialists, and quality control working together
|
||||
- **Product development**: Researchers, designers, and planners collaborating
|
||||
- **Data analysis**: Data collectors, analysts, and visualization specialists
|
||||
|
||||
## Next Steps
|
||||
|
||||
Now that you've built your first crew, you can:
|
||||
|
||||
1. Experiment with different agent configurations and personalities
|
||||
2. Try more complex task structures and workflows
|
||||
3. Implement custom tools to give your agents new capabilities
|
||||
4. Apply your crew to different topics or problem domains
|
||||
5. Explore [CrewAI Flows](/en/guides/flows/first-flow) for more advanced workflows with procedural programming
|
||||
<Warning>
|
||||
Only run JSON crew projects from sources you trust. `custom:<name>` tools and `{"python": "module.attribute"}` references execute local Python code when the crew loads.
|
||||
</Warning>
|
||||
|
||||
<Check>
|
||||
Congratulations! You've successfully built your first CrewAI crew that can research and analyze any topic you provide. This foundational experience has equipped you with the skills to create increasingly sophisticated AI systems that can tackle complex, multi-stage problems through collaborative intelligence.
|
||||
You now have a working JSON-first crew that researches a topic and writes a report.
|
||||
</Check>
|
||||
|
||||
501
docs/en/guides/flows/conversational-flows.mdx
Normal file
@@ -0,0 +1,501 @@
|
||||
---
|
||||
title: Conversational Flows
|
||||
description: Build multi-turn chat apps with handle_turn per turn, message history, intent routing, tracing, and WebSocket bridges.
|
||||
icon: comments
|
||||
mode: "wide"
|
||||
---
|
||||
|
||||
## Overview
|
||||
|
||||
Conversational apps treat each user line as a **new flow run** with the **same session id**. CrewAI adds helpers for message history, optional intent routing, deferred tracing, UI bridges, and a local `flow.chat()` REPL for conversational flows.
|
||||
|
||||
| Concept | Implementation |
|
||||
|---------|----------------|
|
||||
| Session id | `handle_turn(..., session_id=...)` → `kickoff(inputs={"id": ...})` → `state.id` |
|
||||
| User line | `handle_turn(message)` appends to `state.messages` before the graph runs |
|
||||
| Turn complete | `FlowFinished` for **this run** only; chat continues on the next `handle_turn` |
|
||||
| Full-session trace | `ConversationConfig(defer_trace_finalization=True)` + `finalize_session_traces()` |
|
||||
|
||||
## Turn APIs
|
||||
|
||||
Use **`flow.handle_turn(message, session_id=...)`** for every user message from REST, WebSocket, tests, and custom UIs. Use **`flow.chat()`** when you want a local terminal chat loop for a conversational `Flow`.
|
||||
|
||||
`Flow.kickoff()` does **not** accept `user_message=` or `session_id=` keyword arguments. For conversational flows, `handle_turn()` stores the pending message and calls `kickoff(inputs={"id": session_id})` internally after resetting per-turn execution state.
|
||||
|
||||
| API | Use for |
|
||||
|-----|---------|
|
||||
| `handle_turn(message, session_id=...)` | Ergonomic one-turn wrapper for conversational `Flow` |
|
||||
| `chat()` | Local terminal REPL for conversational `Flow` |
|
||||
| `kickoff(inputs={...})` | Advanced flow execution without conversational turn handling |
|
||||
| `ask()` | Blocking prompt **inside** one step (wizard, clarification) |
|
||||
| `@human_feedback` | Approve/reject **a step output** — not the next chat line |
|
||||
| `ChatSession.handle_turn(...)` | Transport layer over `handle_turn` (SSE / WebSocket) |
|
||||
|
||||
## Quick start
|
||||
|
||||
```python
|
||||
from uuid import uuid4
|
||||
|
||||
from crewai import Flow
|
||||
from crewai.flow import listen
|
||||
from crewai.experimental.conversational import (
|
||||
ConversationConfig,
|
||||
ConversationState,
|
||||
)
|
||||
|
||||
|
||||
@ConversationConfig(defer_trace_finalization=True)
|
||||
class SupportFlow(Flow[ConversationState]):
|
||||
conversational = True
|
||||
|
||||
def route_turn(self, context):
|
||||
message = (self.state.current_user_message or "").lower()
|
||||
if "order" in message:
|
||||
return "order"
|
||||
if "bye" in message or "goodbye" in message:
|
||||
return "goodbye"
|
||||
return "help"
|
||||
|
||||
@listen("order")
|
||||
def handle_order(self):
|
||||
reply = "Your order is on the way."
|
||||
self.append_assistant_message(reply)
|
||||
return reply
|
||||
|
||||
@listen("help")
|
||||
def handle_help(self):
|
||||
reply = "How can I help?"
|
||||
self.append_assistant_message(reply)
|
||||
return reply
|
||||
|
||||
@listen("goodbye")
|
||||
def handle_goodbye(self):
|
||||
reply = "Goodbye!"
|
||||
self.append_assistant_message(reply)
|
||||
return reply
|
||||
|
||||
|
||||
session_id = str(uuid4())
|
||||
flow = SupportFlow()
|
||||
|
||||
try:
|
||||
flow.handle_turn("Where is my order?", session_id=session_id)
|
||||
flow.handle_turn("What about returns?", session_id=session_id)
|
||||
finally:
|
||||
flow.finalize_session_traces() # one trace link for the whole chat
|
||||
```
|
||||
|
||||
## Turn lifecycle
|
||||
|
||||
Each `handle_turn` runs this pipeline:
|
||||
|
||||
1. **Turn setup** — stores the pending user message, resolves the session id, resets per-turn execution tracking, and calls `kickoff(inputs={"id": session_id})`.
|
||||
2. **State restore** — if `inputs["id"]` exists and `@persist` is configured, loads the latest snapshot.
|
||||
3. **`FlowStarted`** — emitted on the first deferred session turn only.
|
||||
4. **Pending turn hydration** — appends the user message to `state.messages`, sets `current_user_message` / `last_user_message`, and optionally classifies when `intents` / `default_intents` + `intent_llm` are set.
|
||||
5. **Graph execution** — `conversation_start` → `route_conversation` → the selected `@listen` handler.
|
||||
6. **End of run** — per-turn `flow_finished` and trace finalization are **skipped** when deferral is enabled; nested `Agent.kickoff()` / crews do not close the parent batch either.
|
||||
|
||||
Handlers should call **`append_assistant_message(reply)`** so the next turn’s `conversation_messages` includes assistant text. The user line is already stored by `handle_turn` — do not append it again in handlers.
|
||||
|
||||
## `ConversationConfig` (class-level defaults)
|
||||
|
||||
Decorate your conversational `Flow` subclass with `ConversationConfig`.
|
||||
|
||||
| Field | Default | Purpose |
|
||||
|-------|---------|---------|
|
||||
| `system_prompt` | Framework default | System message used by the built-in `converse_turn`. |
|
||||
| `llm` | `None` | Conversation LLM used by `converse_turn` and as router fallback. |
|
||||
| `router` | `None` | `RouterConfig` for LLM-driven routing. |
|
||||
| `intent_llm` | `None` | LLM for `intents=` / `default_intents` pre-classification. |
|
||||
| `default_intents` | `None` | Outcome labels for pre-classification. |
|
||||
| `defer_trace_finalization` | `True` | Keep one trace batch open across `handle_turn()` calls. |
|
||||
|
||||
Override pre-classification per turn with `handle_turn(..., intents=..., intent_llm=...)`.
|
||||
|
||||
## Lower-level `ChatState` helpers
|
||||
|
||||
`ChatState`, `ConversationalConfig`, and `crewai.flow.conversation` helpers are still importable for advanced orchestration, tests, or custom wrappers. They do not add `user_message=` or `session_id=` keyword arguments to `Flow.kickoff()`.
|
||||
|
||||
```python
|
||||
from crewai.flow import ChatState
|
||||
|
||||
|
||||
class MyChatState(ChatState):
|
||||
# Inherited: id, messages, last_user_message, last_intent, session_ready
|
||||
research_turn_count: int = 0
|
||||
custom_flag: bool = False
|
||||
```
|
||||
|
||||
| Field | Role |
|
||||
|-------|------|
|
||||
| `id` | Session UUID (same as `inputs["id"]`) |
|
||||
| `messages` | `list` of `{role, content}` for LLM history |
|
||||
| `last_user_message` | Latest user line for this turn |
|
||||
| `last_intent` | Route label after classification (if used) |
|
||||
| `session_ready` | One-time bootstrap flag (permissions, caches, etc.) |
|
||||
|
||||
`ConversationalInputs` is a `TypedDict` for conventional `kickoff(inputs={...})` keys: `id`, `user_message`, `last_intent`.
|
||||
|
||||
## `Flow` conversational API
|
||||
|
||||
### `handle_turn` parameters
|
||||
|
||||
| Parameter | Purpose |
|
||||
|-----------|---------|
|
||||
| `message` | This turn’s text |
|
||||
| `session_id` | Conversation UUID → `inputs["id"]` / `state.id` |
|
||||
| `intents` | Outcome labels for pre-kickoff `classify_intent` |
|
||||
| `intent_llm` | LLM for classification (required with `intents`) |
|
||||
| `**kickoff_kwargs` | Forwarded to `kickoff()` for options like `input_files`, `from_checkpoint`, and `restore_from_state_id` |
|
||||
|
||||
### `kickoff` parameters
|
||||
|
||||
`Flow.kickoff()` accepts `inputs`, `input_files`, `from_checkpoint`, and `restore_from_state_id`. Pass `inputs={"id": session_id}` when you need raw flow execution, but use `handle_turn()` when the call represents a chat message.
|
||||
|
||||
### Instance attributes
|
||||
|
||||
| Attribute | Purpose |
|
||||
|-----------|---------|
|
||||
| `conversational` | Set to `True` to enable the conversational graph and `handle_turn()` |
|
||||
| `defer_trace_finalization` | Instance flag; set automatically from config on `handle_turn()` |
|
||||
| `suppress_flow_events` | Hides console flow panels; **tracing still records** method/flow events |
|
||||
| `stream` | Enable streaming; use with `ChatSession.handle_turn(..., stream=True)` |
|
||||
|
||||
### Methods and properties
|
||||
|
||||
| Name | Description |
|
||||
|------|-------------|
|
||||
| `append_assistant_message(content)` | Append a user-visible assistant reply to `state.messages` |
|
||||
| `append_message(role, content, **extra)` | Lower-level append to `state.messages` |
|
||||
| `conversation_messages` | Read-only history for LLM calls |
|
||||
| `classify_intent(text, outcomes, *, llm, context=None)` | Map text to one outcome (same collapse logic as `@human_feedback`) |
|
||||
| `receive_user_message(text, *, outcomes=None, llm=None)` | Append user message; optionally set `last_intent` |
|
||||
| `finalize_session_traces()` | Emit deferred `flow_finished` and finalize the session trace batch |
|
||||
| `_should_defer_trace_finalization()` | Whether this flow defers per-turn trace finalization |
|
||||
| `input_history` | Audit trail of `ask()` prompts and responses |
|
||||
|
||||
### Module helpers (`crewai.flow.conversation`)
|
||||
|
||||
Importable for tests or custom orchestration:
|
||||
|
||||
| Function | Description |
|
||||
|----------|-------------|
|
||||
| `normalize_kickoff_inputs(inputs, user_message=..., session_id=...)` | Merge conversational kwargs into `inputs` |
|
||||
| `get_conversation_messages(flow)` | Read messages from state or internal buffer |
|
||||
| `append_message(flow, role, content, **extra)` | Same as instance method |
|
||||
| `prepare_conversational_turn(flow, user_message=..., intents=..., intent_llm=..., config=...)` | Lower-level turn hydration for custom wrappers |
|
||||
| `receive_user_message(flow, text, ...)` | Same as instance method |
|
||||
| `set_state_field(flow, name, value)` | Set a field on dict or Pydantic state |
|
||||
| `get_conversational_config(flow)` | Read class `conversational_config` |
|
||||
| `input_history_to_messages(entries)` | Convert `input_history` to LLM message format |
|
||||
|
||||
## Intent routing patterns
|
||||
|
||||
### A. Pre-classify via `ConversationConfig` (simplest)
|
||||
|
||||
Set `default_intents` and `intent_llm`. Each `handle_turn()` runs classification before routing; read `self.state.last_intent` in `route_turn()`.
|
||||
|
||||
### B. Classify inside `route_turn` (richer prompts)
|
||||
|
||||
Set `default_intents=None` so `handle_turn()` only appends the user message. In `route_turn()`, call `classify_intent` with a custom prompt or descriptions:
|
||||
|
||||
```python
|
||||
def route_turn(self, context):
|
||||
intent = self.classify_intent(
|
||||
self._routing_prompt(self.state.current_user_message),
|
||||
("GREETING", "ORDER", "RESEARCH", "GOODBYE"),
|
||||
llm="gpt-4o-mini",
|
||||
)
|
||||
self.state.last_intent = intent
|
||||
return intent
|
||||
```
|
||||
|
||||
Use **`@listen("RESEARCH")`** (or similar) for steps that run `Agent.kickoff()` with tools — not bare `LLM.call()` — when you need web research or multi-step tool use.
|
||||
|
||||
## When the flow finishes but the user keeps chatting
|
||||
|
||||
`FlowFinished` means **this graph run** completed. The conversation continues with another `handle_turn()` and the same `session_id`. `@persist` restores `messages`, flags, and context.
|
||||
|
||||
**Persist pattern:** prefer `@persist` on a **single terminal step** (for example `finalize`) rather than on the whole `Flow` class. Class-level persist saves after every method; `load_state` uses the latest row, which may be a mid-run snapshot (for example right after `bootstrap`) and miss handler updates from the same turn.
|
||||
|
||||
Do **not** use `@human_feedback` for follow-up chat lines unless a human must approve a specific step output before it is shown.
|
||||
|
||||
## Conversational `Flow` (experimental)
|
||||
|
||||
<Warning>
|
||||
**This is an experimental feature.** The conversational `Flow` surface
|
||||
(`conversational = True`, `handle_turn`, `ConversationConfig`,
|
||||
`RouterConfig`, `ConversationState`, the built-in graph + helpers) lives
|
||||
under `crewai.experimental` and may change shape before it graduates.
|
||||
Pin your CrewAI version if you depend on specific behavior, and watch the
|
||||
changelog for breaking updates. Open issues / feedback welcome.
|
||||
</Warning>
|
||||
|
||||
Opt into the conversational chat graph by setting `conversational = True` on a `Flow` subclass. The base `Flow` then ships a built-in `@start` / `@router` / `converse_turn` / `end_conversation` graph, manages `state.messages`, can drive a router LLM, and keeps the trace batch open across turns. You write the **custom routes**; the framework owns the rest.
|
||||
|
||||
Use this when you want a multi-turn chat with a router and per-route handlers without wiring the lifecycle yourself. Use `Flow[ChatState]` (the lower-level pattern above) when you need full control.
|
||||
|
||||
### Quick example
|
||||
|
||||
```python
|
||||
from crewai import Flow
|
||||
from crewai.flow import listen
|
||||
from crewai.experimental.conversational import (
|
||||
ConversationConfig,
|
||||
ConversationState,
|
||||
)
|
||||
|
||||
|
||||
@ConversationConfig(defer_trace_finalization=True)
|
||||
class SupportFlow(Flow[ConversationState]):
|
||||
conversational = True
|
||||
|
||||
def route_turn(self, context: dict) -> str | None:
|
||||
message = (self.state.current_user_message or "").lower()
|
||||
if "search" in message or "news" in message:
|
||||
return "INTERNET_SEARCH"
|
||||
if "docs" in message or "crewai" in message:
|
||||
return "CREWAI_DOCS"
|
||||
return "converse"
|
||||
|
||||
@listen("INTERNET_SEARCH")
|
||||
def handle_internet_search(self) -> str:
|
||||
"""Fresh web research, current news, real-time lookups."""
|
||||
reply = "I would run the web research route here."
|
||||
self.append_assistant_message(reply)
|
||||
return reply
|
||||
|
||||
@listen("CREWAI_DOCS")
|
||||
def handle_crewai_docs(self) -> str:
|
||||
"""Look up the CrewAI documentation for framework/API questions."""
|
||||
reply = "I would look up the CrewAI docs here."
|
||||
self.append_assistant_message(reply)
|
||||
return reply
|
||||
|
||||
|
||||
flow = SupportFlow()
|
||||
try:
|
||||
flow.handle_turn("What can you do?") # routes to converse
|
||||
flow.handle_turn("Search the web for AI news.") # routes to INTERNET_SEARCH
|
||||
flow.handle_turn("Check the CrewAI docs.") # routes to CREWAI_DOCS
|
||||
finally:
|
||||
flow.finalize_session_traces()
|
||||
```
|
||||
|
||||
For a local terminal chat, use `chat()`:
|
||||
|
||||
```python
|
||||
def kickoff() -> None:
|
||||
SupportFlow().chat()
|
||||
```
|
||||
|
||||
`chat()` wraps `handle_turn()` in a REPL, exits on `exit` / `quit`, skips blank lines by default, and calls `finalize_session_traces()` when the session ends.
|
||||
|
||||
### `ConversationConfig`
|
||||
|
||||
Class decorator that attaches per-class chat defaults.
|
||||
|
||||
| Field | Default | Purpose |
|
||||
|-------|---------|---------|
|
||||
| `system_prompt` | `slices.conversational_system_prompt` from i18n | System message used by the built-in `converse_turn`. Pass `""` to opt out entirely. |
|
||||
| `llm` | `None` | Conversation LLM (used by `converse_turn` and as router fallback). |
|
||||
| `router` | `None` | `RouterConfig` for LLM-driven routing. Without it, the flow always falls through to `converse`. |
|
||||
| `answer_from_history_prompt` | Framework default | System message for the optional `answer_from_history` route. |
|
||||
| `answer_from_history_llm` | `None` | Enables the `answer_from_history` short-circuit when set. |
|
||||
| `intent_llm` | `None` | LLM for legacy `intents=`/`default_intents` pre-classification. |
|
||||
| `default_intents` | `None` | Outcome labels for legacy pre-classification. |
|
||||
| `visible_agent_outputs` | `None` | `"all"`, or a list of agent names whose `append_agent_result()` calls should be promoted to public assistant messages. |
|
||||
| `defer_trace_finalization` | `True` | Keep one trace batch open across `handle_turn()` calls. |
|
||||
|
||||
### `RouterConfig` and the auto-built route catalog
|
||||
|
||||
```python
|
||||
from typing import Literal
|
||||
|
||||
from pydantic import BaseModel
|
||||
|
||||
from crewai import LLM
|
||||
from crewai.experimental.conversational import RouterConfig
|
||||
|
||||
|
||||
class MyRoute(BaseModel):
|
||||
intent: Literal["INTERNET_SEARCH", "CREWAI_DOCS", "converse"]
|
||||
|
||||
|
||||
ROUTER_LLM = LLM(model="gpt-4o-mini")
|
||||
|
||||
router_config = RouterConfig(
|
||||
prompt="Optional domain framing (policy, voice, persona).",
|
||||
response_format=MyRoute, # optional; auto-generated otherwise
|
||||
llm=ROUTER_LLM, # falls back to ConversationConfig.llm
|
||||
routes=["INTERNET_SEARCH", "CREWAI_DOCS"], # optional; inferred from listeners
|
||||
route_descriptions={
|
||||
"INTERNET_SEARCH": "Override the docstring for this one route.",
|
||||
},
|
||||
default_intent="converse", # used when LLM call fails or no LLM available
|
||||
fallback_intent="converse", # used when LLM returns an invalid route
|
||||
intent_field="intent",
|
||||
)
|
||||
```
|
||||
|
||||
The router prompt that gets sent to the LLM is built automatically. For each route the framework picks a description with this precedence:
|
||||
|
||||
1. `RouterConfig.route_descriptions[label]` — explicit override.
|
||||
2. `Flow.builtin_route_descriptions[label]` — framework-canned text for `converse`, `end`, `answer_from_history` (phrased for the router LLM).
|
||||
3. First non-empty line of the `@listen(label)` handler's docstring.
|
||||
4. Empty (the route is listed without a description).
|
||||
|
||||
So in practice, **adding a new route is `@listen("X")` + a one-line docstring**:
|
||||
|
||||
```python
|
||||
from crewai.flow import listen
|
||||
|
||||
|
||||
@listen("INTERNET_SEARCH")
|
||||
def handle_internet_search(self) -> str:
|
||||
"""Fresh web research, current news, real-time lookups."""
|
||||
...
|
||||
```
|
||||
|
||||
…and the router LLM sees:
|
||||
|
||||
```
|
||||
Routes:
|
||||
- CREWAI_DOCS: Look up the CrewAI documentation for framework/API questions.
|
||||
- INTERNET_SEARCH: Fresh web research, current news, real-time lookups.
|
||||
- converse: Ordinary chat, follow-ups, summaries, clarifications…
|
||||
- end: User signals the conversation is finished (goodbye, exit, done).
|
||||
```
|
||||
|
||||
`RouterConfig.prompt` is for **domain framing** (assistant persona, business rules, voice). The route catalog is auto-built — don't list routes in `prompt`; they'll drift the moment you add a handler.
|
||||
|
||||
### Built-in routes
|
||||
|
||||
| Route | Handler | Purpose |
|
||||
|-------|---------|---------|
|
||||
| `converse` | `converse_turn` | Default chat handler. Calls `ConversationConfig.llm` with the system prompt + canonical message history. |
|
||||
| `end` | `end_conversation` | Sets `state.ended = True` and emits a terminator reply. |
|
||||
| `answer_from_history` | `answer_from_history_turn` | Optional. Routes here when `ConversationConfig.answer_from_history_llm` is set and the message can be answered from existing history. |
|
||||
|
||||
You can override any of these by defining a same-named handler in your subclass.
|
||||
|
||||
### `handle_turn()` semantics
|
||||
|
||||
`flow.handle_turn(message)` runs one turn:
|
||||
|
||||
1. Resets per-execution tracking (`_completed_methods`, `_method_outputs`) so the graph re-runs — without this, repeated `kickoff` calls on the same flow instance would short-circuit on turn 2+ because `Flow.kickoff_async` treats `inputs={"id": ...}` as a checkpoint restore.
|
||||
2. Appends the user message to `state.messages`, sets `current_user_message` / `last_user_message`. `last_intent` is **preserved from the prior turn** so the router LLM can use it as a signal.
|
||||
3. Runs `conversation_start` → `route_conversation` → the chosen `@listen` handler.
|
||||
4. The router stores its decision in `state.last_intent` (visible to the next turn's router context).
|
||||
5. If your handler returned a string and didn't already call `append_assistant_message`, `handle_turn` appends it for you.
|
||||
|
||||
Call `handle_turn()` for chat messages. Calling `kickoff(inputs={"id": ...})` directly runs the flow graph without applying the conversational turn wrapper.
|
||||
|
||||
### `chat()` for local REPLs
|
||||
|
||||
`flow.chat()` is the batteries-included terminal wrapper around `handle_turn()`:
|
||||
|
||||
```python
|
||||
flow = SupportFlow()
|
||||
flow.chat()
|
||||
```
|
||||
|
||||
It handles the common local loop:
|
||||
|
||||
1. Prompts for a user message.
|
||||
2. Stops on `exit` / `quit`, `EOFError`, or `KeyboardInterrupt`.
|
||||
3. Calls `handle_turn(message, session_id=...)`.
|
||||
4. Prints the assistant result.
|
||||
5. Finalizes deferred session traces in a `finally` block.
|
||||
|
||||
Customize the terminal behavior with injectable I/O:
|
||||
|
||||
```python
|
||||
flow.chat(
|
||||
session_id="demo-session",
|
||||
prompt="You: ",
|
||||
assistant_prefix="Assistant: ",
|
||||
exit_commands=("exit", "quit", "bye"),
|
||||
)
|
||||
```
|
||||
|
||||
For web apps, background workers, tests, and custom transports, keep using `handle_turn()` directly.
|
||||
|
||||
### Custom router behavior
|
||||
|
||||
To run side effects (event bus setup, telemetry) on every routing decision, override `route_turn`:
|
||||
|
||||
```python
|
||||
from typing import Any
|
||||
|
||||
from crewai import Flow
|
||||
from crewai.experimental.conversational import ConversationState
|
||||
|
||||
|
||||
class SupportFlow(Flow[ConversationState]):
|
||||
conversational = True
|
||||
|
||||
def route_turn(self, context: dict[str, Any]) -> str | None:
|
||||
self.event_bus = MyBus(self)
|
||||
return super().route_turn(context)
|
||||
```
|
||||
|
||||
To bypass the LLM router entirely and pick a route programmatically, return a string from `route_turn`; returning `None` falls back to `_route_with_config(...)`.
|
||||
|
||||
### `append_assistant_message` and `append_agent_result`
|
||||
|
||||
Inside a `@listen(label)` handler, choose:
|
||||
|
||||
- `self.append_assistant_message(text)` — adds a user-visible assistant turn to `state.messages`. The next turn's `converse_turn` sees it.
|
||||
- `self.append_agent_result(agent_name, result, visibility="private")` — records a structured event in `state.events` and a thread in `state.agent_threads[agent_name]`. Public visibility also calls `append_assistant_message` for you. Use private results for scratch work that shouldn't pollute the canonical history.
|
||||
|
||||
`ConversationConfig.visible_agent_outputs` can promote specific agents' private results to public globally (`"all"`, or a list of agent names).
|
||||
|
||||
## Tracing across turns
|
||||
|
||||
With `defer_trace_finalization=True` (default in `ConversationConfig`):
|
||||
|
||||
- **One trace batch** for the whole chat session.
|
||||
- **`flow_started`** on the first turn only; **`flow_finished`** once in `finalize_session_traces()`.
|
||||
- **Per-turn** `kickoff` does not print “Trace batch finalized”.
|
||||
- **Nested work** (`Agent.kickoff()`, crews, Exa tools) appends to the **parent** batch; inner `AgentExecutor` flows do not close the session batch early.
|
||||
|
||||
```python
|
||||
flow.chat(session_id=session_id)
|
||||
```
|
||||
|
||||
`flow.chat()` calls `finalize_session_traces()` for you. When you own the loop
|
||||
with `handle_turn()`, call `finalize_session_traces()` when
|
||||
the session ends.
|
||||
|
||||
`suppress_flow_events=True` only hides Rich console panels; trace and method events still emit for observability.
|
||||
|
||||
### Conversational `Flow` trace lifecycle
|
||||
|
||||
The experimental [conversational `Flow`](#conversational-flow-experimental) uses the same tracing lifecycle: `defer_trace_finalization` defaults to `True`, so each `handle_turn()` keeps the session trace open. Always finalize at the end of the session — wrap your REPL/loop in `try/finally` and call `flow.finalize_session_traces()` on exit. Without it, the trace batch stays open and the final conversation may never export.
|
||||
|
||||
## Streaming
|
||||
|
||||
Set `stream = True` on the `Flow` class. `kickoff(...)` will then emit `assistant_delta` (and related) events through the standard event bus.
|
||||
|
||||
## Imports
|
||||
|
||||
```python
|
||||
from crewai.flow import (
|
||||
ChatState,
|
||||
ConversationalConfig,
|
||||
ConversationalInputs,
|
||||
Flow,
|
||||
listen,
|
||||
persist,
|
||||
router,
|
||||
start,
|
||||
)
|
||||
```
|
||||
|
||||
## See also
|
||||
|
||||
- [Mastering Flow State Management](/en/guides/flows/mastering-flow-state) — persistence, Pydantic state, `@persist`
|
||||
- [Build Your First Flow](/en/guides/flows/first-flow) — flow basics
|
||||
- Demo: `lib/crewai/runner_conversational_flow_simple.py` — minimal REPL with `RESEARCH` + Exa agent
|
||||
@@ -65,7 +65,7 @@ This will generate a project with the basic structure needed for your flow.
|
||||
|
||||
## Step 2: Understanding the Project Structure
|
||||
|
||||
The generated project has the following structure. Take a moment to familiarize yourself with it, as understanding this structure will help you create more complex flows in the future.
|
||||
The generated project has the following structure. The starter embedded crew uses the classic Python/YAML layout, and in Step 4 we will replace the content crew with a JSONC crew.
|
||||
|
||||
```
|
||||
guide_creator_flow/
|
||||
@@ -73,21 +73,24 @@ guide_creator_flow/
|
||||
├── pyproject.toml
|
||||
├── README.md
|
||||
├── .env
|
||||
├── main.py
|
||||
├── crews/
|
||||
│ └── poem_crew/
|
||||
│ ├── config/
|
||||
│ │ ├── agents.yaml
|
||||
│ │ └── tasks.yaml
|
||||
│ └── poem_crew.py
|
||||
└── tools/
|
||||
└── custom_tool.py
|
||||
└── src/
|
||||
└── guide_creator_flow/
|
||||
├── __init__.py
|
||||
├── main.py
|
||||
├── crews/
|
||||
│ └── poem_crew/
|
||||
│ ├── config/
|
||||
│ │ ├── agents.yaml
|
||||
│ │ └── tasks.yaml
|
||||
│ └── poem_crew.py
|
||||
└── tools/
|
||||
└── custom_tool.py
|
||||
```
|
||||
|
||||
This structure provides a clear separation between different components of your flow:
|
||||
- The main flow logic in the `main.py` file
|
||||
- Specialized crews in the `crews` directory
|
||||
- Custom tools in the `tools` directory
|
||||
- The main flow logic in the `src/guide_creator_flow/main.py` file
|
||||
- Specialized crews in the `src/guide_creator_flow/crews` directory
|
||||
- Custom tools in the `src/guide_creator_flow/tools` directory
|
||||
|
||||
We'll modify this structure to create our guide creator flow, which will orchestrate the process of generating comprehensive learning guides.
|
||||
|
||||
@@ -103,157 +106,82 @@ This command automatically creates the necessary directories and template files
|
||||
|
||||
## Step 4: Configure the Content Writer Crew
|
||||
|
||||
Now, let's modify the generated files for the content writer crew. We'll set up two specialized agents - a writer and a reviewer - that will collaborate to create high-quality content for our guide.
|
||||
Now, let's configure the content writer crew with JSONC. We'll set up two specialized agents - a writer and a reviewer - that collaborate to create high-quality content for our guide.
|
||||
|
||||
1. First, update the agents configuration file to define our content creation team:
|
||||
1. Create `src/guide_creator_flow/crews/content_crew/agents/content_writer.jsonc`:
|
||||
|
||||
Remember to set `llm` to the provider you are using.
|
||||
|
||||
```yaml
|
||||
# src/guide_creator_flow/crews/content_crew/config/agents.yaml
|
||||
content_writer:
|
||||
role: >
|
||||
Educational Content Writer
|
||||
goal: >
|
||||
Create engaging, informative content that thoroughly explains the assigned topic
|
||||
and provides valuable insights to the reader
|
||||
backstory: >
|
||||
You are a talented educational writer with expertise in creating clear, engaging
|
||||
content. You have a gift for explaining complex concepts in accessible language
|
||||
and organizing information in a way that helps readers build their understanding.
|
||||
llm: provider/model-id # e.g. openai/gpt-4o, google/gemini-2.0-flash, anthropic/claude...
|
||||
|
||||
content_reviewer:
|
||||
role: >
|
||||
Educational Content Reviewer and Editor
|
||||
goal: >
|
||||
Ensure content is accurate, comprehensive, well-structured, and maintains
|
||||
consistency with previously written sections
|
||||
backstory: >
|
||||
You are a meticulous editor with years of experience reviewing educational
|
||||
content. You have an eye for detail, clarity, and coherence. You excel at
|
||||
improving content while maintaining the original author's voice and ensuring
|
||||
consistent quality across multiple sections.
|
||||
llm: provider/model-id # e.g. openai/gpt-4o, google/gemini-2.0-flash, anthropic/claude...
|
||||
```jsonc
|
||||
{
|
||||
"role": "Educational Content Writer",
|
||||
"goal": "Create engaging, informative content that thoroughly explains the assigned topic and provides valuable insights to the reader.",
|
||||
"backstory": "You are a talented educational writer who explains complex concepts in accessible language and organizes information clearly.",
|
||||
"llm": "provider/model-id",
|
||||
"settings": {
|
||||
"verbose": true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
These agent definitions establish the specialized roles and perspectives that will shape how our AI agents approach content creation. Notice how each agent has a distinct purpose and expertise.
|
||||
2. Create `src/guide_creator_flow/crews/content_crew/agents/content_reviewer.jsonc`:
|
||||
|
||||
2. Next, update the tasks configuration file to define the specific writing and reviewing tasks:
|
||||
|
||||
```yaml
|
||||
# src/guide_creator_flow/crews/content_crew/config/tasks.yaml
|
||||
write_section_task:
|
||||
description: >
|
||||
Write a comprehensive section on the topic: "{section_title}"
|
||||
|
||||
Section description: {section_description}
|
||||
Target audience: {audience_level} level learners
|
||||
|
||||
Your content should:
|
||||
1. Begin with a brief introduction to the section topic
|
||||
2. Explain all key concepts clearly with examples
|
||||
3. Include practical applications or exercises where appropriate
|
||||
4. End with a summary of key points
|
||||
5. Be approximately 500-800 words in length
|
||||
|
||||
Format your content in Markdown with appropriate headings, lists, and emphasis.
|
||||
|
||||
Previously written sections:
|
||||
{previous_sections}
|
||||
|
||||
Make sure your content maintains consistency with previously written sections
|
||||
and builds upon concepts that have already been explained.
|
||||
expected_output: >
|
||||
A well-structured, comprehensive section in Markdown format that thoroughly
|
||||
explains the topic and is appropriate for the target audience.
|
||||
agent: content_writer
|
||||
|
||||
review_section_task:
|
||||
description: >
|
||||
Review and improve the following section on "{section_title}":
|
||||
|
||||
{draft_content}
|
||||
|
||||
Target audience: {audience_level} level learners
|
||||
|
||||
Previously written sections:
|
||||
{previous_sections}
|
||||
|
||||
Your review should:
|
||||
1. Fix any grammatical or spelling errors
|
||||
2. Improve clarity and readability
|
||||
3. Ensure content is comprehensive and accurate
|
||||
4. Verify consistency with previously written sections
|
||||
5. Enhance the structure and flow
|
||||
6. Add any missing key information
|
||||
|
||||
Provide the improved version of the section in Markdown format.
|
||||
expected_output: >
|
||||
An improved, polished version of the section that maintains the original
|
||||
structure but enhances clarity, accuracy, and consistency.
|
||||
agent: content_reviewer
|
||||
context:
|
||||
- write_section_task
|
||||
```jsonc
|
||||
{
|
||||
"role": "Educational Content Reviewer and Editor",
|
||||
"goal": "Ensure content is accurate, comprehensive, well-structured, and consistent with previously written sections.",
|
||||
"backstory": "You are a meticulous editor with an eye for detail, clarity, and coherence.",
|
||||
"llm": "provider/model-id",
|
||||
"settings": {
|
||||
"verbose": true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
These task definitions provide detailed instructions to our agents, ensuring they produce content that meets our quality standards. Note how the `context` parameter in the review task creates a workflow where the reviewer has access to the writer's output.
|
||||
Replace `provider/model-id` with the model you use, for example `openai/gpt-4o`, `gemini/gemini-2.0-flash-001`, or `anthropic/claude-sonnet-4-6`.
|
||||
|
||||
3. Now, update the crew implementation file to define how our agents and tasks work together:
|
||||
3. Create `src/guide_creator_flow/crews/content_crew/crew.jsonc`:
|
||||
|
||||
```jsonc
|
||||
{
|
||||
"name": "Content Crew",
|
||||
"agents": ["content_writer", "content_reviewer"],
|
||||
"tasks": [
|
||||
{
|
||||
"name": "write_section_task",
|
||||
"description": "Write a comprehensive section on the topic: \"{section_title}\".\n\nSection description: {section_description}\nTarget audience: {audience_level} level learners\n\nYour content should begin with a brief introduction, explain key concepts clearly with examples, include practical applications where appropriate, end with a summary, and be approximately 500-800 words.\n\nPreviously written sections:\n{previous_sections}",
|
||||
"expected_output": "A well-structured, comprehensive section in Markdown format that thoroughly explains the topic and is appropriate for the target audience.",
|
||||
"agent": "content_writer",
|
||||
"markdown": true
|
||||
},
|
||||
{
|
||||
"name": "review_section_task",
|
||||
"description": "Review and improve this section on \"{section_title}\":\n\n{draft_content}\n\nTarget audience: {audience_level} level learners\nPreviously written sections:\n{previous_sections}\n\nFix errors, improve clarity, verify consistency, enhance structure, and add missing key information.",
|
||||
"expected_output": "An improved, polished version of the section that maintains the original structure but enhances clarity, accuracy, and consistency.",
|
||||
"agent": "content_reviewer",
|
||||
"context": ["write_section_task"],
|
||||
"markdown": true
|
||||
}
|
||||
],
|
||||
"process": "sequential",
|
||||
"verbose": true
|
||||
}
|
||||
```
|
||||
|
||||
The `context` field lets the reviewer use the writer's output.
|
||||
|
||||
4. Replace `src/guide_creator_flow/crews/content_crew/content_crew.py` with a small loader:
|
||||
|
||||
```python
|
||||
# src/guide_creator_flow/crews/content_crew/content_crew.py
|
||||
from crewai import Agent, Crew, Process, Task
|
||||
from crewai.project import CrewBase, agent, crew, task
|
||||
from crewai.agents.agent_builder.base_agent import BaseAgent
|
||||
from typing import List
|
||||
from pathlib import Path
|
||||
|
||||
@CrewBase
|
||||
class ContentCrew():
|
||||
"""Content writing crew"""
|
||||
from crewai.project import load_crew
|
||||
|
||||
agents: List[BaseAgent]
|
||||
tasks: List[Task]
|
||||
|
||||
@agent
|
||||
def content_writer(self) -> Agent:
|
||||
return Agent(
|
||||
config=self.agents_config['content_writer'], # type: ignore[index]
|
||||
verbose=True
|
||||
)
|
||||
|
||||
@agent
|
||||
def content_reviewer(self) -> Agent:
|
||||
return Agent(
|
||||
config=self.agents_config['content_reviewer'], # type: ignore[index]
|
||||
verbose=True
|
||||
)
|
||||
|
||||
@task
|
||||
def write_section_task(self) -> Task:
|
||||
return Task(
|
||||
config=self.tasks_config['write_section_task'] # type: ignore[index]
|
||||
)
|
||||
|
||||
@task
|
||||
def review_section_task(self) -> Task:
|
||||
return Task(
|
||||
config=self.tasks_config['review_section_task'], # type: ignore[index]
|
||||
context=[self.write_section_task()]
|
||||
)
|
||||
|
||||
@crew
|
||||
def crew(self) -> Crew:
|
||||
"""Creates the content writing crew"""
|
||||
return Crew(
|
||||
agents=self.agents,
|
||||
tasks=self.tasks,
|
||||
process=Process.sequential,
|
||||
verbose=True,
|
||||
)
|
||||
def kickoff_content_crew(inputs: dict):
|
||||
crew, default_inputs = load_crew(Path(__file__).with_name("crew.jsonc"))
|
||||
return crew.kickoff(inputs={**default_inputs, **inputs})
|
||||
```
|
||||
|
||||
This crew definition establishes the relationship between our agents and tasks, setting up a sequential process where the content writer creates a draft and then the reviewer improves it. While this crew can function independently, in our flow it will be orchestrated as part of a larger system.
|
||||
This loader turns `crew.jsonc` into a `Crew` at runtime. While this crew can function independently, in our flow it will be orchestrated as part of a larger system.
|
||||
|
||||
## Step 5: Create the Flow
|
||||
|
||||
@@ -275,7 +203,7 @@ from typing import List, Dict
|
||||
from pydantic import BaseModel, Field
|
||||
from crewai import LLM
|
||||
from crewai.flow.flow import Flow, listen, start
|
||||
from guide_creator_flow.crews.content_crew.content_crew import ContentCrew
|
||||
from guide_creator_flow.crews.content_crew.content_crew import kickoff_content_crew
|
||||
|
||||
# Define our models for structured data
|
||||
class Section(BaseModel):
|
||||
@@ -380,7 +308,7 @@ class GuideCreatorFlow(Flow[GuideCreatorState]):
|
||||
previous_sections_text = "No previous sections written yet."
|
||||
|
||||
# Run the content crew for this section
|
||||
result = ContentCrew().crew().kickoff(inputs={
|
||||
result = kickoff_content_crew(inputs={
|
||||
"section_title": section.title,
|
||||
"section_description": section.description,
|
||||
"audience_level": self.state.audience_level,
|
||||
@@ -600,7 +528,7 @@ This provides a type-safe way to track and transform data throughout your flow.
|
||||
Flows can seamlessly integrate with crews for complex collaborative tasks:
|
||||
|
||||
```python
|
||||
result = ContentCrew().crew().kickoff(inputs={
|
||||
result = kickoff_content_crew(inputs={
|
||||
"section_title": section.title,
|
||||
# ...
|
||||
})
|
||||
@@ -617,6 +545,7 @@ Now that you've built your first flow, you can:
|
||||
3. Explore the `and_` and `or_` functions for more complex parallel execution
|
||||
4. Connect your flow to external APIs, databases, or user interfaces
|
||||
5. Combine multiple specialized crews in a single flow
|
||||
6. Build multi-turn chat apps with [Conversational Flows](/en/guides/flows/conversational-flows) (`kickoff` per message, `ChatSession`, deferred tracing)
|
||||
|
||||
<Check>
|
||||
Congratulations! You've successfully built your first CrewAI Flow that combines regular code, direct LLM calls, and crew-based processing to create a comprehensive guide. These foundational skills enable you to create increasingly sophisticated AI applications that can tackle complex, multi-stage problems through a combination of procedural control and collaborative intelligence.
|
||||
|
||||
@@ -22,6 +22,8 @@ Effective state management enables you to:
|
||||
5. **Scale your applications** - Support complex workflows with proper data organization
|
||||
6. **Enable conversational applications** - Store and access conversation history for context-aware AI interactions
|
||||
|
||||
For multi-turn chat (`kickoff` per user line, `ChatState`, intent routing, deferred tracing, and `ChatSession`), see [Conversational Flows](/en/guides/flows/conversational-flows).
|
||||
|
||||
Let's explore how to leverage these capabilities effectively.
|
||||
|
||||
## State Management Fundamentals
|
||||
|
||||
@@ -141,7 +141,7 @@ crew = Crew(
|
||||
process=Process.sequential, # or Process.hierarchical
|
||||
memory=True,
|
||||
cache=True,
|
||||
embedder={"provider": "openai", "config": {"model": "text-embedding-3-small"}},
|
||||
embedder={"provider": "openai", "config": {"model": "text-embedding-3-large"}},
|
||||
)
|
||||
```
|
||||
|
||||
@@ -173,7 +173,7 @@ write = Task(
|
||||
|
||||
### Memory & embedder config {#memory-embedder-config}
|
||||
|
||||
If `memory=True` and you're not using the default OpenAI embeddings, you must pass an `embedder`:
|
||||
If `memory=True` and you're not using the default OpenAI `text-embedding-3-large` embeddings, you must pass an `embedder`:
|
||||
|
||||
```python
|
||||
crew = Crew(
|
||||
@@ -187,4 +187,4 @@ crew = Crew(
|
||||
)
|
||||
```
|
||||
|
||||
Set the relevant provider credentials (`OPENAI_API_KEY`, `OLLAMA_HOST`, etc.) in your `.env` file. Memory storage paths are project-local by default — delete the project's memory directory if you change embedders, since dimensions don't mix.
|
||||
Set the relevant provider credentials (`OPENAI_API_KEY`, `OLLAMA_HOST`, etc.) in your `.env` file. Memory storage paths are project-local by default. Existing local memory stores created with 1536-dimensional embeddings may not be compatible with the default OpenAI `text-embedding-3-large` embedder, which uses 3072 dimensions. If you hit a dimension mismatch, delete the project's memory directory, run `crewai reset-memories -m`, or explicitly configure the older embedder model until you migrate.
|
||||
|
||||
@@ -116,7 +116,7 @@ If you haven't installed `uv` yet, follow **step 1** to quickly get it set up on
|
||||
|
||||
# Creating a CrewAI Project
|
||||
|
||||
We recommend using the `YAML` template scaffolding for a structured approach to defining agents and tasks. Here's how to get started:
|
||||
`crewai create crew` now creates a JSON-first crew project. Agents live in `agents/*.jsonc`, tasks and crew-level settings live in `crew.jsonc`, and `crewai run` loads that JSON definition directly.
|
||||
|
||||
<Steps>
|
||||
<Step title="Generate Project Scaffolding">
|
||||
@@ -129,21 +129,20 @@ We recommend using the `YAML` template scaffolding for a structured approach to
|
||||
```
|
||||
my_project/
|
||||
├── .gitignore
|
||||
├── .env
|
||||
├── agents/
|
||||
│ └── researcher.jsonc
|
||||
├── crew.jsonc
|
||||
├── knowledge/
|
||||
├── pyproject.toml
|
||||
├── README.md
|
||||
├── .env
|
||||
└── src/
|
||||
└── my_project/
|
||||
├── __init__.py
|
||||
├── main.py
|
||||
├── crew.py
|
||||
├── tools/
|
||||
│ ├── custom_tool.py
|
||||
│ └── __init__.py
|
||||
└── config/
|
||||
├── agents.yaml
|
||||
└── tasks.yaml
|
||||
├── skills/
|
||||
└── tools/
|
||||
```
|
||||
|
||||
- If you need the older Python/YAML scaffold with `crew.py`, `config/agents.yaml`, and `config/tasks.yaml`, run:
|
||||
```shell
|
||||
crewai create crew <your_project_name> --classic
|
||||
```
|
||||
|
||||
</Step>
|
||||
@@ -152,15 +151,15 @@ We recommend using the `YAML` template scaffolding for a structured approach to
|
||||
- Your project will contain these essential files:
|
||||
| File | Purpose |
|
||||
| --- | --- |
|
||||
| `agents.yaml` | Define your AI agents and their roles |
|
||||
| `tasks.yaml` | Set up agent tasks and workflows |
|
||||
| `crew.jsonc` | Configure the crew, task order, process, and input defaults |
|
||||
| `agents/*.jsonc` | Define each agent's role, goal, backstory, LLM, tools, and behavior |
|
||||
| `.env` | Store API keys and environment variables |
|
||||
| `main.py` | Project entry point and execution flow |
|
||||
| `crew.py` | Crew orchestration and coordination |
|
||||
| `tools/` | Directory for custom agent tools |
|
||||
| `knowledge/` | Directory for knowledge base |
|
||||
| `tools/` | Optional Python files for `custom:<name>` tools |
|
||||
| `knowledge/` | Optional knowledge files for agents |
|
||||
| `skills/` | Optional skill files applied to the crew |
|
||||
|
||||
- Start by editing `agents.yaml` and `tasks.yaml` to define your crew's behavior.
|
||||
- Start by editing `crew.jsonc` and the files in `agents/` to define your crew's behavior.
|
||||
- Use `{placeholder}` values in agent and task text, then set defaults in `crew.jsonc` under `inputs`. When you run `crewai run`, the CLI prompts for any missing values.
|
||||
- Keep sensitive information like API keys in `.env`.
|
||||
|
||||
</Step>
|
||||
|
||||
@@ -1,15 +1,19 @@
|
||||
---
|
||||
title: "Using Annotations in crew.py"
|
||||
description: "Learn how to use annotations to properly structure agents, tasks, and components in CrewAI"
|
||||
description: "Learn how to use classic Python annotations to structure agents, tasks, and components in CrewAI"
|
||||
icon: "at"
|
||||
mode: "wide"
|
||||
---
|
||||
|
||||
This guide explains how to use annotations to properly reference **agents**, **tasks**, and other components in the `crew.py` file.
|
||||
This guide explains how to use annotations to properly reference **agents**, **tasks**, and other components in a classic `crew.py` file.
|
||||
|
||||
<Note>
|
||||
New crew projects created with `crewai create crew <name>` are JSON-first and use `crew.jsonc` plus `agents/*.jsonc`. Use this annotations guide when you are working in a classic project created with `crewai create crew <name> --classic`, migrating an existing Python/YAML project, or need decorator-based Python control.
|
||||
</Note>
|
||||
|
||||
## Introduction
|
||||
|
||||
Annotations in the CrewAI framework are used to decorate classes and methods, providing metadata and functionality to various components of your crew. These annotations help in organizing and structuring your code, making it more readable and maintainable.
|
||||
Annotations in the CrewAI framework are used to decorate classes and methods, providing metadata and functionality to various components of your crew. In classic Python/YAML projects, these annotations help organize the code that loads `config/agents.yaml`, `config/tasks.yaml`, and returns the `Crew` object.
|
||||
|
||||
## Available Annotations
|
||||
|
||||
@@ -113,9 +117,9 @@ def crew(self) -> Crew:
|
||||
|
||||
The `@crew` annotation is used to decorate the method that creates and returns the `Crew` object. This method assembles all the components (agents and tasks) into a functional crew.
|
||||
|
||||
## YAML Configuration
|
||||
## Classic YAML Configuration
|
||||
|
||||
The agent configurations are typically stored in a YAML file. Here's an example of how the `agents.yaml` file might look for the researcher agent:
|
||||
In classic projects, agent configurations are typically stored in a YAML file. Here's an example of how the `agents.yaml` file might look for the researcher agent:
|
||||
|
||||
```yaml
|
||||
researcher:
|
||||
@@ -146,6 +150,6 @@ Note how the `llm` and `tools` in the YAML file correspond to the methods decora
|
||||
- **Consistent Naming**: Use clear and consistent naming conventions for your methods. For example, agent methods could be named after their roles (e.g., researcher, reporting_analyst).
|
||||
- **Environment Variables**: Use environment variables for sensitive information like API keys.
|
||||
- **Flexibility**: Design your crew to be flexible by allowing easy addition or removal of agents and tasks.
|
||||
- **YAML-Code Correspondence**: Ensure that the names and structures in your YAML files correspond correctly to the decorated methods in your Python code.
|
||||
- **YAML-Code Correspondence**: In classic projects, ensure that the names and structures in your YAML files correspond correctly to the decorated methods in your Python code.
|
||||
|
||||
By following these guidelines and properly using annotations, you can create well-structured and maintainable crews using the CrewAI framework.
|
||||
By following these guidelines and properly using annotations, you can maintain classic Python/YAML crews cleanly. For new crews, prefer the JSON-first structure covered in [Crews](/en/concepts/crews).
|
||||
|
||||
@@ -39,85 +39,60 @@ If you have not installed CrewAI yet, follow the [installation guide](/en/instal
|
||||
This creates a Flow app under `src/latest_ai_flow/`, including a starter crew under `crews/content_crew/` that you will replace with a minimal **single-agent** research crew in the next steps.
|
||||
</Step>
|
||||
|
||||
<Step title="Configure one agent in `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=...)`.
|
||||
<Step title="Configure one agent in JSONC">
|
||||
Create `src/latest_ai_flow/crews/content_crew/agents/researcher.jsonc` (create the `agents/` directory if needed). Variables like `{topic}` are filled from `crew.kickoff(inputs=...)`.
|
||||
|
||||
```yaml agents.yaml
|
||||
# src/latest_ai_flow/crews/content_crew/config/agents.yaml
|
||||
researcher:
|
||||
role: >
|
||||
{topic} Senior Data Researcher
|
||||
goal: >
|
||||
Uncover cutting-edge developments in {topic}
|
||||
backstory: >
|
||||
You're a seasoned researcher with a knack for uncovering the latest
|
||||
developments in {topic}. You find the most relevant information and
|
||||
present it clearly.
|
||||
```jsonc agents/researcher.jsonc
|
||||
{
|
||||
"role": "{topic} Senior Data Researcher",
|
||||
"goal": "Uncover cutting-edge developments in {topic}",
|
||||
"backstory": "You're a seasoned researcher who finds relevant information and presents it clearly.",
|
||||
"tools": ["SerperDevTool"],
|
||||
"settings": {
|
||||
"verbose": true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
</Step>
|
||||
|
||||
<Step title="Configure one task in `tasks.yaml`">
|
||||
```yaml tasks.yaml
|
||||
# src/latest_ai_flow/crews/content_crew/config/tasks.yaml
|
||||
research_task:
|
||||
description: >
|
||||
Conduct thorough research about {topic}. Use web search to find current,
|
||||
credible information. The current year is 2026.
|
||||
expected_output: >
|
||||
A markdown report with clear sections: key trends, notable tools or companies,
|
||||
and implications. Aim for 800–1200 words. No fenced code blocks around the whole document.
|
||||
agent: researcher
|
||||
output_file: output/report.md
|
||||
<Step title="Configure the crew in `crew.jsonc`">
|
||||
Create `src/latest_ai_flow/crews/content_crew/crew.jsonc`:
|
||||
|
||||
```jsonc crew.jsonc
|
||||
{
|
||||
"name": "Research Crew",
|
||||
"agents": ["researcher"],
|
||||
"tasks": [
|
||||
{
|
||||
"name": "research_task",
|
||||
"description": "Conduct thorough research about {topic}. Use web search to find recent, credible information.",
|
||||
"expected_output": "A markdown report with clear sections: key trends, notable tools or companies, and implications. Aim for 800-1200 words. No fenced code blocks around the whole document.",
|
||||
"agent": "researcher",
|
||||
"output_file": "output/report.md",
|
||||
"markdown": true
|
||||
}
|
||||
],
|
||||
"process": "sequential",
|
||||
"verbose": true
|
||||
}
|
||||
```
|
||||
|
||||
</Step>
|
||||
|
||||
<Step title="Wire the crew class (`content_crew.py`)">
|
||||
Point the generated crew at your YAML and attach `SerperDevTool` to the researcher.
|
||||
<Step title="Load the JSON crew (`content_crew.py`)">
|
||||
Replace the generated `content_crew.py` with a small loader that turns `crew.jsonc` into a `Crew`.
|
||||
|
||||
```python content_crew.py
|
||||
# src/latest_ai_flow/crews/content_crew/content_crew.py
|
||||
from typing import List
|
||||
from pathlib import Path
|
||||
|
||||
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
|
||||
from crewai.project import load_crew
|
||||
|
||||
|
||||
@CrewBase
|
||||
class ResearchCrew:
|
||||
"""Single-agent research crew used inside the Flow."""
|
||||
|
||||
agents: List[BaseAgent]
|
||||
tasks: List[Task]
|
||||
|
||||
agents_config = "config/agents.yaml"
|
||||
tasks_config = "config/tasks.yaml"
|
||||
|
||||
@agent
|
||||
def researcher(self) -> Agent:
|
||||
return Agent(
|
||||
config=self.agents_config["researcher"], # type: ignore[index]
|
||||
verbose=True,
|
||||
tools=[SerperDevTool()],
|
||||
)
|
||||
|
||||
@task
|
||||
def research_task(self) -> Task:
|
||||
return Task(
|
||||
config=self.tasks_config["research_task"], # type: ignore[index]
|
||||
)
|
||||
|
||||
@crew
|
||||
def crew(self) -> Crew:
|
||||
return Crew(
|
||||
agents=self.agents,
|
||||
tasks=self.tasks,
|
||||
process=Process.sequential,
|
||||
verbose=True,
|
||||
)
|
||||
def kickoff_content_crew(inputs: dict):
|
||||
crew, default_inputs = load_crew(Path(__file__).with_name("crew.jsonc"))
|
||||
return crew.kickoff(inputs={**default_inputs, **inputs})
|
||||
```
|
||||
|
||||
</Step>
|
||||
@@ -131,7 +106,7 @@ If you have not installed CrewAI yet, follow the [installation guide](/en/instal
|
||||
|
||||
from crewai.flow import Flow, listen, start
|
||||
|
||||
from latest_ai_flow.crews.content_crew.content_crew import ResearchCrew
|
||||
from latest_ai_flow.crews.content_crew.content_crew import kickoff_content_crew
|
||||
|
||||
|
||||
class ResearchFlowState(BaseModel):
|
||||
@@ -150,7 +125,7 @@ If you have not installed CrewAI yet, follow the [installation guide](/en/instal
|
||||
|
||||
@listen(prepare_topic)
|
||||
def run_research(self):
|
||||
result = ResearchCrew().crew().kickoff(inputs={"topic": self.state.topic})
|
||||
result = kickoff_content_crew(inputs={"topic": self.state.topic})
|
||||
self.state.report = result.raw
|
||||
print("Research crew finished.")
|
||||
|
||||
@@ -172,7 +147,7 @@ If you have not installed CrewAI yet, follow the [installation guide](/en/instal
|
||||
```
|
||||
|
||||
<Tip>
|
||||
If your package name differs from `latest_ai_flow`, change the import of `ResearchCrew` to match your project’s module path.
|
||||
If your package name differs from `latest_ai_flow`, change the `kickoff_content_crew` import to match your project’s module path.
|
||||
</Tip>
|
||||
</Step>
|
||||
|
||||
@@ -202,7 +177,7 @@ If you have not installed CrewAI yet, follow the [installation guide](/en/instal
|
||||
|
||||
<CodeGroup>
|
||||
```markdown output/report.md
|
||||
# AI Agents in 2026: Landscape and Trends
|
||||
# AI Agents: Recent Landscape and Trends
|
||||
|
||||
## Executive summary
|
||||
…
|
||||
@@ -223,7 +198,7 @@ If you have not installed CrewAI yet, follow the [installation guide](/en/instal
|
||||
## How this run fits together
|
||||
|
||||
1. **Flow** — `LatestAiFlow` runs `prepare_topic` first, then `run_research`, then `summarize`. State (`topic`, `report`) lives on the Flow.
|
||||
2. **Crew** — `ResearchCrew` runs one task with one agent: the researcher uses **Serper** to search the web, then writes the structured report.
|
||||
2. **Crew** — `kickoff_content_crew` loads `crew.jsonc` and runs one task with one agent: the researcher uses **Serper** to search the web, then writes the structured report.
|
||||
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).
|
||||
@@ -234,7 +209,10 @@ You now have an end-to-end Flow with an agent crew and a saved report — a soli
|
||||
|
||||
### Naming consistency
|
||||
|
||||
YAML keys (`researcher`, `research_task`) must match the method names on your `@CrewBase` class. See [Crews](/en/concepts/crews) for the full decorator pattern.
|
||||
The names in `crew.jsonc` must match the files and task references you use:
|
||||
|
||||
- `agents: ["researcher"]` loads `agents/researcher.jsonc`
|
||||
- `tasks[].agent: "researcher"` assigns the task to that agent
|
||||
|
||||
## Deploying
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ That pulls the official skill pack into your agent workflow so it can apply Crew
|
||||
## What your agent gets
|
||||
|
||||
- **Flows** — structure stateful apps, steps, and crew kickoffs the CrewAI way
|
||||
- **Crews & agents** — YAML-first patterns, roles, tasks, and delegation
|
||||
- **Crews & agents** — JSON-first patterns (`crew.jsonc`, `agents/*.jsonc`), roles, tasks, and delegation
|
||||
- **Tools & integrations** — hook agents to search, APIs, and common CrewAI tools
|
||||
- **Project layout** — align with CLI scaffolds and repo conventions
|
||||
- **Up-to-date patterns** — skills track current CrewAI docs and recommended practices
|
||||
|
||||
BIN
docs/images/checkpoint-tui-detail-inputs.png
Normal file
|
After Width: | Height: | Size: 169 KiB |
BIN
docs/images/checkpoint-tui-detail-overview.png
Normal file
|
After Width: | Height: | Size: 200 KiB |
BIN
docs/images/checkpoint-tui-detail-tasks.png
Normal file
|
After Width: | Height: | Size: 189 KiB |
BIN
docs/images/checkpoint-tui-details-fork.png
Normal file
|
After Width: | Height: | Size: 235 KiB |
BIN
docs/images/checkpoint-tui-tree.png
Normal file
|
After Width: | Height: | Size: 156 KiB |
BIN
docs/images/crewai-otel-collector-datadog.png
Normal file
|
After Width: | Height: | Size: 455 KiB |
BIN
docs/images/crewai-otel-collector-opentelemetry.png
Normal file
|
After Width: | Height: | Size: 420 KiB |
BIN
docs/images/enterprise/acp-automation-panel-costs.png
Normal file
|
After Width: | Height: | Size: 199 KiB |
BIN
docs/images/enterprise/acp-automation-panel-health.png
Normal file
|
After Width: | Height: | Size: 178 KiB |
BIN
docs/images/enterprise/acp-automation-panel-tokens.png
Normal file
|
After Width: | Height: | Size: 156 KiB |
BIN
docs/images/enterprise/acp-automations-table.png
Normal file
|
After Width: | Height: | Size: 343 KiB |
BIN
docs/images/enterprise/acp-consumption-table.png
Normal file
|
After Width: | Height: | Size: 327 KiB |
BIN
docs/images/enterprise/acp-overview-automations-sankey.png
Normal file
|
After Width: | Height: | Size: 449 KiB |
BIN
docs/images/enterprise/acp-overview-consumption-sankey.png
Normal file
|
After Width: | Height: | Size: 372 KiB |
BIN
docs/images/enterprise/acp-provider-panel-cost.png
Normal file
|
After Width: | Height: | Size: 165 KiB |
BIN
docs/images/enterprise/acp-provider-panel-tokens.png
Normal file
|
After Width: | Height: | Size: 162 KiB |
BIN
docs/images/enterprise/acp-rules-edit-side-panel.png
Normal file
|
After Width: | Height: | Size: 200 KiB |
BIN
docs/images/enterprise/acp-rules-engaged-modal.png
Normal file
|
After Width: | Height: | Size: 72 KiB |
BIN
docs/images/enterprise/acp-rules-list.png
Normal file
|
After Width: | Height: | Size: 134 KiB |
BIN
docs/images/enterprise/databricks-configure.png
Normal file
|
After Width: | Height: | Size: 5.0 MiB |
BIN
docs/images/enterprise/snowflake-configure.png
Normal file
|
After Width: | Height: | Size: 5.7 MiB |
@@ -4,6 +4,281 @@ description: "CrewAI의 제품 업데이트, 개선 사항 및 버그 수정"
|
||||
icon: "clock"
|
||||
mode: "wide"
|
||||
---
|
||||
<Update label="2026년 6월 11일">
|
||||
## v1.14.7
|
||||
|
||||
[GitHub 릴리스 보기](https://github.com/crewAIInc/crewAI/releases/tag/1.14.7)
|
||||
|
||||
## 변경 사항
|
||||
|
||||
### 기능
|
||||
- 메모리, 지식, RAG 및 흐름에 대한 플러그 가능한 기본 백엔드를 추가했습니다.
|
||||
- LLM 이벤트에서 실제 finish_reason, 샘플링 매개변수 및 response.id를 표시합니다.
|
||||
- 경로 인식 장식자로서의 타입 DSL 트리거를 설정합니다.
|
||||
- 대화 흐름을 위한 채팅 API를 추가했습니다.
|
||||
- 잠금 백엔드를 재정의 가능하도록 만듭니다.
|
||||
- Flow DSL 메타데이터에서 FlowDefinition을 빌드합니다.
|
||||
- 네이티브 Snowflake Cortex LLM 공급자를 추가했습니다.
|
||||
- 훈련된 에이전트 파일 지원을 추가했습니다.
|
||||
|
||||
### 버그 수정
|
||||
- 복원 시 사용자 정의 BaseLLM을 구체적인 LLM으로 재구성하도록 체크포인트를 수정했습니다.
|
||||
- 라이브 스냅샷이 재개로 재생되지 않도록 플래그를 사용하여 복원을 제한합니다.
|
||||
- 실행마다 런타임 상태의 범위를 설정하여 성장을 제한하고 동시 실행을 격리합니다.
|
||||
- crewai-login에서 텔레메트리 설정을 수정했습니다.
|
||||
- 메서드 실행 이벤트에 대해 suppress_flow_events를 존중합니다.
|
||||
- uv 도구 설치를 위해 crewai 패키지에서 [project.scripts]를 복원합니다.
|
||||
- aiohttp, docling 및 docling-core에 대한 pip-audit CVE를 해결합니다.
|
||||
- 파일 입력이 신뢰할 수 없게 작동하는 문제를 수정했습니다.
|
||||
- Snowflake Claude의 불완전한 도구 결과 기록을 수정했습니다.
|
||||
|
||||
### 문서
|
||||
- v1.14.7에 대한 변경 로그 및 버전을 업데이트했습니다.
|
||||
- OpenTelemetry 수집기 문서를 업데이트했습니다.
|
||||
- NVIDIA Nemotron LLM 가이드를 업데이트했습니다.
|
||||
- Databricks 통합 가이드를 추가했습니다.
|
||||
- Snowflake 통합 가이드를 추가했습니다.
|
||||
|
||||
### 성능
|
||||
- docling 가져오기를 지연 로딩하여 crewai 가져오기 속도를 개선했습니다.
|
||||
|
||||
### 리팩토링
|
||||
- 흐름 조건 평가를 이벤트별로 상태 비저장으로 단순화했습니다.
|
||||
- 대화 논리를 런타임에서 분리하고 conversational_definition을 추가했습니다.
|
||||
- `flow.py`를 DSL, 정의 및 런타임으로 분리했습니다.
|
||||
|
||||
## 기여자
|
||||
|
||||
@Luzk, @alex-clawd, @devin-ai-integration[bot], @greysonlalonde, @gvieira, @jessemiller, @lorenzejay, @lucasgomide, @mattatcha, @vinibrsl
|
||||
|
||||
</Update>
|
||||
|
||||
<Update label="2026년 6월 10일">
|
||||
## v1.14.7rc2
|
||||
|
||||
[GitHub 릴리스 보기](https://github.com/crewAIInc/crewAI/releases/tag/1.14.7rc2)
|
||||
|
||||
## 변경 사항
|
||||
|
||||
### 버그 수정
|
||||
- 라이브 스냅샷이 재개로 재생되는 것을 방지하기 위한 플래그에서 게이트 복원
|
||||
|
||||
### 문서
|
||||
- v1.14.7rc1에 대한 변경 로그 및 버전 업데이트
|
||||
|
||||
## 기여자
|
||||
|
||||
@greysonlalonde
|
||||
|
||||
</Update>
|
||||
|
||||
<Update label="2026년 6월 10일">
|
||||
## v1.14.7rc1
|
||||
|
||||
[GitHub 릴리스 보기](https://github.com/crewAIInc/crewAI/releases/tag/1.14.7rc1)
|
||||
|
||||
## 변경 사항
|
||||
|
||||
### 기능
|
||||
- 누적된 버스 상태를 해제하기 위해 `reset_runtime_state` 추가
|
||||
- 사용자 정의 프롬프트를 모두 지원하도록 처리
|
||||
- 대화 논리를 런타임과 분리하고 `conversational_definition` 추가
|
||||
|
||||
### 버그 수정
|
||||
- 실행당 런타임 상태의 범위를 수정하여 성장 제한 및 동시 실행 격리
|
||||
- `crewai-login`에서 원격 측정 설정 수정
|
||||
- 메서드 실행 이벤트에 대한 `suppress_flow_events` 존중 수정
|
||||
|
||||
### 문서
|
||||
- OpenTelemetry 이미지 업데이트
|
||||
- OpenTelemetry 수집기의 새로운 상태를 반영하도록 문서 업데이트
|
||||
- v1.14.7a4에 대한 변경 로그 및 버전 업데이트
|
||||
|
||||
### 리팩토링
|
||||
- 이벤트당 상태 비저장 방식으로 흐름 조건 평가 단순화
|
||||
- 경로를 하나 줄여 대화 라우팅 사이클 개선
|
||||
|
||||
## 기여자
|
||||
|
||||
@greysonlalonde, @lorenzejay, @lucasgomide, @vinibrsl
|
||||
|
||||
</Update>
|
||||
|
||||
<Update label="2026년 6월 9일">
|
||||
## v1.14.7a4
|
||||
|
||||
[GitHub 릴리스 보기](https://github.com/crewAIInc/crewAI/releases/tag/1.14.7a4)
|
||||
|
||||
## 변경 사항
|
||||
|
||||
### 기능
|
||||
- @listen/@router 런타임을 FlowDefinition에서 읽도록 마이그레이션
|
||||
- 메모리, 지식, rag 및 flow에 대한 플러그형 기본 백엔드 추가
|
||||
|
||||
### 문서
|
||||
- v1.14.7a3에 대한 변경 로그 및 버전 업데이트
|
||||
|
||||
## 기여자
|
||||
|
||||
@greysonlalonde, @mattatcha, @vinibrsl
|
||||
|
||||
</Update>
|
||||
|
||||
<Update label="2026년 6월 8일">
|
||||
## v1.14.7a3
|
||||
|
||||
[GitHub 릴리스 보기](https://github.com/crewAIInc/crewAI/releases/tag/1.14.7a3)
|
||||
|
||||
## 변경 사항
|
||||
|
||||
### 버그 수정
|
||||
- 실험적인 `AgentExecutor`에서 `ask_for_human_input` 노출 문제 수정
|
||||
- `aiohttp`, `docling`, `docling-core`, 및 `pip`에 대한 pip-audit CVE 해결
|
||||
|
||||
### 리팩토링
|
||||
- `@start`를 `FlowDefinition`에서 읽도록 마이그레이션
|
||||
|
||||
### 문서화
|
||||
- v1.14.7a2에 대한 변경 로그 및 버전 업데이트
|
||||
|
||||
## 기여자
|
||||
|
||||
@greysonlalonde, @lorenzejay, @vinibrsl
|
||||
|
||||
</Update>
|
||||
|
||||
<Update label="2026년 6월 5일">
|
||||
## v1.14.7a2
|
||||
|
||||
[GitHub 릴리스 보기](https://github.com/crewAIInc/crewAI/releases/tag/1.14.7a2)
|
||||
|
||||
## 변경 사항
|
||||
|
||||
### 기능
|
||||
- 대화 흐름 추적 지원 추가.
|
||||
- `handle_turn`을 활용하도록 대화 흐름 문서 업데이트.
|
||||
- LLM 이벤트에서 실제 `finish_reason`, 샘플링 매개변수 및 `response.id` 표시.
|
||||
- 라우트 인식 데코레이터로서 DSL 트리거 유형 지정.
|
||||
- 대화 흐름을 위한 채팅 API 구현.
|
||||
- 잠금 저장소에서 백엔드 잠금 오버라이드 가능하게 설정.
|
||||
- 흐름 DSL 모놀리스를 집중된 데코레이터 모듈로 분할.
|
||||
- `_usage_to_dict`에서 LiteLLM 캐시/추론 사용 하위 카운트 평탄화.
|
||||
- 흐름 DSL 메타데이터에서 `FlowDefinition` 구축.
|
||||
|
||||
### 문서
|
||||
- NVIDIA Nemotron LLM 가이드 추가.
|
||||
- 모노레포 배포 문서화.
|
||||
- v1.14.7a1에 대한 변경 로그 및 버전 업데이트.
|
||||
|
||||
## 기여자
|
||||
|
||||
@alex-clawd, @gvieira, @lorenzejay, @lucasgomide, @mattatcha, @vinibrsl
|
||||
|
||||
</Update>
|
||||
|
||||
<Update label="2026년 6월 3일">
|
||||
## v1.14.7a1
|
||||
|
||||
[GitHub 릴리스 보기](https://github.com/crewAIInc/crewAI/releases/tag/1.14.7a1)
|
||||
|
||||
## 변경 사항
|
||||
|
||||
### 기능
|
||||
- 승무원 교육을 받은 에이전트 파일 지원 추가
|
||||
- 네이티브 Snowflake Cortex LLM 공급자 추가
|
||||
- Databricks 통합 가이드 추가
|
||||
- Snowflake 통합 가이드 추가
|
||||
|
||||
### 버그 수정
|
||||
- UV 도구 설치를 위한 crewai 패키지에서 `[project.scripts]` 복원하여 CLI 수정
|
||||
- 파일 입력 신뢰성 문제 해결
|
||||
- Snowflake Claude에서 불완전한 도구 결과 기록 수정
|
||||
- Snowflake Claude를 위한 문자열화된 도구 호출 처리
|
||||
- 라우터 주도 사이클 전반에 걸쳐 다중 소스 `or_` 리스너 재장착
|
||||
|
||||
### 성능
|
||||
- docling 가져오기를 지연 로딩하여 crewai 가져오기 속도 개선
|
||||
|
||||
### 리팩토링
|
||||
- `flow.py`를 DSL, 정의 및 런타임으로 분할
|
||||
|
||||
## 기여자
|
||||
|
||||
@Luzk, @alex-clawd, @devin-ai-integration[bot], @greysonlalonde, @jessemiller, @lorenzejay, @vinibrsl
|
||||
|
||||
</Update>
|
||||
|
||||
<Update label="2026년 5월 28일">
|
||||
## v1.14.6
|
||||
|
||||
[GitHub 릴리스 보기](https://github.com/crewAIInc/crewAI/releases/tag/1.14.6)
|
||||
|
||||
## 변경 사항
|
||||
|
||||
### 기능
|
||||
- 환경 변수 유출을 방지하기 위해 StdioTransport 강화
|
||||
- 계획 구성 및 관찰 처리 개선
|
||||
- DatabricksQueryTool에서 env_vars 선언
|
||||
- 에이전트 제어 평면 문서 추가
|
||||
|
||||
### 버그 수정
|
||||
- 도구 호출 루프에서 구조화된 출력 유출 수정
|
||||
- 체크포인트에서 원형으로 돌아갈 수 없는 콜백 및 어댑터 상태 제거
|
||||
- 체크포인트에서 type[BaseModel] 필드를 JSON 스키마로 직렬화
|
||||
- 복원 범위 복원 시 고아 task_started 방지
|
||||
- AgentExecutor가 체크포인트에서 복원할 수 있도록 허용
|
||||
- package_dependencies에서 mongodb 오타를 pymongo로 수정
|
||||
|
||||
### 문서
|
||||
- 에이전트 제어 평면 페이지에 ACP (Beta) 문서 탐색 블록 추가
|
||||
- 프로세스 페이지에서 합의 프로세스 참조 제거
|
||||
- 체크포인트 페이지 구조 재편성
|
||||
- 일회성 관리자 패키지 설치 단계 문서화
|
||||
- Secrets Manager / Workload Identity를 replicated-config에서 마이그레이션
|
||||
- `<Steps>` 렌더링을 방해하는 `{" "}` JSX 표현 제거
|
||||
|
||||
### 리팩토링
|
||||
- Skills Repository를 실험적 + CREWAI_EXPERIMENTAL 게이트로 이동
|
||||
|
||||
## 기여자
|
||||
|
||||
@akaKuruma, @alex-clawd, @github-actions[bot], @greysonlalonde, @heitorado, @iris-clawd, @lorenzejay, @lucasgomide, @mattatcha, @thiagomoretto, @vinibrsl
|
||||
|
||||
</Update>
|
||||
|
||||
<Update label="2026년 5월 27일">
|
||||
## v1.14.6a2
|
||||
|
||||
[GitHub 릴리스 보기](https://github.com/crewAIInc/crewAI/releases/tag/1.14.6a2)
|
||||
|
||||
## 변경 사항
|
||||
|
||||
### 기능
|
||||
- 환경 변수 유출을 방지하기 위해 `StdioTransport` 개선
|
||||
- 계획 구성 및 관찰 처리 개선
|
||||
- `DatabricksQueryTool`에서 `env_vars` 선언
|
||||
- 에이전트 제어 평면 문서 추가
|
||||
|
||||
### 버그 수정
|
||||
- 도구 호출 루프에서 구조화된 출력 유출 수정
|
||||
- 체크포인팅에서 원형으로 돌아갈 수 없는 콜백 및 어댑터 상태 제거
|
||||
- 체크포인팅에서 `type[BaseModel]` 필드를 JSON 스키마로 직렬화
|
||||
- 복원 범위 복원 시 고아 `task_started` 방지
|
||||
- `AgentExecutor`가 체크포인트에서 복원할 수 있도록 허용
|
||||
- 패키지 종속성에서 MongoDB 오타를 `pymongo`로 수정
|
||||
|
||||
### 문서
|
||||
- 체크포인팅 페이지 구조 재편성
|
||||
- 일회성 관리자 패키지 설치 단계 문서화
|
||||
- 복제된 구성에서 비밀 관리자 / 작업 부하 ID 마이그레이션
|
||||
- 변경 로그에서 기술 리포지토리 항목 제거
|
||||
|
||||
## 기여자
|
||||
|
||||
@github-actions[bot], @greysonlalonde, @heitorado, @iris-clawd, @lorenzejay, @lucasgomide, @mattatcha, @thiagomoretto, @vinibrsl
|
||||
|
||||
</Update>
|
||||
|
||||
<Update label="2026년 5월 21일">
|
||||
## v1.14.6a1
|
||||
|
||||
@@ -12,7 +287,6 @@ mode: "wide"
|
||||
## 변경 사항
|
||||
|
||||
### 기능
|
||||
- 레지스트리, 캐시, CLI 및 SDK 통합이 포함된 기술 저장소 추가
|
||||
- 기업용으로 분류된 릴리스 노트 생성
|
||||
|
||||
### 버그 수정
|
||||
|
||||
@@ -66,13 +66,39 @@ CrewAI AOP에는 코드를 작성하지 않고도 에이전트 생성 및 구성
|
||||
|
||||
## 에이전트 생성
|
||||
|
||||
CrewAI에서 에이전트를 생성하는 방법에는 **YAML 구성(권장)**을 사용하는 방법과 **코드에서 직접 정의**하는 두 가지가 있습니다.
|
||||
CrewAI에서 에이전트를 생성하는 일반적인 방법은 **JSONC 프로젝트 구성(새 crew 권장)** 또는 **코드에서 직접 정의**입니다.
|
||||
|
||||
### YAML 구성 (권장)
|
||||
### JSONC 구성 (권장)
|
||||
|
||||
YAML 구성을 사용하면 에이전트를 보다 깔끔하고 유지 관리하기 쉽도록 정의할 수 있습니다. CrewAI 프로젝트에서 이 방식을 사용하는 것을 강력히 권장합니다.
|
||||
`crewai create crew <name>`으로 만든 새 프로젝트는 JSON-first 구성을 사용합니다. 각 에이전트는 `agents/<agent_name>.jsonc`에 정의하고, `crew.jsonc`에서 crew에 포함할 에이전트를 나열합니다.
|
||||
|
||||
[설치](/ko/installation) 섹션에 설명된 대로 CrewAI 프로젝트를 생성한 후, `src/latest_ai_development/config/agents.yaml` 파일로 이동하여 템플릿을 여러분의 요구 사항에 맞게 수정하세요.
|
||||
```jsonc agents/researcher.jsonc
|
||||
{
|
||||
"role": "{topic} Senior Data Researcher",
|
||||
"goal": "Uncover cutting-edge developments in {topic}",
|
||||
"backstory": "You find the most relevant information and present it clearly.",
|
||||
"llm": "openai/gpt-4o",
|
||||
"tools": ["SerperDevTool"],
|
||||
"settings": {
|
||||
"verbose": true,
|
||||
"allow_delegation": false
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
`role`, `goal`, `backstory`에 `{placeholder}`를 사용할 수 있습니다. 기본값은 `crew.jsonc`의 `inputs`에 넣고, 빠진 값은 `crewai run`이 실행 시 물어봅니다. `verbose`, `allow_delegation`, `max_iter`, `memory`, `cache`, `planning_config` 같은 동작 필드는 최상위 또는 `settings` 안에 둘 수 있습니다.
|
||||
|
||||
<Note>
|
||||
JSONC는 주석과 trailing comma를 지원합니다. `agents/<name>.jsonc`와 `agents/<name>.json`이 모두 있으면 CrewAI는 JSONC 파일을 사용합니다.
|
||||
</Note>
|
||||
|
||||
### 클래식 YAML 구성
|
||||
|
||||
`crewai create crew <name> --classic`으로 만든 클래식 프로젝트는 `config/agents.yaml`과 `crew.py`의 `@CrewBase` 클래스를 사용합니다.
|
||||
|
||||
YAML 구성은 기존 Python/YAML 프로젝트와 `@CrewBase` 클래스에서 에이전트를 정의하려는 팀을 위해 계속 지원됩니다.
|
||||
|
||||
클래식 프로젝트를 만든 후, `src/<project_name>/config/agents.yaml` 파일로 이동하여 템플릿을 여러분의 요구 사항에 맞게 수정하세요.
|
||||
|
||||
<Note>
|
||||
YAML 파일의 변수(예: `{topic}`)는 crew를 실행할 때 입력값에서 가져온 값으로 대체됩니다:
|
||||
@@ -84,7 +110,7 @@ crew.kickoff(inputs={'topic': 'AI Agents'})
|
||||
아래는 YAML을 사용하여 에이전트를 구성하는 예시입니다:
|
||||
|
||||
```yaml agents.yaml
|
||||
# src/latest_ai_development/config/agents.yaml
|
||||
# src/<project_name>/config/agents.yaml
|
||||
researcher:
|
||||
role: >
|
||||
{topic} Senior Data Researcher
|
||||
@@ -109,7 +135,7 @@ reporting_analyst:
|
||||
이 YAML 구성을 코드에서 사용하려면, `CrewBase`를 상속하는 crew 클래스를 생성하세요:
|
||||
|
||||
```python Code
|
||||
# src/latest_ai_development/crew.py
|
||||
# src/<project_name>/crew.py
|
||||
from crewai import Agent, Crew, Process
|
||||
from crewai.project import CrewBase, agent, crew
|
||||
from crewai_tools import SerperDevTool
|
||||
|
||||
@@ -5,225 +5,419 @@ icon: floppy-disk
|
||||
mode: "wide"
|
||||
---
|
||||
|
||||
<Warning>
|
||||
체크포인팅은 초기 릴리스 단계입니다. API는 향후 버전에서 변경될 수 있습니다.
|
||||
</Warning>
|
||||
체크포인팅은 실행 중 실행 상태의 스냅샷을 저장하여 크루, 플로우, 에이전트가 실패 후 재개하거나 대체 브랜치로 분기될 수 있도록 합니다.
|
||||
|
||||
## 개요
|
||||
<CardGroup cols={2}>
|
||||
<Card title="설명" icon="lightbulb" href="#설명">
|
||||
체크포인팅의 작동 방식: 이벤트, 스토리지, 상속.
|
||||
</Card>
|
||||
<Card title="튜토리얼" icon="graduation-cap" href="#튜토리얼-실패한-크루-재개하기">
|
||||
5분 가이드: 실행, 중단, 재개.
|
||||
</Card>
|
||||
<Card title="사용 방법" icon="screwdriver-wrench" href="#사용-방법">
|
||||
일반적인 워크플로우를 위한 작업 중심 레시피.
|
||||
</Card>
|
||||
<Card title="레퍼런스" icon="book" href="#레퍼런스">
|
||||
`CheckpointConfig`, 이벤트, 프로바이더, CLI.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
체크포인팅은 실행 중 자동으로 실행 상태를 저장합니다. 크루, 플로우 또는 에이전트가 실행 도중 실패하면 마지막 체크포인트에서 복원하여 이미 완료된 작업을 다시 실행하지 않고 재개할 수 있습니다.
|
||||
## 설명
|
||||
|
||||
## 빠른 시작
|
||||
### 체크포인트란
|
||||
|
||||
```python
|
||||
from crewai import Crew, CheckpointConfig
|
||||
체크포인트는 실행 중인 작업을 재현하기 위해 CrewAI가 필요한 모든 것을 캡처합니다: 크루, 플로우 또는 에이전트의 전체 상태 — 구성, 에이전트의 메모리 및 지식 소스, 태스크 진행 상황, 중간 출력값, 내부 상태 및 속성 — 그리고 kickoff 입력, 해당 시점까지의 이벤트 기록, 그리고 체크포인트를 원본 실행에 연결하는 lineage ID를 포함합니다.
|
||||
|
||||
crew = Crew(
|
||||
agents=[...],
|
||||
tasks=[...],
|
||||
checkpoint=True, # 기본값 사용: ./.checkpoints, task_completed 이벤트
|
||||
)
|
||||
result = crew.kickoff()
|
||||
```
|
||||
복원하면 해당 상태를 재구성하고 계속 진행합니다. 완료된 태스크는 건너뛰고, 메모리와 지식은 재수화되며, 다운스트림 작업은 원본 실행이 생성한 동일한 출력을 기반으로 실행됩니다. 포크하면 새 lineage 아래에서 동일한 복원을 수행하여 새 브랜치와 원본 실행이 서로 덮어쓰지 않고 나란히 체크포인트를 기록할 수 있습니다.
|
||||
|
||||
각 태스크가 완료된 후 `./.checkpoints/`에 체크포인트 파일이 기록됩니다.
|
||||
### 체크포인트가 기록되는 시점
|
||||
|
||||
## 설정
|
||||
체크포인팅은 이벤트 기반입니다. 런타임은 `on_events`로 선택한 이벤트를 구독하고, 이벤트가 발생할 때마다 체크포인트를 기록합니다. 기본값 `task_completed`는 완료된 태스크당 하나의 체크포인트를 생성합니다 — 세분화와 디스크 사용의 합리적인 균형입니다. `llm_call_completed`와 같은 고빈도 이벤트는 더 세밀한 복구를 위해 사용 가능하지만 훨씬 많은 파일을 기록합니다.
|
||||
|
||||
`CheckpointConfig`를 사용하여 세부 설정을 제어합니다:
|
||||
### 스토리지
|
||||
|
||||
```python
|
||||
from crewai import Crew, CheckpointConfig
|
||||
CrewAI에는 두 가지 프로바이더가 포함되어 있습니다:
|
||||
|
||||
crew = Crew(
|
||||
agents=[...],
|
||||
tasks=[...],
|
||||
checkpoint=CheckpointConfig(
|
||||
location="./my_checkpoints",
|
||||
on_events=["task_completed", "crew_kickoff_completed"],
|
||||
max_checkpoints=5,
|
||||
),
|
||||
)
|
||||
```
|
||||
- `JsonProvider`는 체크포인트당 하나의 파일을 기록합니다. 사람이 읽기 쉽고 검사하기 편리합니다.
|
||||
- `SqliteProvider`는 단일 SQLite 데이터베이스에 기록합니다. 고빈도 체크포인팅에 적합합니다.
|
||||
|
||||
### CheckpointConfig 필드
|
||||
`max_checkpoints`가 설정되면 두 프로바이더 모두 가장 오래된 체크포인트를 자동으로 제거합니다.
|
||||
|
||||
| 필드 | 타입 | 기본값 | 설명 |
|
||||
|:-----|:-----|:-------|:-----|
|
||||
| `location` | `str` | `"./.checkpoints"` | 체크포인트 파일 경로 |
|
||||
| `on_events` | `list[str]` | `["task_completed"]` | 체크포인트를 트리거하는 이벤트 타입 |
|
||||
| `provider` | `BaseProvider` | `JsonProvider()` | 스토리지 백엔드 |
|
||||
| `max_checkpoints` | `int \| None` | `None` | 보관할 최대 파일 수; 오래된 것부터 삭제 |
|
||||
<Note>
|
||||
체크포인트 기록은 best-effort 방식입니다. 실패한 체크포인트는 로그에 기록되지만 실행을 중단시키지 않습니다.
|
||||
</Note>
|
||||
|
||||
### 상속 및 옵트아웃
|
||||
### 상속 모델
|
||||
|
||||
Crew, Flow, Agent의 `checkpoint` 필드는 `CheckpointConfig`, `True`, `False`, `None`을 받습니다:
|
||||
`Crew`, `Flow`, `Agent` 모두 `checkpoint` 인수를 받습니다. 자식은 자체 값을 설정하거나 `False`를 전달하여 옵트아웃하지 않는 한 부모로부터 상속합니다. 크루에서 체크포인팅을 한 번 활성화하면 모든 에이전트가 참여하거나, 특정 에이전트만 선택적으로 제외할 수 있습니다.
|
||||
|
||||
| 값 | 동작 |
|
||||
|:---|:-----|
|
||||
| `None` (기본값) | 부모에서 상속. 에이전트는 크루의 설정을 상속합니다. |
|
||||
| `True` | 기본값으로 활성화. |
|
||||
| `False` | 명시적 옵트아웃. 부모 상속을 중단합니다. |
|
||||
| `CheckpointConfig(...)` | 사용자 정의 설정. |
|
||||
## 튜토리얼: 실패한 크루 재개하기
|
||||
|
||||
```python
|
||||
crew = Crew(
|
||||
agents=[
|
||||
Agent(role="Researcher", ...), # 크루의 checkpoint 상속
|
||||
Agent(role="Writer", ..., checkpoint=False), # 옵트아웃, 체크포인트 없음
|
||||
],
|
||||
tasks=[...],
|
||||
checkpoint=True,
|
||||
)
|
||||
```
|
||||
이 가이드는 약 5분이 소요됩니다. 두 개의 태스크가 있는 크루를 실행하고 중간에 종료한 다음, 저장된 체크포인트에서 재개합니다.
|
||||
|
||||
## 체크포인트에서 재개
|
||||
<Steps>
|
||||
<Step title="체크포인팅이 활성화된 크루를 생성합니다">
|
||||
```python
|
||||
from crewai import Agent, Crew, Task
|
||||
|
||||
```python
|
||||
# 복원 및 재개
|
||||
crew = Crew.from_checkpoint("./my_checkpoints/20260407T120000_abc123.json")
|
||||
result = crew.kickoff() # 마지막으로 완료된 태스크부터 재개
|
||||
```
|
||||
researcher = Agent(role="Researcher", goal="Research", backstory="Expert")
|
||||
writer = Agent(role="Writer", goal="Write", backstory="Expert")
|
||||
|
||||
복원된 크루는 이미 완료된 태스크를 건너뛰고 첫 번째 미완료 태스크부터 재개합니다.
|
||||
crew = Crew(
|
||||
agents=[researcher, writer],
|
||||
tasks=[
|
||||
Task(description="Research AI trends", agent=researcher, expected_output="bullets"),
|
||||
Task(description="Write a summary", agent=writer, expected_output="paragraph"),
|
||||
],
|
||||
checkpoint=True,
|
||||
)
|
||||
```
|
||||
</Step>
|
||||
<Step title="실행하고 첫 번째 태스크 후에 중단합니다">
|
||||
```python
|
||||
result = crew.kickoff()
|
||||
```
|
||||
|
||||
## Crew, Flow, Agent에서 사용 가능
|
||||
첫 번째 태스크가 완료된 후 `Ctrl+C`를 누릅니다. `./.checkpoints/` 디렉토리에서 `<timestamp>_<uuid>.json` 형식의 파일이 체크포인트입니다.
|
||||
</Step>
|
||||
<Step title="체크포인트에서 재개합니다">
|
||||
```python
|
||||
from crewai import CheckpointConfig
|
||||
|
||||
### Crew
|
||||
result = crew.kickoff(
|
||||
from_checkpoint=CheckpointConfig(
|
||||
restore_from="./.checkpoints/<timestamp>_<uuid>.json",
|
||||
),
|
||||
)
|
||||
```
|
||||
|
||||
```python
|
||||
crew = Crew(
|
||||
agents=[researcher, writer],
|
||||
tasks=[research_task, write_task, review_task],
|
||||
checkpoint=CheckpointConfig(location="./crew_cp"),
|
||||
)
|
||||
```
|
||||
연구 태스크는 건너뛰고, 작성자는 저장된 연구 출력에 대해 실행되며, 크루가 완료됩니다.
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
기본 트리거: `task_completed` (완료된 태스크당 하나의 체크포인트).
|
||||
## 사용 방법
|
||||
|
||||
### Flow
|
||||
<AccordionGroup>
|
||||
<Accordion title="기본값으로 체크포인팅 활성화" icon="play">
|
||||
```python
|
||||
crew = Crew(agents=[...], tasks=[...], checkpoint=True)
|
||||
```
|
||||
|
||||
```python
|
||||
from crewai.flow.flow import Flow, start, listen
|
||||
from crewai import CheckpointConfig
|
||||
`task_completed` 이벤트마다 `./.checkpoints/`에 기록합니다.
|
||||
</Accordion>
|
||||
|
||||
class MyFlow(Flow):
|
||||
@start()
|
||||
def step_one(self):
|
||||
return "data"
|
||||
<Accordion title="스토리지와 빈도 사용자 정의" icon="sliders">
|
||||
```python
|
||||
from crewai import Crew, CheckpointConfig
|
||||
|
||||
@listen(step_one)
|
||||
def step_two(self, data):
|
||||
return process(data)
|
||||
crew = Crew(
|
||||
agents=[...],
|
||||
tasks=[...],
|
||||
checkpoint=CheckpointConfig(
|
||||
location="./my_checkpoints",
|
||||
on_events=["task_completed", "crew_kickoff_completed"],
|
||||
max_checkpoints=5,
|
||||
),
|
||||
)
|
||||
```
|
||||
</Accordion>
|
||||
|
||||
flow = MyFlow(
|
||||
checkpoint=CheckpointConfig(
|
||||
location="./flow_cp",
|
||||
on_events=["method_execution_finished"],
|
||||
),
|
||||
)
|
||||
result = flow.kickoff()
|
||||
<Accordion title="스토리지 프로바이더 선택" icon="database">
|
||||
<CodeGroup>
|
||||
```python JsonProvider
|
||||
from crewai import Crew, CheckpointConfig
|
||||
from crewai.state import JsonProvider
|
||||
|
||||
# 재개
|
||||
flow = MyFlow.from_checkpoint("./flow_cp/20260407T120000_abc123.json")
|
||||
result = flow.kickoff()
|
||||
```
|
||||
crew = Crew(
|
||||
agents=[...],
|
||||
tasks=[...],
|
||||
checkpoint=CheckpointConfig(
|
||||
location="./my_checkpoints",
|
||||
provider=JsonProvider(),
|
||||
max_checkpoints=5,
|
||||
),
|
||||
)
|
||||
```
|
||||
```python SqliteProvider
|
||||
from crewai import Crew, CheckpointConfig
|
||||
from crewai.state import SqliteProvider
|
||||
|
||||
### Agent
|
||||
crew = Crew(
|
||||
agents=[...],
|
||||
tasks=[...],
|
||||
checkpoint=CheckpointConfig(
|
||||
location="./.checkpoints.db",
|
||||
provider=SqliteProvider(),
|
||||
max_checkpoints=50,
|
||||
),
|
||||
)
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
```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"}])
|
||||
```
|
||||
<Tip>
|
||||
SQLite는 동시 읽기를 위해 WAL 저널 모드를 활성화합니다. 고빈도 체크포인팅에는 SQLite를 선호하세요.
|
||||
</Tip>
|
||||
</Accordion>
|
||||
|
||||
## 스토리지 프로바이더
|
||||
<Accordion title="특정 에이전트 옵트아웃" icon="user-slash">
|
||||
```python
|
||||
crew = Crew(
|
||||
agents=[
|
||||
Agent(role="Researcher", ...),
|
||||
Agent(role="Writer", ..., checkpoint=False),
|
||||
],
|
||||
tasks=[...],
|
||||
checkpoint=True,
|
||||
)
|
||||
```
|
||||
</Accordion>
|
||||
|
||||
CrewAI는 두 가지 체크포인트 스토리지 프로바이더를 제공합니다.
|
||||
<Accordion title="새 브랜치로 포크" icon="code-branch">
|
||||
`fork()`는 새 lineage 아래에 체크포인트를 복원하여 새 실행이 원본과 충돌하지 않도록 합니다.
|
||||
|
||||
### JsonProvider (기본값)
|
||||
```python
|
||||
config = CheckpointConfig(restore_from="./my_checkpoints/<file>.json")
|
||||
crew = Crew.fork(config, branch="experiment-a")
|
||||
result = crew.kickoff(inputs={"strategy": "aggressive"})
|
||||
```
|
||||
|
||||
각 체크포인트를 별도의 JSON 파일로 저장합니다.
|
||||
`branch` 레이블은 선택 사항이며, 생략하면 자동 생성됩니다.
|
||||
</Accordion>
|
||||
|
||||
```python
|
||||
from crewai import Crew, CheckpointConfig
|
||||
from crewai.state import JsonProvider
|
||||
<Accordion title="Crew, Flow, Agent 체크포인트" icon="cubes">
|
||||
<Tabs>
|
||||
<Tab title="Crew">
|
||||
```python
|
||||
crew = Crew(
|
||||
agents=[researcher, writer],
|
||||
tasks=[research_task, write_task, review_task],
|
||||
checkpoint=CheckpointConfig(location="./crew_cp"),
|
||||
)
|
||||
```
|
||||
|
||||
crew = Crew(
|
||||
agents=[...],
|
||||
tasks=[...],
|
||||
checkpoint=CheckpointConfig(
|
||||
location="./my_checkpoints",
|
||||
provider=JsonProvider(),
|
||||
max_checkpoints=5,
|
||||
),
|
||||
)
|
||||
```
|
||||
기본 트리거: `task_completed`.
|
||||
</Tab>
|
||||
<Tab title="Flow">
|
||||
```python
|
||||
from crewai.flow.flow import Flow, start, listen
|
||||
from crewai import CheckpointConfig
|
||||
|
||||
### SqliteProvider
|
||||
class MyFlow(Flow):
|
||||
@start()
|
||||
def step_one(self):
|
||||
return "data"
|
||||
|
||||
모든 체크포인트를 단일 SQLite 데이터베이스 파일에 저장합니다.
|
||||
@listen(step_one)
|
||||
def step_two(self, data):
|
||||
return process(data)
|
||||
|
||||
```python
|
||||
from crewai import Crew, CheckpointConfig
|
||||
from crewai.state import SqliteProvider
|
||||
flow = MyFlow(
|
||||
checkpoint=CheckpointConfig(
|
||||
location="./flow_cp",
|
||||
on_events=["method_execution_finished"],
|
||||
),
|
||||
)
|
||||
result = flow.kickoff()
|
||||
```
|
||||
</Tab>
|
||||
<Tab title="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"}])
|
||||
```
|
||||
</Tab>
|
||||
</Tabs>
|
||||
</Accordion>
|
||||
|
||||
crew = Crew(
|
||||
agents=[...],
|
||||
tasks=[...],
|
||||
checkpoint=CheckpointConfig(
|
||||
location="./.checkpoints.db",
|
||||
provider=SqliteProvider(),
|
||||
),
|
||||
)
|
||||
```
|
||||
<Accordion title="수동으로 체크포인트 기록" icon="code">
|
||||
모든 이벤트에 핸들러를 등록하고 `state.checkpoint()`를 호출합니다.
|
||||
|
||||
<CodeGroup>
|
||||
```python Sync
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING, Any
|
||||
|
||||
from crewai.events.event_bus import crewai_event_bus
|
||||
from crewai.events.types.llm_events import LLMCallCompletedEvent
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from crewai.state.runtime import RuntimeState
|
||||
|
||||
|
||||
## 이벤트 타입
|
||||
@crewai_event_bus.on(LLMCallCompletedEvent)
|
||||
def on_llm_done(source: Any, event: LLMCallCompletedEvent, state: RuntimeState) -> None:
|
||||
path = state.checkpoint("./my_checkpoints")
|
||||
print(f"체크포인트 저장: {path}")
|
||||
```
|
||||
```python Async
|
||||
from __future__ import annotations
|
||||
|
||||
`on_events` 필드는 이벤트 타입 문자열의 조합을 받습니다. 일반적인 선택:
|
||||
from typing import TYPE_CHECKING, Any
|
||||
|
||||
| 사용 사례 | 이벤트 |
|
||||
|:----------|:-------|
|
||||
| 각 태스크 완료 후 (Crew) | `["task_completed"]` |
|
||||
| 각 플로우 메서드 완료 후 | `["method_execution_finished"]` |
|
||||
| 에이전트 실행 완료 후 | `["agent_execution_completed"]`, `["lite_agent_execution_completed"]` |
|
||||
| 크루 완료 시에만 | `["crew_kickoff_completed"]` |
|
||||
| 모든 LLM 호출 후 | `["llm_call_completed"]` |
|
||||
| 모든 이벤트 | `["*"]` |
|
||||
from crewai.events.event_bus import crewai_event_bus
|
||||
from crewai.events.types.llm_events import LLMCallCompletedEvent
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from crewai.state.runtime import RuntimeState
|
||||
|
||||
|
||||
@crewai_event_bus.on(LLMCallCompletedEvent)
|
||||
async def on_llm_done_async(source: Any, event: LLMCallCompletedEvent, state: RuntimeState) -> None:
|
||||
path = await state.acheckpoint("./my_checkpoints")
|
||||
print(f"체크포인트 저장: {path}")
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
핸들러가 세 개의 매개변수를 받을 때 `state` 인수가 자동으로 제공됩니다. 전체 이벤트 카탈로그는 [Event Listeners](/ko/concepts/event-listener) 문서를 참조하세요.
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="CLI에서 탐색, 재개, 포크" icon="terminal">
|
||||
```bash
|
||||
crewai checkpoint
|
||||
crewai checkpoint --location ./my_checkpoints
|
||||
crewai checkpoint --location ./.checkpoints.db
|
||||
```
|
||||
|
||||
<Frame caption="체크포인트 트리 — 브랜치와 포크가 부모 아래에 중첩됩니다.">
|
||||
<img src="/images/checkpoint-tui-tree.png" alt="Checkpoint TUI tree view" />
|
||||
</Frame>
|
||||
|
||||
왼쪽 패널은 체크포인트를 브랜치별로 그룹화하며, 포크는 부모 아래에 중첩됩니다. 체크포인트를 선택하면 메타데이터, 엔티티 상태, 태스크 진행 상황이 있는 세부 정보 패널이 열립니다. **Resume**은 실행을 계속하고, **Fork**는 새 브랜치를 시작합니다.
|
||||
|
||||
<Frame caption="개요 탭 — 메타데이터, 엔티티 상태, 실행 요약.">
|
||||
<img src="/images/checkpoint-tui-detail-overview.png" alt="Checkpoint detail overview tab" />
|
||||
</Frame>
|
||||
|
||||
세부 정보 패널에는 두 개의 편집 가능한 영역이 있습니다:
|
||||
|
||||
- **Inputs** — 원래 kickoff의 입력으로, 미리 채워져 있으며 편집 가능합니다.
|
||||
|
||||
<Frame>
|
||||
<img src="/images/checkpoint-tui-detail-inputs.png" alt="Editable kickoff inputs" />
|
||||
</Frame>
|
||||
|
||||
- **태스크 출력** — 완료된 태스크의 출력. 출력을 편집하고 **Fork**를 누르면 다운스트림 태스크가 무효화되어 수정된 컨텍스트로 다시 실행됩니다.
|
||||
|
||||
<Frame>
|
||||
<img src="/images/checkpoint-tui-detail-tasks.png" alt="Editable task outputs" />
|
||||
</Frame>
|
||||
|
||||
<Frame caption="포크 화면 — 선택한 체크포인트에서 새 브랜치를 확인합니다.">
|
||||
<img src="/images/checkpoint-tui-details-fork.png" alt="Fork confirmation panel" />
|
||||
</Frame>
|
||||
|
||||
<Tip>
|
||||
"what if" 탐색에 유용합니다: 포크, 조정, 관찰.
|
||||
</Tip>
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="TUI 없이 체크포인트 검사" icon="magnifying-glass">
|
||||
```bash
|
||||
crewai checkpoint list ./my_checkpoints
|
||||
crewai checkpoint info ./my_checkpoints/<file>.json
|
||||
crewai checkpoint info ./.checkpoints.db
|
||||
```
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
## 레퍼런스
|
||||
|
||||
### `CheckpointConfig`
|
||||
|
||||
<ParamField path="location" type="str" default='"./.checkpoints"'>
|
||||
스토리지 대상. `JsonProvider`는 디렉토리, `SqliteProvider`는 데이터베이스 파일 경로.
|
||||
</ParamField>
|
||||
|
||||
<ParamField path="on_events" type='list[CheckpointEventType | Literal["*"]]' default='["task_completed"]'>
|
||||
체크포인트를 트리거하는 이벤트 타입. `CheckpointEventType`은 `Literal`이므로 타입 체커가 자동 완성하고 지원되지 않는 값을 거부합니다. 전체 목록은 [이벤트 타입](#이벤트-타입) 참조.
|
||||
</ParamField>
|
||||
|
||||
<ParamField path="provider" type="BaseProvider" default="JsonProvider()">
|
||||
스토리지 백엔드. `JsonProvider` 또는 `SqliteProvider`.
|
||||
</ParamField>
|
||||
|
||||
<ParamField path="max_checkpoints" type="int | None" default="None">
|
||||
보관할 최대 체크포인트 수. 각 기록 후 가장 오래된 것이 제거됩니다.
|
||||
</ParamField>
|
||||
|
||||
<ParamField path="restore_from" type="Path | str | None" default="None">
|
||||
`from_checkpoint`를 통해 전달될 때 복원할 체크포인트.
|
||||
</ParamField>
|
||||
|
||||
### `checkpoint` 필드 값
|
||||
|
||||
`Crew`, `Flow`, `Agent`에서 사용 가능.
|
||||
|
||||
<ParamField path="None" type="기본값">
|
||||
부모에서 상속.
|
||||
</ParamField>
|
||||
|
||||
<ParamField path="True" type="bool">
|
||||
기본값으로 활성화.
|
||||
</ParamField>
|
||||
|
||||
<ParamField path="False" type="bool">
|
||||
명시적 옵트아웃. 상속을 중단합니다.
|
||||
</ParamField>
|
||||
|
||||
<ParamField path="CheckpointConfig(...)" type="CheckpointConfig">
|
||||
사용자 정의 설정.
|
||||
</ParamField>
|
||||
|
||||
### 이벤트 타입
|
||||
|
||||
`on_events`는 `CheckpointEventType` 값의 임의 조합을 받습니다. 기본값 `["task_completed"]`는 완료된 태스크당 하나의 체크포인트를 기록하며, `["*"]`는 모든 이벤트와 일치합니다.
|
||||
|
||||
<Warning>
|
||||
`["*"]` 또는 `llm_call_completed`와 같은 고빈도 이벤트를 사용하면 많은 체크포인트 파일이 생성되어 성능에 영향을 줄 수 있습니다. `max_checkpoints`를 사용하여 디스크 사용량을 제한하세요.
|
||||
`["*"]` 및 `llm_call_completed`와 같은 고빈도 이벤트는 많은 체크포인트를 기록하고 성능을 저하시킬 수 있습니다. `max_checkpoints`와 함께 사용하세요.
|
||||
</Warning>
|
||||
|
||||
## 수동 체크포인팅
|
||||
<Expandable title="지원되는 모든 이벤트">
|
||||
|
||||
완전한 제어를 위해 자체 이벤트 핸들러를 등록하고 `state.checkpoint()`를 직접 호출할 수 있습니다:
|
||||
- **Task** — `task_started`, `task_completed`, `task_failed`, `task_evaluation`
|
||||
- **Crew** — `crew_kickoff_started`, `crew_kickoff_completed`, `crew_kickoff_failed`, `crew_train_started`, `crew_train_completed`, `crew_train_failed`, `crew_test_started`, `crew_test_completed`, `crew_test_failed`, `crew_test_result`
|
||||
- **Agent** — `agent_execution_started`, `agent_execution_completed`, `agent_execution_error`, `lite_agent_execution_started`, `lite_agent_execution_completed`, `lite_agent_execution_error`, `agent_evaluation_started`, `agent_evaluation_completed`, `agent_evaluation_failed`
|
||||
- **Flow** — `flow_created`, `flow_started`, `flow_finished`, `flow_paused`, `method_execution_started`, `method_execution_finished`, `method_execution_failed`, `method_execution_paused`, `human_feedback_requested`, `human_feedback_received`, `flow_input_requested`, `flow_input_received`
|
||||
- **LLM** — `llm_call_started`, `llm_call_completed`, `llm_call_failed`, `llm_stream_chunk`, `llm_thinking_chunk`
|
||||
- **LLM Guardrail** — `llm_guardrail_started`, `llm_guardrail_completed`, `llm_guardrail_failed`
|
||||
- **Tool** — `tool_usage_started`, `tool_usage_finished`, `tool_usage_error`, `tool_validate_input_error`, `tool_selection_error`, `tool_execution_error`
|
||||
- **Memory** — `memory_save_started`, `memory_save_completed`, `memory_save_failed`, `memory_query_started`, `memory_query_completed`, `memory_query_failed`, `memory_retrieval_started`, `memory_retrieval_completed`, `memory_retrieval_failed`
|
||||
- **Knowledge** — `knowledge_search_query_started`, `knowledge_search_query_completed`, `knowledge_query_started`, `knowledge_query_completed`, `knowledge_query_failed`, `knowledge_search_query_failed`
|
||||
- **Reasoning** — `agent_reasoning_started`, `agent_reasoning_completed`, `agent_reasoning_failed`
|
||||
- **MCP** — `mcp_connection_started`, `mcp_connection_completed`, `mcp_connection_failed`, `mcp_tool_execution_started`, `mcp_tool_execution_completed`, `mcp_tool_execution_failed`, `mcp_config_fetch_failed`
|
||||
- **Observation** — `step_observation_started`, `step_observation_completed`, `step_observation_failed`, `plan_refinement`, `plan_replan_triggered`, `goal_achieved_early`
|
||||
- **Skill** — `skill_discovery_started`, `skill_discovery_completed`, `skill_loaded`, `skill_activated`, `skill_load_failed`
|
||||
- **Logging** — `agent_logs_started`, `agent_logs_execution`
|
||||
- **A2A** — `a2a_delegation_started`, `a2a_delegation_completed`, `a2a_conversation_started`, `a2a_conversation_completed`, `a2a_message_sent`, `a2a_response_received`, `a2a_polling_started`, `a2a_polling_status`, `a2a_push_notification_registered`, `a2a_push_notification_received`, `a2a_push_notification_sent`, `a2a_push_notification_timeout`, `a2a_streaming_started`, `a2a_streaming_chunk`, `a2a_agent_card_fetched`, `a2a_authentication_failed`, `a2a_artifact_received`, `a2a_connection_error`, `a2a_server_task_started`, `a2a_server_task_completed`, `a2a_server_task_canceled`, `a2a_server_task_failed`, `a2a_parallel_delegation_started`, `a2a_parallel_delegation_completed`, `a2a_transport_negotiated`, `a2a_content_type_negotiated`, `a2a_context_created`, `a2a_context_expired`, `a2a_context_idle`, `a2a_context_completed`, `a2a_context_pruned`
|
||||
- **시스템 시그널** — `SIGTERM`, `SIGINT`, `SIGHUP`, `SIGTSTP`, `SIGCONT`
|
||||
- **와일드카드** — `"*"`는 모든 이벤트와 일치합니다.
|
||||
|
||||
```python
|
||||
from crewai.events.event_bus import crewai_event_bus
|
||||
from crewai.events.types.llm_events import LLMCallCompletedEvent
|
||||
</Expandable>
|
||||
|
||||
# 동기 핸들러
|
||||
@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}")
|
||||
```
|
||||
<ParamField path="JsonProvider" type="provider">
|
||||
체크포인트당 하나의 파일, `location` 내부에 `<timestamp>_<uuid>.json` 형식으로 명명.
|
||||
</ParamField>
|
||||
|
||||
`state` 인수는 핸들러가 3개의 매개변수를 받을 때 이벤트 버스가 자동으로 전달하는 `RuntimeState`입니다. [Event Listeners](/ko/concepts/event-listener) 문서에 나열된 모든 이벤트 타입에 핸들러를 등록할 수 있습니다.
|
||||
<ParamField path="SqliteProvider" type="provider">
|
||||
WAL 저널링이 있는 `location`의 단일 데이터베이스 파일.
|
||||
</ParamField>
|
||||
|
||||
체크포인팅은 best-effort입니다: 체크포인트 기록이 실패하면 오류가 로그에 기록되지만 실행은 중단 없이 계속됩니다.
|
||||
### CLI
|
||||
|
||||
| 명령 | 목적 |
|
||||
|:-----|:-----|
|
||||
| `crewai checkpoint` | TUI 실행; 스토리지 자동 감지. |
|
||||
| `crewai checkpoint --location <path>` | 특정 위치에 대해 TUI 실행. |
|
||||
| `crewai checkpoint list <path>` | 체크포인트 나열. |
|
||||
| `crewai checkpoint info <path>` | 체크포인트 파일 또는 SQLite 데이터베이스의 최신 항목 검사. |
|
||||
|
||||
@@ -52,6 +52,8 @@ crewai create crew my_new_crew
|
||||
crewai create flow my_new_flow
|
||||
```
|
||||
|
||||
기본적으로 `crewai create crew`는 `crew.jsonc`와 `agents/*.jsonc`가 있는 JSON-first 프로젝트를 만듭니다. `crew.py`, `config/agents.yaml`, `config/tasks.yaml`을 사용하는 기존 Python/YAML 스캐폴드가 필요할 때만 `crewai create crew my_new_crew --classic`을 사용하세요.
|
||||
|
||||
### 2. 버전
|
||||
|
||||
설치된 CrewAI의 버전을 표시합니다.
|
||||
@@ -183,7 +185,20 @@ crewai chat
|
||||
이 명령어들은 CrewAI 프로젝트의 루트 디렉터리에서 실행해야 합니다.
|
||||
</Note>
|
||||
<Note>
|
||||
중요: 이 명령어를 사용하려면 `crew.py` 파일에서 `chat_llm` 속성을 설정해야 합니다.
|
||||
중요: 이 명령어를 사용하려면 crew 정의에 `chat_llm` 속성을 설정해야 합니다.
|
||||
|
||||
JSON-first crew에서는 `crew.jsonc`에 추가합니다:
|
||||
|
||||
```jsonc
|
||||
{
|
||||
"name": "My Crew",
|
||||
"agents": ["researcher"],
|
||||
"tasks": [],
|
||||
"chat_llm": "openai/gpt-4o"
|
||||
}
|
||||
```
|
||||
|
||||
클래식 Python/YAML crew에서는 `crew.py`에 설정합니다:
|
||||
|
||||
```python
|
||||
@crew
|
||||
@@ -313,7 +328,7 @@ CLI를 사용하여 [CrewAI AMP](http://app.crewai.com)에 crew를 배포하는
|
||||
|
||||
### 11. API 키
|
||||
|
||||
`crewai create crew` 명령어를 실행하면, CLI에서 선택할 수 있는 LLM 제공업체 목록이 표시되고, 그 다음으로 선택한 제공업체에 대한 모델 선택이 이어집니다.
|
||||
`crewai create crew` 명령어를 실행하면, CLI에서 선택할 수 있는 LLM 제공업체 목록이 표시되고, 그 다음으로 선택한 제공업체에 대한 모델 선택이 이어집니다. 선택한 모델은 생성된 `.env`에 저장되며 각 에이전트 JSONC 파일은 자체 `llm`을 설정할 수 있습니다.
|
||||
|
||||
LLM 제공업체와 모델을 선택하면, API 키를 입력하라는 메시지가 표시됩니다.
|
||||
|
||||
|
||||
@@ -41,13 +41,54 @@ crewAI에서 crew는 일련의 작업을 달성하기 위해 함께 협력하는
|
||||
|
||||
## 크루 생성하기
|
||||
|
||||
CrewAI에서 크루를 생성하는 방법은 두 가지가 있습니다: **YAML 구성(권장)**을 사용하는 방법과 **코드에서 직접 정의**하는 방법입니다.
|
||||
CrewAI에서 크루를 생성하는 주요 방법은 **JSONC 구성(새 crew 권장)**을 사용하는 방법과 클래식 프로젝트나 고급 사용 사례에서 **코드로 직접 정의**하는 방법입니다.
|
||||
|
||||
### YAML 구성 (권장)
|
||||
### JSONC 구성 (권장)
|
||||
|
||||
YAML 구성을 사용하면 crew를 정의할 때 더 깔끔하고 유지 관리하기 쉬운 방법을 제공하며, CrewAI 프로젝트에서 agent 및 task를 정의하는 방식과 일관성을 유지할 수 있습니다.
|
||||
`crewai create crew <name>`으로 만든 새 프로젝트는 crew 수준 설정과 태스크를 `crew.jsonc`에 두고, 각 에이전트를 `agents/`의 별도 파일에 둡니다. `crewai run`은 `crew.jsonc` 또는 `crew.json`을 감지해 에이전트를 로드하고, 빠진 placeholder 값을 물은 뒤 crew를 시작합니다.
|
||||
|
||||
[설치](/ko/installation) 섹션에 설명된 대로 CrewAI 프로젝트를 생성한 후, `CrewBase`를 상속받는 클래스에서 데코레이터를 이용해 agent, task, 그리고 crew 자체를 정의할 수 있습니다.
|
||||
```jsonc crew.jsonc
|
||||
{
|
||||
"name": "Market Research Crew",
|
||||
"agents": ["researcher", "analyst"],
|
||||
"tasks": [
|
||||
{
|
||||
"name": "research",
|
||||
"description": "Research {topic} and collect the most relevant facts.",
|
||||
"expected_output": "Structured research notes about {topic}.",
|
||||
"agent": "researcher"
|
||||
},
|
||||
{
|
||||
"name": "analysis",
|
||||
"description": "Analyze the research and write a concise report.",
|
||||
"expected_output": "A markdown report with findings and recommendations.",
|
||||
"agent": "analyst",
|
||||
"context": ["research"],
|
||||
"output_file": "output/report.md"
|
||||
}
|
||||
],
|
||||
"process": "sequential",
|
||||
"verbose": true,
|
||||
"memory": true,
|
||||
"inputs": {
|
||||
"topic": "AI Agents"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
`agents`의 각 문자열은 먼저 `agents/<name>.jsonc`, 그 다음 `agents/<name>.json`으로 해석됩니다. 계층형 crew는 `"process": "hierarchical"`와 `manager_llm` 또는 `manager_agent`를 사용하세요.
|
||||
|
||||
<Warning>
|
||||
신뢰하는 출처의 JSON crew 프로젝트만 실행하세요. `custom:<name>` 도구와 `{"python": "module.attribute"}` 참조는 crew 로드 시 로컬 Python 코드를 실행합니다.
|
||||
</Warning>
|
||||
|
||||
### 클래식 YAML 구성
|
||||
|
||||
`crewai create crew <name> --classic`으로 만든 클래식 프로젝트는 `crew.py`, `config/agents.yaml`, `config/tasks.yaml`, `@CrewBase`, `@agent`, `@task`, `@crew` 데코레이터를 사용합니다.
|
||||
|
||||
이 방식은 기존 Python/YAML 프로젝트와 Python 데코레이터 제어가 필요한 팀을 위해 계속 지원됩니다.
|
||||
|
||||
클래식 프로젝트를 만든 후, `CrewBase`를 상속받는 클래스에서 데코레이터를 이용해 agent, task, 그리고 crew 자체를 정의할 수 있습니다.
|
||||
|
||||
#### 데코레이터가 적용된 예시 Crew 클래스
|
||||
|
||||
@@ -416,4 +457,4 @@ crewai log-tasks-outputs
|
||||
crewai replay -t <task_id>
|
||||
```
|
||||
|
||||
이 명령어들을 사용하면 이전에 실행된 작업의 컨텍스트를 유지하면서 최신 kickoff 작업부터 다시 실행할 수 있습니다.
|
||||
이 명령어들을 사용하면 이전에 실행된 작업의 컨텍스트를 유지하면서 최신 kickoff 작업부터 다시 실행할 수 있습니다.
|
||||
|
||||
@@ -221,6 +221,48 @@ Flow가 실행된 후, 이러한 메소드들에 의해 수행된 업데이트
|
||||
최종 메소드의 출력이 반환되고 상태에 접근할 수 있도록 함으로써, CrewAI Flow는 AI 워크플로우의 결과를 더 큰 애플리케이션이나 시스템에 쉽게 통합할 수 있게 하며,
|
||||
Flow 실행 과정 전반에 걸쳐 상태를 유지하고 접근하면서도 이를 용이하게 만듭니다.
|
||||
|
||||
## 플로우 사용 메트릭
|
||||
|
||||
Flow 실행이 완료된 후, `usage_metrics` 속성에 접근하여 실행 동안 발생한 **모든 LLM 호출**의 토큰 사용량 집계를 확인할 수 있습니다. 여기에는 Flow가 오케스트레이션한 모든 Crew의 호출, Agent의 도구 내부에서 발생한 호출, 그리고 Flow 메서드에서 직접 호출한 `LLM.call(...)`이 모두 포함됩니다. 이는 CrewAI Enterprise UI에 표시되는 총량과 동등한 SDK 측 값입니다.
|
||||
|
||||
```python Code
|
||||
from crewai import LLM
|
||||
from crewai.flow.flow import Flow, listen, start
|
||||
|
||||
class UsageMetricsFlow(Flow):
|
||||
@start()
|
||||
def run_first_crew(self):
|
||||
self.state.first_result = FirstCrew().crew().kickoff()
|
||||
|
||||
@listen(run_first_crew)
|
||||
def call_llm_directly(self):
|
||||
# 직접 LLM 호출 — flow.usage_metrics에서도 집계됩니다
|
||||
llm = LLM(model="openai/gpt-4o-mini")
|
||||
self.state.summary = llm.call("핵심 내용을 요약해 주세요.")
|
||||
|
||||
@listen(call_llm_directly)
|
||||
def run_second_crew(self):
|
||||
self.state.second_result = SecondCrew().crew().kickoff()
|
||||
|
||||
flow = UsageMetricsFlow()
|
||||
flow.kickoff()
|
||||
|
||||
print(flow.usage_metrics)
|
||||
# UsageMetrics(total_tokens=8579, prompt_tokens=6210, completion_tokens=2369,
|
||||
# cached_prompt_tokens=0, reasoning_tokens=0,
|
||||
# cache_creation_tokens=0, successful_requests=5)
|
||||
```
|
||||
|
||||
<Note>
|
||||
`flow.usage_metrics`는 `flow.kickoff().token_usage`와 **동일하지 않습니다**.
|
||||
후자는 `CrewOutput`을 반환한 **마지막** `@listen` 메서드의
|
||||
`CrewOutput.token_usage`만 반환하므로, 이전에 실행된 Crew들과 Flow 메서드에서
|
||||
직접 호출한 `LLM.call(...)`은 전혀 포함되지 않습니다. Flow 실행에 대한
|
||||
**전체** 토큰 집계가 필요할 때는 항상 `flow.usage_metrics`를 사용하십시오.
|
||||
</Note>
|
||||
|
||||
반환되는 [`UsageMetrics`](https://github.com/crewAIInc/crewAI/blob/main/lib/crewai/src/crewai/types/usage_metrics.py)의 각 항목은 단일 `flow.kickoff()` 실행 동안 발생한 모든 LLM 호출의 합계입니다. 다음 `kickoff()` 호출(및 `kickoff_for_each`의 각 반복)에서 카운터가 초기화되므로 연속 실행이 이중으로 집계되지 않습니다. 이 속성은 `kickoff()` 완료 후 언제든지 안전하게 읽을 수 있으며, 실행 중에 읽으면 그 시점까지 누적된 부분 합계를 반환합니다.
|
||||
|
||||
## 플로우 상태 관리
|
||||
|
||||
상태를 효과적으로 관리하는 것은 신뢰할 수 있고 유지 보수가 용이한 AI 워크플로를 구축하는 데 매우 중요합니다. CrewAI 플로우는 비정형 및 정형 상태 관리를 위한 강력한 메커니즘을 제공하여, 개발자가 자신의 애플리케이션에 가장 적합한 접근 방식을 선택할 수 있도록 합니다.
|
||||
@@ -781,7 +823,7 @@ CrewAI에서 여러 crews로 flow를 생성하는 것은 간단합니다.
|
||||
crewai create flow name_of_flow
|
||||
```
|
||||
|
||||
이 명령어는 필요한 폴더 구조를 갖춘 새 CrewAI 프로젝트를 생성합니다. 생성된 프로젝트에는 이미 동작 중인 미리 구축된 crew인 `poem_crew`가 포함되어 있습니다. 이 crew를 템플릿으로 사용하여 복사, 붙여넣기, 수정함으로써 다른 crew를 만들 수 있습니다.
|
||||
이 명령어는 필요한 폴더 구조를 갖춘 새 CrewAI 프로젝트를 생성합니다. 생성된 프로젝트에는 이미 동작 중인 미리 구축된 crew인 `poem_crew`가 포함되어 있습니다. 시작용 embedded crew는 클래식 Python/YAML 레이아웃을 사용하며, `crewai create crew`로 만든 새 독립 실행형 crew는 JSON-first 레이아웃을 사용합니다.
|
||||
|
||||
### 폴더 구조
|
||||
|
||||
@@ -811,7 +853,29 @@ crewai create flow name_of_flow
|
||||
- `config/tasks.yaml`: 크루의 task를 정의합니다.
|
||||
- `poem_crew.py`: agent, task, 그리고 크루 자체를 포함한 crew 정의가 들어 있습니다.
|
||||
|
||||
`poem_crew`를 복사, 붙여넣기, 그리고 편집하여 다른 크루를 생성할 수 있습니다.
|
||||
`poem_crew`를 복사, 붙여넣기, 그리고 편집하여 다른 클래식 embedded crew를 생성할 수 있습니다.
|
||||
|
||||
JSON-first embedded crew는 `crew.jsonc`와 `agents/*.jsonc`가 있는 폴더를 사용하세요:
|
||||
|
||||
```text
|
||||
crews/
|
||||
└── research_crew/
|
||||
├── agents/
|
||||
│ └── researcher.jsonc
|
||||
└── crew.jsonc
|
||||
```
|
||||
|
||||
그런 다음 Flow 단계에서 로드합니다:
|
||||
|
||||
```python
|
||||
from pathlib import Path
|
||||
from crewai.project import load_crew
|
||||
|
||||
crew, default_inputs = load_crew(
|
||||
Path(__file__).parent / "crews" / "research_crew" / "crew.jsonc"
|
||||
)
|
||||
result = crew.kickoff(inputs={**default_inputs, "topic": "AI Agents"})
|
||||
```
|
||||
|
||||
### `main.py`에서 Crew 연결하기
|
||||
|
||||
|
||||
@@ -106,7 +106,7 @@ CrewAI 코드 내에는 사용할 모델을 지정할 수 있는 여러 위치
|
||||
</Tabs>
|
||||
|
||||
<Info>
|
||||
CrewAI는 OpenAI, Anthropic, Google (Gemini API), Azure, AWS Bedrock에 대해 네이티브 SDK 통합을 제공합니다 — 제공자별 extras(예: `uv add "crewai[openai]"`) 외에 추가 설치가 필요하지 않습니다.
|
||||
CrewAI는 OpenAI, Anthropic, Google (Gemini API), Azure, AWS Bedrock, Snowflake Cortex에 대해 네이티브 SDK 통합을 제공합니다 — 제공자별 extras(예: `uv add "crewai[openai]"`) 외에 추가 설치가 필요하지 않습니다.
|
||||
|
||||
그 외 모든 제공자는 **LiteLLM**을 통해 지원됩니다. 이를 사용하려면 프로젝트에 의존성으로 추가하세요:
|
||||
```bash
|
||||
@@ -230,6 +230,55 @@ CrewAI는 고유한 기능, 인증 방법, 모델 역량을 제공하는 다양
|
||||
```
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Snowflake Cortex">
|
||||
CrewAI는 OpenAI 호환 Chat Completions 엔드포인트를 통해 Snowflake Cortex REST API와 네이티브로 통합됩니다. `snowflake/...` 모델은 LiteLLM fallback 없이 사용됩니다. CrewAI에서 Snowflake Cortex는 현재 Chat Completions만 지원하므로 기본 `api` 모드를 사용하고 `api="responses"`를 설정하지 마세요.
|
||||
|
||||
```toml Code
|
||||
# Required
|
||||
SNOWFLAKE_PAT=<your-programmatic-access-token>
|
||||
SNOWFLAKE_ACCOUNT_URL=https://<account-identifier>.snowflakecomputing.com
|
||||
|
||||
# Alternative account configuration
|
||||
SNOWFLAKE_ACCOUNT=<account-identifier>
|
||||
```
|
||||
|
||||
**기본 사용법:**
|
||||
```python Code
|
||||
from crewai import LLM
|
||||
|
||||
llm = LLM(
|
||||
model="snowflake/openai-gpt-4.1",
|
||||
temperature=0.7,
|
||||
max_completion_tokens=1024,
|
||||
)
|
||||
```
|
||||
|
||||
**Cortex의 Claude 모델:**
|
||||
```python Code
|
||||
from crewai import LLM
|
||||
|
||||
llm = LLM(
|
||||
model="snowflake/claude-sonnet-4-5",
|
||||
max_completion_tokens=1024,
|
||||
stream=True,
|
||||
)
|
||||
```
|
||||
|
||||
**지원 환경 변수:**
|
||||
- `SNOWFLAKE_PAT`, `SNOWFLAKE_TOKEN`, 또는 `SNOWFLAKE_JWT`: Bearer 자격 증명으로 사용할 토큰
|
||||
- `SNOWFLAKE_ACCOUNT_URL`: 전체 Snowflake 계정 URL
|
||||
- `SNOWFLAKE_ACCOUNT`, `SNOWFLAKE_ACCOUNT_ID`, 또는 `SNOWFLAKE_ACCOUNT_IDENTIFIER`: 계정 URL을 만들 계정 식별자
|
||||
|
||||
Snowflake REST 요청은 사용자의 기본 Snowflake role을 사용합니다. 해당 role에 `SNOWFLAKE.CORTEX_USER` 또는 `SNOWFLAKE.CORTEX_REST_API_USER`가 있는지 확인하세요. Cortex REST Chat Completions 엔드포인트에는 database, schema, warehouse, 명시적 role 파라미터가 필요하지 않습니다.
|
||||
|
||||
**기능:**
|
||||
- `model="snowflake/<model-name>"`을 통한 네이티브 provider 선택
|
||||
- Streaming 및 non-streaming Chat Completions만 지원; `api="responses"`는 지원되지 않음
|
||||
- 토큰 사용량 추적
|
||||
- Snowflake 호스팅 OpenAI 및 Claude 모델의 함수 호출
|
||||
- Snowflake Claude 모델에서 유효하지 않은 마지막 assistant prefill 자동 제거
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Anthropic">
|
||||
```toml Code
|
||||
# Required
|
||||
|
||||
@@ -16,7 +16,6 @@ mode: "wide"
|
||||
|
||||
- **순차적(Sequential)**: 작업을 순차적으로 실행하여 작업이 질서 있게 진행되도록 보장합니다.
|
||||
- **계층적(Hierarchical)**: 작업을 관리 계층 구조로 조직하며, 작업은 체계적인 명령 체계를 기반으로 위임 및 실행됩니다. 계층적 프로세스를 활성화하려면 매니저 언어 모델(`manager_llm`) 또는 커스텀 매니저 에이전트(`manager_agent`)를 crew에서 지정해야 하며, 이를 통해 매니저가 작업을 생성하고 관리할 수 있도록 지원합니다.
|
||||
- **합의 프로세스(Consensual Process, 계획됨)**: 에이전트들 간에 작업 실행에 대한 협력적 의사결정을 목표로 하며, 이 프로세스 유형은 CrewAI 내에서 작업 관리를 민주적으로 접근하도록 도입됩니다. 앞으로 개발될 예정이며, 현재 코드베이스에는 구현되어 있지 않습니다.
|
||||
|
||||
## 팀워크에서 프로세스의 역할
|
||||
프로세스는 개별 에이전트가 통합된 단위로 작동할 수 있도록 하여, 공통된 목표를 효율적이고 일관성 있게 달성하도록 노력하는 과정을 간소화합니다.
|
||||
@@ -59,9 +58,9 @@ crew = Crew(
|
||||
|
||||
## Process 클래스: 상세 개요
|
||||
|
||||
`Process` 클래스는 열거형(`Enum`)으로 구현되어 타입 안전성을 보장하며, 프로세스 값을 정의된 타입(`sequential`, `hierarchical`)으로 제한합니다. 합의 기반(consensual) 프로세스는 향후 추가될 예정이며, 이는 지속적인 개발과 혁신에 대한 우리의 의지를 강조합니다.
|
||||
`Process` 클래스는 열거형(`Enum`)으로 구현되어 타입 안전성을 보장하며, 프로세스 값을 정의된 타입(`sequential`, `hierarchical`)으로 제한합니다.
|
||||
|
||||
## 결론
|
||||
|
||||
CrewAI 내의 프로세스를 통해 촉진되는 구조화된 협업은 에이전트 간 체계적인 팀워크를 가능하게 하는 데 매우 중요합니다.
|
||||
이 문서는 최신 기능, 향상 사항, 그리고 예정된 Consensual Process 통합을 반영하도록 업데이트되었으며, 사용자가 가장 최신이고 포괄적인 정보를 이용할 수 있도록 보장합니다.
|
||||
이 문서는 최신 기능과 향상 사항을 반영하도록 업데이트되었으며, 사용자가 가장 최신이고 포괄적인 정보를 이용할 수 있도록 보장합니다.
|
||||
@@ -64,13 +64,48 @@ crew = Crew(
|
||||
|
||||
## 작업 생성하기
|
||||
|
||||
CrewAI에서 작업을 생성하는 방법에는 **YAML 구성(권장)** 을 사용하는 방법과 **코드에서 직접 정의하는 방법** 두 가지가 있습니다.
|
||||
CrewAI에서 작업을 생성하는 일반적인 방법은 **JSONC 프로젝트 구성(새 crew 권장)** 또는 **코드에서 직접 정의**입니다.
|
||||
|
||||
### YAML 구성 (권장)
|
||||
### JSONC 구성 (권장)
|
||||
|
||||
YAML 구성을 사용하면 작업을 정의할 때 더 깔끔하고 유지 관리가 용이한 방법을 제공합니다. CrewAI 프로젝트에서 작업을 정의할 때 이 방식을 사용하는 것을 강력히 권장합니다.
|
||||
`crewai create crew <name>`으로 만든 새 프로젝트는 `crew.jsonc`에 태스크를 정의합니다.
|
||||
|
||||
[설치](/ko/installation) 섹션에 따라 CrewAI 프로젝트를 생성한 후, `src/latest_ai_development/config/tasks.yaml` 파일로 이동하여 템플릿을 귀하의 특정 작업 요구 사항에 맞게 수정하세요.
|
||||
```jsonc crew.jsonc
|
||||
{
|
||||
"name": "Research Crew",
|
||||
"agents": ["researcher", "reporting_analyst"],
|
||||
"tasks": [
|
||||
{
|
||||
"name": "research_task",
|
||||
"description": "Conduct thorough research about {topic}.",
|
||||
"expected_output": "A list of the most relevant information about {topic}.",
|
||||
"agent": "researcher"
|
||||
},
|
||||
{
|
||||
"name": "reporting_task",
|
||||
"description": "Review the research and expand it into a detailed report.",
|
||||
"expected_output": "A polished markdown report.",
|
||||
"agent": "reporting_analyst",
|
||||
"context": ["research_task"],
|
||||
"markdown": true,
|
||||
"output_file": "report.md"
|
||||
}
|
||||
],
|
||||
"inputs": {
|
||||
"topic": "AI Agents"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
각 태스크에는 `description`과 `expected_output`이 필요합니다. `agent` 값은 `agents`에 나열된 에이전트 이름과 일치해야 합니다. `context`는 이전 태스크 이름만 참조할 수 있으며, 이후 태스크 참조는 거부됩니다.
|
||||
|
||||
### 클래식 YAML 구성
|
||||
|
||||
`crewai create crew <name> --classic`으로 만든 클래식 프로젝트는 `config/tasks.yaml`과 `crew.py`의 `@CrewBase` 클래스를 사용합니다.
|
||||
|
||||
YAML 구성은 기존 Python/YAML 프로젝트와 `@CrewBase` 클래스에서 태스크를 정의하려는 팀을 위해 계속 지원됩니다.
|
||||
|
||||
클래식 프로젝트를 만든 후, `src/<project_name>/config/tasks.yaml` 파일로 이동하여 템플릿을 작업 요구 사항에 맞게 수정하세요.
|
||||
|
||||
<Note>
|
||||
YAML 파일 내 변수(예: `{topic}`)는 크루를 실행할 때 입력값에서 가져온 값으로 대체됩니다:
|
||||
@@ -106,7 +141,7 @@ reporting_task:
|
||||
이 YAML 구성을 코드에서 사용하려면 `CrewBase`를 상속받는 크루 클래스를 생성하세요:
|
||||
|
||||
```python crew.py
|
||||
# src/latest_ai_development/crew.py
|
||||
# src/<project_name>/crew.py
|
||||
|
||||
from crewai import Agent, Crew, Process, Task
|
||||
from crewai.project import CrewBase, agent, crew, task
|
||||
|
||||
112
docs/ko/enterprise/features/agent-control-plane/monitoring.mdx
Normal file
@@ -0,0 +1,112 @@
|
||||
---
|
||||
title: "자동화 살펴보기"
|
||||
description: "Automations 탭에서 플릿 상태, LLM 소비, 자동화별 동작을 확인합니다."
|
||||
sidebarTitle: "모니터링"
|
||||
icon: "gauge"
|
||||
mode: "wide"
|
||||
---
|
||||
|
||||
<Info>
|
||||
**ACP (베타) 문서 내비게이션**
|
||||
|
||||
- [개요](/ko/enterprise/features/agent-control-plane/overview)
|
||||
- **모니터링** *(현재 페이지)*
|
||||
- [규칙](/ko/enterprise/features/agent-control-plane/rules)
|
||||
</Info>
|
||||
|
||||
## 개요
|
||||
|
||||
**Automations** 탭은 [Agent Control Plane](/ko/enterprise/features/agent-control-plane/overview)의 읽기 전용 운영 뷰입니다. 두 개의 메트릭 카드, 인터랙티브 sankey, 그리고 **Automations**와 **Consumption** 두 개의 서브 테이블을 결합해 검색·필터·정렬을 지원합니다.
|
||||
|
||||
<Frame>
|
||||

|
||||
</Frame>
|
||||
|
||||
모든 차트와 테이블은 오른쪽 상단의 **지난 24시간 / 지난 1주 / 지난 30일** 선택기를 따릅니다. 변화량은 선택한 윈도우를 같은 길이의 이전 윈도우와 비교합니다.
|
||||
|
||||
<Note>
|
||||
행은 **crewAI v1.13 이상**의 deployment에 대해서만 데이터를 표시합니다. 그 이전 deployment는 sankey 아래 *"We've detected N other automations that we can't display"* 배너에 나타나며, 업데이트하고 재배포할 때까지 어떤 메트릭에도 기여하지 않습니다. [개요 — 요구사항](/ko/enterprise/features/agent-control-plane/overview#요구사항)을 참고하세요.
|
||||
</Note>
|
||||
|
||||
## 대시보드
|
||||
|
||||
페이지 상단에는 두 개의 메트릭 카드와 인터랙티브 sankey가 있습니다. 어느 카드를 클릭해도 sankey가 다음 두 모드 사이를 전환합니다:
|
||||
|
||||
- **상태 모드** — `전체 자동화 → 상태 버킷(Critical / Warning / Healthy)`. 버킷을 클릭하면 Automations 테이블이 해당 deployment로 필터링됩니다.
|
||||
- **소비 모드** — `모델 공급자 → 자동화 → 총 비용`. 공급자를 클릭하면 Consumption 테이블이 해당 공급자로 필터링됩니다.
|
||||
|
||||
| 카드 | 표시 내용 |
|
||||
|------|---------------|
|
||||
| **Automations** | `active` 자동화(및 전체 개수), 윈도우 내 총 `errors`, 현재 `active executions`(및 윈도우 내 총합), 이전 기간 대비 변화량. |
|
||||
| **Consumption** | 총 `cost`와 `tokens used`, 이전 기간 대비 비용 변화량. |
|
||||
|
||||
<Frame>
|
||||

|
||||
</Frame>
|
||||
|
||||
## Automations 테이블
|
||||
|
||||
**Automations** 서브 탭은 deployment 단위의 플릿 상태 분해입니다. 각 행은 배포된 하나의 crew 또는 flow입니다.
|
||||
|
||||
<Frame>
|
||||

|
||||
</Frame>
|
||||
|
||||
| 열 | 표시 내용 |
|
||||
|--------|---------------|
|
||||
| **Automation** | deployment 이름과 할당된 태그(예: `production`, `financial`). |
|
||||
| **Last execution** | 가장 최근 실행 이후 경과 시간. |
|
||||
| **Health Status Breakdown** | 윈도우 내 실행에 대한 `Critical` / `Warning` / `Healthy` 비율의 누적 막대. |
|
||||
| **Executions with Errors** | 윈도우 내 총 실패 실행 수. |
|
||||
| **PII detection applied** | deployment별 PII 설정 또는 일치하는 [PII 규칙](/ko/enterprise/features/agent-control-plane/rules)이 활성화된 경우 `Yes`. |
|
||||
| **Executions** | 윈도우 내 총 실행 수. |
|
||||
| **Last updated** | deployment의 마지막 재배포 시점. |
|
||||
| **Crew Version** | deployment가 보고한 `crewai` 버전. `1.13` 미만 버전 옆의 정보 아이콘은 메트릭에 기여할 수 없는 행을 표시합니다. |
|
||||
|
||||
이름으로 검색하고 `Status`(`Healthy` / `Warning` / `Critical`)로 필터링하며, 컬럼 헤더로 정렬할 수 있습니다. deployment 이름을 클릭하면 **Automation 패널**이 열립니다.
|
||||
|
||||
## Consumption 테이블
|
||||
|
||||
**Consumption** 서브 탭은 deployment 단위의 LLM 지출 및 토큰 사용량 분해입니다.
|
||||
|
||||
<Frame>
|
||||

|
||||
</Frame>
|
||||
|
||||
| 열 | 표시 내용 |
|
||||
|--------|---------------|
|
||||
| **Automation** | deployment 이름. |
|
||||
| **Last execution** | 가장 최근 실행 이후 경과 시간. |
|
||||
| **Tokens used** | 이 자동화가 사용한 LLM 공급자별로 한 행, 이전 기간 대비 변화량 포함. |
|
||||
| **Cost** | LLM 공급자별 비용, 이전 기간 대비 변화량 포함. |
|
||||
| **Total cost** | 모든 공급자의 합계, 변화량 포함. |
|
||||
| **Executions** | 윈도우 내 총 실행 수. |
|
||||
| **Last updated** | deployment의 마지막 재배포 시점. |
|
||||
| **Crew Version** | deployment가 보고한 `crewai` 버전. |
|
||||
|
||||
**LLM provider**로 필터링하고 `Cost`, `Executions` 또는 `Last run`으로 정렬할 수 있습니다.
|
||||
|
||||
<Info>
|
||||
**빈 셀(`—` 또는 `$0.00`)은 보통 deployment가 crewAI v1.13 미만임을 의미합니다.** 위 스크린샷에서 *Automation F*(`1.7.0`)와 *Automation I*(`1.12.2`)는 토큰과 비용이 비어 있습니다. 실행은 여전히 동작하지만, 이 테이블을 채우는 공급자 수준 텔레메트리를 emit하지 않습니다. 이 crew들을 업데이트하고 재배포하면 소비 데이터가 수집되기 시작합니다.
|
||||
</Info>
|
||||
|
||||
## 관련 문서
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Agent Control Plane — 개요" icon="book-open" href="/ko/enterprise/features/agent-control-plane/overview">
|
||||
ACP란 무엇이며, 요구사항, 플랜 등급, RBAC에 대해.
|
||||
</Card>
|
||||
<Card title="Agent Control Plane — 규칙" icon="shield-check" href="/ko/enterprise/features/agent-control-plane/rules">
|
||||
조직 단위 PII Redaction 규칙을 여러 자동화에 적용합니다.
|
||||
</Card>
|
||||
<Card title="Traces" icon="timeline" href="/ko/enterprise/features/traces">
|
||||
개별 실행을 드릴다운하여 에이전트의 추론, 도구 호출, 토큰 사용량을 확인합니다.
|
||||
</Card>
|
||||
<Card title="AMP에 배포" icon="rocket" href="/ko/enterprise/guides/deploy-to-amp">
|
||||
Agent Control Plane을 지원하는 crewAI 버전으로 crew를 배포합니다.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
<Card title="도움이 필요하신가요?" icon="headset" href="mailto:support@crewai.com">
|
||||
Agent Control Plane에서 메트릭을 해석하는 데 도움이 필요하시면 지원 팀에 문의하세요.
|
||||
</Card>
|
||||