소개

CrewAI 도구는 웹 검색과 데이터 분석부터 협업 및 동료 간 업무 위임에 이르는 다양한 기능을 에이전트에게 제공한다. 이 문서에서는 CrewAI 프레임워크 내에서 이러한 도구를 생성, 통합, 활용하는 방법을 설명하며, 특히 협업 도구에 초점을 맞춘 새로운 내용을 다룬다.

도구란 무엇인가?

CrewAI에서 도구는 에이전트가 다양한 작업을 수행하기 위해 활용할 수 있는 기능이나 함수를 의미한다. 이는 CrewAI ToolkitLangChain Tools에서 제공하는 도구를 포함하며, 단순한 검색부터 복잡한 상호작용, 그리고 에이전트 간의 효과적인 협업까지 가능하게 한다.

도구의 주요 특징

  • 유용성: 웹 검색, 데이터 분석, 콘텐츠 생성, 에이전트 협업과 같은 작업을 위해 설계됨
  • 통합성: 도구를 에이전트의 워크플로우에 원활하게 통합해 기능을 강화함
  • 커스터마이징: 특정 요구 사항에 맞게 커스텀 도구를 개발하거나 기존 도구를 활용할 수 있는 유연성을 제공함
  • 오류 처리: 원활한 운영을 보장하기 위해 견고한 오류 처리 메커니즘을 내장함
  • 캐싱 메커니즘: 성능 최적화와 중복 작업 감소를 위해 지능형 캐싱 기능을 탑재함

CrewAI 도구 사용하기

에이전트의 기능을 강화하기 위해 crewAI 도구를 사용하려면 먼저 추가 도구 패키지를 설치한다:

pip install 'crewai[tools]'

다음은 이 도구를 사용하는 예제이다:

import os
from crewai import Agent, Task, Crew
# crewAI 도구 임포트
from crewai_tools import (
    DirectoryReadTool,
    FileReadTool,
    SerperDevTool,
    WebsiteSearchTool
)

# API 키 설정
os.environ["SERPER_API_KEY"] = "Your Key" # serper.dev API 키
os.environ["OPENAI_API_KEY"] = "Your Key"

# 도구 인스턴스 생성
docs_tool = DirectoryReadTool(directory='./blog-posts')
file_tool = FileReadTool()
search_tool = SerperDevTool()
web_rag_tool = WebsiteSearchTool()

# 에이전트 생성
researcher = Agent(
    role='시장 조사 분석가',
    goal='AI 산업의 최신 시장 분석 제공',
    backstory='시장 트렌드를 꿰뚫어 보는 전문 분석가',
    tools=[search_tool, web_rag_tool],
    verbose=True
)

writer = Agent(
    role='콘텐츠 작가',
    goal='AI 산업에 대한 흥미로운 블로그 글 작성',
    backstory='기술에 열정을 가진 숙련된 작가',
    tools=[docs_tool, file_tool],
    verbose=True
)

# 작업 정의
research = Task(
    description='AI 산업의 최신 트렌드를 조사하고 요약 제공',
    expected_output='AI 산업의 상위 3개 트렌드 개발 동향과 그 중요성에 대한 독창적인 관점을 담은 요약',
    agent=researcher
)

write = Task(
    description='조사 분석가의 요약을 바탕으로 AI 산업에 대한 흥미로운 블로그 글 작성. 최신 블로그 글에서 영감을 얻는다.',
    expected_output='복잡한 전문 용어를 피하고, 흥미롭고 정보가 풍부하며 접근 가능한 콘텐츠로 구성된 4단락의 마크다운 형식 블로그 글',
    agent=writer,
    output_file='blog-posts/new_post.md'  # 최종 블로그 글 저장 위치
)

# 플래닝 기능을 활성화한 크루 구성
crew = Crew(
    agents=[researcher, writer],
    tasks=[research, write],
    verbose=True,
    planning=True,  # 플래닝 기능 활성화
)

# 작업 실행
crew.kickoff()

사용 가능한 CrewAI 도구

  • 에러 처리: 모든 도구는 에러 처리 기능을 내장하고 있어, 에이전트가 예외 상황을 우아하게 처리하고 작업을 계속할 수 있다.
  • 캐싱 메커니즘: 모든 도구는 캐싱을 지원하며, 이전에 얻은 결과를 효율적으로 재사용할 수 있다. 이를 통해 외부 리소스에 대한 부하를 줄이고 실행 시간을 단축한다. 또한 cache_function 속성을 사용해 캐싱 메커니즘을 더 세밀하게 제어할 수 있다.

