에이전트 개요

CrewAI 프레임워크에서 에이전트는 다음과 같은 기능을 수행하는 자율적인 단위다:

  • 특정 작업을 수행한다
  • 역할과 목표에 따라 의사결정을 내린다
  • 목표 달성을 위해 도구를 활용한다
  • 다른 에이전트와 소통하고 협업한다
  • 상호작용에 대한 기억을 유지한다
  • 허용된 경우 작업을 위임한다

에이전트를 특정 기술, 전문성, 책임을 가진 전문 팀원으로 생각하면 된다. 예를 들어, 리서처 에이전트는 정보 수집과 분석에 능숙하고, 작가 에이전트는 콘텐츠 생성에 더 적합할 수 있다.

에이전트 속성

속성파라미터타입설명
역할rolestr에이전트의 기능과 전문성을 정의한다.
목표goalstr에이전트의 의사결정을 이끄는 개별 목표를 설정한다.
배경 스토리backstorystr에이전트의 컨텍스트와 개성을 제공해 상호작용을 풍부하게 한다.
LLM (선택사항)llmUnion[str, LLM, Any]에이전트를 구동하는 언어 모델. 기본값은 OPENAI_MODEL_NAME 또는 “gpt-4”로 설정된다.
도구 (선택사항)toolsList[BaseTool]에이전트가 사용할 수 있는 기능 또는 도구. 기본값은 빈 리스트다.
함수 호출 LLM (선택사항)function_calling_llmOptional[Any]도구 호출을 위한 언어 모델. 지정 시 크루의 LLM을 대체한다.
최대 반복 횟수 (선택사항)max_iterint에이전트가 최선의 답을 제공하기 전까지의 최대 반복 횟수. 기본값은 20이다.
최대 RPM (선택사항)max_rpmOptional[int]속도 제한을 피하기 위한 최대 분당 요청 수.
최대 실행 시간 (선택사항)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’(Docker 사용) 또는 ‘unsafe’(직접 실행). 기본값은 ‘safe’다.
임베더 (선택사항)embedderOptional[Dict[str, Any]]에이전트가 사용하는 임베더 설정.
지식 소스 (선택사항)knowledge_sourcesOptional[List[BaseKnowledgeSource]]에이전트가 사용할 수 있는 지식 소스.
시스템 프롬프트 사용 (선택사항)use_system_promptOptional[bool]시스템 프롬프트 사용 여부(o1 모델 지원용). 기본값은 True다.

에이전트 생성하기

CrewAI에서 에이전트를 생성하는 방법은 두 가지가 있다: YAML 설정 파일 사용(권장) 또는 코드에서 직접 정의하는 방법이다.

YAML 설정 (권장)

YAML 설정을 사용하면 에이전트를 정의하는 더 깔끔하고 유지보수하기 쉬운 방법을 제공한다. CrewAI 프로젝트에서 이 방식을 사용하는 것을 강력히 권장한다.

설치 섹션에서 설명한 대로 CrewAI 프로젝트를 생성한 후, src/latest_ai_development/config/agents.yaml 파일로 이동해 템플릿을 자신의 요구사항에 맞게 수정한다.

YAML 파일의 변수(예: {topic})는 crew를 실행할 때 입력값으로 대체된다:

crew.kickoff(inputs={'topic': 'AI Agents'})

다음은 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.

이 YAML 설정을 코드에서 사용하려면 CrewBase를 상속받는 crew 클래스를 생성한다:

# 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'],
      verbose=True,
      tools=[SerperDevTool()]
    )

  @agent
  def reporting_analyst(self) -> Agent:
    return Agent(
      config=self.agents_config['reporting_analyst'],
      verbose=True
    )

YAML 파일(agents.yaml)에서 사용하는 이름은 Python 코드의 메서드 이름과 일치해야 한다.

코드로 직접 정의하기

Agent 클래스를 인스턴스화하여 코드에서 직접 에이전트를 생성할 수 있다. 다음은 사용 가능한 모든 매개변수를 포함한 포괄적인 예제다:

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" (옵션: "safe", "unsafe")
    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,  # 선택사항: 모니터링을 위한 콜백 함수
)

일반적인 사용 사례에 대한 주요 매개변수 조합을 살펴보자:

기본 리서치 에이전트

research_agent = Agent(
    role="Research Analyst",
    goal="특정 주제에 대한 정보를 찾고 요약한다",
    backstory="세부 사항에 주의를 기울이는 경험 많은 연구원이다",
    tools=[SerperDevTool()],
    verbose=True  # 디버깅을 위해 로깅을 활성화한다
)

코드 개발 에이전트

dev_agent = Agent(
    role="Senior Python Developer",
    goal="파이썬 코드 작성 및 디버깅",
    backstory="10년 경력의 파이썬 개발 전문가",
    allow_code_execution=True,
    code_execution_mode="safe",  # 안전을 위해 Docker 사용
    max_execution_time=300,  # 5분 타임아웃
    max_retry_limit=3  # 복잡한 코드 작업을 위해 재시도 횟수 증가
)

장기 실행 분석 에이전트

analysis_agent = Agent(
    role="Data Analyst",
    goal="Perform deep analysis of large datasets",
    backstory="Specialized in big data analysis and pattern recognition",
    memory=True,
    respect_context_window=True,
    max_rpm=10,  # API 호출 제한
    function_calling_llm="gpt-4o-mini"  # 도구 호출을 위한 저렴한 모델
)

