CrewAI 에이전트 구조
CrewAI 프레임워크에서 에이전트의 역할과 주요 속성에 대해 정리합니다.
에이전트란?
CrewAI에서 Agent
는 다음과 같은 기능을 가진 자율적인 유닛입니다:
- 특정 작업을 수행할 수 있음
- 자신의 역할과 목표에 따라 의사결정을 수행함
- 목표 달성을 위해 도구를 사용할 수 있음
- 다른 에이전트와 소통 및 협업 가능
- 상호작용 내역을 기억할 수 있음
- 필요 시 작업을 다른 에이전트에게 위임 가능함
Tip: 에이전트는 각자의 기술과 전문성을 가진 팀원이라고 생각하면 됩니다. 예를 들어
Researcher
에이전트는 정보를 탐색하고 분석하는 데 능숙하고,Writer
에이전트는 콘텐츠 작성에 특화되어 있을 수 있습니다.
Enterprise 기능 - Visual Agent Builder CrewAI Enterprise에는 코드를 작성하지 않고도 시각적으로 에이전트를 만들고 설정할 수 있는 Visual Agent Builder가 포함되어 있습니다. 실시간 테스트와 검증, 폼 기반 설정 인터페이스, 템플릿 라이브러리 등으로 구성되어 있습니다.
에이전트 속성 (Agent Attributes)
속성명 | 파라미터명 | 타입 | 설명 |
---|---|---|---|
역할 (Role) | role | str | 해당 에이전트의 기능과 전문성을 정의합니다. |
목표 (Goal) | goal | str | 에이전트가 수행해야 하는 개별 목표를 명시합니다. |
배경 (Backstory) | backstory | str | 에이전트의 배경과 성격을 부여하여 상호작용을 풍부하게 만듭니다. |
언어모델 (LLM) | llm | Union[str, LLM, Any] | 에이전트가 사용하는 LLM (기본: 환경변수 또는 gpt-4). |
도구 목록 (Tools) | tools | List[BaseTool] | 에이전트가 사용할 수 있는 도구 목록. 기본은 빈 리스트입니다. |
툴 전용 LLM | function_calling_llm | Optional[Any] | 도구 실행 전용 LLM (설정 시 crew 전체 설정을 무시하고 사용함). |
최대 반복 횟수 | max_iter | int | 에이전트가 답을 내놓기 전 최대 반복 횟수 (기본값: 20). |
최대 요청 수 (RPM) | max_rpm | Optional[int] | API Rate Limit 회피를 위한 분당 요청 제한 수. |
최대 실행 시간 | max_execution_time | Optional[int] | 에이전트의 최대 실행 시간 (초). |
메모리 유지 여부 | memory | bool | 상호작용 메모리 유지 여부 (기본: True). |
로그 출력 여부 | verbose | bool | 디버깅용 상세 로그 활성화 (기본: False). |
작업 위임 허용 | allow_delegation | bool | 다른 에이전트에게 작업 위임 허용 여부 (기본: False). |
단계별 콜백 | step_callback | Optional[Any] | 각 단계 실행 후 호출될 콜백 함수 지정. |
도구 캐시 사용 | cache | bool | 도구 결과 캐싱 여부 (기본: True). |
시스템 프롬프트 템플릿 | system_template | Optional[str] | 에이전트에 적용할 시스템 프롬프트 템플릿. |
프롬프트 템플릿 | prompt_template | Optional[str] | 사용자 입력 프롬프트 템플릿. |
응답 템플릿 | response_template | Optional[str] | 에이전트의 응답 형식 템플릿. |
코드 실행 허용 여부 | allow_code_execution | Optional[bool] | 에이전트가 코드를 실행할 수 있는지 여부. (기본: False). |
재시도 횟수 제한 | max_retry_limit | int | 오류 발생 시 재시도 가능한 최대 횟수 (기본: 2). |
컨텍스트 창 제한 준수 여부 | respect_context_window | bool | 토큰 제한 초과 방지를 위한 요약 처리 (기본: True). |
코드 실행 모드 | code_execution_mode | Literal["safe", "unsafe"] | 코드 실행 방식: safe (도커 사용), unsafe (직접 실행). 기본은 safe. |
임베더 설정 | embedder | Optional[Dict[str, Any]] | 에이전트가 사용하는 임베더 설정. |
지식 소스 | knowledge_sources | Optional[List[BaseKnowledgeSource]] | 에이전트가 참고할 지식 소스 목록. |
시스템 프롬프트 사용 여부 | use_system_prompt | Optional[bool] | 시스템 프롬프트를 사용할지 여부 (기본: True). |
에이전트 생성 방법
CrewAI에서 에이전트를 생성하는 방법은 두 가지가 있습니다:
- YAML 설정을 사용하는 방법 (추천)
- 직접 코드를 통해 정의하는 방법
YAML 설정 사용 (추천)
YAML 파일을 사용하면 에이전트를 보다 깔끔하고 유지보수하기 쉬운 방식으로 정의할 수 있습니다. CrewAI 프로젝트에서는 이 방식을 가장 추천합니다.
CrewAI 프로젝트를 생성한 후, src/latest_ai_development/config/agents.yaml
파일로 이동하여 에이전트 설정 템플릿을 자신의 요구에 맞게 수정합니다.
참고: YAML 설정 파일 내 변수 (
{topic}
등)는 실행 시점에 입력값으로 치환됩니다.
1
crew.kickoff(inputs={'topic': 'AI Agents'})
YAML 파일의 예시는 다음과 같습니다:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# src/latest_ai_development/config/agents.yaml
researcher:
role: >
{topic} 수석 데이터 리서처
goal: >
{topic}의 최신 기술 동향을 조사하고 분석합니다
backstory: >
당신은 {topic} 분야에서 오랜 경험을 가진 리서처입니다. 가장 핵심적인 정보를 빠르게 찾아내어 간결하게 정리하는 능력이 탁월합니다.
reporting_analyst:
role: >
{topic} 리포트 애널리스트
goal: >
{topic} 데이터를 분석하고 연구 내용을 기반으로 보고서를 작성합니다
backstory: >
당신은 디테일에 강한 분석가로, 복잡한 데이터를 누구나 이해하기 쉬운 형태의 보고서로 정리하는 데 특화되어 있습니다.
이 YAML 설정을 코드에서 사용하려면 CrewBase
를 상속한 크루 클래스를 정의합니다:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# 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 크루 클래스"""
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
)
YAML 설정에서 정의한 이름(
researcher
,reporting_analyst
)은 반드시 Python 코드 내 메서드 이름과 일치해야 합니다.
직접 코드 정의 방식
에이전트는 Python 코드에서 Agent
클래스를 직접 인스턴스화하여 정의할 수도 있습니다. 아래는 사용 가능한 거의 모든 파라미터를 포함한 예시입니다:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
from crewai import Agent
from crewai_tools import SerperDevTool
# 전체 파라미터를 포함한 에이전트 생성 예시
agent = Agent(
role="수석 데이터 사이언티스트", # 필수
goal="복잡한 데이터를 분석하고 실행 가능한 인사이트를 도출", # 필수
backstory="데이터 사이언스와 머신러닝 분야에서 10년 이상 경험을 가진 전문가로, 복잡한 데이터에서 패턴을 찾아내는 데 탁월합니다.", # 필수
llm="gpt-4", # 기본값: OPENAI_MODEL_NAME 또는 "gpt-4"
function_calling_llm=None, # 옵션: 도구 호출 전용 LLM
memory=True, # 기본값: True, 상호작용 메모리 사용 여부
verbose=False, # 기본값: False, 디버깅 로그 출력 여부
allow_delegation=False, # 기본값: False, 작업 위임 허용 여부
max_iter=20, # 기본값: 20, 최대 반복 횟수
max_rpm=None, # 옵션: API 호출 제한 설정
max_execution_time=None, # 옵션: 최대 실행 시간(초)
max_retry_limit=2, # 기본값: 2, 오류 발생 시 재시도 횟수
allow_code_execution=False, # 기본값: False, 코드 실행 허용 여부
code_execution_mode="safe", # 기본값: "safe" (Docker 기반 안전 실행)
respect_context_window=True, # 기본값: True, 토큰 컨텍스트 초과 방지
use_system_prompt=True, # 기본값: True, 시스템 프롬프트 사용 여부
tools=[SerperDevTool()], # 옵션: 사용할 도구 리스트
knowledge_sources=None, # 옵션: 지식 소스 리스트
embedder=None, # 옵션: 커스텀 임베더 설정
system_template=None, # 옵션: 시스템 프롬프트 템플릿
prompt_template=None, # 옵션: 입력 프롬프트 템플릿
response_template=None, # 옵션: 응답 출력 템플릿
step_callback=None, # 옵션: 단계별 콜백 함수
)
다양한 상황에 맞춘 구성 예시:
정보 조사용 에이전트
1
2
3
4
5
6
7
research_agent = Agent(
role="리서치 애널리스트",
goal="특정 주제에 대한 정보를 조사하고 요약",
backstory="세부사항에 집중하는 능력이 뛰어난 경험 많은 리서처입니다.",
tools=[SerperDevTool()],
verbose=True # 디버깅 로그 활성화
)
코드 작성용 에이전트
1
2
3
4
5
6
7
8
9
dev_agent = Agent(
role="시니어 파이썬 개발자",
goal="파이썬 코드를 작성하고 디버깅",
backstory="10년 경력의 파이썬 전문가입니다.",
allow_code_execution=True,
code_execution_mode="safe", # Docker를 통한 안전 실행
max_execution_time=300, # 최대 5분 실행 제한
max_retry_limit=3 # 복잡한 코드 작업 시 더 많은 재시도
)
장시간 분석용 에이전트
1
2
3
4
5
6
7
8
9
analysis_agent = Agent(
role="데이터 애널리스트",
goal="대규모 데이터셋의 심층 분석 수행",
backstory="빅데이터 분석과 패턴 인식에 특화된 전문가입니다.",
memory=True,
respect_context_window=True,
max_rpm=10, # API 호출 제한 설정
function_calling_llm="gpt-4o-mini" # 저렴한 모델을 도구 호출용으로 사용
)
템플릿을 활용한 고객 지원용 에이전트
1
2
3
4
5
6
7
8
9
10
11
custom_agent = Agent(
role="고객 지원 담당자",
goal="고객의 문의에 친절하고 신속하게 응답",
backstory="고객 만족을 우선으로 생각하는 경험 많은 고객 응대 전문가입니다.",
system_template="""<|start_header_id|>system<|end_header_id|>
<|eot_id|>""",
prompt_template="""<|start_header_id|>user<|end_header_id|>
<|eot_id|>""",
response_template="""<|start_header_id|>assistant<|end_header_id|>
<|eot_id|>""",
)
파라미터 요약 정리
필수 핵심 파라미터
role
,goal
,backstory
: 에이전트의 행동을 결정짓는 핵심 요소llm
: 사용할 언어모델 지정 (기본은 GPT-4)
메모리 및 컨텍스트
memory
: 이전 상호작용 내용 유지respect_context_window
: 토큰 한도 초과 방지knowledge_sources
: 도메인 기반 지식 활용 가능
실행 제어
max_iter
: 최대 반복 횟수 지정max_execution_time
: 최대 실행 시간 설정max_rpm
: API 호출 속도 제한max_retry_limit
: 오류 발생 시 재시도 횟수
코드 실행
allow_code_execution
: 코드 실행 허용 여부code_execution_mode
:"safe"
: Docker 기반 안전 실행 (권장)"unsafe"
: 직접 실행 (신뢰된 환경에서만)
템플릿 커스터마이징
system_template
: 에이전트의 핵심 시스템 프롬프트prompt_template
: 사용자 입력 형식 구조화response_template
: 에이전트 응답 포맷 지정
참고: 템플릿 내에서는
{role}
,{goal}
,{input}
등의 변수를 사용하여 동적으로 내용이 채워집니다.
에이전트 도구 구성 (Agent Tools)
에이전트는 다양한 도구를 장착하여 기능을 확장할 수 있습니다. CrewAI는 다음과 같은 도구 생태계를 지원합니다:
아래는 도구를 에이전트에 연결하는 예시입니다:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
from crewai import Agent
from crewai_tools import SerperDevTool, WikipediaTools
# 도구 생성
search_tool = SerperDevTool()
wiki_tool = WikipediaTools()
# 에이전트에 도구 추가
researcher = Agent(
role="AI 기술 리서처",
goal="최신 AI 기술을 조사하고 분석",
tools=[search_tool, wiki_tool],
verbose=True
)
에이전트 메모리 및 컨텍스트 관리
에이전트는 이전 상호작용을 기억하고, 이를 바탕으로 더 복잡한 작업을 수행할 수 있습니다. 아래는 메모리 사용 예시입니다:
1
2
3
4
5
6
7
8
from crewai import Agent
analyst = Agent(
role="데이터 분석가",
goal="복잡한 데이터 패턴을 분석하고 기억",
memory=True, # 메모리 사용 활성화
verbose=True
)
참고:
memory
가 활성화되어 있으면 에이전트는 여러 작업 간의 컨텍스트를 유지하며, 다단계 작업에 더욱 적합해집니다.
유의사항 및 베스트 프랙티스
보안 및 코드 실행
allow_code_execution
을 사용하는 경우 사용자 입력을 항상 검증해야 함- 실서비스에서는
code_execution_mode: "safe"
(Docker 기반) 사용 권장 max_execution_time
을 설정하여 무한 루프 방지
성능 최적화
respect_context_window: true
설정으로 토큰 초과 방지max_rpm
을 적절히 설정하여 Rate Limit 회피cache: true
설정으로 반복 작업 성능 향상max_iter
,max_retry_limit
은 작업 복잡도에 따라 조정
메모리 및 컨텍스트 전략
- 과거 맥락이 필요한 작업에는
memory: true
사용 knowledge_sources
를 사용하여 도메인 기반 지식 연계- 사용자 정의 임베딩을 사용하는 경우
embedder_config
구성 필요 - 템플릿(
system_template
,prompt_template
,response_template
)을 커스터마이징하여 에이전트 행동을 세밀히 제어
에이전트 협업
- 여러 에이전트 간 협업이 필요할 경우
allow_delegation: true
활성화 step_callback
을 설정하면 각 단계의 로그 추적 및 모니터링 가능- 복잡한 추론은 메인
llm
, 도구 실행은function_calling_llm
등 목적에 따라 LLM을 분리해서 설정 가능
모델 호환성
- 오래된 모델 사용 시
use_system_prompt: false
설정 필요 - 사용하는 LLM이 필요한 기능(예: 함수 호출)을 지원하는지 확인 필요
자주 발생하는 문제 및 해결 방법
- Rate Limit 초과
max_rpm
으로 요청 속도 조절- 반복적인 요청은 캐시 기능 활용
- 요청을 묶어서(batch) 처리하는 것도 고려
- 컨텍스트 초과 오류
respect_context_window
설정 활성화- 프롬프트를 더 간결하게 구성
- 주기적으로 메모리 초기화
- 코드 실행 문제
safe
모드를 사용할 경우 Docker 설치 여부 확인- 실행 권한 및 보안 설정 확인
- 코드 샌드박스 관련 설정 점검
- 메모리 관련 이슈
memory
설정 여부 점검knowledge_sources
가 제대로 연결되었는지 확인- 대화 기록 관리 방식 재검토
에이전트는 용도에 따라 다르게 구성되어야 하며, 목적에 맞는 설정을 통해 최적의 성능을 발휘할 수 있습니다.