Ver3.0 ๐ค AI ์์ด์ ํธ์ ๋๊ตฌ์ฌ์ฉ, ์์ ์ ๋ณต!

๐ค AI ์์ด์ ํธ์ ๋๊ตฌ์ฌ์ฉ, ์์ ์ ๋ณต!
์น๊ตฌ์ฒ๋ผ ์ฝ๊ฒ ์๋ ค์ฃผ๋ Agent Tool Use์ ๋ชจ๋ ๊ฒ ๐ ๏ธโจ
์๋ ! ๐ ์์ฆ AI ์์ด์ ํธ๊ฐ ์ ๋ง ํซํ์ง? ChatGPT๊ฐ ๊ณ์ฐ๊ธฐ๋ฅผ ์ฐ๊ณ , ๋ ์จ๋ฅผ ๊ฒ์ํ๊ณ , ์ฌ์ง์ด ์ฝ๋๊น์ง ์คํํ๋ ๊ฑธ ๋ณด๋ฉด "์, ์ด๋ป๊ฒ ์ ๋ฐ ๊ฒ ๊ฐ๋ฅํ์ง?"๋ผ๋ ์๊ฐ์ด ๋ค ๊ฑฐ์ผ. ๋ฐ๋ก ๊ทธ ๋น๋ฐ์ด ๋๊ตฌ์ฌ์ฉ(Tool Use)์ด๋ผ๋ ๊ฐ๋ ์ ์จ์ด์์ด! ๐ฏ
์ค๋์ AI ์์ด์ ํธ๊ฐ ์ด๋ป๊ฒ ๋๊ตฌ๋ฅผ ์ฌ์ฉํ๋์ง, ๊ทธ ์๋ฆฌ๋ถํฐ ์ค์ ๊ตฌํ ๋ฐฉ๋ฒ๊น์ง ์น๊ตฌํํ ์ค๋ช ํ๋ฏ์ด ์ฌ๋ฏธ์๊ฒ ํ์ด๋ณผ๊ฒ. ํ๋ก๊ทธ๋๋ฐ์ ๊ด์ฌ ์๋ ์ฌ๋์ด๋ผ๋ฉด ๊ผญ ์์์ผ ํ ๋ด์ฉ์ด๋๊น ์ง์ค! ๐
๐ฏ ๋๊ตฌ์ฌ์ฉ(Tool Use)์ด ๋ญ๊ธธ๋?
๋จผ์ ๊ธฐ๋ณธ ๊ฐ๋ ๋ถํฐ ์ก๊ณ ๊ฐ์! AI ์์ด์ ํธ์ ๋๊ตฌ์ฌ์ฉ(Tool Use)์ ์ฝ๊ฒ ๋งํด์ AI๊ฐ ์ธ๋ถ ๊ธฐ๋ฅ์ด๋ ํ๋ก๊ทธ๋จ์ ํธ์ถํด์ ์์ ์ ๋ฅ๋ ฅ์ ํ์ฅํ๋ ๊ฒ์ด์ผ. ๐ช
์๊ฐํด๋ด. ์์ํ ์ธ์ด ๋ชจ๋ธ(LLM)์ ํ ์คํธ ์์ฑ์๋ ์ฒ์ฌ์ง๋ง, ์ค์๊ฐ ์ ๋ณด๋ฅผ ๋ชจ๋ฅด๊ณ , ๊ณ์ฐ๋ ์ ํํ์ง ์๊ณ , ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ ๊ทผํ ์๋ ์์ด. ๋ง์น ์์ฒญ ๋๋ํ๋ฐ ์๋ฐ์ด ์๋ ์ํ๋๊น? ๐ค
๐ ์์๋ก ์ดํดํ๊ธฐ
์ฌ์ฉ์: "์ค๋ ์์ธ ๋ ์จ ์ด๋?"
๋๊ตฌ ์๋ AI: "์ฃ์กํ์ง๋ง ์ค์๊ฐ ์ ๋ณด๋ ์ ์ ์์ต๋๋ค..." ๐ข
๋๊ตฌ ์๋ AI: [๋ ์จ API ํธ์ถ] โ "์ค๋ ์์ธ์ ๋ง๊ณ ๊ธฐ์จ์ 18๋์
๋๋ค!" โ๏ธ
๋ฐ๋ก ์ด๊ฒ ๋๊ตฌ์ฌ์ฉ์ ํต์ฌ์ด์ผ. AI๊ฐ ํ์ํ ๋ ์ ์ ํ ๋๊ตฌ๋ฅผ ์ ํํ๊ณ , ๊ทธ ๋๊ตฌ๋ฅผ ์คํํด์ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ์์ค๋ ๊ฑฐ์ง. ๋ง์น ์ฐ๋ฆฌ๊ฐ ๊ณ์ฐํ ๋ ๊ณ์ฐ๊ธฐ๋ฅผ ๊บผ๋ด ์ฐ๋ ๊ฒ์ฒ๋ผ ๋ง์ด์ผ! ๐ฑ
๐งฉ ๋๊ตฌ์ฌ์ฉ์ ํต์ฌ ๊ตฌ์ฑ์์
AI ์์ด์ ํธ์ ๋๊ตฌ์ฌ์ฉ ์์คํ ์ ํฌ๊ฒ 4๊ฐ์ง ์์๋ก ๊ตฌ์ฑ๋ผ:
1๏ธโฃ ๋๊ตฌ ์ ์(Tool Definition)
AI์๊ฒ "์ด๋ฐ ๋๊ตฌ๊ฐ ์์ด!"๋ผ๊ณ ์๋ ค์ฃผ๋ ๋จ๊ณ์ผ. ๊ฐ ๋๊ตฌ์ ์ด๋ฆ, ์ค๋ช , ํ์ํ ์ ๋ ฅ๊ฐ(ํ๋ผ๋ฏธํฐ)์ ๋ช ํํ๊ฒ ์ ์ํด์ค์ผ ํด.
{
"name": "get_weather",
"description": "ํน์ ๋์์ ํ์ฌ ๋ ์จ ์ ๋ณด๋ฅผ ๊ฐ์ ธ์ต๋๋ค",
"parameters": {
"city": {
"type": "string",
"description": "๋ ์จ๋ฅผ ํ์ธํ ๋์ ์ด๋ฆ"
}
}
}
2๏ธโฃ ๋๊ตฌ ์ ํ(Tool Selection)
AI๊ฐ ์ฌ์ฉ์์ ์์ฒญ์ ๋ถ์ํด์ "์, ์ด ์ํฉ์๋ ์ด ๋๊ตฌ๋ฅผ ์จ์ผ๊ฒ ๋ค!"๋ผ๊ณ ํ๋จํ๋ ๋จ๊ณ. ์ด๊ฒ ์ง์ง ์ค์ํ๋ฐ, AI์ ์ถ๋ก ๋ฅ๋ ฅ์ด ์ฌ๊ธฐ์ ๋น์ ๋ฐํด! ๐
3๏ธโฃ ๋๊ตฌ ์คํ(Tool Execution)
์ ํํ ๋๊ตฌ๋ฅผ ์ค์ ๋ก ์คํํ๋ ๋จ๊ณ. API๋ฅผ ํธ์ถํ๊ฑฐ๋, ํจ์๋ฅผ ์คํํ๊ฑฐ๋, ์ธ๋ถ ์์คํ ๊ณผ ํต์ ํ๋ ๊ณผ์ ์ด์ง.
4๏ธโฃ ๊ฒฐ๊ณผ ํตํฉ(Result Integration)
๋๊ตฌ ์คํ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ์์ AI๊ฐ ์ดํดํ๊ณ , ์ฌ์ฉ์์๊ฒ ์์ฐ์ค๋ฌ์ด ๋ต๋ณ์ผ๋ก ๋ง๋ค์ด์ฃผ๋ ๋จ๊ณ์ผ. ๋จ์ํ ๊ฒฐ๊ณผ๋ฅผ ๋ณต๋ถํ๋ ๊ฒ ์๋๋ผ ๋งฅ๋ฝ์ ๋ง๊ฒ ๊ฐ๊ณตํ๋ ๊ฑฐ์ง! โจ
๐ง ๋๊ตฌ์ฌ์ฉ์ ์๋ ์๋ฆฌ
์, ์ด์ ์ข ๋ ๊น์ด ๋ค์ด๊ฐ๋ณผ๊น? AI ์์ด์ ํธ๊ฐ ๋๊ตฌ๋ฅผ ์ฌ์ฉํ๋ ์ ์ฒด ํ๋ก์ธ์ค๋ฅผ ๋จ๊ณ๋ณ๋ก ์ดํด๋ณด์! ๐ฌ
๐ Step-by-Step ํ๋ก์ธ์ค
์ฌ์ฉ์๊ฐ "2024๋ 3์ 15์ผ๋ถํฐ 20์ผ๊น์ง ๋ฉฐ์น ์ด์ผ?"๋ผ๊ณ ๋ฌผ์๋ค๊ณ ๊ฐ์ ํด๋ณด์. AI๋ ๋จผ์ ์ด ์์ฒญ์ ๋ถ์ํด:
AI์ ๋ด๋ถ ์ฌ๊ณ ๊ณผ์ :
- ๋ ์ง ๊ณ์ฐ์ด ํ์ํ๋ค? ๐ค
- ์ ํํ ๊ณ์ฐ์ด ํ์ํ๋๊น ๊ณ์ฐ ๋๊ตฌ๋ฅผ ์จ์ผ๊ฒ ์ด!
- ์์์ผ: 2024-03-15, ์ข
๋ฃ์ผ: 2024-03-20
- calculate_date_difference ๋๊ตฌ๋ฅผ ํธ์ถํด์ผ๊ฒ ๋ค!
์ต์ LLM๋ค์ Function Calling์ด๋ผ๋ ํน๋ณํ ๊ธฐ๋ฅ์ ์ง์ํด. ์ด๊ฑด AI๊ฐ ๊ตฌ์กฐํ๋ ํ์์ผ๋ก "์ด ํจ์๋ฅผ ์ด๋ ๊ฒ ํธ์ถํด์ค!"๋ผ๊ณ ์์ฒญํ๋ ๊ฑฐ์ผ.
{
"function_call": {
"name": "calculate_date_difference",
"arguments": {
"start_date": "2024-03-15",
"end_date": "2024-03-20"
}
}
}
์ด JSON ํ์์ ์ถ๋ ฅ์ด ํต์ฌ์ด์ผ! AI๊ฐ ์์ฐ์ด๊ฐ ์๋ ํ๋ก๊ทธ๋จ์ด ์ดํดํ ์ ์๋ ๊ตฌ์กฐํ๋ ๋ฐ์ดํฐ๋ก ์๋๋ฅผ ํํํ๋ ๊ฑฐ์ง. ๐ฏ
์ด์ ์์ด์ ํธ ์์คํ (์ฐ๋ฆฌ๊ฐ ๋ง๋ ํ๋ก๊ทธ๋จ)์ด ์ด ์์ฒญ์ ๋ฐ์์ ์ค์ ํจ์๋ฅผ ์คํํด:
def calculate_date_difference(start_date, end_date):
from datetime import datetime
start = datetime.strptime(start_date, "%Y-%m-%d")
end = datetime.strptime(end_date, "%Y-%m-%d")
difference = (end - start).days
return {
"days": difference,
"message": f"{start_date}๋ถํฐ {end_date}๊น์ง๋ {difference}์ผ์
๋๋ค."
}
์คํ ๊ฒฐ๊ณผ: {"days": 5, "message": "2024-03-15๋ถํฐ 2024-03-20๊น์ง๋ 5์ผ์ ๋๋ค."}
๋๊ตฌ ์คํ ๊ฒฐ๊ณผ๋ฅผ AI์๊ฒ ๋๋ ค์ค. ๊ทธ๋ฌ๋ฉด AI๋ ์ด ๊ฒฐ๊ณผ๋ฅผ ์์ฐ์ค๋ฌ์ด ๋ต๋ณ์ผ๋ก ๋ง๋ค์ด:
AI์ ์ต์ข ๋ต๋ณ: "2024๋ 3์ 15์ผ๋ถํฐ 20์ผ๊น์ง๋ ์ด 5์ผ์ด์์! ๐ "
๐ ๋ฐ๋ณต์ ๋๊ตฌ ์ฌ์ฉ (Multi-Step Reasoning)
์ง์ง ๋ฉ์ง ๊ฑด AI๊ฐ ์ฌ๋ฌ ๋๊ตฌ๋ฅผ ์ฐ์์ผ๋ก ์ฌ์ฉํ ์ ์๋ค๋ ๊ฑฐ์ผ! ์ด๊ฑธ ์ฒด์ธ(Chain)์ด๋ผ๊ณ ๋ถ๋ฅด๊ธฐ๋ ํด. ๐
๐ฏ ๋ณต์กํ ์๋๋ฆฌ์ค ์์
์ฌ์ฉ์: "์์ธ์ ํ์ฌ ๋ ์จ๋ฅผ ํ์ธํ๊ณ , ๋น๊ฐ ์จ๋ค๋ฉด ์ฐ์ฐ ์ถ์ฒ ์ํ์ ๊ฒ์ํด์ค"
AI์ ์คํ ํ๋ฆ:
1๏ธโฃ get_weather("์์ธ") ํธ์ถ โ ๊ฒฐ๊ณผ: "๋น, 15๋"
2๏ธโฃ ๊ฒฐ๊ณผ ๋ถ์: "๋น๊ฐ ์ค๋ค!"
3๏ธโฃ search_products("์ฐ์ฐ") ํธ์ถ โ ๊ฒฐ๊ณผ: ์ํ ๋ฆฌ์คํธ
4๏ธโฃ ์ต์ข
๋ต๋ณ ์์ฑ: "์์ธ์ ํ์ฌ ๋น๊ฐ ์ค๊ณ ์์ด์. ์ด๋ฐ ์ฐ์ฐ ์ํ๋ค์ ์ด๋ ์ธ์? โ"
์ด๋ ๊ฒ AI๊ฐ ์ํฉ์ ํ๋จํ๊ณ , ํ์ํ ๋๊ตฌ๋ฅผ ์์ฐจ์ ์ผ๋ก ์ฌ์ฉํ๋ฉด์ ๋ณต์กํ ์์ ์ ์ํํ๋ ๊ฑฐ์ผ. ๋ง์น ์ฌ๋์ด ๋ฌธ์ ๋ฅผ ๋จ๊ณ๋ณ๋ก ํด๊ฒฐํ๋ ๊ฒ์ฒ๋ผ! ๐ง
๐ ๏ธ ์ฃผ์ ๋๊ตฌ ์ฌ์ฉ ํจํด
์ค์ ๋ก AI ์์ด์ ํธ๊ฐ ์ฌ์ฉํ๋ ๋๊ตฌ๋ค์ ์ด๋ค ์ข ๋ฅ๊ฐ ์์๊น? ์นดํ ๊ณ ๋ฆฌ๋ณ๋ก ์ ๋ฆฌํด๋ดค์ด! ๐
| ์นดํ ๊ณ ๋ฆฌ | ๋๊ตฌ ์์ | ์ฌ์ฉ ๋ชฉ์ |
|---|---|---|
| ์ ๋ณด ๊ฒ์ ๐ | ์น ๊ฒ์, ์ํคํผ๋์, ๋ด์ค API | ์ค์๊ฐ ์ ๋ณด, ์ต์ ๋ฐ์ดํฐ ํ์ธ |
| ๊ณ์ฐ/๋ถ์ ๐ข | ๊ณ์ฐ๊ธฐ, ํต๊ณ ๋ถ์, ๋ฐ์ดํฐ ์ฒ๋ฆฌ | ์ ํํ ์์น ๊ณ์ฐ, ๋ณต์กํ ์ฐ์ฐ |
| ๋ฐ์ดํฐ๋ฒ ์ด์ค ๐พ | SQL ์ฟผ๋ฆฌ, NoSQL ์กฐํ, ๋ฒกํฐDB | ์ ์ฅ๋ ๋ฐ์ดํฐ ์กฐํ/์์ |
| ์ธ๋ถ API ๐ | ๋ ์จ, ์ง๋, ๋ฒ์ญ, ๊ฒฐ์ | ์ธ๋ถ ์๋น์ค ์ฐ๋ |
| ์ฝ๋ ์คํ ๐ป | Python ์ธํฐํ๋ฆฌํฐ, ์๋๋ฐ์ค | ๋์ ์ฝ๋ ์คํ, ๋ฐ์ดํฐ ์ฒ๋ฆฌ |
| ํ์ผ ์์ ๐ | ํ์ผ ์ฝ๊ธฐ/์ฐ๊ธฐ, ์ด๋ฏธ์ง ์์ฑ | ํ์ผ ์์คํ ์กฐ์ |
๐จ ์ค์ ๋๊ตฌ ๊ตฌํ ์์
์ด๋ก ๋ง ๋ณด๋ฉด ์ฌ๋ฏธ์์ผ๋๊น, ์ค์ ๋ก ์ด๋ป๊ฒ ๊ตฌํํ๋์ง ์ฝ๋๋ก ๋ณผ๊น? Python์ผ๋ก ๊ฐ๋จํ ๋๊ตฌ ์์คํ ์ ๋ง๋ค์ด๋ณด์! ๐
๊ธฐ๋ณธ ๋๊ตฌ ํด๋์ค ์ ์
from typing import Dict, Any, Callable
import json
class Tool:
def __init__(self, name: str, description: str,
function: Callable, parameters: Dict):
self.name = name
self.description = description
self.function = function
self.parameters = parameters
def to_schema(self) -> Dict:
"""AI๊ฐ ์ดํดํ ์ ์๋ ์คํค๋ง ํ์์ผ๋ก ๋ณํ"""
return {
"name": self.name,
"description": self.description,
"parameters": self.parameters
}
def execute(self, **kwargs) -> Any:
"""๋๊ตฌ ์คํ"""
return self.function(**kwargs)
๊ตฌ์ฒด์ ์ธ ๋๊ตฌ ๊ตฌํ
# ๋ ์จ ์กฐํ ๋๊ตฌ
def get_weather_impl(city: str) -> Dict:
# ์ค์ ๋ก๋ API ํธ์ถํ๊ฒ ์ง๋ง, ์ฌ๊ธฐ์๋ ์๋ฎฌ๋ ์ด์
weather_data = {
"์์ธ": {"temp": 18, "condition": "๋ง์"},
"๋ถ์ฐ": {"temp": 20, "condition": "ํ๋ฆผ"}
}
return weather_data.get(city, {"temp": 0, "condition": "์ ๋ณด์์"})
weather_tool = Tool(
name="get_weather",
description="ํน์ ๋์์ ํ์ฌ ๋ ์จ๋ฅผ ์กฐํํฉ๋๋ค",
function=get_weather_impl,
parameters={
"type": "object",
"properties": {
"city": {
"type": "string",
"description": "๋ ์จ๋ฅผ ํ์ธํ ๋์ ์ด๋ฆ"
}
},
"required": ["city"]
}
)
# ๊ณ์ฐ๊ธฐ ๋๊ตฌ
def calculator_impl(expression: str) -> float:
# ์์ ํ ๊ณ์ฐ์ ์ํด eval ๋์ ast ์ฌ์ฉ ๊ถ์ฅ
try:
return eval(expression)
except:
return "๊ณ์ฐ ์ค๋ฅ"
calculator_tool = Tool(
name="calculator",
description="์ํ ๊ณ์ฐ์ ์ํํฉ๋๋ค",
function=calculator_impl,
parameters={
"type": "object",
"properties": {
"expression": {
"type": "string",
"description": "๊ณ์ฐํ ์์ (์: '2 + 2', '10 * 5')"
}
},
"required": ["expression"]
}
)
๋๊ตฌ ๊ด๋ฆฌ์ (Tool Manager)
class ToolManager:
def __init__(self):
self.tools: Dict[str, Tool] = {}
def register_tool(self, tool: Tool):
"""๋๊ตฌ ๋ฑ๋ก"""
self.tools[tool.name] = tool
print(f"โ
๋๊ตฌ ๋ฑ๋ก๋จ: {tool.name}")
def get_tools_schema(self) -> list:
"""๋ชจ๋ ๋๊ตฌ์ ์คํค๋ง๋ฅผ AI์๊ฒ ์ ๋ฌํ ํ์์ผ๋ก ๋ฐํ"""
return [tool.to_schema() for tool in self.tools.values()]
def execute_tool(self, tool_name: str, arguments: Dict) -> Any:
"""๋๊ตฌ ์คํ"""
if tool_name not in self.tools:
return {"error": f"๋๊ตฌ '{tool_name}'๋ฅผ ์ฐพ์ ์ ์์ต๋๋ค"}
tool = self.tools[tool_name]
try:
result = tool.execute(**arguments)
return {"success": True, "result": result}
except Exception as e:
return {"success": False, "error": str(e)}
# ์ฌ์ฉ ์์
manager = ToolManager()
manager.register_tool(weather_tool)
manager.register_tool(calculator_tool)
# ๋๊ตฌ ์คํ
result = manager.execute_tool("get_weather", {"city": "์์ธ"})
print(result) # {'success': True, 'result': {'temp': 18, 'condition': '๋ง์'}}
์ด๋ ๊ฒ ๋๊ตฌ๋ฅผ ์ฒด๊ณ์ ์ผ๋ก ๊ด๋ฆฌํ๋ฉด, AI ์์ด์ ํธ๊ฐ ํ์ํ ๋ ์ฝ๊ฒ ํธ์ถํ ์ ์์ด! ๐
๐ค ์ฃผ์ ํ๋ ์์ํฌ์ ๊ตฌํ ๋ฐฉ๋ฒ
์ง์ ๋ค ๋ง๋ค ์๋ ์์ง๋ง, ์ด๋ฏธ ์ ๋ง๋ค์ด์ง ํ๋ ์์ํฌ๋ค์ด ๋ง์. ์ค๋ฌด์์ ๋ง์ด ์ฐ์ด๋ ๊ฒ๋ค์ ์๊ฐํ ๊ฒ! ๐
1๏ธโฃ LangChain - ๊ฐ์ฅ ์ธ๊ธฐ ์๋ ํ๋ ์์ํฌ
LangChain์ AI ์์ด์ ํธ ๊ฐ๋ฐ์ ํ์ค์ฒ๋ผ ์๋ฆฌ์ก์ ํ๋ ์์ํฌ์ผ. ๋๊ตฌ ์ฌ์ฉ์ ์ ๋ง ์ฝ๊ฒ ๋ง๋ค์ด์ค! ๐ฆ
from langchain.agents import initialize_agent, Tool
from langchain.agents import AgentType
from langchain.llms import OpenAI
# ๋๊ตฌ ์ ์
tools = [
Tool(
name="Calculator",
func=lambda x: eval(x),
description="์ํ ๊ณ์ฐ์ ์ ์ฉํฉ๋๋ค. ์
๋ ฅ์ ์์์ด์ด์ผ ํฉ๋๋ค."
),
Tool(
name="Search",
func=search_function, # ์ค์ ๊ฒ์ ํจ์
description="์ต์ ์ ๋ณด๋ฅผ ๊ฒ์ํ ๋ ์ฌ์ฉํฉ๋๋ค."
)
]
# ์์ด์ ํธ ์ด๊ธฐํ
llm = OpenAI(temperature=0)
agent = initialize_agent(
tools,
llm,
agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION,
verbose=True
)
# ์คํ
response = agent.run("2024๋
์ฌ๋ฆผํฝ์ ์ด๋์ ์ด๋ฆฌ๋์? ๊ทธ๋ฆฌ๊ณ 123 * 456์ ๊ณ์ฐํด์ฃผ์ธ์")
print(response)
๐ฏ LangChain์ ์ฅ์ :
โ
๋ค์ํ LLM ์ง์ (OpenAI, Anthropic, Hugging Face ๋ฑ)
โ
ํ๋ถํ ๋ด์ฅ ๋๊ตฌ๋ค
โ
์ฒด์ธ(Chain) ๊ตฌ์ฑ์ด ์ง๊ด์
โ
์ปค๋ฎค๋ํฐ๊ฐ ํ๋ฐํ๊ณ ๋ฌธ์๊ฐ ์ ๋์ด์์
2๏ธโฃ OpenAI Function Calling
OpenAI๊ฐ ์ง์ ์ ๊ณตํ๋ Function Calling ๊ธฐ๋ฅ์ ์ ๋ง ๊ฐ๋ ฅํด! GPT-4, GPT-3.5-turbo ๋ชจ๋ธ์์ ์ฌ์ฉ ๊ฐ๋ฅํ์ง. ๐
import openai
# ํจ์ ์ ์
functions = [
{
"name": "get_current_weather",
"description": "ํน์ ์์น์ ํ์ฌ ๋ ์จ๋ฅผ ๊ฐ์ ธ์ต๋๋ค",
"parameters": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "๋์ ์ด๋ฆ, ์: Seoul"
},
"unit": {
"type": "string",
"enum": ["celsius", "fahrenheit"]
}
},
"required": ["location"]
}
}
]
# API ํธ์ถ
response = openai.ChatCompletion.create(
model="gpt-4",
messages=[
{"role": "user", "content": "์์ธ ๋ ์จ ์ด๋?"}
],
functions=functions,
function_call="auto"
)
# ์๋ต ์ฒ๋ฆฌ
message = response["choices"][0]["message"]
if message.get("function_call"):
function_name = message["function_call"]["name"]
arguments = json.loads(message["function_call"]["arguments"])
# ์ค์ ํจ์ ์คํ
if function_name == "get_current_weather":
weather_result = get_current_weather(**arguments)
# ๊ฒฐ๊ณผ๋ฅผ ๋ค์ AI์๊ฒ ์ ๋ฌ
second_response = openai.ChatCompletion.create(
model="gpt-4",
messages=[
{"role": "user", "content": "์์ธ ๋ ์จ ์ด๋?"},
message,
{
"role": "function",
"name": function_name,
"content": json.dumps(weather_result)
}
]
)
print(second_response["choices"][0]["message"]["content"])
๐ก ํต์ฌ ํฌ์ธํธ:
- AI๊ฐ function_call ํ๋๋ก ์ด๋ค ํจ์๋ฅผ ํธ์ถํ ์ง ๊ฒฐ์
- ์ฐ๋ฆฌ๊ฐ ์ค์ ํจ์๋ฅผ ์คํํ๊ณ ๊ฒฐ๊ณผ๋ฅผ ๋ค์ ์ ๋ฌ
- AI๊ฐ ๊ฒฐ๊ณผ๋ฅผ ์์ฐ์ด๋ก ๋ณํํด์ ๋ต๋ณ
3๏ธโฃ Anthropic Claude Tool Use
Claude๋ ์ต๊ทผ ๊ฐ๋ ฅํ ๋๊ตฌ ์ฌ์ฉ ๊ธฐ๋ฅ์ ์ถ๊ฐํ์ด! ํนํ ์ ํ๋๊ฐ ๋๋ค๊ณ ํ๊ฐ๋ฐ๊ณ ์์ง. ๐ฏ
import anthropic
client = anthropic.Anthropic(api_key="your-api-key")
tools = [
{
"name": "get_weather",
"description": "๋ ์จ ์ ๋ณด๋ฅผ ๊ฐ์ ธ์ต๋๋ค",
"input_schema": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "๋์ ์ด๋ฆ"
}
},
"required": ["location"]
}
}
]
message = client.messages.create(
model="claude-3-opus-20240229",
max_tokens=1024,
tools=tools,
messages=[
{"role": "user", "content": "์์ธ ๋ ์จ ์๋ ค์ค"}
]
)
# Tool use ์ฒ๋ฆฌ
if message.stop_reason == "tool_use":
tool_use = next(block for block in message.content if block.type == "tool_use")
tool_name = tool_use.name
tool_input = tool_use.input
# ๋๊ตฌ ์คํ ๋ฐ ๊ฒฐ๊ณผ ๋ฐํ...
4๏ธโฃ AutoGPT / BabyAGI ์คํ์ผ
์ข ๋ ์์จ์ ์ธ ์์ด์ ํธ๋ฅผ ์ํ๋ค๋ฉด AutoGPT ์คํ์ผ๋ ์์ด. ์ด๊ฑด AI๊ฐ ์ค์ค๋ก ๋ชฉํ๋ฅผ ์ค์ ํ๊ณ , ํ์ํ ๋๊ตฌ๋ฅผ ์ ํํด์ ์์ ์ ์์ํ๋ ๋ฐฉ์์ด์ผ! ๐ค
๐ก ํ๋ ์์ํฌ ์ ํ ๊ฐ์ด๋
LangChain: ๋ณต์กํ ์ฒด์ธ๊ณผ ๋ค์ํ ๋๊ตฌ ํตํฉ์ด ํ์ํ ๋
OpenAI Function Calling: GPT ๋ชจ๋ธ ์ฌ์ฉ + ๊ฐ๋จํ ๋๊ตฌ ํตํฉ
Claude Tool Use: ๋์ ์ ํ๋์ ์์ ์ฑ์ด ์ค์ํ ๋
์ง์ ๊ตฌํ: ์์ ํ ์ปค์คํฐ๋ง์ด์ง๊ณผ ์ธ๋ฐํ ์ ์ด๊ฐ ํ์ํ ๋
๐ฏ ์ค์ ํ์ฉ ์ฌ๋ก
์ด๋ก ์ ์ถฉ๋ถํ ๋ดค์ผ๋, ์ด์ ์ค์ ๋ก ์ด๋ป๊ฒ ํ์ฉ๋๋์ง ๊ตฌ์ฒด์ ์ธ ์ฌ๋ก๋ค์ ๋ณผ๊น? ๐ผ
๐ Case 1: ๋ฐ์ดํฐ ๋ถ์ ์์ด์ ํธ
์๋๋ฆฌ์ค: ์ฌ์ฉ์๊ฐ "์ง๋ 3๊ฐ์ ๋งค์ถ ๋ฐ์ดํฐ๋ฅผ ๋ถ์ํ๊ณ ์๊ฐํํด์ค"๋ผ๊ณ ์์ฒญ
์์ด์ ํธ์ ์์ ํ๋ฆ:
1๏ธโฃ query_database ๋๊ตฌ๋ก ๋งค์ถ ๋ฐ์ดํฐ ์กฐํ
2๏ธโฃ pandas_analysis ๋๊ตฌ๋ก ํต๊ณ ๋ถ์ (ํ๊ท , ์ถ์ธ ๋ฑ)
3๏ธโฃ create_chart ๋๊ตฌ๋ก ๊ทธ๋ํ ์์ฑ
4๏ธโฃ generate_report ๋๊ตฌ๋ก ๋ถ์ ๋ฆฌํฌํธ ์์ฑ
# ์ค์ ๊ตฌํ ์์
class DataAnalysisAgent:
def __init__(self):
self.tools = {
"query_database": self.query_db,
"analyze_data": self.analyze,
"create_chart": self.visualize,
"generate_report": self.report
}
def query_db(self, query: str):
# SQL ์คํ
return pd.read_sql(query, connection)
def analyze(self, data: pd.DataFrame):
return {
"mean": data.mean(),
"trend": calculate_trend(data),
"insights": generate_insights(data)
}
def visualize(self, data: pd.DataFrame, chart_type: str):
# ์ฐจํธ ์์ฑ
plt.figure(figsize=(10, 6))
# ... ์ฐจํธ ๊ทธ๋ฆฌ๊ธฐ
return "chart.png"
def report(self, analysis: dict, chart_path: str):
# ๋ฆฌํฌํธ ์์ฑ
return f"""
## ๋งค์ถ ๋ถ์ ๋ฆฌํฌํธ
ํ๊ท ๋งค์ถ: {analysis['mean']}
์ถ์ธ: {analysis['trend']}

์ฃผ์ ์ธ์ฌ์ดํธ:
{analysis['insights']}
"""
๐ Case 2: ์ผํ ์ด์์คํดํธ
์๋๋ฆฌ์ค: "30๋ง์ ์ดํ ๋ ธํธ๋ถ ์ถ์ฒํด์ฃผ๊ณ , ๊ฐ์ฅ ์ ๋ ดํ ๊ณณ์์ ๊ตฌ๋งค ๋งํฌ ์๋ ค์ค"
๋๊ตฌ ์ฌ์ฉ ์ฒด์ธ:
1๏ธโฃ search_products: ์กฐ๊ฑด์ ๋ง๋ ์ ํ ๊ฒ์
2๏ธโฃ compare_prices: ์ฌ๋ฌ ์ผํ๋ชฐ ๊ฐ๊ฒฉ ๋น๊ต
3๏ธโฃ get_reviews: ๋ฆฌ๋ทฐ ์ ์ ํ์ธ
4๏ธโฃ generate_recommendation: ์ต์ ์ ํ ์ถ์ฒ
์ด๋ฐ ์์ผ๋ก ์ฌ๋ฌ ๋๊ตฌ๋ฅผ ์กฐํฉํด์ ์ฌ์ฉ์์๊ฒ ์ต์์ ์ผํ ๊ฒฝํ์ ์ ๊ณตํ ์ ์์ด! ๐๏ธ
๐ง Case 3: ์ด๋ฉ์ผ ์๋ํ ์์ด์ ํธ
์๋๋ฆฌ์ค: "์ค์ํ ์ด๋ฉ์ผ๋ง ์์ฝํด์ ์ฌ๋์ผ๋ก ๋ณด๋ด์ค"
์์ ํ๋ฆ:
1๏ธโฃ fetch_emails: Gmail API๋ก ์ ์ด๋ฉ์ผ ๊ฐ์ ธ์ค๊ธฐ
2๏ธโฃ classify_importance: AI๋ก ์ค์๋ ํ๋จ
3๏ธโฃ summarize_content: ์ด๋ฉ์ผ ๋ด์ฉ ์์ฝ
4๏ธโฃ send_slack_message: ์ฌ๋์ผ๋ก ์๋ฆผ ์ ์ก
async def email_automation_agent(user_id):
# 1. ์ด๋ฉ์ผ ๊ฐ์ ธ์ค๊ธฐ
emails = await fetch_emails(user_id, unread=True)
for email in emails:
# 2. ์ค์๋ ํ๋จ
importance = await classify_importance(email)
if importance > 0.7: # ์ค์ํ ์ด๋ฉ์ผ๋ง
# 3. ์์ฝ
summary = await summarize_content(email.body)
# 4. ์ฌ๋ ์ ์ก
await send_slack_message(
channel=user_id,
message=f"""
๐ง ์ค์ ์ด๋ฉ์ผ ๋์ฐฉ!
๋ฐ์ : {email.sender}
์ ๋ชฉ: {email.subject}
์์ฝ: {summary}
[์ด๋ฉ์ผ ๋ณด๊ธฐ]({email.link})
"""
)
์ด๋ฐ ์์ผ๋ก AI ์์ด์ ํธ๋ ๋ฐ๋ณต์ ์ด๊ณ ์๊ฐ ์๋ชจ์ ์ธ ์์ ์ ์๋ํํด์ค ์ ์์ด. ์์ฐ์ฑ์ด ์์ฒญ ์ฌ๋ผ๊ฐ์ง! ๐
โ ๏ธ ๋๊ตฌ์ฌ์ฉ ์ ์ฃผ์์ฌํญ๊ณผ ๋ฒ ์คํธ ํ๋ํฐ์ค
๋๊ตฌ์ฌ์ฉ์ ๊ฐ๋ ฅํ์ง๋ง, ์๋ชป ์ฌ์ฉํ๋ฉด ๋ฌธ์ ๊ฐ ์๊ธธ ์ ์์ด. ์ค์ ์์ ๊ผญ ์์์ผ ํ ์ฃผ์์ฌํญ๋ค์ ์ ๋ฆฌํ์ด! ๐จ
๐ ๋ณด์ ๊ณ ๋ ค์ฌํญ
โ ๏ธ ์ํํ ํจํด๋ค
1. ๋ฌด์ ํ ์ฝ๋ ์คํ
โ ๋์ ์: eval(user_input)
โ
์ข์ ์: ์๋๋ฐ์ค ํ๊ฒฝ์์ ์ ํ๋ ๋ช
๋ น์ด๋ง ์คํ
2. ๋ฏผ๊ฐํ ์ ๋ณด ๋
ธ์ถ
โ API ํค๋ฅผ ๋๊ตฌ ์ค๋ช
์ ํฌํจ
โ
ํ๊ฒฝ ๋ณ์๋ก ๊ด๋ฆฌํ๊ณ ๋ก๊ทธ์ ๋จ๊ธฐ์ง ์๊ธฐ
3. ๋ฌดํ ๋ฃจํ ์ํ
โ ๋๊ตฌ๊ฐ ๋๊ตฌ๋ฅผ ๊ณ์ ํธ์ถ
โ
์ต๋ ์คํ ํ์ ์ ํ ์ค์
์์ ํ ๋๊ตฌ ์คํ ํจํด
class SafeToolExecutor:
def __init__(self, max_iterations=10, timeout=30):
self.max_iterations = max_iterations
self.timeout = timeout
self.execution_count = 0
def execute_with_safety(self, tool, arguments):
# 1. ์คํ ํ์ ์ฒดํฌ
if self.execution_count >= self.max_iterations:
raise Exception("์ต๋ ์คํ ํ์ ์ด๊ณผ")
# 2. ์
๋ ฅ ๊ฒ์ฆ
validated_args = self.validate_arguments(arguments)
# 3. ํ์์์ ์ค์
with timeout_context(self.timeout):
try:
result = tool.execute(**validated_args)
self.execution_count += 1
# 4. ๊ฒฐ๊ณผ ๊ฒ์ฆ
return self.validate_result(result)
except Exception as e:
# 5. ์๋ฌ ์ฒ๋ฆฌ
return self.handle_error(e)
def validate_arguments(self, args):
# SQL Injection ๋ฐฉ์ง
# XSS ๋ฐฉ์ง
# ํ์ผ ๊ฒฝ๋ก ๊ฒ์ฆ ๋ฑ
return sanitized_args
def validate_result(self, result):
# ๋ฏผ๊ฐํ ์ ๋ณด ํํฐ๋ง
# ํฌ๊ธฐ ์ ํ
return filtered_result
๐ฏ ํจ์จ์ ์ธ ๋๊ตฌ ์ค๊ณ
โจ ์ข์ ๋๊ตฌ์ ํน์ง
1. ๋ช
ํํ ๋จ์ผ ์ฑ
์
ํ๋์ ๋๊ตฌ๋ ํ๋์ ์ผ๋ง ์ํด์ผ ํด. "๋ชจ๋ ๊ฑธ ๋ค ํ๋ ๋๊ตฌ"๋ AI๊ฐ ์ธ์ ์ฌ์ฉํด์ผ ํ ์ง ํผ๋์ค๋ฌ์ํด.
โ ๋์ ์: do_everything(action, data, options...)
โ
์ข์ ์: search_products(query), get_product_details(id)
2. ์์ธํ ์ค๋ช
(Description)
AI๊ฐ ๋๊ตฌ๋ฅผ ์ ํํ ๋ ์ค๋ช
์ ์ฝ๊ณ ํ๋จํด. ๋ช
ํํ๊ณ ๊ตฌ์ฒด์ ์ผ๋ก ์์ฑํด์ผ ํด!
โ ๋์ ์ค๋ช
: "๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ต๋๋ค"
โ
์ข์ ์ค๋ช
: "๋ฐ์ดํฐ๋ฒ ์ด์ค์์ ์ฌ์ฉ์ ์ ๋ณด๋ฅผ ์กฐํํฉ๋๋ค.
์ด๋ฉ์ผ, ์ด๋ฆ, ๊ฐ์
์ผ ๋ฑ์ ์ ๋ณด๋ฅผ ๋ฐํํ๋ฉฐ,
user_id ๋๋ email๋ก ๊ฒ์ ๊ฐ๋ฅํฉ๋๋ค."
3. ๋ช
ํํ ํ๋ผ๋ฏธํฐ ์ ์
ํ์
, ํ์ ์ฌ๋ถ, ๊ธฐ๋ณธ๊ฐ, ์์๋ฅผ ๋ชจ๋ ๋ช
์ํด์ค.
{
"name": "send_email",
"parameters": {
"to": {
"type": "string",
"description": "์์ ์ ์ด๋ฉ์ผ ์ฃผ์",
"required": true,
"example": "user@example.com"
},
"subject": {
"type": "string",
"description": "์ด๋ฉ์ผ ์ ๋ชฉ",
"required": true
},
"body": {
"type": "string",
"description": "์ด๋ฉ์ผ ๋ณธ๋ฌธ (HTML ์ง์)",
"required": true
},
"priority": {
"type": "string",
"enum": ["low", "normal", "high"],
"default": "normal",
"description": "์ด๋ฉ์ผ ์ฐ์ ์์"
}
}
}
๐ ๋๋ฒ๊น ๊ณผ ๋ชจ๋ํฐ๋ง
AI ์์ด์ ํธ๋ ๋ธ๋๋ฐ์ค์ฒ๋ผ ๋๊ปด์ง ์ ์์ด. ๊ทธ๋์ ๋ก๊น ๊ณผ ๋ชจ๋ํฐ๋ง์ด ์ ๋ง ์ค์ํด! ๐
import logging
from datetime import datetime
class ToolLogger:
def __init__(self):
self.logger = logging.getLogger("AgentTools")
self.execution_history = []
def log_tool_call(self, tool_name, arguments, result, duration):
log_entry = {
"timestamp": datetime.now().isoformat(),
"tool": tool_name,
"arguments": arguments,
"result": result,
"duration_ms": duration,
"success": result.get("success", False)
}
self.execution_history.append(log_entry)
# ์ฝ์ ์ถ๋ ฅ
self.logger.info(f"""
๐ง ๋๊ตฌ ์คํ: {tool_name}
๐ฅ ์
๋ ฅ: {arguments}
๐ค ์ถ๋ ฅ: {result}
โฑ๏ธ ์์์๊ฐ: {duration}ms
""")
# ์คํจ ์ ์๋ฆผ
if not result.get("success"):
self.logger.error(f"๋๊ตฌ ์คํ ์คํจ: {tool_name}")
self.send_alert(log_entry)
def get_statistics(self):
"""๋๊ตฌ ์ฌ์ฉ ํต๊ณ"""
return {
"total_calls": len(self.execution_history),
"success_rate": self.calculate_success_rate(),
"avg_duration": self.calculate_avg_duration(),
"most_used_tool": self.get_most_used_tool()
}
๐ฐ ๋น์ฉ ์ต์ ํ
AI API๋ ํ ํฐ ๋จ์๋ก ๊ณผ๊ธ๋๋๊น, ๋๊ตฌ ์ฌ์ฉ์ ์ต์ ํํ๋ฉด ๋น์ฉ์ ํฌ๊ฒ ์ค์ผ ์ ์์ด! ๐ธ
๐ก ๋น์ฉ ์ ๊ฐ ํ
1. ์บ์ฑ ํ์ฉ
๊ฐ์ ์์ฒญ์ ์บ์์์ ๊ฐ์ ธ์ค๊ธฐ. ํนํ ๋ ์จ, ํ์จ ๊ฐ์ ์์ฃผ ์กฐํ๋๋ ๋ฐ์ดํฐ!
from functools import lru_cache
from datetime import datetime, timedelta
class CachedTool:
def __init__(self, ttl_seconds=300):
self.cache = {}
self.ttl = ttl_seconds
def get_cached(self, key):
if key in self.cache:
value, timestamp = self.cache[key]
if datetime.now() - timestamp < timedelta(seconds=self.ttl):
return value
return None
def set_cache(self, key, value):
self.cache[key] = (value, datetime.now())
2. ๋ฐฐ์น ์ฒ๋ฆฌ
์ฌ๋ฌ ๊ฐ์ ์์ฒญ์ ํ ๋ฒ์ ์ฒ๋ฆฌํ๋ฉด API ํธ์ถ ํ์๋ฅผ ์ค์ผ ์ ์์ด.
3. ๊ฒฐ๊ณผ ํฌ๊ธฐ ์ ํ
ํ์ํ ์ ๋ณด๋ง ๋ฐํํ๋๋ก ์ ํ. ๊ธด ํ
์คํธ๋ ์์ฝํด์ ์ ๋ฌ!
๐ ๊ณ ๊ธ ํจํด๊ณผ ๊ธฐ๋ฒ
๊ธฐ๋ณธ์ ๋์ด์ ์ข ๋ ๊ณ ๊ธ ๊ธฐ์ ๋ค์ ์์๋ณผ๊น? ์ด๋ฐ ํจํด๋ค์ ์๋ฉด ์ง์ง ํ๋ก์ฒ๋ผ AI ์์ด์ ํธ๋ฅผ ๋ง๋ค ์ ์์ด! ๐
๐ ReAct ํจํด (Reasoning + Acting)
ReAct๋ AI๊ฐ ์๊ฐ(Reasoning)ํ๊ณ ํ๋(Acting)ํ๋ ๊ณผ์ ์ ๋ฐ๋ณตํ๋ ํจํด์ด์ผ. ๋ง์น ์ฌ๋์ด ๋ฌธ์ ๋ฅผ ํธ๋ ๊ฒ์ฒ๋ผ!
๐ง ReAct ์ฌ๊ณ ๊ณผ์ ์์
์ฌ์ฉ์: "2024๋
ํ๋ฆฌ ์ฌ๋ฆผํฝ ๊ธ๋ฉ๋ฌ 1์ ๊ตญ๊ฐ์ ๊ทธ ๋๋ผ์ ์๋๋ฅผ ์๋ ค์ค"
Thought 1: ๋จผ์ 2024 ํ๋ฆฌ ์ฌ๋ฆผํฝ ๊ธ๋ฉ๋ฌ ์์๋ฅผ ๊ฒ์ํด์ผ๊ฒ ๋ค.
Action 1: search("2024 ํ๋ฆฌ ์ฌ๋ฆผํฝ ๊ธ๋ฉ๋ฌ ์์")
Observation 1: ๋ฏธ๊ตญ์ด 40๊ฐ๋ก 1์์
๋๋ค.
Thought 2: ๋ฏธ๊ตญ์ ์๋๋ฅผ ํ์ธํด์ผ๊ฒ ๋ค.
Action 2: search("๋ฏธ๊ตญ ์๋")
Observation 2: ์์ฑํด D.C.์
๋๋ค.
Thought 3: ์ด์ ๋ต๋ณํ ์ ์๋ค!
Final Answer: 2024๋
ํ๋ฆฌ ์ฌ๋ฆผํฝ ๊ธ๋ฉ๋ฌ 1์๋ ๋ฏธ๊ตญ(40๊ฐ)์ด๋ฉฐ,
๋ฏธ๊ตญ์ ์๋๋ ์์ฑํด D.C.์
๋๋ค.
์ด ํจํด์ ํต์ฌ์ AI๊ฐ ๊ฐ ๋จ๊ณ์์ ์ ๊ทธ ๋๊ตฌ๋ฅผ ์ฌ์ฉํ๋์ง ์ค๋ช ํ๋ค๋ ๊ฑฐ์ผ. ๋๋ฒ๊น ํ ๋ ์์ฒญ ์ ์ฉํด! ๐
๐ญ Multi-Agent ํ์
์ฌ๋ฌ ๊ฐ์ ์ ๋ฌธํ๋ ์์ด์ ํธ๊ฐ ํ๋ ฅํ๋ ํจํด๋ ์์ด. ๊ฐ์ ์ํ๋ ๋ถ์ผ๊ฐ ๋ค๋ฅธ ๊ฑฐ์ง!
์์: ์ฝํ ์ธ ์ ์ ํ
๐จ Designer Agent: ์ด๋ฏธ์ง ์์ฑ, ๋ ์ด์์ ๋์์ธ
โ๏ธ Writer Agent: ํ
์คํธ ์์ฑ, ํธ์ง
๐ Analyst Agent: ๋ฐ์ดํฐ ๋ถ์, ํธ๋ ๋ ํ์
๐ฏ Manager Agent: ์ ์ฒด ์กฐ์จ, ์ต์ข
๊ฒฐ์
class MultiAgentSystem:
def __init__(self):
self.agents = {
"designer": DesignerAgent(),
"writer": WriterAgent(),
"analyst": AnalystAgent(),
"manager": ManagerAgent()
}
async def create_content(self, topic):
# 1. ๋ถ์๊ฐ๊ฐ ํธ๋ ๋ ๋ถ์
trends = await self.agents["analyst"].analyze_trends(topic)
# 2. ์๊ฐ๊ฐ ์ด์ ์์ฑ
draft = await self.agents["writer"].write_draft(topic, trends)
# 3. ๋์์ด๋๊ฐ ์ด๋ฏธ์ง ์์ฑ
images = await self.agents["designer"].create_images(draft)
# 4. ๋งค๋์ ๊ฐ ์ต์ข
๊ฒํ ๋ฐ ์กฐํฉ
final_content = await self.agents["manager"].finalize(
draft, images, trends
)
return final_content
๐งฉ Tool Composition (๋๊ตฌ ์กฐํฉ)
๊ธฐ๋ณธ ๋๊ตฌ๋ค์ ์กฐํฉํด์ ๋ ๋ณต์กํ ๋๊ตฌ๋ฅผ ๋ง๋๋ ๊ธฐ๋ฒ์ด์ผ. ๋ ๊ณ ๋ธ๋ก์ฒ๋ผ! ๐งฑ
class ComposedTool:
def __init__(self, name, steps):
self.name = name
self.steps = steps # ์คํํ ๋๊ตฌ๋ค์ ์์
async def execute(self, initial_input):
result = initial_input
for step in self.steps:
tool = step["tool"]
transform = step.get("transform", lambda x: x)
# ์ด์ ๊ฒฐ๊ณผ๋ฅผ ๋ณํํด์ ๋ค์ ๋๊ตฌ์ ์
๋ ฅ์ผ๋ก
tool_input = transform(result)
result = await tool.execute(tool_input)
return result
# ์ฌ์ฉ ์์: "์นํ์ด์ง ์์ฝ" ๋๊ตฌ
summarize_webpage = ComposedTool(
name="summarize_webpage",
steps=[
{
"tool": fetch_webpage_tool,
"transform": lambda url: {"url": url}
},
{
"tool": extract_text_tool,
"transform": lambda html: {"html": html}
},
{
"tool": summarize_text_tool,
"transform": lambda text: {"text": text, "max_length": 200}
}
]
)
# ์คํ
summary = await summarize_webpage.execute("https://example.com")
๐ฏ Conditional Tool Use (์กฐ๊ฑด๋ถ ๋๊ตฌ ์ฌ์ฉ)
์ํฉ์ ๋ฐ๋ผ ๋ค๋ฅธ ๋๊ตฌ๋ฅผ ์ฌ์ฉํ๋ ํจํด์ด์ผ. if-else์ฒ๋ผ!
class ConditionalAgent:
async def process_request(self, user_input):
# ์๋ ํ์
intent = await self.classify_intent(user_input)
if intent == "calculation":
return await self.calculator_tool.execute(user_input)
elif intent == "search":
# ๊ฒ์ ์ข
๋ฅ๋ ์ธ๋ถํ
search_type = await self.classify_search_type(user_input)
if search_type == "recent_news":
return await self.news_search_tool.execute(user_input)
elif search_type == "product":
return await self.product_search_tool.execute(user_input)
else:
return await self.web_search_tool.execute(user_input)
elif intent == "data_analysis":
# ๋ฐ์ดํฐ ํฌ๊ธฐ์ ๋ฐ๋ผ ๋ค๋ฅธ ๋๊ตฌ ์ฌ์ฉ
data_size = await self.estimate_data_size(user_input)
if data_size > 1000000:
return await self.big_data_tool.execute(user_input)
else:
return await self.simple_analysis_tool.execute(user_input)
else:
return "์ฃ์กํฉ๋๋ค. ์์ฒญ์ ์ดํดํ์ง ๋ชปํ์ต๋๋ค."
๐ ์ค์ ์๋น์ค ๊ตฌ์ถํ๊ธฐ
์ด๋ก ๊ณผ ์์ ๋ ์ถฉ๋ถํ ๋ดค์ผ๋, ์ด์ ์ค์ ๋ก ์๋น์ค๋ฅผ ๋ง๋ค์ด๋ณผ๊น? ๊ฐ๋จํ AI ์ด์์คํดํธ API๋ฅผ ๊ตฌ์ถํด๋ณด์! ๐๏ธ
๐๏ธ ์ ์ฒด ์ํคํ ์ฒ
๐ป FastAPI๋ก ๊ตฌํํ๊ธฐ
1. ๊ธฐ๋ณธ ์๋ฒ ๊ตฌ์กฐ
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from typing import List, Dict, Optional
import asyncio
app = FastAPI(title="AI Agent API")
class ChatRequest(BaseModel):
message: str
user_id: str
session_id: Optional[str] = None
class ChatResponse(BaseModel):
response: str
tools_used: List[str]
execution_time: float
# ์ ์ญ ์์ด์ ํธ ์ธ์คํด์ค
agent = AIAgent()
@app.post("/chat", response_model=ChatResponse)
async def chat(request: ChatRequest):
"""๋ฉ์ธ ์ฑํ
์๋ํฌ์ธํธ"""
try:
start_time = time.time()
# ์์ด์ ํธ ์คํ
result = await agent.process(
message=request.message,
user_id=request.user_id,
session_id=request.session_id
)
execution_time = time.time() - start_time
return ChatResponse(
response=result["response"],
tools_used=result["tools_used"],
execution_time=execution_time
)
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
@app.get("/tools")
async def list_tools():
"""์ฌ์ฉ ๊ฐ๋ฅํ ๋๊ตฌ ๋ชฉ๋ก"""
return {
"tools": agent.get_available_tools()
}
@app.post("/tools/{tool_name}/execute")
async def execute_tool(tool_name: str, arguments: Dict):
"""ํน์ ๋๊ตฌ ์ง์ ์คํ (ํ
์คํธ์ฉ)"""
try:
result = await agent.execute_tool(tool_name, arguments)
return {"success": True, "result": result}
except Exception as e:
return {"success": False, "error": str(e)}
2. ์์ด์ ํธ ์ฝ์ด ๊ตฌํ
import openai
from typing import List, Dict, Any
class AIAgent:
def __init__(self):
self.tool_manager = ToolManager()
self.memory = ConversationMemory()
self.logger = AgentLogger()
# ๋๊ตฌ ๋ฑ๋ก
self._register_tools()
def _register_tools(self):
"""๋ชจ๋ ๋๊ตฌ ๋ฑ๋ก"""
self.tool_manager.register(WeatherTool())
self.tool_manager.register(CalculatorTool())
self.tool_manager.register(SearchTool())
self.tool_manager.register(DatabaseTool())
# ... ๋ ๋ง์ ๋๊ตฌ๋ค
async def process(self, message: str, user_id: str,
session_id: str = None) -> Dict:
"""๋ฉ์ธ ์ฒ๋ฆฌ ๋ก์ง"""
# 1. ๋ํ ๊ธฐ๋ก ๋ก๋
history = await self.memory.get_history(session_id)
# 2. ๋๊ตฌ ์คํค๋ง ์ค๋น
tools_schema = self.tool_manager.get_schemas()
# 3. LLM ํธ์ถ
messages = self._build_messages(message, history)
response = await openai.ChatCompletion.acreate(
model="gpt-4",
messages=messages,
functions=tools_schema,
function_call="auto"
)
# 4. ๋๊ตฌ ํธ์ถ์ด ํ์ํ์ง ํ์ธ
message_obj = response["choices"][0]["message"]
if message_obj.get("function_call"):
# ๋๊ตฌ ์คํ
result = await self._execute_tool_call(message_obj)
# ๊ฒฐ๊ณผ๋ฅผ ๋ค์ LLM์ ์ ๋ฌ
final_response = await self._get_final_response(
messages, message_obj, result
)
tools_used = [message_obj["function_call"]["name"]]
else:
final_response = message_obj["content"]
tools_used = []
# 5. ๋ํ ๊ธฐ๋ก ์ ์ฅ
await self.memory.save_turn(
session_id, message, final_response
)
# 6. ๋ก๊น
self.logger.log_interaction(
user_id, message, final_response, tools_used
)
return {
"response": final_response,
"tools_used": tools_used
}
async def _execute_tool_call(self, message_obj):
"""๋๊ตฌ ์คํ"""
function_name = message_obj["function_call"]["name"]
arguments = json.loads(
message_obj["function_call"]["arguments"]
)
return await self.tool_manager.execute(
function_name, arguments
)
def _build_messages(self, current_message, history):
"""๋ฉ์์ง ๊ตฌ์ฑ"""
messages = [
{
"role": "system",
"content": """๋น์ ์ ๋์์ด ๋๋ AI ์ด์์คํดํธ์
๋๋ค.
ํ์ํ ๋ ์ ๊ณต๋ ๋๊ตฌ๋ค์ ์ฌ์ฉํ์ธ์."""
}
]
# ์ด์ ๋ํ ์ถ๊ฐ
messages.extend(history)
# ํ์ฌ ๋ฉ์์ง ์ถ๊ฐ
messages.append({
"role": "user",
"content": current_message
})
return messages
๐๏ธ ๋ฉ๋ชจ๋ฆฌ ๊ด๋ฆฌ
๋ํ ๊ธฐ๋ก์ ์ ์ฅํ๊ณ ๊ด๋ฆฌํ๋ ๊ฒ๋ ์ค์ํด! Redis๋ฅผ ์ฌ์ฉํ ์์๋ฅผ ๋ณผ๊ฒ.
import redis
import json
from datetime import timedelta
class ConversationMemory:
def __init__(self):
self.redis_client = redis.Redis(
host='localhost',
port=6379,
decode_responses=True
)
self.ttl = timedelta(hours=24) # 24์๊ฐ ํ ์๋ ์ญ์
async def get_history(self, session_id: str,
max_turns: int = 10) -> List[Dict]:
"""๋ํ ๊ธฐ๋ก ์กฐํ"""
key = f"conversation:{session_id}"
history_json = self.redis_client.get(key)
if not history_json:
return []
history = json.loads(history_json)
# ์ต๊ทผ N๊ฐ๋ง ๋ฐํ (ํ ํฐ ์ ์ฝ)
return history[-max_turns * 2:] # user + assistant ์
async def save_turn(self, session_id: str,
user_message: str,
assistant_message: str):
"""๋ํ ํด ์ ์ฅ"""
key = f"conversation:{session_id}"
# ๊ธฐ์กด ๊ธฐ๋ก ๊ฐ์ ธ์ค๊ธฐ
history = await self.get_history(session_id)
# ์ ํด ์ถ๊ฐ
history.extend([
{"role": "user", "content": user_message},
{"role": "assistant", "content": assistant_message}
])
# ์ ์ฅ (TTL ์ค์ )
self.redis_client.setex(
key,
self.ttl,
json.dumps(history)
)
async def clear_history(self, session_id: str):
"""๋ํ ๊ธฐ๋ก ์ญ์ """
key = f"conversation:{session_id}"
self.redis_client.delete(key)
๐ ์ฑ๋ฅ ์ต์ ํ์ ์ค์ผ์ผ๋ง
์๋น์ค๊ฐ ์ปค์ง๋ฉด ์ฑ๋ฅ์ด ์ค์ํด์ ธ. ์ค์ ์ต์ ํ ๊ธฐ๋ฒ๋ค์ ์์๋ณด์! โก
๐ ๋ณ๋ ฌ ์ฒ๋ฆฌ
์ฌ๋ฌ ๋๊ตฌ๋ฅผ ๋์์ ์คํํ ์ ์๋ค๋ฉด ์๋๊ฐ ์์ฒญ ๋นจ๋ผ์ ธ!
import asyncio
class ParallelAgent:
async def process_parallel_tools(self, tool_calls: List[Dict]):
"""์ฌ๋ฌ ๋๊ตฌ๋ฅผ ๋์์ ์คํ"""
# ๊ฐ ๋๊ตฌ ํธ์ถ์ ๋น๋๊ธฐ ํ์คํฌ๋ก ์์ฑ
tasks = [
self.execute_tool(call["name"], call["arguments"])
for call in tool_calls
]
# ๋ชจ๋ ํ์คํฌ๋ฅผ ๋์์ ์คํ
results = await asyncio.gather(*tasks, return_exceptions=True)
# ๊ฒฐ๊ณผ ์ฒ๋ฆฌ
processed_results = []
for i, result in enumerate(results):
if isinstance(result, Exception):
processed_results.append({
"tool": tool_calls[i]["name"],
"success": False,
"error": str(result)
})
else:
processed_results.append({
"tool": tool_calls[i]["name"],
"success": True,
"result": result
})
return processed_results
# ์ฌ์ฉ ์์
tool_calls = [
{"name": "get_weather", "arguments": {"city": "์์ธ"}},
{"name": "get_weather", "arguments": {"city": "๋ถ์ฐ"}},
{"name": "get_weather", "arguments": {"city": "๋๊ตฌ"}}
]
# ์์ฐจ ์คํ: 3์ด (๊ฐ 1์ด์ฉ)
# ๋ณ๋ ฌ ์คํ: 1์ด (๋์์!)
results = await agent.process_parallel_tools(tool_calls)
๐พ ์ค๋งํธ ์บ์ฑ
from functools import wraps
import hashlib
def cached_tool(ttl_seconds=300):
"""๋๊ตฌ ๊ฒฐ๊ณผ๋ฅผ ์บ์ฑํ๋ ๋ฐ์ฝ๋ ์ดํฐ"""
def decorator(func):
cache = {}
@wraps(func)
async def wrapper(*args, **kwargs):
# ์บ์ ํค ์์ฑ
cache_key = hashlib.md5(
f"{func.__name__}:{args}:{kwargs}".encode()
).hexdigest()
# ์บ์ ํ์ธ
if cache_key in cache:
cached_value, timestamp = cache[cache_key]
if time.time() - timestamp < ttl_seconds:
print(f"โ
์บ์ ํํธ: {func.__name__}")
return cached_value
# ์บ์ ๋ฏธ์ค - ์ค์ ์คํ
result = await func(*args, **kwargs)
cache[cache_key] = (result, time.time())
return result
return wrapper
return decorator
# ์ฌ์ฉ ์์
@cached_tool(ttl_seconds=600) # 10๋ถ ์บ์ฑ
async def get_weather(city: str):
# API ํธ์ถ (๋น์ฉ ๋ฐ์)
return await weather_api.fetch(city)
๐ ๋ก๋ ๋ฐธ๋ฐ์ฑ
์ฌ๋ฌ LLM ์ ๊ณต์๋ฅผ ์ฌ์ฉํด์ ๋ถํ๋ฅผ ๋ถ์ฐ์ํฌ ์๋ ์์ด!
class LLMLoadBalancer:
def __init__(self):
self.providers = [
{"name": "openai", "client": openai_client, "weight": 0.6},
{"name": "anthropic", "client": anthropic_client, "weight": 0.3},
{"name": "cohere", "client": cohere_client, "weight": 0.1}
]
self.current_loads = {p["name"]: 0 for p in self.providers}
async def get_completion(self, messages, **kwargs):
"""๊ฐ์ฅ ๋ถํ๊ฐ ์ ์ ์ ๊ณต์ ์ ํ"""
# ๊ฐ์ค์น์ ํ์ฌ ๋ถํ๋ฅผ ๊ณ ๋ คํด์ ์ ํ
selected = min(
self.providers,
key=lambda p: self.current_loads[p["name"]] / p["weight"]
)
self.current_loads[selected["name"]] += 1
try:
result = await selected["client"].complete(messages, **kwargs)
return result
finally:
self.current_loads[selected["name"]] -= 1
๐ ํ์ต ์๋ฃ์ ์ปค๋ฎค๋ํฐ
AI ์์ด์ ํธ ๊ฐ๋ฐ์ ๋ ๊น์ด ๊ณต๋ถํ๊ณ ์ถ๋ค๋ฉด? ์ด๋ฐ ์๋ฃ๋ค์ ์ถ์ฒํด! ๐
๐ ์ถ์ฒ ํ์ต ๊ฒฝ๋ก
1๋จ๊ณ: ๊ธฐ์ด ๋ค์ง๊ธฐ
- LangChain ๊ณต์ ๋ฌธ์ (langchain.com)
- OpenAI Cookbook (github.com/openai/openai-cookbook)
- Anthropic Claude ๋ฌธ์
2๋จ๊ณ: ์ค์ ํ๋ก์ ํธ
- ๊ฐ๋จํ ์ฑ๋ด ๋ง๋ค๊ธฐ
- ๋ฐ์ดํฐ ๋ถ์ ์์ด์ ํธ ๊ตฌ์ถ
- ์๋ํ ์ํฌํ๋ก์ฐ ๊ฐ๋ฐ
3๋จ๊ณ: ๊ณ ๊ธ ์ฃผ์
- Multi-Agent Systems
- Reinforcement Learning from Human Feedback (RLHF)
- Agent ํ๊ฐ ๋ฐ ๋ฒค์น๋งํน
๐ก ์ปค๋ฎค๋ํฐ ์ฐธ์ฌํ๊ธฐ
ํผ์ ๊ณต๋ถํ๊ธฐ ํ๋ค๋ค๋ฉด ์ปค๋ฎค๋ํฐ์ ์ฐธ์ฌํด๋ด!
- LangChain Discord
- r/MachineLearning (Reddit)
- AI Agent ๊ด๋ จ GitHub ํ๋ก์ ํธ๋ค
- ํ๊ตญ AI ๊ฐ๋ฐ์ ์ปค๋ฎค๋ํฐ
๊ทธ๋ฆฌ๊ณ ์ฌ๋ฅ๋ท(jaenung.net)์์๋ AI ๊ฐ๋ฐ ๊ด๋ จ ์ฌ๋ฅ์ ๊ณต์ ํ๋ ์ฌ๋๋ค์ด ๋ง์! ๋ฉํ ๋ง์ ๋ฐ๊ฑฐ๋, ํ๋ก์ ํธ๋ฅผ ์๋ขฐํ๊ฑฐ๋, ์์ ์ ์ง์์ ๋๋ ์๋ ์์ง. ๐ค
๐ฏ ์ค์ ํ๋ก์ ํธ ์์ด๋์ด
์ด๋ก ์ ์ถฉ๋ถํ ๋ฐฐ์ ์ผ๋, ์ด์ ์ง์ ๋ง๋ค์ด๋ณผ ์ฐจ๋ก! ๋์ด๋๋ณ๋ก ํ๋ก์ ํธ ์์ด๋์ด๋ฅผ ์ ๋ฆฌํด๋ดค์ด. ๐
๐ฑ ์ด๊ธ ํ๋ก์ ํธ
1. ๋ ์จ ์๋ฆผ ๋ด ๋งค์ผ ์์นจ ๋ ์จ๋ฅผ ํ์ธํ๊ณ , ์ฐ์ฐ์ด ํ์ํ์ง ์๋ ค์ฃผ๋ ๋ด
์ฌ์ฉ ๋๊ตฌ:
- ๋ ์จ API
- ์ค์ผ์ค๋ฌ
- ๋ฉ์์ง ์ ์ก (์ฌ๋/ํ
๋ ๊ทธ๋จ)
2. ๊ฐ๋จํ ๊ณ์ฐ ์ด์์คํดํธ
์์ฐ์ด๋ก ์ํ ๋ฌธ์ ๋ฅผ ์
๋ ฅํ๋ฉด ๊ณ์ฐํด์ฃผ๋ ๋ด
์ฌ์ฉ ๋๊ตฌ:
- ๊ณ์ฐ๊ธฐ
- ๋จ์ ๋ณํ๊ธฐ
- ์์ ํ์
๐ฟ ์ค๊ธ ํ๋ก์ ํธ
1. ๊ฐ์ธ ๋น์ ์์ด์ ํธ ์ผ์ ๊ด๋ฆฌ, ์ด๋ฉ์ผ ์์ฝ, ํ ์ผ ์ถ์ ์ ํด์ฃผ๋ ์ข ํฉ ๋น์
์ฌ์ฉ ๋๊ตฌ:
- Google Calendar API
- Gmail API
- Notion API
- ๋ฆฌ๋ง์ธ๋ ์์คํ
2. ์ผํ ๋น๊ต ์์ด์ ํธ
์ฌ๋ฌ ์ผํ๋ชฐ์์ ๊ฐ๊ฒฉ์ ๋น๊ตํ๊ณ ์ต์ ๊ฐ๋ฅผ ์ฐพ์์ฃผ๋ ์์ด์ ํธ
์ฌ์ฉ ๋๊ตฌ:
- ์น ์คํฌ๋ํ
- ๊ฐ๊ฒฉ ๋น๊ต API
- ์๋ฆผ ์์คํ
- ๋ฐ์ดํฐ๋ฒ ์ด์ค
๐ณ ๊ณ ๊ธ ํ๋ก์ ํธ
1. ์ฝ๋ ๋ฆฌ๋ทฐ ์์ด์ ํธ GitHub PR์ ์๋์ผ๋ก ๋ถ์ํ๊ณ ๋ฆฌ๋ทฐ ์ฝ๋ฉํธ๋ฅผ ๋ฌ์์ฃผ๋ ์์ด์ ํธ
์ฌ์ฉ ๋๊ตฌ:
- GitHub API
- ์ฝ๋ ๋ถ์ ๋๊ตฌ
- ์ ์ ๋ถ์๊ธฐ
- ํ
์คํธ ์คํ๊ธฐ
2. ๋ฐ์ดํฐ ๋ถ์ ํ๋ซํผ
์์ฐ์ด๋ก ์ง๋ฌธํ๋ฉด ๋ฐ์ดํฐ๋ฅผ ๋ถ์ํ๊ณ ์๊ฐํํด์ฃผ๋ ํ๋ซํผ
์ฌ์ฉ ๋๊ตฌ:
- SQL ์์ฑ๊ธฐ
- Pandas ์คํ๊ธฐ
- ์ฐจํธ ์์ฑ๊ธฐ
- ๋ฆฌํฌํธ ์์ฑ๊ธฐ
3. Multi-Agent ํ์
์์คํ
์ฌ๋ฌ ์ ๋ฌธ ์์ด์ ํธ๊ฐ ํ๋ ฅํด์ ๋ณต์กํ ์์
์ ์ํ
๊ตฌ์ฑ ์์:
- ๋ฆฌ์์น ์์ด์ ํธ
- ์์ฑ ์์ด์ ํธ
- ๊ฒ์ฆ ์์ด์ ํธ
- ์กฐ์จ ์์ด์ ํธ
๐ฎ ๋ฏธ๋ ์ ๋ง๊ณผ ํธ๋ ๋
AI ์์ด์ ํธ ๊ธฐ์ ์ ์ ๋ง ๋น ๋ฅด๊ฒ ๋ฐ์ ํ๊ณ ์์ด. ์์ผ๋ก ์ด๋ป๊ฒ ๋ ๊น? ๐
๐ ์ฃผ์ ํธ๋ ๋
1. ๋ ๋๋ํ ๋๊ตฌ ์ ํ AI๊ฐ ์ํฉ์ ๋ง๋ ๋๊ตฌ๋ฅผ ๋ ์ ํํ๊ฒ ์ ํํ๊ฒ ๋ ๊ฑฐ์ผ. ์ง๊ธ๋ ์ข์ง๋ง, ์์ผ๋ก๋ ๊ฑฐ์ ์๋ฒฝํด์ง ๊ฑฐ๋ผ๊ณ !
2. ์ฅ๊ธฐ ๊ธฐ์ต ๋ฅ๋ ฅ
ํ์ฌ๋ ๋ํ ๊ธฐ๋ก์ด ์ ํ์ ์ด์ง๋ง, ์์ผ๋ก๋ ๋ช ๋ฌ, ๋ช ๋
์น ๊ธฐ์ต์ ์ ์งํ๋ฉด์ ๋ ๊ฐ์ธํ๋ ์๋น์ค๋ฅผ ์ ๊ณตํ ๊ฑฐ์ผ. ๐ง
3. ์์จ์ฑ ์ฆ๊ฐ
์ฌ๋์ ๊ฐ์
์์ด ๋ณต์กํ ์์
์ ์์ ํ ์๋์ผ๋ก ์ฒ๋ฆฌํ๋ ์์ด์ ํธ๊ฐ ๋์ด๋ ๊ฑฐ์ผ. AutoGPT๊ฐ ์์์ผ ๋ฟ!
4. ๋ฉํฐ๋ชจ๋ฌ ํตํฉ
ํ
์คํธ๋ฟ๋ง ์๋๋ผ ์ด๋ฏธ์ง, ์์ฑ, ๋น๋์ค๋ฅผ ๋ชจ๋ ์ดํดํ๊ณ ์์ฑํ๋ ์์ด์ ํธ๊ฐ ํ์ค์ด ๋ ๊ฑฐ์ผ. ๐ธ๐ต๐ฌ
5. ์ฐ์
๋ณ ํนํ
์๋ฃ, ๋ฒ๋ฅ , ๊ธ์ต ๋ฑ ๊ฐ ์ฐ์
์ ํนํ๋ ์ ๋ฌธ ์์ด์ ํธ๋ค์ด ๋ฑ์ฅํ ๊ฑฐ์ผ. ์ผ๋ฐ ์์ด์ ํธ๋ณด๋ค ํจ์ฌ ์ ํํ๊ณ ์ ๋ขฐํ ์ ์์ง!
โก ์๋ก์ด ๊ธฐ์ ๋ค
๐ฅ ์ฃผ๋ชฉํ ๋งํ ๊ธฐ์
Function Calling 2.0
๋ ๋ณต์กํ ํ๋ผ๋ฏธํฐ, ์ค์ฒฉ๋ ํจ์ ํธ์ถ, ์กฐ๊ฑด๋ถ ์คํ ๋ฑ์ด ๊ฐ๋ฅํด์ง ๊ฑฐ์ผ.
Agent-to-Agent Communication
์์ด์ ํธ๋ผ๋ฆฌ ์ง์ ๋ํํ๊ณ ํ๋ ฅํ๋ ํ๋กํ ์ฝ์ด ํ์คํ๋ ๊ฑฐ์ผ.
Self-Improving Agents
์ฌ์ฉํ๋ฉด์ ์ค์ค๋ก ํ์ตํ๊ณ ๊ฐ์ ๋๋ ์์ด์ ํธ. ๊ฐํํ์ต์ ์งํ!
Verifiable Agents
์์ด์ ํธ์ ํ๋์ ๊ฒ์ฆํ๊ณ ์ถ์ ํ ์ ์๋ ์์คํ
. ์ ๋ขฐ์ฑ๊ณผ ์์ ์ฑ์ด ํต์ฌ!
๐ผ ๋น์ฆ๋์ค ํ์ฉ๊ณผ ์์ตํ
AI ์์ด์ ํธ๋ก ์ด๋ป๊ฒ ๋์ ๋ฒ ์ ์์๊น? ์ค์ ๋น์ฆ๋์ค ๋ชจ๋ธ๋ค์ ์ดํด๋ณด์! ๐ฐ
๐ฏ ์์ต ๋ชจ๋ธ
1. SaaS ๊ตฌ๋ ๋ชจ๋ธ ์ ๊ตฌ๋ ๋ฃ๋ฅผ ๋ฐ๊ณ ์์ด์ ํธ ์๋น์ค๋ฅผ ์ ๊ณตํ๋ ๋ฐฉ์. ๊ฐ์ฅ ์ผ๋ฐ์ ์ด์ง!
์์:
- ๊ธฐ๋ณธ: ์ $9.99 (์ ํ๋ ๊ธฐ๋ฅ)
- ํ๋ก: ์ $29.99 (๋ชจ๋ ๊ธฐ๋ฅ)
- ์ํฐํ๋ผ์ด์ฆ: ๋ง์ถค ๊ฐ๊ฒฉ (์ ์ฉ ์ง์)
2. API ์ข
๋์
API ํธ์ถ ํ์๋ ์ฌ์ฉ๋์ ๋ฐ๋ผ ๊ณผ๊ธํ๋ ๋ฐฉ์.
์์:
- 1,000 ์์ฒญ: $10
- 10,000 ์์ฒญ: $80 (20% ํ ์ธ)
- 100,000 ์์ฒญ: $600 (40% ํ ์ธ)
3. ํ๋ฆฌ๋ฏธ์ ๋๊ตฌ ํ๋งค
๊ธฐ๋ณธ ์์ด์ ํธ๋ ๋ฌด๋ฃ, ํน์ ๋๊ตฌ๋ ์ ๋ฃ๋ก ์ ๊ณต.
4. ์ปจ์คํ
& ์ปค์คํฐ๋ง์ด์ง
๊ธฐ์
๋ง์ถคํ ์์ด์ ํธ ๊ฐ๋ฐ ์๋น์ค. ๊ณ ์์ต!
๐ก ์ฌ๋ฅ๋ท์์ AI ์์ด์ ํธ ์๋น์ค ์ ๊ณตํ๊ธฐ
AI ์์ด์ ํธ ๊ฐ๋ฐ ๋ฅ๋ ฅ์ด ์๋ค๋ฉด ์ฌ๋ฅ๋ท์์ ๋ค์ํ ๋ฐฉ์์ผ๋ก ์์ต์ ์ฐฝ์ถํ ์ ์์ด:
โ
AI ์ฑ๋ด ๊ฐ๋ฐ ์๋น์ค
โ
์๋ํ ์ํฌํ๋ก์ฐ ๊ตฌ์ถ
โ
๋ง์ถคํ ์์ด์ ํธ ์ ์
โ
AI ๋๊ตฌ ํตํฉ ์ปจ์คํ
โ
์์ด์ ํธ ์ ์ง๋ณด์ ์๋น์ค
ํนํ ์ค์๊ธฐ์ ์ด๋ ์คํํธ์ ์ AI ์๋ํ์ ๋ํ ์์๊ฐ ๋ง์๋ฐ, ์ง์ ๊ฐ๋ฐํ ์ธ๋ ฅ์ด ๋ถ์กฑํ ๊ฒฝ์ฐ๊ฐ ๋ง์. ์ด๋ฐ ์์ฅ์ ๋ ธ๋ ค๋ณด๋ ๊ฒ๋ ์ข์ ์ ๋ต์ด์ผ! ๐ฏ
๐ฌ ๋ง๋ฌด๋ฆฌํ๋ฉฐ
์, ์ฌ๊ธฐ๊น์ง ์ฝ์๋ค๋ฉด ์ ๋ง ๋๋จํด! ๐ AI ์์ด์ ํธ์ ๋๊ตฌ์ฌ์ฉ์ ๋ํด ์ ๋ง ๋ง์ ๊ฑธ ๋ฐฐ์ ์ ๊ฑฐ์ผ.
ํต์ฌ์ ๋ค์ ํ๋ฒ ์ ๋ฆฌํ๋ฉด:
๐ฏ ํต์ฌ ์์ฝ
โ
๋๊ตฌ์ฌ์ฉ์ AI๊ฐ ์ธ๋ถ ๊ธฐ๋ฅ์ ํธ์ถํด์ ๋ฅ๋ ฅ์ ํ์ฅํ๋ ๊ฒ
โ
Function Calling์ผ๋ก ๊ตฌ์กฐํ๋ ๋๊ตฌ ํธ์ถ์ด ๊ฐ๋ฅ
โ
ReAct ํจํด์ผ๋ก ์ถ๋ก ๊ณผ ํ๋์ ๋ฐ๋ณต
โ
LangChain, OpenAI, Claude ๋ฑ ๋ค์ํ ํ๋ ์์ํฌ ํ์ฉ
โ
๋ณด์, ์ฑ๋ฅ, ๋น์ฉ์ ํญ์ ๊ณ ๋ คํด์ผ ํจ
โ
์ค์ ํ๋ก์ ํธ๋ก ๊ฒฝํ์ ์๋ ๊ฒ ์ค์
โ
์ปค๋ฎค๋ํฐ์ ํจ๊ป ์ฑ์ฅํ์!
AI ์์ด์ ํธ ๊ธฐ์ ์ ์ ๋ง ๋น ๋ฅด๊ฒ ๋ฐ์ ํ๊ณ ์์ด. ์ง๊ธ ์์ํ๋ฉด ์ถฉ๋ถํ ๋ฐ๋ผ์ก์ ์ ์๊ณ , ์์ผ๋ก ์์ฒญ๋ ๊ธฐํ๊ฐ ์์ ๊ฑฐ์ผ! ๐
ํน์ ๋งํ๋ ๋ถ๋ถ์ด ์๊ฑฐ๋, ๋ ๊น์ด ๋ฐฐ์ฐ๊ณ ์ถ๋ค๋ฉด ์ปค๋ฎค๋ํฐ์ ์ง๋ฌธํ๊ฑฐ๋, ์ฌ๋ฅ๋ท์์ ๋ฉํ ๋ฅผ ์ฐพ์๋ณด๋ ๊ฒ๋ ์ข์ ๋ฐฉ๋ฒ์ด์ผ. ํจ๊ป ์ฑ์ฅํ๋ ๊ฒ ์ ์ผ ๋น ๋ฅด๊ฑฐ๋ ! ๐ช
์, ์ด์ ์ง์ ๋ง๋ค์ด๋ณผ ์๊ฐ์ด์ผ! ๊ฐ๋จํ ํ๋ก์ ํธ๋ถํฐ ์์ํด์ ์ ์ ๋ณต์กํ ์์ด์ ํธ๋ฅผ ๋ง๋ค์ด๋ณด์. ์คํจํด๋ ๊ด์ฐฎ์. ๊ทธ๊ฒ ๋ฐฐ์ฐ๋ ๊ณผ์ ์ด๋๊น! ๐
๐ Happy Coding! ๐คโจ
AI ์์ด์ ํธ์ ํจ๊ปํ๋ ๋ฉ์ง ๋ฏธ๋๋ฅผ ๋ง๋ค์ด๊ฐ์! ๐
๐ ๋ ์์๋ณด๊ธฐ
์ด ๊ธ์ด ๋์์ด ๋์๋ค๋ฉด, ์ฌ๋ฅ๋ท์์ ๋ ๋ง์ AI ๊ฐ๋ฐ ์ง์์ ํํํด๋ณด์ธ์!
์ฌ๋ฌ๋ถ์ ์ฌ๋ฅ์ ๋๋๊ณ , ์๋ก์ด ์ฌ๋ฅ์ ๋ฐฐ์ธ ์ ์๋ ๊ณณ์
๋๋ค. ๐
๊ด๋ จ ํค์๋
๋๊ธ ์์ฑ
์ด ๊ธ์ ๋ํ ์ฌ๋ฌ๋ถ์ ์๊ฐ์ ๋ค๋ ค์ฃผ์ธ์
๋ก๊ทธ์ธ์ด ํ์ํฉ๋๋ค
๋๊ธ์ ์์ฑํ๋ ค๋ฉด ๋จผ์ ๋ก๊ทธ์ธํด์ฃผ์ธ์.
๋๊ธ 0
์ง์์ธ์ ์ฒ - ์ง์ ์ฌ์ฐ๊ถ ๋ณดํธ ๊ณ ์ง
์ง์ ์ฌ์ฐ๊ถ ๋ณดํธ ๊ณ ์ง
- ์ ์๊ถ ๋ฐ ์์ ๊ถ: ๋ณธ ์ปจํ ์ธ ๋ ์ฌ๋ฅ๋ท์ ๋ ์ AI ๊ธฐ์ ๋ก ์์ฑ๋์์ผ๋ฉฐ, ๋ํ๋ฏผ๊ตญ ์ ์๊ถ๋ฒ ๋ฐ ๊ตญ์ ์ ์๊ถ ํ์ฝ์ ์ํด ๋ณดํธ๋ฉ๋๋ค.
- AI ์์ฑ ์ปจํ ์ธ ์ ๋ฒ์ ์ง์: ๋ณธ AI ์์ฑ ์ปจํ ์ธ ๋ ์ฌ๋ฅ๋ท์ ์ง์ ์ฐฝ์๋ฌผ๋ก ์ธ์ ๋๋ฉฐ, ๊ด๋ จ ๋ฒ๊ท์ ๋ฐ๋ผ ์ ์๊ถ ๋ณดํธ๋ฅผ ๋ฐ์ต๋๋ค.
- ์ฌ์ฉ ์ ํ: ์ฌ๋ฅ๋ท์ ๋ช ์์ ์๋ฉด ๋์ ์์ด ๋ณธ ์ปจํ ์ธ ๋ฅผ ๋ณต์ , ์์ , ๋ฐฐํฌ, ๋๋ ์์ ์ ์ผ๋ก ํ์ฉํ๋ ํ์๋ ์๊ฒฉํ ๊ธ์ง๋ฉ๋๋ค.
- ๋ฐ์ดํฐ ์์ง ๊ธ์ง: ๋ณธ ์ปจํ ์ธ ์ ๋ํ ๋ฌด๋จ ์คํฌ๋ํ, ํฌ๋กค๋ง, ๋ฐ ์๋ํ๋ ๋ฐ์ดํฐ ์์ง์ ๋ฒ์ ์ ์ฌ์ ๋์์ด ๋ฉ๋๋ค.
- AI ํ์ต ์ ํ: ์ฌ๋ฅ๋ท์ AI ์์ฑ ์ปจํ ์ธ ๋ฅผ ํ AI ๋ชจ๋ธ ํ์ต์ ๋ฌด๋จ ์ฌ์ฉํ๋ ํ์๋ ๊ธ์ง๋๋ฉฐ, ์ด๋ ์ง์ ์ฌ์ฐ๊ถ ์นจํด๋ก ๊ฐ์ฃผ๋ฉ๋๋ค.
์์ง ๋๊ธ์ด ์์ต๋๋ค.