커스텀 템플릿 에이전트

custom_agent = Agent(
    role="고객 서비스 담당자",
    goal="고객 문의를 지원한다",
    backstory="고객 만족을 중점으로 한 고객 지원 경험",
    system_template="""<|start_header_id|>system<|end_header_id|>
                        {{ .System }}<|eot_id|>""",
    prompt_template="""<|start_header_id|>user<|end_header_id|>
                        {{ .Prompt }}<|eot_id|>""",
    response_template="""<|start_header_id|>assistant<|end_header_id|>
                        {{ .Response }}<|eot_id|>""",
)

파라미터 상세 설명

필수 파라미터

  • role, goal, backstory는 필수 항목이며, 에이전트의 행동을 결정한다.
  • llm은 사용할 언어 모델을 지정한다 (기본값: OpenAI의 GPT-4).

메모리와 컨텍스트

  • memory: 대화 기록을 유지할 수 있도록 활성화
  • respect_context_window: 토큰 제한 문제를 방지
  • knowledge_sources: 도메인별 지식 기반 추가

실행 제어

  • max_iter: 최적의 답변을 찾기 전 최대 시도 횟수
  • max_execution_time: 타임아웃(초 단위)
  • max_rpm: API 호출 속도 제한
  • max_retry_limit: 오류 발생 시 재시도 횟수

코드 실행

  • allow_code_execution: 코드를 실행하려면 True로 설정해야 한다
  • code_execution_mode:
    • "safe": Docker를 사용한다 (프로덕션 환경에 권장)
    • "unsafe": 직접 실행한다 (신뢰할 수 있는 환경에서만 사용)

템플릿

  • system_template: 에이전트의 핵심 동작을 정의
  • prompt_template: 입력 형식을 구조화
  • response_template: 에이전트 응답을 포맷팅

커스텀 템플릿을 사용할 때는 {role}, {goal}, {input}과 같은 변수를 활용할 수 있다. 이 변수들은 실행 중에 자동으로 채워진다.

에이전트 도구

에이전트는 다양한 도구를 장착해 능력을 강화할 수 있다. CrewAI는 다음 도구를 지원한다:

에이전트에 도구를 추가하는 방법은 다음과 같다:

from crewai import Agent
from crewai_tools import SerperDevTool, WikipediaTools

# 도구 생성
search_tool = SerperDevTool()
wiki_tool = WikipediaTools()

# 에이전트에 도구 추가
researcher = Agent(
    role="AI Technology Researcher",
    goal="Research the latest AI developments",
    tools=[search_tool, wiki_tool],
    verbose=True
)

에이전트 메모리와 컨텍스트

에이전트는 상호작용을 기억하고 이전 작업에서 얻은 컨텍스트를 활용할 수 있다. 이 기능은 여러 작업에 걸쳐 정보를 유지해야 하는 복잡한 워크플로우에서 특히 유용하다.

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 값을 설정한다.
  • 반복 작업의 성능을 향상시키기 위해 cache: true를 활성화한다.
  • 작업 복잡도에 따라 max_itermax_retry_limit을 조정한다.

메모리와 컨텍스트 관리

  • 과거 컨텍스트가 필요한 작업에는 memory: true를 사용한다.
  • 도메인 특화 정보를 활용하려면 knowledge_sources를 활용한다.
  • 커스텀 임베딩 모델을 사용할 때는 embedder_config를 설정한다.
  • 에이전트 동작을 세밀하게 제어하려면 커스텀 템플릿(system_template, prompt_template, response_template)을 사용한다.

에이전트 협업

  • 에이전트들이 함께 작업해야 할 때는 allow_delegation: true를 활성화한다.
  • step_callback을 사용해 에이전트 간 상호작용을 모니터링하고 로깅한다.
  • 다양한 목적에 따라 서로 다른 LLM을 사용하는 것을 고려한다:
    • 복잡한 추론 작업에는 메인 llm을 활용
    • 도구 사용 효율성을 높이기 위해 function_calling_llm을 적용

모델 호환성

  • 시스템 메시지를 지원하지 않는 이전 모델의 경우 use_system_prompt: false로 설정한다.
  • 선택한 llm이 함수 호출과 같은 필요한 기능을 지원하는지 확인한다.

일반적인 문제 해결 방법

  1. API 요청 제한: API 요청 제한에 도달한 경우:

    • 적절한 max_rpm 값을 설정한다
    • 반복 작업에 캐싱을 사용한다
    • 요청을 일괄 처리하는 방법을 고려한다
  2. 컨텍스트 윈도우 오류: 컨텍스트 제한을 초과한 경우:

    • respect_context_window를 활성화한다
    • 더 효율적인 프롬프트를 사용한다
    • 주기적으로 에이전트 메모리를 비운다
  3. 코드 실행 문제: 코드 실행이 실패한 경우:

    • 안전 모드를 위해 Docker가 설치되었는지 확인한다
    • 실행 권한을 확인한다
    • 코드 샌드박스 설정을 검토한다
  4. 메모리 문제: 에이전트 응답이 일관되지 않은 경우:

    • 메모리가 활성화되었는지 확인한다
    • 지식 소스 구성을 확인한다
    • 대화 기록 관리 방식을 검토한다

에이전트는 특정 사용 사례에 맞게 구성할 때 가장 효과적으로 작동한다. 요구 사항을 충분히 이해하고 이에 맞게 매개변수를 조정한다.