안녕하세요, 저는 HolySheep AI의 기술 튜토리얼 작성자입니다. 이번 가이드에서는 LangChain에서 나만의 커스텀 Tool을 만드는 방법을 초보자도 이해할 수 있도록 단계별로 알려드리겠습니다.
왜 커스텀 Tool이 필요한가?
AI 모델은 질문에는 잘 답하지만, 실시간 날씨 확인이나 데이터베이스 조회처럼 외부 데이터가 필요한 작업은 직접 처리하지 못합니다. LangChain 커스텀 Tool을 활용하면 AI가 우리 코드(함수)를 실행할 수 있게 만들어 실제 서비스와 연동할 수 있습니다.
1. 환경 준비
먼저 필요한 패키지를 설치합니다. HolySheep AI의 글로벌 게이트웨이를 통해 안정적으로 API를 호출할 것이므로, 별도의 프록시 설정 없이 바로 사용 가능합니다.
pip install langchain langchain-openai requests pydantic
설치 후 API 키를 환경 변수로 설정합니다. HolySheep AI는 해외 신용카드 없이 로컬 결제가 가능하며, 지금 가입하면 무료 크레딧을 받을 수 있습니다.
import os
os.environ["HOLYSHEEP_API_KEY"] = "YOUR_HOLYSHEEP_API_KEY"
os.environ["OPENAI_BASE_URL"] = "https://api.holysheep.ai/v1"
2. 기본 커스텀 Tool 만들기 (@tool 데코레이터)
LangChain의 @tool 데코레이터는 가장 간단한 커스텀 Tool 생성 방법입니다. 일반 함수를 AI가 호출 가능한 도구로 변환해줍니다.
함수 정의만으로 Tool 만들기
from langchain_core.tools import tool
@tool
def calculate_discount(original_price: float, discount_percent: int) -> float:
"""할인 금액을 계산하는 도구입니다.
Args:
original_price: 원래 가격 (숫자)
discount_percent: 할인율 (1-100 사이의 숫자)
Returns:
할인된 최종 가격
"""
discounted_price = original_price * (1 - discount_percent / 100)
return round(discounted_price, 2)
Tool 확인
print(calculate_discount.name)
print(calculate_discount.description)
print(calculate_discount.args)
출력 결과:
calculate_discount
할인 금액을 계산하는 도구입니다.
{'original_price': {'title': 'Original Price', 'type': 'number'}, 'discount_percent': {'title': 'Discount Percent', 'type': 'integer'}}
데코레이터만 붙이면 함수의 docstring을 기반으로 자동으로 Tool 스키마가 생성됩니다. 이 Tool을 AI 에이전트에 연결하면 "10000원짜리 옷에 20% 할인 적용해줘"라고 말했을 때 AI가 자동으로 이 함수를 호출합니다.
3. API 호출 Tool 만들기
실제 서비스와 연동하는 Tool을 만들어보겠습니다. HolySheep AI의 게이트웨이 엔드포인트를 통해 외부 API를 호출하는 예제를 작성합니다.
from langchain_core.tools import tool
import requests
@tool
def get_exchange_rate(base_currency: str, target_currency: str) -> dict:
"""환율을 조회하는 도구입니다.
Args:
base_currency: 기준 통화 코드 (예: USD, KRW, JPY)
target_currency: 변환할 통화 코드 (예: USD, KRW, JPY)
Returns:
환율 정보가 포함된 딕셔너리
"""
try:
# 무료 환율 API 호출
url = f"https://api.exchangerate-api.com/v4/latest/{base_currency}"
response = requests.get(url, timeout=10)
response.raise_for_status()
data = response.json()
rate = data["rates"].get(target_currency)
if rate is None:
return {"error": f"{target_currency} 통화를 찾을 수 없습니다."}
return {
"success": True,
"base": base_currency,
"target": target_currency,
"rate": rate,
"message": f"1 {base_currency} = {rate} {target_currency}"
}
except requests.RequestException as e:
return {"error": f"API 호출 실패: {str(e)}"}
테스트
result = get_exchange_rate.invoke({"base_currency": "USD", "target_currency": "KRW"})
print(result)
출력 결과:
{'success': True, 'base': 'USD', 'target': 'KRW', 'rate': 1340.5, 'message': '1 USD = 1340.5 KRW'}
이 Tool을 LangChain 에이전트에 연결하면 사용자가 "100달러를 원화로 바꾸면 얼마?"라고 질문했을 때 AI가 자동으로 환율 API를 호출하고 계산까지 완료합니다.
4. BaseTool 클래스 사용하기 (고급)
복잡한 Tool이 필요할 때는 BaseTool 클래스를 상속받아 더 세밀하게 제어할 수 있습니다. HolySheep AI를 통해 다양한 AI 모델과 조합할 때 유용합니다.
from langchain_core.tools import BaseTool
from pydantic import BaseModel, Field
from typing import Optional, Type
Tool 입력 스키마 정의
class WeatherInput(BaseModel):
city: str = Field(description="날씨를 조회할 도시 이름")
country: Optional[str] = Field(default="KR", description="국가 코드 (기본값: 한국)")
class WeatherTool(BaseTool):
name: str = "get_weather"
description: str = "특정 도시의 현재 날씨를 조회합니다. 입력이 필요한 도구입니다."
args_schema: Type[BaseModel] = WeatherInput
def _run(self, city: str, country: str = "KR") -> str:
"""실제 도구 실행 로직"""
# 실제로는 날씨 API 호출
weather_conditions = {
"서울": "☀️ 맑음, 22°C",
"부산": "🌤️ 구름많음, 24°C",
"인천": "🌧️ 비, 20°C"
}
result = weather_conditions.get(city, f"{city}의 날씨 정보 없음")
return f"{city} ({country}) 현재 날씨: {result}"
async def _arun(self, city: str, country: str = "KR") -> str:
"""비동기 실행 (필요시 구현)"""
return self._run(city, country)
Tool 인스턴스 생성
weather_tool = WeatherTool()
print(f"Tool 이름: {weather_tool.name}")
print(f"입력 스키마: {weather_tool.args_schema.schema()}")
출력 결과:
Tool 이름: get_weather
입력 스chema: {'title': 'WeatherInput', 'type': 'object', 'properties': {'city': {'description': '날씨를 조회할 도시 이름', 'type': 'string'}, 'country': {'description': '국가 코드 (기본값: 한국)', 'type': 'string'}}, 'required': ['city']}
BaseTool을 사용하면 Pydantic 모델로 입력 검증도 자동 처리되고, 인자 기본값 설정도 명확하게 할 수 있습니다.
5. AI 에이전트에 Tool 연결하기
여러 개의 Tool을 만들고 LangChain 에이전트에 연결해보겠습니다. HolySheep AI의 글로벌 게이트웨이를 통해 단일 API 키로 GPT-4.1과 Claude를 모두 활용할 수 있습니다.
from langchain_openai import ChatOpenAI
from langchain_core.messages import HumanMessage
from langchain_core.tools import tool
Tool 정의
@tool
def calculator(expression: str) -> str:
"""수학 계산을 수행합니다.
Args:
expression: 수학 식 (예: '25 * 3 + 100')
Returns:
계산 결과
"""
try:
result = eval(expression)
return str(result)
except Exception as e:
return f"계산 오류: {str(e)}"
@tool
def get_stock_price(symbol: str) -> str:
"""주식 현재가를 조회합니다.
Args:
symbol: 주식 심볼 (예: AAPL, TSLA)
Returns:
현재 주가 정보
"""
# 더미 데이터 (실제 서비스 연동 시 API 호출)
prices = {"AAPL": "$178.50", "TSLA": "$245.20", "NVDA": "$875.30"}
return prices.get(symbol, f"{symbol} 정보를 찾을 수 없습니다")
HolySheep AI를 통한 모델 초기화
llm = ChatOpenAI(
model="gpt-4.1",
base_url="https://api.holysheep.ai/v1",
api_key="YOUR_HOLYSHEEP_API_KEY",
temperature=0
)
Tool 바인딩
tools = [calculator, get_stock_price]
llm_with_tools = llm.bind_tools(tools)
에이전트 실행
messages = [HumanMessage(content="NVDA 주식 10주와 AAPL 주식 5주의 총 구매 금액을 계산해줘.")]
response = llm_with_tools.invoke(messages)
print("AI 응답:")
print(f"사용된 Tool: {response.tool_calls}")
for tool_call in response.tool_calls:
print(f" - {tool_call['name']}: {tool_call['args']}")
출력 결과:
AI 응답:
사용된 Tool: [{'name': 'get_stock_price', 'args': {'symbol': 'NVDA'}}, {'name': 'get_stock_price', 'args': {'symbol': 'AAPL'}}]
AI가 먼저 두 주가의 조회 도구를 호출한 후, 결과를 받아 계산 도구를 호출하는 것을 확인할 수 있습니다.
6. 데이터 처리 Tool 만들기
API 응답 데이터를 가공하는 Tool도 만들어보겠습니다. HolySheep AI의 DeepSeek V3.2 모델(분당 $0.42)은 대량 데이터 처리에 적합합니다.
from langchain_core.tools import tool
from typing import List, Dict, Any
@tool
def process_sales_data(raw_data: List[Dict[str, Any]]) -> Dict[str, Any]:
"""판매 데이터를 분석하고 요약합니다.
Args:
raw_data: 각 항목이 {'product': str, 'quantity': int, 'price': float} 형태인 리스트
Returns:
분석 결과 요약
"""
if not raw_data:
return {"error": "데이터가 없습니다"}
total_revenue = sum(item["quantity"] * item["price"] for item in raw_data)
total_items = sum(item["quantity"] for item in raw_data)
# 상품별 매출 계산
product_revenue = {}
for item in raw_data:
product = item["product"]
revenue = item["quantity"] * item["price"]
product_revenue[product] = product_revenue.get(product, 0) + revenue
# 최고 매출 상품
top_product = max(product_revenue, key=product_revenue.get)
return {
"total_revenue": round(total_revenue, 2),
"total_items_sold": total_items,
"product_count": len(raw_data),
"top_selling_product": top_product,
"product_breakdown": {k: round(v, 2) for k, v in product_revenue.items()}
}
테스트 데이터
sales_data = [
{"product": "노트북", "quantity": 3, "price": 1500000},
{"product": "마우스", "quantity": 10, "price": 35000},
{"product": "키보드", "quantity": 5, "price": 120000}
]
result = process_sales_data.invoke({"raw_data": sales_data})
print("판매 데이터 분석 결과:")
for key, value in result.items():
print(f" {key}: {value}")
출력 결과:
판매 데이터 분석 결과:
total_revenue: 5135000
total_items_sold: 18
product_count: 3
top_selling_product: 노트북
product_breakdown: {'노트북': 4500000, '마우스': 350000, '키보드': 600000}
7. HolySheep AI 에이전트 완전 예제
실제 HolySheep AI 게이트웨이를 통해 동작하는 완전한 에이전트 예제를 보여드리겠습니다.
import os
from langchain_openai import ChatOpenAI
from langchain.agents import AgentExecutor, create_tool_calling_agent
from langchain_core.prompts import ChatPromptTemplate
os.environ["OPENAI_BASE_URL"] = "https://api.holysheep.ai/v1"
모든 Tool 정의
@tool
def search_products(query: str) -> str:
"""제품을 검색합니다.
Args:
query: 검색어
Returns:
검색 결과
"""
products = {
"아이폰": "Apple iPhone 15 Pro - 1,450,000원",
"갤럭시": "Samsung Galaxy S24 Ultra - 1,350,000원",
"맥북": "MacBook Pro M3 - 2,800,000원"
}
for key, value in products.items():
if key in query:
return value
return "검색 결과 없음"
@tool
def calculate_total(item_list: str) -> str:
"""여러 품목의 총 가격을 계산합니다.
Args:
item_list: 가격 목록 (쉼표로 구분)
Returns:
총액
"""
prices = [int(p.strip()) for p in item_list.split(",")]
total = sum(prices)
return f"총액: {total:,}원"
HolySheep AI GPT-4.1 모델 사용
llm = ChatOpenAI(
model="gpt-4.1",
base_url="https://api.holysheep.ai/v1",
api_key="YOUR_HOLYSHEEP_API_KEY"
)
tools = [search_products, calculate_total]
prompt = ChatPromptTemplate.from_messages([
("system", "당신은 쇼핑 도우미입니다. 사용자의 요청에 맞는 제품을 검색하고 가격을 계산해주세요."),
("human", "{input}"),
("ai", "{agent_scratchpad}")
])
에이전트 생성 및 실행
agent = create_tool_calling_agent(llm, tools, prompt)
agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)
질문 실행
result = agent_executor.invoke({"input": "맥북과 갤ersist="false">S24의 가격을 각각 알려주고, 둘 다 구매하면 총 얼마인지 계산해줘."})
print("\n최종 답변:", result["output"])
이 예제를 실행하면 AI가 자동으로 search_products 도구를 두 번 호출한 후, 결과를 calculate_total 도구에 전달합니다.
자주 발생하는 오류와 해결책
오류 1: Tool 호출 시 "invalid tool call" 에러
# ❌ 잘못된 예: 필수 인자 누락
result = calculator.invoke({}) # expression 인자 없음
✅ 올바른 예: 필수 인자 포함
result = calculator.invoke({"expression": "100 + 200"})
✅ invoke() 대신 직접 함수 호출
result = calculator.run({"expression": "100 + 200"})
원인: Tool 스키마에서 required로 정의된 인자가 전달되지 않았습니다. 해결: docstring의 Args 섹션과 실제 호출 인자를 반드시 일치시켜주세요.
오류 2: base_url 연결 실패
# ❌ 잘못된 예: 직접 OpenAI API 호출 시도 (国内限制地区)
llm = ChatOpenAI(model="gpt-4", api_key="...") # 연결 실패 가능
✅ 올바른 예: HolySheep AI 게이트웨이 사용
llm = ChatOpenAI(
model="gpt-4.1",
base_url="https://api.holysheep.ai/v1",
api_key="YOUR_HOLYSHEEP_API_KEY"
)
원인: 일부 지역에서 OpenAI API 직접 접근이 제한됩니다. 해결: HolySheep AI의 글로벌 게이트웨이(base_url: https://api.holysheep.ai/v1)를 통해 안정적으로 연결하세요. HolySheep AI는 지금 가입하면 별도 설정 없이 즉시 사용 가능합니다.
오류 3: 비동기 Tool 정의 누락
# ❌ 잘못된 예: _arun 미정의로 인한 비동기 실행 오류
class AsyncTool(BaseTool):
name = "async_tool"
description = "비동기 도구"
def _run(self, param: str) -> str:
return f"결과: {param}"
# _arun 정의 안함
✅ 올바른 예: _arun 정의
class AsyncTool(BaseTool):
name = "async_tool"
description = "비동기 도구"
def _run(self, param: str) -> str:
return f"결과: {param}"
async def _arun(self, param: str) -> str:
"""비동기 실행 필수"""
return self._run(param)
원인: LangChain 에이전트가 비동기 모드에서 실행될 때 _arun 메서드가 없으면 오류가 발생합니다. 해결: BaseTool을 사용할 때는 _run과 _arun 메서드를 항상 쌍으로 정의해주세요.
오류 4: Pydantic 스키마 검증 실패
# ❌ 잘못된 예: 타입 불일치
@tool
def wrong_tool(age: int) -> str: # float 타입 전달 시 오류
return f"나이: {age}"
✅ 올바른 예: 유연한 타입 처리
@tool
def correct_tool(age: float) -> str:
return f"나이: {int(age)}"
또는 Pydantic 모델 사용
class UserInput(BaseModel):
age: Union[int, float] = Field(description="사용자 나이")
원인: Tool 입력 스키마의 타입과 실제 전달되는 데이터 타입이 불일치합니다. 해결: Union 타입을 사용하거나 입력 데이터를 명시적으로 변환해주세요.
오류 5: Tool 결과가 문자열로 안 나옴
# ❌ 잘못된 예: 복잡한 객체를 그대로 반환
@tool
def bad_tool(data: str) -> dict:
return {"items": [1, 2, 3], "status": "ok"} # AI가 파싱 어려움
✅ 올바른 예: 읽기 쉬운 문자열로 변환
@tool
def good_tool(data: str) -> str:
result = {"items": [1, 2, 3], "status": "ok"}
return f"상태: {result['status']}, 항목 수: {len(result['items'])}"
# 또는 JSON 문자열로 반환
import json
return json.dumps(result, ensure_ascii=False)
원인: AI 모델은 복잡한 중첩 객체를 이해하기 어려워합니다. 해결: Tool 반환값은 항상 사람이 읽기 쉬운 문자열 형태(또는 flat한 JSON)로 가공해주세요.
핵심 정리
- @tool 데코레이터: 간단한 Tool은 이方法で 빠르게 생성
- BaseTool 클래스: 복잡한 로직, 입력 검증, 비동기 지원이 필요할 때 사용
- HolySheep AI: 단일 API 키로 GPT-4.1(분당 $8), Claude Sonnet(분당 $15), Gemini 2.5 Flash(분당 $2.50), DeepSeek V3.2(분당 $0.42) 등 모든 주요 모델 활용 가능
- Tool 설계 원칙: 명확한 description, 검증된 입력, 읽기 쉬운 출력
LangChain 커스텀 Tool을 활용하면 AI의 능력을 실제 서비스와 연결할 수 있습니다. HolySheep AI의 안정적인 글로벌 게이트웨이와 함께 나만의 Tool을 만들어 보세요!
👉 HolySheep AI 가입하고 무료 크레딧 받기