CrewAI - framework open source do organizacji zespołów wysoko wydajnych agentów AI.
- CrewAI Enterprise - platforma hostingowa (monetyzacja)
- CrewAI UI Studio - narzędzie low-code/no-code
- CrewAI Framework - framework open source (nasz fokus)
| Aspekt | CrewAI Crews | CrewAI Flows |
|---|---|---|
| Charakter | Autonomiczne, kreatywna współpraca | Deterministyczne, stałe przepływy |
| Zastosowanie | Eksploracyjne zadania, burze mózgów | Precyzyjna kontrola, audytowalność |
| Kontrola | Większa swoboda agentów | Ściśle określony przepływ |
Fokus kursu: CrewAI Crews (autonomiczność)
- Autonomiczna jednostka pracy powiązana z LLM
- Składa się z: Role, Goal, Backstory
- Opcjonalnie: Memory, Tools
- Analogia: Agent z Tygodnia 2, ale bardziej ustrukturyzowany
- Konkretne, jednorazowe zadanie do wykonania
- Ma opis i oczekiwany wynik
- Przypisane do jednego agenta
- Brak bezpośredniej analogii w Tygodniu 2!
- Agregat Agentów i Zadań
- Koordynuje przepływ pracy
- Analogia: Runner/Trace (Orkiestrator) z wbudowaną logiką
| Tryb | Opis | Zastosowanie |
|---|---|---|
| Sequential | Zadania jedno po drugim w określonej kolejności | Determinatywne, audytowalne przepływy |
| Hierarchical | Manager LLM przydziela zadania innym agentom | Złożone, autonomiczne, eksploracyjne zadania |
- ✅ Wymusza dobre praktyki: Role, Goal, Backstory
- ✅ Promuje kompleksowy kontekst dla LLM
- ✅ Separacja konfiguracji (YAML)
- ✅ Automatyzacja orkiestracji
- ❌ Mniej elastyczności niż OpenAI Agents SDK
- ❌ Monit systemowy jest składany z 3 elementów (ukryty)
- ❌ Mniej bezpośredniej kontroli nad promptem
- LiteLLM - biblioteka abstrakcyjna ujednolicająca API wielu dostawców
- Format w YAML: Może być z prefiksem lub bez:
- Z prefiksem:
openai/gpt-4o-mini,anthropic/claude-3-haiku,google/gemini-2.5-flash - Bez prefiksu:
gpt-4o-mini(domyślnie OpenAI)
- Z prefiksem:
- Zaleta: Łatwe przełączanie modeli, integracja z Ollama/OpenRouter
- W projekcie:
llm: gpt-4o-mini(bez prefiksu, domyślnie OpenAI)
crew create crew my_project_name
# lub
crew create flow my_project_namemy_project/
└── src/
└── my_project/
├── config/
│ ├── agents.yaml # Konfiguracja agentów
│ └── tasks.yaml # Konfiguracja zadań
├── crew.py # Definicja agentów, zadań, załogi (dekoratory)
└── main.py # Punkt wejścia
crewai run
# lub przez Python
python -m ai_agents_crewai_debate.mainUżywane w crew.py:
@CrewBase- dekorator dla głównej klasy zarządzającej (dekoruje klasę, nie funkcję)@agent- dekorator dla metody tworzącej Agenta (automatycznie dodaje doself.agents)@task- dekorator dla metody tworzącej Zadanie (automatycznie dodaje doself.tasks)@crew- dekorator dla metody zwracającej Załogę (określaprocess)
from crewai.project import CrewBase, agent, crew, task
from crewai import Agent, Crew, Process, Task
@CrewBase
class AiAgentsCrewaiDebate:
"""AiAgentsCrewaiDebate crew"""
agents: List[BaseAgent]
tasks: List[Task]
@agent
def debater(self) -> Agent:
return Agent(
config=self.agents_config["debater"],
verbose=True,
)
@agent
def judge(self) -> Agent:
return Agent(
config=self.agents_config["judge"],
verbose=True,
)
@task
def propose_task(self) -> Task:
return Task(
config=self.tasks_config["propose"],
)
@task
def oppose_task(self) -> Task:
return Task(
config=self.tasks_config["oppose"],
)
@task
def decide_task(self) -> Task:
return Task(
config=self.tasks_config["decide"],
)
@crew
def crew(self) -> Crew:
return Crew(
agents=self.agents, # Automatycznie wypełnione przez @agent
tasks=self.tasks, # Automatycznie wypełnione przez @task
process=Process.sequential, # Enum, nie string!
verbose=True,
)| Pole | Opis | Rola w Prompt Engineering |
|---|---|---|
role |
Zawodowa tożsamość agenta | Określa kim jest agent |
goal |
Główny cel do osiągnięcia | Definiuje intencję |
backstory |
Historia/kontekst agenta | Wprowadza kontekst i ton |
llm |
Model LLM (format: dostawca/model) |
Określa użyty model |
debater:
role: >
Przekonujący Debatant
goal: >
Przedstaw jasny argument za lub przeciw wnioskowi. Wnioskowanie to: {motion}
backstory: >
Jesteś doświadczonym dyskutantem z talentem do podawania zwięzłych, ale przekonujących argumentów.
Wnioskowanie to: {motion}
llm: gpt-4o-mini # Może być bez prefiksu lub z prefiksem: openai/gpt-4o-minijudge:
role: >
Wyłonienie zwycięzcy debaty na podstawie przedstawionych argumentów
goal: >
Przedstawione argumenty za i przeciw wnioskowi: {motion}, wyłonienie strony, która jest bardziej przekonująca,
na podstawie przedstawionych argumentów.
backstory: >
Jesteś uczciwym sędzią z reputacją oceniającym argumenty bez uwzględniania własnych poglądów i podejmowania decyzji na podstawie meritów argumentu.
Wnioskowanie to: {motion}
llm: gpt-4o-miniUwaga: Szablony {motion}, {current_year} są wypełniane przez inputs w main.py
description- co ma być wykonane (może zawierać szablony{motion})expected_output- oczekiwany wynikoutput_file- plik wyjściowy (opcjonalnie, zapisuje wynik do pliku)agent- nazwa agenta przypisanego do zadania (musi odpowiadać kluczowi wagents.yaml)
propose:
description: >
Jesteś proponującym wnioskowanie: {motion}.
Przedstaw jasny argument za wnioskowanie.
Bądź bardzo przekonujący.
expected_output: >
Twój jasny argument za wnioskowanie, w zwięzły sposób.
agent: debater
output_file: output/propose.md
oppose:
description: >
Jesteś przeciwnikiem wnioskowania: {motion}.
Przedstaw jasny argument przeciw wnioskowaniu.
Bądź bardzo przekonujący.
expected_output: >
Twój jasny argument przeciw wnioskowaniu, w zwięzły sposób.
agent: debater
output_file: output/oppose.md
decide:
description: >
Przejrzyj przedstawione argumenty przez dyskutantów i wyłonienie strony, która jest bardziej przekonująca.
expected_output: >
Twoja decyzja na temat strony, która jest bardziej przekonująca, i dlaczego.
agent: judge
output_file: output/decide.mdUwaga: W projekcie debaty jeden agent (debater) wykonuje dwa zadania (propose i oppose), a judge wykonuje decide.
| Etap | Akcja | Kluczowa Koncepcja |
|---|---|---|
| Inicjalizacja | crewai create crew my_project |
Scaffolding projektu (UV) |
| Konfiguracja Agentów | config/agents.yaml |
Role, Goal, Backstory, LLM (szablony {motion}) |
| Konfiguracja Zadań | config/tasks.yaml |
Description, expected_output, output_file, agent |
| Orkiestracja | src/project/crew.py |
Dekoratory, Process.sequential (enum) |
| Inputs | main.py |
Słownik inputs z wartościami dla szablonów |
| Uruchomienie | crewai run lub python -m project.main |
crew().kickoff(inputs=inputs) |
- Opiniotwórczość - wymusza dobrą inżynierię podpowiedzi
- Separacja konfiguracji (YAML) - oddzielenie treści od logiki
- Sekwencyjny proces - deterministyczne wykonanie zadań (
Process.sequential) - Dekoratory - automatyczna rejestracja komponentów (
self.agents,self.tasks) - Szablony w YAML -
{motion},{current_year}wypełniane przezinputs - Output files - automatyczne zapisywanie wyników zadań do plików
from ai_agents_crewai_debate.crew import AiAgentsCrewaiDebate
from datetime import datetime
def run():
inputs = {
"motion": "Samoświadomość i AI LLMs",
"current_year": str(datetime.now().year),
}
AiAgentsCrewaiDebate().crew().kickoff(inputs=inputs)Kluczowe:
inputsto słownik z wartościami dla szablonów w YAMLkickoff(inputs=inputs)uruchamia załogę- Szablony
{motion}i{current_year}są automatycznie zastępowane
| Aspekt | OpenAI Agents SDK | CrewAI |
|---|---|---|
| Struktura | Minimalistyczna | Opiniotwórcza, ustrukturyzowana |
| Prompt | Bezpośrednia kontrola (instructions) |
Składany z Role/Goal/Backstory |
| Zadania | W kodzie lub w agencie | Osobny byt (Task) |
| Orkiestracja | Manualna (asyncio) | Automatyczna (Crew) |
| Modele | Głównie OpenAI | Wiele dostawców (LiteLLM) |
| Elastyczność | Wysoka | Średnia (kompromis) |
Agenci mogą używać narzędzi do wykonywania akcji. Przykład custom tool:
from typing import Type
from crewai.tools import BaseTool
from pydantic import BaseModel, Field
class MyCustomToolInput(BaseModel):
"""Input schema for MyCustomTool."""
argument: str = Field(..., description="Description of the argument.")
class MyCustomTool(BaseTool):
name: str = "Name of my tool"
description: str = "Dokładny opis zastosowania danego narzędzia."
args_schema: Type[BaseModel] = MyCustomToolInput
def _run(self, argument: str) -> str:
# Implementation goes here
return "Wynik działania narzędzia"Użycie w agencie:
@agent
def debater(self) -> Agent:
return Agent(
config=self.agents_config["debater"],
tools=[MyCustomTool()], # Dodanie narzędzia
verbose=True,
)Zrealizowane w projekcie:
- ✅ Dwa zadania dla debatanta:
propose(za) ioppose(przeciw) - ✅ Trzy zadania sekwencyjne: propose → oppose → decide
⚠️ Różne modele: Można przypisać różne LLM do różnych agentów
Do zrobienia:
- Przypisz różne modele do
debaterijudge(np.gpt-4ovsgpt-4o-mini) - Obserwuj wpływ modelu na jakość argumentów i decyzji
- Tydzień 2:
asyncioi Function Calling - fundamenty - Tydzień 3: CrewAI - co robi inaczej (terminologia) i co upraszcza (orkiestracja)
- Agent = Role + Goal + Backstory + LLM (definiowane w
agents.yaml) - Task = osobny byt (nie w agencie, nie w kodzie) - definiowane w
tasks.yaml - Crew = agregat Agentów + Zadań z trybem procesu (
Process.sequentiallubProcess.hierarchical) - YAML = separacja konfiguracji od logiki (szablony
{variable}) - Dekoratory = automatyczna rejestracja (
@CrewBase,@agent,@task,@crew) - LiteLLM = elastyczność modeli (format:
dostawca/modellub bez prefiksu) - Inputs = wypełnianie szablonów (
kickoff(inputs={...})) - Output files = automatyczne zapisywanie wyników zadań do plików
ai_agents_crewai_debate/
├── src/
│ └── ai_agents_crewai_debate/
│ ├── config/
│ │ ├── agents.yaml # 2 agenty: debater, judge
│ │ └── tasks.yaml # 3 zadania: propose, oppose, decide
│ ├── tools/
│ │ └── custom_tool.py # Przykład custom tool
│ ├── crew.py # Klasa z dekoratorami
│ └── main.py # Inputs i kickoff()
├── output/ # Wyniki zadań (propose.md, oppose.md, decide.md)
├── pyproject.toml # Zależności (crewai[tools]==1.5.0)
└── README.md
# Tworzenie projektu
crewai create crew my_project
# Instalacja zależności
crewai install
# Uruchomienie
crewai run
# Inne funkcje (z main.py)
python -m ai_agents_crewai_debate.main train <iterations> <filename>
python -m ai_agents_crewai_debate.main replay <task_id>
python -m ai_agents_crewai_debate.main test <iterations> <eval_llm>