Post

CrewAI 에이전트 구조

CrewAI 프레임워크에서 에이전트의 역할과 주요 속성에 대해 정리합니다.

CrewAI 에이전트 구조

에이전트란?

CrewAI에서 Agent는 다음과 같은 기능을 가진 자율적인 유닛입니다:

  • 특정 작업을 수행할 수 있음
  • 자신의 역할과 목표에 따라 의사결정을 수행함
  • 목표 달성을 위해 도구를 사용할 수 있음
  • 다른 에이전트와 소통 및 협업 가능
  • 상호작용 내역을 기억할 수 있음
  • 필요 시 작업을 다른 에이전트에게 위임 가능함

Tip: 에이전트는 각자의 기술과 전문성을 가진 팀원이라고 생각하면 됩니다. 예를 들어 Researcher 에이전트는 정보를 탐색하고 분석하는 데 능숙하고, Writer 에이전트는 콘텐츠 작성에 특화되어 있을 수 있습니다.

Enterprise 기능 - Visual Agent Builder CrewAI Enterprise에는 코드를 작성하지 않고도 시각적으로 에이전트를 만들고 설정할 수 있는 Visual Agent Builder가 포함되어 있습니다. 실시간 테스트와 검증, 폼 기반 설정 인터페이스, 템플릿 라이브러리 등으로 구성되어 있습니다.

에이전트 속성 (Agent Attributes)

속성명파라미터명타입설명
역할 (Role)rolestr해당 에이전트의 기능과 전문성을 정의합니다.
목표 (Goal)goalstr에이전트가 수행해야 하는 개별 목표를 명시합니다.
배경 (Backstory)backstorystr에이전트의 배경과 성격을 부여하여 상호작용을 풍부하게 만듭니다.
언어모델 (LLM)llmUnion[str, LLM, Any]에이전트가 사용하는 LLM (기본: 환경변수 또는 gpt-4).
도구 목록 (Tools)toolsList[BaseTool]에이전트가 사용할 수 있는 도구 목록. 기본은 빈 리스트입니다.
툴 전용 LLMfunction_calling_llmOptional[Any]도구 실행 전용 LLM (설정 시 crew 전체 설정을 무시하고 사용함).
최대 반복 횟수max_iterint에이전트가 답을 내놓기 전 최대 반복 횟수 (기본값: 20).
최대 요청 수 (RPM)max_rpmOptional[int]API Rate Limit 회피를 위한 분당 요청 제한 수.
최대 실행 시간max_execution_timeOptional[int]에이전트의 최대 실행 시간 (초).
메모리 유지 여부memorybool상호작용 메모리 유지 여부 (기본: True).
로그 출력 여부verbosebool디버깅용 상세 로그 활성화 (기본: False).
작업 위임 허용allow_delegationbool다른 에이전트에게 작업 위임 허용 여부 (기본: False).
단계별 콜백step_callbackOptional[Any]각 단계 실행 후 호출될 콜백 함수 지정.
도구 캐시 사용cachebool도구 결과 캐싱 여부 (기본: True).
시스템 프롬프트 템플릿system_templateOptional[str]에이전트에 적용할 시스템 프롬프트 템플릿.
프롬프트 템플릿prompt_templateOptional[str]사용자 입력 프롬프트 템플릿.
응답 템플릿response_templateOptional[str]에이전트의 응답 형식 템플릿.
코드 실행 허용 여부allow_code_executionOptional[bool]에이전트가 코드를 실행할 수 있는지 여부. (기본: False).
재시도 횟수 제한max_retry_limitint오류 발생 시 재시도 가능한 최대 횟수 (기본: 2).
컨텍스트 창 제한 준수 여부respect_context_windowbool토큰 제한 초과 방지를 위한 요약 처리 (기본: True).
코드 실행 모드code_execution_modeLiteral["safe", "unsafe"]코드 실행 방식: safe (도커 사용), unsafe (직접 실행). 기본은 safe.
임베더 설정embedderOptional[Dict[str, Any]]에이전트가 사용하는 임베더 설정.
지식 소스knowledge_sourcesOptional[List[BaseKnowledgeSource]]에이전트가 참고할 지식 소스 목록.
시스템 프롬프트 사용 여부use_system_promptOptional[bool]시스템 프롬프트를 사용할지 여부 (기본: True).

에이전트 생성 방법

CrewAI에서 에이전트를 생성하는 방법은 두 가지가 있습니다:

  1. YAML 설정을 사용하는 방법 (추천)
  2. 직접 코드를 통해 정의하는 방법

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이 필요한 기능(예: 함수 호출)을 지원하는지 확인 필요

자주 발생하는 문제 및 해결 방법

  1. Rate Limit 초과
    • max_rpm으로 요청 속도 조절
    • 반복적인 요청은 캐시 기능 활용
    • 요청을 묶어서(batch) 처리하는 것도 고려
  2. 컨텍스트 초과 오류
    • respect_context_window 설정 활성화
    • 프롬프트를 더 간결하게 구성
    • 주기적으로 메모리 초기화
  3. 코드 실행 문제
    • safe 모드를 사용할 경우 Docker 설치 여부 확인
    • 실행 권한 및 보안 설정 확인
    • 코드 샌드박스 관련 설정 점검
  4. 메모리 관련 이슈
    • memory 설정 여부 점검
    • knowledge_sources가 제대로 연결되었는지 확인
    • 대화 기록 관리 방식 재검토

에이전트는 용도에 따라 다르게 구성되어야 하며, 목적에 맞는 설정을 통해 최적의 성능을 발휘할 수 있습니다.

This post is licensed under CC BY 4.0 by the author.