📌개요
ChatDev를 실험하며 멀티 에이전트 시스템의 가능성을 확인한 뒤, 다음 실험 대상으로 CrewAI를 선택했다. CrewAI는 역할 기반의 AI 에이전트 팀을 구성하여 복잡한 태스크를 자동화하는 Python 프레임워크로, 코드 중심의 접근 방식이 특징이다.
이 포스팅에서는 CrewAI를 처음 설치하고 첫 번째 Crew를 실행하기까지의 전 과정을 정리한다. 프로젝트 구조 이해, 에이전트 및 태스크 정의, LLM 연동까지 한 번에 파악할 수 있도록 구성했다.
📌내용
왜 CrewAI를 선택했나?
멀티 에이전트 프레임워크를 비교할 때, CrewAI는 “비즈니스 프로세스 자동화” 에 가장 특화된 구조를 갖고 있다. 특히 에이전트에게 명확한 역할(Role), 목표(Goal), 배경(Backstory)을 부여하는 방식이 실제 팀 운영 모델과 잘 맞아떨어진다.
| 프레임워크 | 핵심 컨셉 | 특징 |
|---|---|---|
| CrewAI | 전문화된 팀(Crew) | 역할 기반, 비즈니스 프로세스 자동화에 적합 |
| ChatDev | 가상 소프트웨어 회사 | CEO/CTO 등 역할극 기반, 노드/엣지 UI |
| AutoGen | 에이전트 간 대화 | Microsoft 개발, 코드 실행/디버깅 능력이 강력 |
| MetaGPT | 표준 운영 절차(SOP) | 한 줄 요구사항으로 설계 문서부터 코드까지 생성 |
CrewAI를 선택한 이유는 세 가지다.
- 코드 기반의 세밀한 제어: YAML로 에이전트와 태스크를 선언하고, Python으로 오케스트레이션 로직을 직접 작성하여 세밀하게 제어할 수 있다.
- Flows + Crews 이중 구조: 상위 레벨의 실행 흐름(Flow)과 실제 작업 단위(Crew)를 분리하는 아키텍처가 복잡한 자동화에 적합하다.
- 풍부한 내장 도구: 웹 검색(SerperDev), 파일 읽기/쓰기, 코드 실행 등 다양한 도구가 기본 제공된다.
CrewAI 아키텍처 이해
CrewAI는 Flows와 Crews 두 개의 레이어로 구성된다.
| 레이어 | 역할 | 핵심 기능 |
|---|---|---|
| Flows | 애플리케이션의 뼈대 | 상태 관리, 이벤트 기반 실행, 조건 분기/루프 |
| Crews | 실제 작업 단위 | 역할 기반 에이전트, 자율 협업, 태스크 위임 |
실행 흐름:
- Flow가 이벤트를 발생시키거나 프로세스를 시작한다.
- Flow가 상태를 관리하고 다음 동작을 결정한다.
- Flow가 복잡한 태스크를 Crew에 위임한다.
- Crew의 에이전트들이 협업하여 태스크를 완료한다.
- Crew가 결과를 Flow에 반환한다.
- Flow가 결과에 따라 실행을 이어간다.
환경 구성 및 설치
사전 요구사항
아래 항목이 모두 준비되지 않으면 설치 자체가 진행되지 않는다.
| 항목 | 필요 버전 | 확인 명령 |
|---|---|---|
| Python | 3.10 이상, 3.14 미만 | python --version |
| uv | 최신 | uv --version |
uv는 pip보다 훨씬 빠른 Python 패키지 매니저로, CrewAI의 공식 의존성 관리 도구다.
| |
CrewAI CLI 설치
| |
Windows에서 chroma-hnswlib 빌드 오류(fatal error C1083: Cannot open include file: 'float.h')가 발생하면, Visual Studio Build Tools를 설치하고 Desktop development with C++ 워크로드를 선택한다.
프로젝트 생성
CrewAI는 CLI 명령 하나로 바로 실행 가능한 프로젝트 골격을 생성해준다.
| |
현재 버전에서 생성된 프로젝트 구조는 다음과 같다.
| |
| 파일 | 역할 |
|---|---|
agents.yaml | AI 에이전트의 역할, 목표, 배경 정의 |
tasks.yaml | 에이전트가 수행할 태스크와 워크플로우 설정 |
.env | API 키 등 민감한 환경 변수 보관 |
main.py | 프로젝트 진입점 및 실행 흐름 |
crew.py | Crew 오케스트레이션 및 조정 |
tools/ | 커스텀 에이전트 도구 디렉토리 |
knowledge/ | 에이전트 지식 베이스 디렉토리 |
에이전트 & 태스크 정의
agents.yaml — 에이전트 역할 정의
{topic} 같은 플레이스홀더를 사용해 실행 시점에 동적으로 값을 주입할 수 있다.
| |
tasks.yaml — 태스크 및 실행 순서 정의
| |
crew.py — Crew 오케스트레이션
| |
main.py — 진입점 및 입력값 전달
| |
LLM 및 API 키 설정
.env 파일에 사용할 LLM 제공자의 API 키를 입력한다.
| |
CrewAI는 OpenAI 외에도 Gemini, Claude, Ollama(로컬) 등 다양한 LLM을 지원한다. LLM별 상세 설정은 공식 LLM 가이드를 참고한다.
실행
| |
실행이 완료되면 output/report.md 파일에 최종 보고서가 생성된다.
crewai run이 실행하는 것
crewai run은 서버를 띄우거나 백그라운드 프로세스를 유지하는 명령이 아니다. 에이전트팀에게 태스크를 주고, 완료되면 결과물을 파일로 저장한 뒤 프로세스가 종료되는 일회성 실행이다.
내부적으로는 pyproject.toml의 [project.scripts]에 정의된 진입점을 읽어 main.py의 run() 함수를 호출한다.
flowchart TD
A("`**crewai run**`") --> B["`pyproject.toml 조회
\[project.scripts\]
my_crew = 'my_crew.main:run'`"]
B --> C["`main.py → run\(\)
inputs = \{'topic': 'AI LLMs', ...\}`"]
C --> D["`MyCrew\(\).crew\(\).kickoff\(inputs\)`"]
D --> E["`**1단계** researcher 에이전트
research_task 수행
LLM API 호출`"]
E --> F["`**2단계** reporting_analyst 에이전트
reporting_task 수행
LLM API 호출`"]
F --> G["`output/report.md 저장`"]
G --> H(["`✅ 프로세스 종료`"])
| 구분 | 웹 서버 실행 (예: npm run dev) | crewai run |
|---|---|---|
| 성격 | 서버 프로세스 상시 대기 (Listening) | 일회성 스크립트 실행 (Task Execution) |
| 종료 시점 | 사용자가 Ctrl+C로 수동 종료할 때까지 | 정의된 모든 태스크 완료 후 자동 종료 |
| 결과물 | HTTP 요청을 처리하는 인터페이스 제공 | 최종 결과 파일 (report.md 등) 및 로그 |
| 비유 | 식당 문 열기 (손님 기다리기) | 요리사에게 요리 한 접시 주문하기 |
관리자로서 Crew 다루기
CrewAI에서 개발자는 단순한 코드 작성자가 아니라 팀을 지휘하는 관리자(Director) 역할을 맡는다. 에이전트에게 무엇을 할지 지시하는 방법, 완전 자율로 실행시키는 방법, 중간에 개입하는 방법, 그리고 루프에 빠졌을 때 대응하는 방법을 알아야 한다.
지시 설계 — 관리자가 명령서를 작성하는 법
Crew에 대한 지시는 코드가 아니라 YAML 파일에 자연어로 작성한다. 명확하고 구체적인 지시일수록 에이전트의 결과물 품질이 높아진다.
| 지시 위치 | 역할 | 핵심 작성 원칙 |
|---|---|---|
agents.yaml → goal | 에이전트의 최종 목적 | 측정 가능한 목표로 작성 |
agents.yaml → backstory | 에이전트의 전문성·성격 | 역할에 맞는 구체적 배경 부여 |
tasks.yaml → description | 수행할 작업의 상세 내용 | 5W1H 기반으로 구체적으로 서술 |
tasks.yaml → expected_output | 결과물의 형식과 기준 | 포맷·분량·조건을 명시 |
main.py → inputs | 실행 시 동적으로 주입하는 변수 | {topic} 등 플레이스홀더에 값 전달 |
| |
프로젝트를 끝까지 자율 완수시키기
별도 개입 없이 처음부터 끝까지 자동으로 완료하게 하려면 tasks.yaml에서 context로 태스크 간 의존성을 연결하고, output_file로 최종 결과물 저장 경로를 지정하면 된다.
| |
Process.sequential에서는 앞 태스크의 결과가 자동으로 다음 태스크의 컨텍스트로 전달된다. 명시적으로 연결하려면 crew.py에서 context 파라미터를 사용한다.
| |
중간에 개입하기 — Human-in-the-Loop
에이전트가 특정 태스크를 완료한 후 사람의 검토·승인을 받도록 하려면 human_input=True를 사용한다.
| |
실행 시 해당 태스크가 끝나면 터미널에 결과물을 출력하고 “Provide feedback (or press Enter to approve):” 프롬프트가 뜬다. 피드백을 입력하면 에이전트가 재작업하고, 빈 값으로 Enter를 누르면 승인 후 다음 태스크로 진행한다.
flowchart TD
A(["`crewai run`"]) --> B["`research_task 완료`"]
B --> C["`reporting_task 수행`"]
C --> D{"`human_input=True
검토 대기`"}
D -- "피드백 입력" --> C
D -- "Enter\n승인" --> E["`output/report.md 저장`"]
E --> F(["`✅ 프로세스 종료`"])
Flow 레벨에서 더 세밀한 승인 분기가 필요하다면 @human_feedback 데코레이터(v1.8.0+)를 사용한다. emit=["approved", "rejected"]로 분기 라우팅을 정의할 수 있다.
루프 방지
LLM이 도구를 반복 호출하거나 같은 추론을 반복하는 루프에 빠지는 것은 흔한 문제다. 아래 세 가지 파라미터로 상한선을 설정한다.
| 파라미터 | 기본값 | 역할 | 설정 위치 |
|---|---|---|---|
max_iter | 20 | 에이전트가 최종 답변 전 시도할 수 있는 최대 반복 횟수 | Agent() |
max_execution_time | None | 에이전트 실행 최대 시간(초). 초과 시 강제 중단 | Agent() |
max_retry_limit | 2 | 오류 발생 시 재시도 최대 횟수 | Agent() |
| |
실행 중 루프가 감지되면 Ctrl+C로 즉시 중단할 수 있다. 중단된 지점부터 재실행하려면 crewai replay -t <task_id>를 사용한다. task_id는 crewai log-tasks-outputs로 확인한다.
| |
주요 Troubleshooting
| 증상 | 원인 | 해결책 |
|---|---|---|
uv tool install crewai 빌드 실패 (Windows) | C++ 빌드 도구 미설치 | Visual Studio Build Tools 설치 후 Desktop development with C++ 선택 |
PATH 경고 발생 | uv 바이너리 경로 미등록 | uv tool update-shell 실행 후 터미널 재시작 |
crewai 명령을 찾을 수 없음 | PATH 미반영 | 터미널 재시작 또는 uv tool update-shell 재실행 |
SERPER_API_KEY 관련 오류 | .env 파일 미설정 | .env에 SERPER_API_KEY 키 추가 |
| LLM API 연결 실패 | API 키 오류 또는 잔액 부족 | API 키 및 결제 상태 확인 |
| Python 버전 오류 | 3.10 미만 또는 3.14 이상 | Python 3.10~3.13 버전으로 재설치 |
🎯결론
uv tool install crewai -> crewai create crew <name> -> .env 작성 -> crewai install -> crewai run, 이 다섯 단계만 기억하면 CrewAI의 첫 번째 멀티 에이전트 실행을 마칠 수 있다.
CrewAI는 YAML로 에이전트와 태스크를 선언하고 Python으로 오케스트레이션 로직을 작성하는 코드 중심 프레임워크다. ChatDev의 노드/엣지 UI와 달리 세밀한 제어가 가능하고, Flows와 Crews의 이중 레이어 구조 덕분에 단순한 실험부터 프로덕션 수준의 자동화까지 확장하기 좋다. 다음 단계는 커스텀 Tool을 작성하고, Flow를 활용한 멀티 Crew 파이프라인을 구축해보는 것이다.
⚙️EndNote
사전 지식
- Multi-Agent System: 여러 자율적 에이전트가 상호작용하며 문제를 해결하는 시스템
- LLM (Large Language Model): ChatGPT, Gemini, Claude 등 대규모 언어 모델
- Role-Playing Agent: 특정 역할(Role), 목표(Goal), 배경(Backstory)을 부여받아 그에 맞게 행동하는 AI 에이전트
- Process.sequential: 태스크를 정의된 순서대로 하나씩 순차 실행하는 CrewAI 실행 모드.
Process.hierarchical을 사용하면 매니저 에이전트가 위임 구조로 실행한다. - Kickoff: Crew를 시작하는 메서드.
crew().kickoff(inputs={...})로 동적 입력값을 전달할 수 있다. - uv: Rust로 작성된 고속 Python 패키지 매니저. pip 대비 10~100배 빠른 속도를 자랑하며, CrewAI의 공식 의존성 관리 도구다.
더 알아보기
- CrewAI 공식 문서: https://docs.crewai.com
- CrewAI GitHub: https://github.com/crewAIInc/crewAI
- CrewAI AMP (SaaS): https://app.crewai.com
- uv 공식 문서: https://docs.astral.sh/uv/
- CrewAI LLM 연동 가이드: https://docs.crewai.com/concepts/llms
- SerperDev (웹 검색 API): https://serper.dev/
- Visual Studio Build Tools: https://visualstudio.microsoft.com/downloads/
- CrewAI 커뮤니티: https://community.crewai.com