[AI] ๐ค CrewAI: ๋ฉํฐ ์์ด์ ํธ AI ํ์ ํ๋ ์์ํฌ ์๋ฒฝ ๊ฐ์ด๋
CrewAI๋ ์ฌ๋ฌ AI Agent๊ฐ ์ญํ ์ ๋ถ๋ดํ๊ณ ํ๋ ฅํ๋ ๋ฉํฐ ์์ด์ ํธ ํ๋ ์์ํฌ์ ๋๋ค. AgentยทTaskยทToolยทCrew ๊ตฌ์ฑ์์๋ถํฐ Sequential/Hierarchical ํ๋ก์ธ์ค, ๋ฉ๋ชจ๋ฆฌ ์์คํ , Python ์ฝ๋ ์์ ๊น์ง ์ค๋ฌด ๊ธฐ์ค์ผ๋ก ์ ๋ฆฌํ์ต๋๋ค.
CrewAI๋ ์ฌ๋ฌ AI Agent๊ฐ ์ธ๊ฐ ํ์ฒ๋ผ ์ญํ ์ ๋๋๊ณ ํ๋ ฅํ์ฌ ๋ณต์กํ ์์ ์ ์ฒ๋ฆฌํ๋ ๋ฉํฐ ์์ด์ ํธ ์ค์ผ์คํธ๋ ์ด์ ํ๋ ์์ํฌ์ ๋๋ค. ๋จ์ผ LLM ํธ์ถ๋ก๋ ํด๊ฒฐํ๊ธฐ ์ด๋ ค์ด ๋ฆฌ์์นยท์์ฑยท๋ถ์ยท์ฝ๋ฉ ๋ฑ ๋ค๋จ๊ณ ์์ ์ Agent ํ์ด ๋ถ์ ํ์ฌ ์ฒ๋ฆฌํฉ๋๋ค. ์ด ๊ธ์์๋ ํต์ฌ ๊ตฌ์ฑ์์, ํ๋ก์ธ์ค ์ ํ, ๋ฉ๋ชจ๋ฆฌ ์์คํ , Python ์ฝ๋ ์์ ๋ฅผ ์ค๋ฌด ๊ธฐ์ค์ผ๋ก ์ ๋ฆฌํฉ๋๋ค.
๐ค CrewAI๋?
CrewAI๋ ์ญํ ๊ธฐ๋ฐ AI Agent ํ์ ํ๋ซํผ์ ๋๋ค. ๊ฐ Agent๋ ํน์ ์ ๋ฌธ ์ญํ (๋ฆฌ์์ฒ, ์๊ฐ, ๋ถ์๊ฐ ๋ฑ)์ ๋ถ์ฌ๋ฐ๊ณ , ๋ ๋ฆฝ์ ์ผ๋ก ์์ ์ ์ํํ๊ฑฐ๋ ๋ค๋ฅธ Agent์๊ฒ ์์ํ๋ฉด์ ํ ๋ชฉํ๋ฅผ ๋ฌ์ฑํฉ๋๋ค.
1
2
3
4
5
6
7
8
์ฌ์ฉ์ ์
๋ ฅ (๋ชฉํ)
โ
Crew ์ค์ผ์คํธ๋ ์ดํฐ
โโโโโโดโโโโโ
Agent A Agent B Agent C
(๋ฆฌ์์ฒ) (์๊ฐ) (๊ฒ์์)
โโโโโโฌโโโโโ
์ต์ข
๊ฒฐ๊ณผ๋ฌผ
| ํญ๋ชฉ | ๋จ์ผ LLM | CrewAI ๋ฉํฐ ์์ด์ ํธ |
|---|---|---|
| ์์ ๋ณต์ก๋ | ๋จ์ ๋จ๋ฐ์ฑ | ๋ค๋จ๊ณยท๋ณตํฉ ์์ |
| ์ ๋ฌธํ | ๋ฒ์ฉ | ์ญํ ๋ณ ์ ๋ฌธํ |
| ์ปจํ ์คํธ | ๋จ์ผ ๋ํ | ์์ด์ ํธ ๊ฐ ๊ณต์ ยท๋์ |
| ํ์ฅ์ฑ | ์ ํ์ | Agent ์ถ๊ฐ๋ก ์ํ ํ์ฅ |
๐งฑ ํต์ฌ ๊ตฌ์ฑ์์
Agent โ ์์จ ์์ ๋จ์
Agent๋ ํน์ ์ญํ ๊ณผ ๋ชฉํ๋ฅผ ๊ฐ์ง ์์จ์ AI ์ํํธ์จ์ด์ ๋๋ค.
| ํ๋ผ๋ฏธํฐ | ์ค๋ช |
|---|---|
role | Agent์ ๊ธฐ๋ฅ/์ง์ฑ ์ ์ |
goal | ๊ฐ๋ณ ๋ชฉํ๋ก ์์ฌ๊ฒฐ์ ๋ฐฉํฅ ์ ์ |
backstory | ๋ฐฐ๊ฒฝ ์คํ ๋ฆฌ๋ก ์ญํ ๋งฅ๋ฝ ๊ฐํ |
tools | ์ฌ์ฉ ๊ฐ๋ฅํ ๋๊ตฌ ๋ชฉ๋ก |
llm | ์ฌ์ฉํ LLM (๊ธฐ๋ณธ๊ฐ: OpenAI GPT-4) |
verbose | True ์ค์ ์ ์คํ ๋ก๊ทธ ์ถ๋ ฅ |
allow_delegation | True๋ฉด ๋ค๋ฅธ Agent์๊ฒ ์์
์์ ๊ฐ๋ฅ |
memory | True๋ฉด ๋ฉ๋ชจ๋ฆฌ ์์คํ
ํ์ฑํ |
max_iter | ์ต๋ ๋ฐ๋ณต ํ์ (๊ธฐ๋ณธ๊ฐ: 15) |
Task โ ๊ตฌ์ฒด์ ์์ ๋จ์
Agent๊ฐ ์ํํ ๋ช ํํ ๊ณผ์ ๋ฅผ ์ ์ํฉ๋๋ค.
| ํ๋ผ๋ฏธํฐ | ์ค๋ช |
|---|---|
description | ์์ ๋ด์ฉ๊ณผ ์ํ ๋ฐฉ๋ฒ |
agent | ๋ด๋น Agent ์ง์ |
expected_output | ๊ธฐ๋ ๊ฒฐ๊ณผ๋ฌผ ํ์ ์ค๋ช |
tools | ํด๋น Task์๋ง ์ฌ์ฉ๋๋ ๋๊ตฌ |
context | ์ด์ Task ์ถ๋ ฅ์ ์ปจํ ์คํธ๋ก ์ ๋ฌ |
output_file | ๊ฒฐ๊ณผ๋ฅผ ํ์ผ๋ก ์ ์ฅ |
Tool โ Agent์ ์ธ๋ถ ๋ฅ๋ ฅ
Agent๊ฐ ์ค์ ๋ฐ์ดํฐ๋ฅผ ์์งํ๊ฑฐ๋ ์ธ๋ถ ์๋น์ค์ ์ํธ์์ฉํ๋ ํจ์์ ๋๋ค.
1
2
3
4
5
from crewai_tools import SerperDevTool, ScrapeWebsiteTool, WebsiteSearchTool
search_tool = SerperDevTool() # Google ๊ฒ์
scrape_tool = ScrapeWebsiteTool() # ์น ํ์ด์ง ์คํฌ๋ํ
rag_tool = WebsiteSearchTool() # ์น ์ฝํ
์ธ RAG ๊ฒ์
Process โ ์์ ํ๋ฆ ์กฐ์จ ๋ฐฉ์
| ํ๋ก์ธ์ค | ์ค๋ช |
|---|---|
Process.sequential | ์์ ์ ์์๋๋ก ์คํ, ์ ๊ฒฐ๊ณผ๊ฐ ๋ค์ ์ปจํ ์คํธ๊ฐ ๋จ |
Process.hierarchical | ๋งค๋์ Agent๊ฐ ์์ ์ ํ์ Agent์๊ฒ ์์ยท๊ฒ์ |
Crew โ ์ต์์ ์ค์ผ์คํธ๋ ์ดํฐ
Agent์ Task๋ฅผ ๋ชจ์์ ์คํ ๊ณํ์ ๊ด๋ฆฌํ๋ ์ต์์ ๊ตฌ์กฐ์ ๋๋ค.
๐ฆ ์ค์น
1
2
pip install crewai
pip install 'crewai[tools]' # ๊ธฐ๋ณธ ๋๊ตฌ ๋ชจ์ ํฌํจ
ํ๊ฒฝ ๋ณ์ ์ค์ (.env ํ์ผ):
1
2
OPENAI_API_KEY=sk-...
SERPER_API_KEY=... # SerperDevTool ์ฌ์ฉ ์ ํ์
๐ ๋น ๋ฅธ ์์: ๋ธ๋ก๊ทธ ๊ธ ์๋ ์์ฑ ์์ด์ ํธ
๋ฆฌ์์ฒ Agent๊ฐ ์ฃผ์ ๋ฅผ ์กฐ์ฌํ๊ณ , ์๋ํฐ Agent๊ฐ ๋ธ๋ก๊ทธ ๊ธ์ ์์ฑํ๋ 2์ธ ํ ์์ ์ ๋๋ค.
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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
import os
from dotenv import load_dotenv
from crewai import Agent, Task, Crew, Process
from crewai_tools import SerperDevTool, ScrapeWebsiteTool
load_dotenv()
os.environ["OPENAI_MODEL_NAME"] = "gpt-4o"
# โโ Tools โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
search_tool = SerperDevTool()
scrape_tool = ScrapeWebsiteTool()
# โโ Agents โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
researcher = Agent(
role="์๋์ด ๋ฆฌ์์ฒ",
goal="์ฃผ์ด์ง ์ฃผ์ ์ ๋ํด ์น์์ ์ต์ ์ ๋ณด๋ฅผ ์์งํ๊ณ ํต์ฌ ์ธ์ฌ์ดํธ๋ฅผ ์ ๋ฆฌํ๋ค",
backstory="๋ค์ํ ๊ธฐ์ ๋ฌธ์์ ๋ธ๋ก๊ทธ๋ฅผ ๋ถ์ํ์ฌ ์ต๊ณ ์ ๋ฆฌ์์น ๊ฒฐ๊ณผ๋ฅผ ๋ง๋๋ ์ ๋ฌธ๊ฐ",
tools=[search_tool, scrape_tool],
allow_delegation=False,
verbose=True,
)
editor = Agent(
role="IT ๋ธ๋ก๊ฑฐ / ์๋ํฐ",
goal="๋ฆฌ์์น ๊ฒฐ๊ณผ๋ฅผ ๋ฐํ์ผ๋ก ์ฝ๊ธฐ ์ฝ๊ณ ์ค์ฉ์ ์ธ ๋ธ๋ก๊ทธ ๊ธ์ ์์ฑํ๋ค",
backstory="๊ฐ๋ฐ์ ๋
์๋ฅผ ์ํด ๋ช
ํํ๊ณ ์ ์ตํ ๊ธฐ์ ์ฝํ
์ธ ๋ฅผ ์์ฑํ๋ ์ ๋ฌธ ๋ธ๋ก๊ฑฐ",
verbose=True,
)
# โโ Tasks โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
research_task = Task(
description="""'{topic}'์ ๊ดํ ์ต์ ์ ๋ณด๋ฅผ ์น์์ ๊ฒ์ํ๊ณ ๋ถ์ํ์ธ์.
ํต์ฌ ๊ฐ๋
, ์ฃผ์ ๊ธฐ๋ฅ, ์ค์ ํ์ฉ ์ฌ๋ก๋ฅผ ์ ๋ฆฌํ์ธ์.""",
agent=researcher,
expected_output="์ฃผ์ ์ ํต์ฌ ๋ด์ฉ, ์ฃผ์ ๊ธฐ๋ฅ, ํ์ฉ ์ฌ๋ก๋ฅผ ํฌํจํ ๋ฆฌ์์น ๋ณด๊ณ ์",
)
writing_task = Task(
description="""๋ฆฌ์์น ๊ฒฐ๊ณผ๋ฅผ ๋ฐํ์ผ๋ก '{topic}'์ ๋ํ ๋ธ๋ก๊ทธ ํฌ์คํธ๋ฅผ ์์ฑํ์ธ์.
๋์
๋ถ, ์ฃผ์ 3๊ฐ ์น์
, ์ค์ฉ์ ์์, ๊ฒฐ๋ก ์ผ๋ก ๊ตฌ์ฑํ์ธ์.""",
agent=editor,
expected_output="๋งํฌ๋ค์ด ํ์์ ๋ธ๋ก๊ทธ ํฌ์คํธ (๋์
๋ถ, 3๊ฐ ์น์
, ๊ฒฐ๋ก ํฌํจ)",
context=[research_task], # ๋ฆฌ์์น ๊ฒฐ๊ณผ๋ฅผ ์ปจํ
์คํธ๋ก ์ ๋ฌ
output_file="output_blog.md",
)
# โโ Crew โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
crew = Crew(
agents=[researcher, editor],
tasks=[research_task, writing_task],
process=Process.sequential,
verbose=True,
)
result = crew.kickoff(inputs={"topic": "CrewAI ๋ฉํฐ ์์ด์ ํธ ํ๋ ์์ํฌ"})
print(result.raw)
โ๏ธ ํ๋ก์ธ์ค ์ ํ
Sequential (์์ฐจ ์ฒ๋ฆฌ)
์์ ๋ชฉ๋ก ์์๋๋ก ์คํํ๋ฉฐ, ์ Task์ ์ถ๋ ฅ์ด ๋ค์ Task์ ์ปจํ ์คํธ๊ฐ ๋ฉ๋๋ค. ๊ฐ์ฅ ๋จ์ํ๊ณ ์์ธก ๊ฐ๋ฅํ ํ๋ฆ์ ๋๋ค.
1
2
3
4
5
crew = Crew(
agents=[researcher, editor, reviewer],
tasks=[research_task, writing_task, review_task],
process=Process.sequential,
)
1
2
research_task โ writing_task โ review_task
(์ถ๋ ฅ) โ (์ปจํ
์คํธ) โ (์ปจํ
์คํธ)
Hierarchical (๊ณ์ธต ์ฒ๋ฆฌ)
๋งค๋์ Agent๊ฐ ์๋ ์์ฑ๋์ด ์์ ์ ํ์ Agent์๊ฒ ์์ํ๊ณ ๊ฒฐ๊ณผ๋ฅผ ๊ฒ์ํฉ๋๋ค. ๋ณต์กํ๊ณ ๋์ ์ธ ์ํฌํ๋ก์ ์ ํฉํฉ๋๋ค.
1
2
3
4
5
6
7
8
from langchain_openai import ChatOpenAI
crew = Crew(
agents=[researcher, editor, reviewer],
tasks=[complex_task],
process=Process.hierarchical,
manager_llm=ChatOpenAI(model="gpt-4o"), # ๋งค๋์ LLM ์ง์
)
1
2
3
4
Manager Agent (์๋ ์์ฑ)
โโโ researcher ์๊ฒ ์กฐ์ฌ ์์
โโโ editor ์๊ฒ ์์ฑ ์์
โโโ ๊ฒฐ๊ณผ ๊ฒ์ ํ ์ต์ข
์น์ธ
๐ง ๋ฉ๋ชจ๋ฆฌ ์์คํ
CrewAI v1.10+ ์์๋ ํตํฉ ๋ฉ๋ชจ๋ฆฌ ์์คํ ์ ์ ๊ณตํฉ๋๋ค. Agent๊ฐ ์ด์ ์คํ ๋งฅ๋ฝ์ ๊ธฐ์ตํ๊ณ ์ค๋ณต ์์ ์ ์ค์ผ ์ ์์ต๋๋ค.
| ๋ฉ๋ชจ๋ฆฌ ์ ํ | ๋ฒ์ | ์ค๋ช |
|---|---|---|
| Short-term | ํ์ฌ Crew ์คํ ๋ด | ๋ํ ์ค ์ปจํ ์คํธ ์ ์ง |
| Long-term | ์คํ ๊ฐ ์์ | ๋ฒกํฐ ์คํ ์ด์ ์ ์ฅ, ์ฌ์คํ ์ ํ์ฉ |
| Entity | ํ์ฌ ์คํ ๋ด | ์ธ๊ธ๋ ์ธ๋ฌผยท์กฐ์งยท๊ฐ๋ ์ถ์ |
1
2
3
4
5
6
7
8
9
10
11
12
researcher = Agent(
role="๋ฆฌ์์ฒ",
goal="์ ๋ณด ์์ง",
backstory="...",
memory=True, # ๋ฉ๋ชจ๋ฆฌ ํ์ฑํ
)
crew = Crew(
agents=[researcher],
tasks=[task],
memory=True, # Crew ๋ ๋ฒจ ๋ฉ๋ชจ๋ฆฌ ํ์ฑํ
)
๐ง ์ปค์คํ Tool ๊ตฌํ
@tool ๋ฐ์ฝ๋ ์ดํฐ๋ก Python ํจ์๋ฅผ Agent๊ฐ ์ฌ์ฉํ ์ ์๋ ๋๊ตฌ๋ก ๋ฑ๋กํฉ๋๋ค.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
from crewai.tools import tool
@tool('naver_news_search')
def search_naver_news(query: str) -> str:
"""๋ค์ด๋ฒ ๋ด์ค API์์ ์ต์ ๊ธฐ์ฌ URL์ ๊ฒ์ํฉ๋๋ค."""
import requests
# ์ค์ API ํธ์ถ ๊ตฌํ
response = requests.get(
"https://openapi.naver.com/v1/search/news.json",
params={"query": query, "display": 5},
headers={
"X-Naver-Client-Id": os.getenv("NAVER_CLIENT_ID"),
"X-Naver-Client-Secret": os.getenv("NAVER_CLIENT_SECRET"),
}
)
items = response.json().get("items", [])
return "\n".join(item["link"] for item in items)
Tip: docstring์ด Tool์ ์ค๋ช ์ผ๋ก ์ฌ์ฉ๋ฉ๋๋ค. Agent๊ฐ ์ธ์ ์ด Tool์ ์จ์ผ ํ๋์ง ๋ช ํํ ์์ฑํ๋ฉด ํธ์ถ ์ ํ๋๊ฐ ๋์์ง๋๋ค.
๐ YAML ์ค์ ๋ฐฉ์ (๋๊ท๋ชจ ํ๋ก์ ํธ ๊ถ์ฅ)
Agent์ Task ์ ์๋ฅผ YAML ํ์ผ๋ก ๋ถ๋ฆฌํ๋ฉด ์ฝ๋์ ์ค์ ์ ๋ถ๋ฆฌํ์ฌ ๊ด๋ฆฌํ๊ธฐ ์ฝ์ต๋๋ค.
config/agents.yaml:
1
2
3
4
5
6
7
8
9
researcher:
role: ์๋์ด ๋ฆฌ์์ฒ
goal: ์ฃผ์ด์ง ์ฃผ์ ์ ์ต์ ์ ๋ณด๋ฅผ ์์งํ๊ณ ํต์ฌ ์ธ์ฌ์ดํธ๋ฅผ ์ ๋ฆฌํ๋ค
backstory: ๋ค์ํ ๊ธฐ์ ๋ฌธ์๋ฅผ ๋ถ์ํ์ฌ ์ต๊ณ ์ ๋ฆฌ์์น ๊ฒฐ๊ณผ๋ฅผ ๋ง๋๋ ์ ๋ฌธ๊ฐ
editor:
role: IT ๋ธ๋ก๊ฑฐ ์๋ํฐ
goal: ๋ฆฌ์์น ๊ฒฐ๊ณผ๋ฅผ ์ฝ๊ธฐ ์ฌ์ด ๋ธ๋ก๊ทธ ๊ธ๋ก ์์ฑํ๋ค
backstory: ๊ฐ๋ฐ์ ๋
์๋ฅผ ์ํด ๋ช
ํํ ๊ธฐ์ ์ฝํ
์ธ ๋ฅผ ์์ฑํ๋ ์ ๋ฌธ ๋ธ๋ก๊ฑฐ
config/tasks.yaml:
1
2
3
4
5
6
7
8
9
10
11
research_task:
description: "{topic}"์ ๊ดํ ์ต์ ์ ๋ณด๋ฅผ ์์งํ๊ณ ํต์ฌ ๋ด์ฉ์ ์ ๋ฆฌํ์ธ์.
expected_output: ํต์ฌ ๊ฐ๋
, ์ฃผ์ ๊ธฐ๋ฅ, ํ์ฉ ์ฌ๋ก๋ฅผ ํฌํจํ ๋ฆฌ์์น ๋ณด๊ณ ์
agent: researcher
writing_task:
description: ๋ฆฌ์์น ๊ฒฐ๊ณผ๋ฅผ ๋ฐํ์ผ๋ก "{topic}" ๋ธ๋ก๊ทธ ํฌ์คํธ๋ฅผ ์์ฑํ์ธ์.
expected_output: ๋งํฌ๋ค์ด ๋ธ๋ก๊ทธ ํฌ์คํธ
agent: editor
context:
- research_task
crew.py:
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
30
31
from crewai import Agent, Task, Crew, Process
from crewai.project import CrewBase, agent, task, crew
@CrewBase
class BlogCrew:
agents_config = 'config/agents.yaml'
tasks_config = 'config/tasks.yaml'
@agent
def researcher(self) -> Agent:
return Agent(config=self.agents_config['researcher'], tools=[search_tool])
@agent
def editor(self) -> Agent:
return Agent(config=self.agents_config['editor'])
@task
def research_task(self) -> Task:
return Task(config=self.tasks_config['research_task'])
@task
def writing_task(self) -> Task:
return Task(config=self.tasks_config['writing_task'])
@crew
def crew(self) -> Crew:
return Crew(
agents=self.agents,
tasks=self.tasks,
process=Process.sequential,
)
๐๏ธ ์ค์ ์์ : ๋ด์ค ๋ฆฌ์์น ๋ฉํฐ ์์ด์ ํธ
๊ฒ์ โ ๋ด์ฉ ์ถ์ถ โ ์์ฝ ์๋ต์ 3๊ฐ 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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
from crewai import Agent, Task, Crew, Process
from crewai.tools import tool
@tool('fetch_article')
def fetch_article(url: str) -> str:
"""์ฃผ์ด์ง URL์ ๊ธฐ์ฌ ๋ณธ๋ฌธ์ ์ถ์ถํฉ๋๋ค."""
from newspaper import Article
article = Article(url)
article.download()
article.parse()
return article.text
# Agents
searcher = Agent(
role="๋ด์ค ๊ฒ์ ์ ๋ฌธ๊ฐ",
goal="์ฌ์ฉ์ ์ง๋ฌธ์ ๋ง๋ ์ต์ ๋ด์ค URL์ ์์งํ๋ค",
backstory="๋ค์ํ ๋ด์ค ์์ค์์ ์ ํํ ๊ธฐ์ฌ๋ฅผ ์ฐพ๋ ๋ฆฌ์์น ์ ๋ฌธ๊ฐ",
tools=[search_tool],
)
analyzer = Agent(
role="์ฝํ
์ธ ๋ถ์๊ฐ",
goal="๊ธฐ์ฌ URL์์ ๋ณธ๋ฌธ์ ์ถ์ถํ๊ณ ํต์ฌ ๋ด์ฉ์ ๋ถ์ํ๋ค",
backstory="๋ณต์กํ ๊ธฐ์ฌ๋ฅผ ๋น ๋ฅด๊ฒ ํ์
ํ๊ณ ํต์ฌ์ ์ถ์ถํ๋ ๋ถ์๊ฐ",
tools=[fetch_article],
)
answerman = Agent(
role="์ต์ข
์๋ต ์์ฑ์",
goal="๋ถ์๋ ์ ๋ณด๋ฅผ ๋ฐํ์ผ๋ก ์ฌ์ฉ์์๊ฒ ๋ช
ํํ ๋ต๋ณ์ ์ ๊ณตํ๋ค",
backstory="๋ณต์กํ ์ ๋ณด๋ฅผ ์ฝ๊ณ ์ ํํ๊ฒ ์ ๋ฌํ๋ ์ปค๋ฎค๋์ผ์ด์
์ ๋ฌธ๊ฐ",
)
# Tasks
search_task = Task(
description="'{query}'์ ๊ดํ ์ต์ ๋ด์ค ๊ธฐ์ฌ URL 5๊ฐ๋ฅผ ์์งํ์ธ์.",
agent=searcher,
expected_output="๊ด๋ จ ๋ด์ค ๊ธฐ์ฌ URL ๋ชฉ๋ก (์ต์ 5๊ฐ)",
)
analysis_task = Task(
description="์์ง๋ URL์์ ๊ธฐ์ฌ ๋ณธ๋ฌธ์ ์ถ์ถํ๊ณ ํต์ฌ ๋ด์ฉ์ ์ ๋ฆฌํ์ธ์.",
agent=analyzer,
expected_output="๊ฐ ๊ธฐ์ฌ์ ํต์ฌ ๋ด์ฉ ์์ฝ",
context=[search_task],
)
answer_task = Task(
description="๋ถ์ ๊ฒฐ๊ณผ๋ฅผ ๋ฐํ์ผ๋ก '{query}'์ ๋ํ ์ข
ํฉ ๋ต๋ณ์ ์์ฑํ์ธ์.",
agent=answerman,
expected_output="์ถ์ฒ์ ๊ทผ๊ฑฐ๋ฅผ ํฌํจํ ๋ช
ํํ ๋ต๋ณ",
context=[analysis_task],
)
# Crew ์คํ
crew = Crew(
agents=[searcher, analyzer, answerman],
tasks=[search_task, analysis_task, answer_task],
process=Process.sequential,
)
result = crew.kickoff(inputs={"query": "2026๋
AI Agent ํธ๋ ๋"})
print(result.raw)
โ ์์ฃผ ๋ฌป๋ ์ง๋ฌธ
Q. CrewAI์ LangChain์ ์ฐจ์ด๋?
LangChain์ LLM ์ฒด์ด๋๊ณผ ๋๊ตฌ ํตํฉ์ ์ํ ๋ฒ์ฉ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๋๋ค. CrewAI๋ ๋ฉํฐ ์์ด์ ํธ ํ์ ์ค์ผ์คํธ๋ ์ด์ ์ ํนํ๋์ด ์์ผ๋ฉฐ, LangChain ์์์ ๋์ํ ์ ์์ต๋๋ค.
Q. OpenAI ์ธ์ ๋ค๋ฅธ LLM์ ์ฌ์ฉํ ์ ์๋์?
๋ค, llm ํ๋ผ๋ฏธํฐ๋ก Anthropic Claude, Google Gemini, Ollama(๋ก์ปฌ LLM) ๋ฑ์ ์ง์ ํ ์ ์์ต๋๋ค.
1
2
3
4
5
6
7
8
from langchain_anthropic import ChatAnthropic
agent = Agent(
role="๋ถ์๊ฐ",
goal="...",
backstory="...",
llm=ChatAnthropic(model="claude-sonnet-4-6"),
)
Q. Sequential๊ณผ Hierarchical ์ค ์ด๋ค ๊ฑธ ์จ์ผ ํ๋์?
๋จ๊ณ๋ณ ํ๋ฆ์ด ๋ช ํํ๊ณ ์์ธก ๊ฐ๋ฅํ๋ฉด Sequential, ์์ ์ ๋ณต์ก๋๊ฐ ๋๊ณ ๋์ ์์์ด ํ์ํ๋ฉด Hierarchical์ ์ ํํ์ธ์.