다음은 사용 가능한 도구와 그 설명이다:

도구설명
BrowserbaseLoadTool웹 브라우저와 상호작용하고 데이터를 추출하는 도구.
CodeDocsSearchTool코드 문서 및 관련 기술 문서를 검색하기에 최적화된 RAG 도구.
CodeInterpreterTool파이썬 코드를 해석하는 도구.
ComposioToolComposio 도구를 사용할 수 있게 하는 도구.
CSVSearchToolCSV 파일 내에서 검색하기 위해 설계된 RAG 도구로, 구조화된 데이터를 처리한다.
DALL-E ToolDALL-E API를 사용해 이미지를 생성하는 도구.
DirectorySearchTool디렉토리 내에서 검색하기 위한 RAG 도구로, 파일 시스템 탐색에 유용하다.
DOCXSearchToolDOCX 문서 내에서 검색하기 위한 RAG 도구로, Word 파일 처리에 적합하다.
DirectoryReadTool디렉토리 구조와 그 내용을 읽고 처리하는 도구.
EXASearchTool다양한 데이터 소스에서 철저한 검색을 수행하기 위해 설계된 도구.
FileReadTool다양한 파일 형식을 지원하며 파일에서 데이터를 읽고 추출하는 도구.
FirecrawlSearchToolFirecrawl을 사용해 웹페이지를 검색하고 결과를 반환하는 도구.
FirecrawlCrawlWebsiteToolFirecrawl을 사용해 웹페이지를 크롤링하는 도구.
FirecrawlScrapeWebsiteToolFirecrawl을 사용해 웹페이지 URL을 스크랩하고 그 내용을 반환하는 도구.
GithubSearchToolGitHub 저장소 내에서 검색하기 위한 RAG 도구로, 코드 및 문서 검색에 유용하다.
SerperDevTool개발 목적으로 특화된 도구로, 개발 중인 특정 기능을 제공한다.
TXTSearchTool텍스트 (.txt) 파일 내에서 검색하기 위한 RAG 도구로, 비구조화된 데이터 처리에 적합하다.
JSONSearchToolJSON 파일 내에서 검색하기 위해 설계된 RAG 도구로, 구조화된 데이터 처리에 적합하다.
LlamaIndexToolLlamaIndex 도구를 사용할 수 있게 하는 도구.
MDXSearchTool마크다운 (MDX) 파일 내에서 검색하기 위한 RAG 도구로, 문서 처리에 유용하다.
PDFSearchToolPDF 문서 내에서 검색하기 위한 RAG 도구로, 스캔된 문서 처리에 적합하다.
PGSearchToolPostgreSQL 데이터베이스 내에서 검색하기 위해 최적화된 RAG 도구로, 데이터베이스 쿼리에 적합하다.
Vision ToolDALL-E API를 사용해 이미지를 생성하는 도구.
RagTool다양한 데이터 소스와 타입을 처리할 수 있는 범용 RAG 도구.
ScrapeElementFromWebsiteTool웹사이트에서 특정 엘리먼트를 스크랩하는 도구로, 특정 데이터 추출에 유용하다.
ScrapeWebsiteTool전체 웹사이트를 스크랩하는 도구로, 포괄적인 데이터 수집에 적합하다.
WebsiteSearchTool웹사이트 콘텐츠를 검색하기 위한 RAG 도구로, 웹 데이터 추출에 최적화되어 있다.
XMLSearchToolXML 파일 내에서 검색하기 위해 설계된 RAG 도구로, 구조화된 데이터 형식 처리에 적합하다.
YoutubeChannelSearchToolYouTube 채널 내에서 검색하기 위한 RAG 도구로, 비디오 콘텐츠 분석에 유용하다.
YoutubeVideoSearchToolYouTube 비디오 내에서 검색하기 위한 RAG 도구로, 비디오 데이터 추출에 적합하다.

나만의 도구 만들기

개발자는 에이전트의 필요에 맞게 커스텀 도구를 직접 만들거나, 미리 만들어진 옵션을 활용할 수 있다.

CrewAI 도구를 만드는 데는 크게 두 가지 방법이 있다:

BaseTool 서브클래싱

