크루(Crew)란 무엇인가?
크루(Crew)는 crewAI에서 여러 에이전트가 협력하여 일련의 작업을 수행하는 협업 그룹을 의미한다. 각 크루는 작업 실행 전략, 에이전트 간 협업 방식, 그리고 전체 워크플로우를 정의한다.
크루 속성
속성 | 매개변수 | 설명 |
---|
Tasks | tasks | 크루에 할당된 작업 목록 |
Agents | agents | 크루에 속한 에이전트 목록 |
Process (선택 사항) | process | 크루가 따르는 프로세스 흐름 (예: 순차적, 계층적). 기본값은 sequential . |
Verbose (선택 사항) | verbose | 실행 중 로깅을 위한 상세 정보 수준. 기본값은 False . |
Manager LLM (선택 사항) | manager_llm | 계층적 프로세스에서 관리자 에이전트가 사용하는 언어 모델. 계층적 프로세스 사용 시 필수. |
Function Calling LLM (선택 사항) | function_calling_llm | 이 값을 전달하면 크루는 모든 에이전트의 도구에 대해 함수 호출을 수행할 때 이 LLM을 사용한다. 각 에이전트는 자체 LLM을 가질 수 있으며, 이는 크루의 LLM을 재정의한다. |
Config (선택 사항) | config | 크루를 위한 선택적 구성 설정. Json 또는 Dict[str, Any] 형식. |
Max RPM (선택 사항) | max_rpm | 실행 중 크루가 준수하는 최대 분당 요청 수. 기본값은 None . |
Language (선택 사항) | language | 크루에서 사용할 언어. 기본값은 영어. |
Language File (선택 사항) | language_file | 크루에서 사용할 언어 파일의 경로. |
Memory (선택 사항) | memory | 실행 메모리(단기, 장기, 엔티티 메모리)를 저장하는 데 사용. |
Memory Config (선택 사항) | memory_config | 크루가 사용할 메모리 프로바이더의 구성. |
Cache (선택 사항) | cache | 도구 실행 결과를 캐시에 저장할지 여부를 지정. 기본값은 True . |
Embedder (선택 사항) | embedder | 크루가 사용할 임베더의 구성. 현재는 주로 메모리에서 사용. 기본값은 {"provider": "openai"} . |
Full Output (선택 사항) | full_output | 크루가 모든 작업의 출력을 포함한 전체 출력을 반환할지, 아니면 최종 출력만 반환할지 여부. 기본값은 False . |
Step Callback (선택 사항) | step_callback | 각 에이전트의 각 단계 후에 호출되는 함수. 에이전트의 작업을 기록하거나 다른 작업을 수행하는 데 사용할 수 있으며, 에이전트별 step_callback 을 재정의하지 않는다. |
Task Callback (선택 사항) | task_callback | 각 작업 완료 후 호출되는 함수. 작업 실행 후 모니터링 또는 추가 작업에 유용. |
Share Crew (선택 사항) | share_crew | 크루 정보와 실행 결과를 crewAI 팀과 공유하여 라이브러리를 개선하고 모델을 훈련할 수 있도록 할지 여부. |
Output Log File (선택 사항) | output_log_file | 로그를 현재 디렉토리에 logs.txt로 저장하거나 파일 경로를 제공. 파일 이름이 .json으로 끝나면 JSON 형식, 그렇지 않으면 .txt 형식으로 저장. 기본값은 None . |
Manager Agent (선택 사항) | manager_agent | manager 는 관리자로 사용할 커스텀 에이전트를 설정한다. |
Prompt File (선택 사항) | prompt_file | 크루에서 사용할 프롬프트 JSON 파일의 경로. |
Planning (선택 사항) | planning | 크루에 계획 능력을 추가. 활성화하면 각 크루 반복 전에 모든 크루 데이터가 AgentPlanner로 전송되어 작업을 계획하고, 이 계획이 각 작업 설명에 추가된다. |
Planning LLM (선택 사항) | planning_llm | 계획 프로세스에서 AgentPlanner가 사용하는 언어 모델. |
Crew Max RPM: max_rpm
속성은 크루가 분당 수행할 수 있는 최대 요청 수를 설정하여 속도 제한을 피한다. 이 값을 설정하면 개별 에이전트의 max_rpm
설정을 재정의한다.
크루 생성하기
CrewAI에서 크루를 생성하는 방법은 두 가지가 있다: YAML 설정 파일 사용(권장) 또는 코드에서 직접 정의하는 방법이다.
YAML 설정 (권장)
YAML 설정을 사용하면 크루를 정의하는 더 깔끔하고 유지보수하기 쉬운 방법을 제공하며, CrewAI 프로젝트에서 에이전트와 태스크를 정의하는 방식과 일관성을 유지한다.
설치 섹션에서 설명한 대로 CrewAI 프로젝트를 생성한 후, CrewBase
를 상속받는 클래스에서 크루를 정의하고 데코레이터를 사용해 에이전트, 태스크, 그리고 크루 자체를 정의할 수 있다.
데코레이터를 활용한 Crew 클래스 예제
from crewai import Agent, Crew, Task, Process
from crewai.project import CrewBase, agent, task, crew, before_kickoff, after_kickoff
@CrewBase
class YourCrewName:
"""여러분의 크루에 대한 설명"""
# YAML 설정 파일 경로
# YAML로 정의된 에이전트와 태스크 예제는 다음 링크를 참고하세요:
# - 태스크: https://docs.crewai.com/concepts/tasks#yaml-configuration-recommended
# - 에이전트: https://docs.crewai.com/concepts/agents#yaml-configuration-recommended
agents_config = 'config/agents.yaml'
tasks_config = 'config/tasks.yaml'
@before_kickoff
def prepare_inputs(self, inputs):
# 크루 시작 전 입력값 수정
inputs['additional_data'] = "추가 정보"
return inputs
@after_kickoff
def process_output(self, output):
# 크루 완료 후 출력값 처리
output.raw += "\n크루 완료 후 처리됨."
return output
@agent
def agent_one(self) -> Agent:
return Agent(
config=self.agents_config['agent_one'],
verbose=True
)
@agent
def agent_two(self) -> Agent:
return Agent(
config=self.agents_config['agent_two'],
verbose=True
)
@task
def task_one(self) -> Task:
return Task(
config=self.tasks_config['task_one']
)
@task
def task_two(self) -> Task:
return Task(
config=self.tasks_config['task_two']
)
@crew
def crew(self) -> Crew:
return Crew(
agents=self.agents, # @agent 데코레이터로 자동 수집
tasks=self.tasks, # @task 데코레이터로 자동 수집
process=Process.sequential,
verbose=True,
)
CrewBase
클래스와 이 데코레이터들은 에이전트와 태스크를 자동으로 수집해 관리 작업을 줄여준다.
annotations.py
의 데코레이터 개요
CrewAI는 annotations.py
파일에 여러 데코레이터를 제공한다. 이 데코레이터들은 여러분의 crew 클래스 내부의 메서드에 특별한 처리를 위해 사용된다:
@CrewBase
: 클래스를 crew 베이스 클래스로 표시한다.
@agent
: Agent
객체를 반환하는 메서드를 나타낸다.
@task
: Task
객체를 반환하는 메서드를 나타낸다.
@crew
: Crew
객체를 반환하는 메서드를 나타낸다.
@before_kickoff
: (선택 사항) crew가 시작되기 전에 실행될 메서드를 표시한다.
@after_kickoff
: (선택 사항) crew가 종료된 후에 실행될 메서드를 표시한다.
이 데코레이터들은 crew의 구조를 조직화하고, 에이전트와 작업을 수동으로 나열하지 않고도 자동으로 수집하는 데 도움을 준다.
직접 코드로 정의하기 (대안)
YAML 설정 파일을 사용하지 않고 코드 내에서 직접 크루를 정의할 수도 있다.
from crewai import Agent, Crew, Task, Process
from crewai_tools import YourCustomTool
class YourCrewName:
def agent_one(self) -> Agent:
return Agent(
role="데이터 분석가",
goal="시장 내 데이터 트렌드 분석",
backstory="경제학 배경을 가진 경험 많은 데이터 분석가",
verbose=True,
tools=[YourCustomTool()]
)
def agent_two(self) -> Agent:
return Agent(
role="시장 조사원",
goal="시장 동향에 대한 정보 수집",
backstory="세부 사항에 민감한 성실한 연구원",
verbose=True
)
def task_one(self) -> Task:
return Task(
description="최근 시장 데이터를 수집하고 트렌드를 파악한다.",
expected_output="시장의 주요 트렌드를 요약한 보고서",
agent=self.agent_one()
)
def task_two(self) -> Task:
return Task(
description="시장 동향에 영향을 미치는 요인을 조사한다.",
expected_output="시장에 영향을 미치는 요인 분석",
agent=self.agent_two()
)
def crew(self) -> Crew:
return Crew(
agents=[self.agent_one(), self.agent_two()],
tasks=[self.task_one(), self.task_two()],
process=Process.sequential,
verbose=True
)
이 예시에서:
- 에이전트와 태스크를 데코레이터 없이 클래스 내에서 직접 정의한다.
- 에이전트와 태스크 리스트를 수동으로 생성하고 관리한다.
- 이 방식은 더 많은 제어권을 제공하지만, 대규모 프로젝트에서는 유지보수가 어려울 수 있다.
CrewAI 프레임워크의 Crew Output
CrewAI 프레임워크에서 크루의 출력은 CrewOutput
클래스로 캡슐화된다. 이 클래스는 크루 실행 결과에 접근할 수 있는 구조화된 방식을 제공하며, 원시 문자열, JSON, Pydantic 모델 등 다양한 형식의 결과를 포함한다. CrewOutput
은 최종 작업의 출력 결과, 토큰 사용량, 그리고 각 작업의 개별 출력 결과를 담고 있다.
크루 출력 속성
속성 | 매개변수 | 타입 | 설명 |
---|
원본 출력 | raw | str | 크루의 원본 출력. 이는 기본 출력 형식이다. |
Pydantic | pydantic | Optional[BaseModel] | 크루의 구조화된 출력을 나타내는 Pydantic 모델 객체. |
JSON 딕셔너리 | json_dict | Optional[Dict[str, Any]] | 크루의 JSON 출력을 나타내는 딕셔너리. |
태스크 출력 | tasks_output | List[TaskOutput] | 크루 내 각 태스크의 출력을 나타내는 TaskOutput 객체의 리스트. |
토큰 사용량 | token_usage | Dict[str, Any] | 실행 중 언어 모델의 성능을 보여주는 토큰 사용량 요약. |
Crew 출력 메서드와 속성
메서드/속성 | 설명 |
---|
json | 출력 형식이 JSON일 경우, JSON 문자열 표현을 반환한다. |
to_dict | JSON과 Pydantic 출력을 딕셔너리로 변환한다. |
**str** | Crew 출력의 문자열 표현을 반환하며, Pydantic을 우선시하고, 그다음 JSON, 마지막으로 원시 데이터를 반환한다. |
크루 실행 결과 접근하기
크루를 실행한 후, 그 결과는 Crew
객체의 output
속성을 통해 접근할 수 있다. CrewOutput
클래스는 이 결과를 다양한 방식으로 상호작용하고 표시하는 방법을 제공한다.
# 크루 실행 예제
crew = Crew(
agents=[research_agent, writer_agent],
tasks=[research_task, write_article_task],
verbose=True
)
crew_output = crew.kickoff()
# 크루 출력에 접근
print(f"원본 출력: {crew_output.raw}")
if crew_output.json_dict:
print(f"JSON 출력: {json.dumps(crew_output.json_dict, indent=2)}")
if crew_output.pydantic:
print(f"Pydantic 출력: {crew_output.pydantic}")
print(f"작업 출력: {crew_output.tasks_output}")
print(f"토큰 사용량: {crew_output.token_usage}")
크루 실행 로그 접근
output_log_file
을 True(불리언)
또는 file_name(문자열)
로 설정하면 크루 실행 로그를 실시간으로 확인할 수 있다. 이벤트 로그는 file_name.txt
와 file_name.json
두 가지 형식으로 저장된다.
True(불리언)
로 설정하면 logs.txt
파일로 저장된다.
output_log_file
이 False(불리언)
또는 None
으로 설정되면 로그가 저장되지 않는다.
# 크루 로그 저장
crew = Crew(output_log_file = True) # 로그가 logs.txt로 저장됨
crew = Crew(output_log_file = file_name) # 로그가 file_name.txt로 저장됨
crew = Crew(output_log_file = file_name.txt) # 로그가 file_name.txt로 저장됨
crew = Crew(output_log_file = file_name.json) # 로그가 file_name.json로 저장됨
메모리 활용
크루는 단기, 장기, 엔티티 메모리를 활용해 시간이 지남에 따라 실행과 학습을 개선할 수 있다. 이 기능을 통해 크루는 실행 메모리를 저장하고 불러올 수 있어 의사결정과 작업 실행 전략에 도움을 준다.
캐시 활용
캐시는 도구 실행 결과를 저장하는 데 사용할 수 있다. 이를 통해 동일한 작업을 다시 실행할 필요가 줄어들어 전체 프로세스의 효율성을 높일 수 있다.
크루 사용 메트릭
크루 실행이 완료되면, usage_metrics
속성을 통해 모든 작업에서 사용된 언어 모델(LLM)의 사용 메트릭을 확인할 수 있다. 이를 통해 운영 효율성과 개선이 필요한 부분을 파악할 수 있다.
# 크루의 사용 메트릭에 접근
crew = Crew(agents=[agent1, agent2], tasks=[task1, task2])
crew.kickoff()
print(crew.usage_metrics)
크루 실행 프로세스
- 순차적 프로세스: 작업을 하나씩 순서대로 실행하여 선형적인 작업 흐름을 유지한다.
- 계층적 프로세스: 매니저 에이전트가 크루를 조율하고 작업을 위임한 후 결과를 검증한다. 참고: 이 프로세스에는
manager_llm
또는 manager_agent
가 필요하며, 프로세스 흐름을 검증하는 데 필수적이다.
크루 작업 시작하기
크루가 구성되면 kickoff()
메서드를 사용해 워크플로우를 시작한다. 이 메서드는 정의된 프로세스 흐름에 따라 작업 실행을 시작한다.
# 크루의 작업 실행 시작
result = my_crew.kickoff()
print(result)
크루 작업 시작 방법
크루를 구성한 후, 적절한 방법으로 작업 흐름을 시작한다. CrewAI는 작업 시작 과정을 더 잘 제어할 수 있도록 여러 메서드를 제공한다: kickoff()
, kickoff_for_each()
, kickoff_async()
, kickoff_for_each_async()
.
kickoff()
: 정의된 프로세스 흐름에 따라 실행을 시작한다.
kickoff_for_each()
: 제공된 입력 이벤트나 컬렉션의 각 항목에 대해 순차적으로 작업을 실행한다.
kickoff_async()
: 비동기적으로 작업 흐름을 시작한다.
kickoff_for_each_async()
: 제공된 입력 이벤트나 컬렉션의 각 항목에 대해 비동기 처리를 활용해 동시에 작업을 실행한다.
# 크루의 작업 실행 시작
result = my_crew.kickoff()
print(result)
# kickoff_for_each 사용 예제
inputs_array = [{'topic': 'AI in healthcare'}, {'topic': 'AI in finance'}]
results = my_crew.kickoff_for_each(inputs=inputs_array)
for result in results:
print(result)
# kickoff_async 사용 예제
inputs = {'topic': 'AI in healthcare'}
async_result = my_crew.kickoff_async(inputs=inputs)
print(async_result)
# kickoff_for_each_async 사용 예제
inputs_array = [{'topic': 'AI in healthcare'}, {'topic': 'AI in finance'}]
async_results = my_crew.kickoff_for_each_async(inputs=inputs_array)
for async_result in async_results:
print(async_result)
이 메서드들은 동기 및 비동기 작업 흐름을 필요에 맞게 관리하고 실행할 수 있는 유연성을 제공한다.
특정 작업부터 재실행하기
이제 CLI 커맨드 replay
를 사용해 특정 작업부터 재실행할 수 있다.
CrewAI의 재실행 기능은 커맨드라인 인터페이스(CLI)를 통해 특정 작업부터 재실행할 수 있게 해준다. crewai replay -t <task_id>
커맨드를 실행하면 재실행할 task_id
를 지정할 수 있다.
Kickoffs는 이제 최신 kickoffs에서 반환된 작업 결과를 로컬에 저장하여 재실행할 수 있도록 한다.
특정 작업부터 다시 실행하기 (CLI 사용)
다시 실행 기능을 사용하려면 다음 단계를 따르면 된다.
- 터미널이나 커맨드라인을 연다.
- CrewAI 프로젝트가 있는 디렉토리로 이동한다.
- 다음 명령어를 실행한다:
가장 최근의 킥오프 작업 ID를 확인하려면:
그리고 특정 작업부터 다시 실행하려면:
crewai replay -t <task_id>
이 명령어들은 가장 최근의 킥오프 작업부터 다시 실행할 수 있게 해주며, 이전에 실행한 작업의 컨텍스트도 유지된다.