from crewai.tools import BaseTool
from pydantic import BaseModel, Field

class MyToolInput(BaseModel):
    """MyCustomTool의 입력 스키마."""
    argument: str = Field(..., description="인자의 설명.")

class MyCustomTool(BaseTool):
    name: str = "내 도구의 이름"
    description: str = "이 도구가 수행하는 작업. 효과적인 활용을 위해 중요하다."
    args_schema: Type[BaseModel] = MyToolInput

    def _run(self, argument: str) -> str:
        # 도구의 로직을 여기에 작성
        return "도구의 결과"

tool 데코레이터 활용하기

from crewai.tools import tool
@tool("내 도구 이름")
def my_tool(question: str) -> str:
    """이 도구가 어떤 용도로 사용되는지 명확히 설명한다. 에이전트가 이를 사용하려면 이 정보가 필요하다."""
    # 함수 로직 작성
    return "커스텀 도구의 결과"

구조화된 도구

StructuredTool 클래스는 함수를 도구로 감싸서 유연성과 검증 기능을 제공하며, 보일러플레이트 코드를 줄여준다. 이 클래스는 커스텀 스키마와 동적 로직을 지원하여 복잡한 기능을 원활하게 통합할 수 있게 한다.

예제:

StructuredTool.from_function을 사용해 외부 API나 시스템과 상호작용하는 함수를 감싸면 구조화된 인터페이스를 제공할 수 있다. 이를 통해 강력한 검증과 일관된 실행이 가능해지며, 복잡한 기능을 애플리케이션에 통합하기가 더 쉬워진다. 다음 예제에서 이를 확인할 수 있다:

from crewai.tools.structured_tool import CrewStructuredTool
from pydantic import BaseModel

# Pydantic을 사용해 도구의 입력 스키마 정의
class APICallInput(BaseModel):
    endpoint: str
    parameters: dict

# API 호출을 실행하는 래퍼 함수
def tool_wrapper(*args, **kwargs):
    # 여기서는 일반적으로 매개변수를 사용해 API를 호출
    # 예시를 위해 플레이스홀더 문자열 반환
    return f"Call the API at {kwargs['endpoint']} with parameters {kwargs['parameters']}"

# 구조화된 도구 생성 및 반환
def create_structured_tool():
    return CrewStructuredTool.from_function(
        name='Wrapper API',
        description="구조화된 입력으로 API 호출을 감싸는 도구.",
        args_schema=APICallInput,
        func=tool_wrapper,
    )

# 예시 사용법
structured_tool = create_structured_tool()

# 구조화된 입력으로 도구 실행
result = structured_tool._run(**{
    "endpoint": "https://example.com/api",
    "parameters": {"key1": "value1", "key2": "value2"}
})
print(result)  # 출력: Call the API at https://example.com/api with parameters {'key1': 'value1', 'key2': 'value2'}

커스텀 캐싱 메커니즘

도구는 선택적으로 cache_function을 구현해 캐싱 동작을 파인튜닝할 수 있다. 이 함수는 특정 조건에 따라 결과를 캐시할 시점을 결정하며, 캐싱 로직에 대한 세밀한 제어를 제공한다.

from crewai.tools import tool

@tool
def multiplication_tool(first_number: int, second_number: int) -> str:
    """두 숫자를 곱해야 할 때 유용한 도구이다."""
    return first_number * second_number

def cache_func(args, result):
    # 이 경우, 결과가 2의 배수일 때만 캐시한다
    cache = result % 2 == 0
    return cache

multiplication_tool.cache_function = cache_func

writer1 = Agent(
        role="Writer",
        goal="어린이를 위한 수학 교재를 작성한다.",
        backstory="글쓰기 전문가이며 아이들을 가르치는 것을 좋아하지만, 수학에 대한 지식은 전무하다.",
        tools=[multiplication_tool],
        allow_delegation=False,
    )
    #...

결론

CrewAI 에이전트의 능력을 확장하는 데 도구는 매우 중요하다. 도구를 활용하면 다양한 작업을 수행하고 효과적으로 협업할 수 있다. CrewAI로 솔루션을 구축할 때는 커스텀 도구와 기존 도구를 모두 활용해 에이전트의 능력을 강화하고 AI 생태계를 발전시켜야 한다. 에러 처리, 캐싱 메커니즘, 도구 인자의 유연성을 고려해 에이전트의 성능과 기능을 최적화한다.