LangChain 도구
LangChain 도구 (Tools)
도구(Tools)는 에이전트가 할 수 있는 일을 확장해 줘요. 실시간 데이터를 가져오고, 코드를 실행하고, 외부 데이터베이스를 질의하고, 세상에서 실제 행동까지 취할 수 있게 해 주죠. 내부적으로 도구는 명확히 정의된 입력·출력을 가진 호출 가능한 함수(callable)이고, 채팅 모델에 전달돼요. 모델은 대화 맥락을 보고 언제 도구를 호출할지, 어떤 인자를 넘길지 결정해요.
도구는 에이전트를 만들 때 tools= 파라미터로 전달해요. LangChain은 일반 파이썬 콜러블, @tool로 정의한 함수, 또는 도구 딕셔너리를 모두 받아요.
도구 만들기
기본 도구 정의
가장 간단한 방법은 @tool 데코레이터를 쓰는 거예요. 기본적으로 함수의 docstring이 도구의 설명이 되어 모델이 언제 써야 할지 이해하는 데 도움을 줘요.
from langchain.tools import tool
@tool
def search_database(query: str, limit: int = 10) -> str:
"""Search the customer database for records matching the query.
Args:
query: Search terms to look for
limit: Maximum number of results to return
"""
return f"Found {limit} results for '{query}'"
타입 힌트는 필수예요. 도구의 입력 스키마를 정의하기 때문이에요. docstring은 모델이 도구의 목적을 이해하도록 간결하고 유익하게 작성하는 게 좋아요.
⚠️ 도구 이름은
snake_case를 권장해요. (예:Web Search대신web_search) 일부 모델 프로바이더는 공백이나 특수문자가 포함된 이름에 문제가 생길 수 있어서, 영숫자·밑줄·하이픈만 쓰면 프로바이더 간 호환성이 좋아져요.
도구 속성 커스터마이즈
이름을 바꾸거나 설명을 덮어쓸 수 있어요.
@tool("web_search") # 커스텀 이름
def search(query: str) -> str:
"""Search the web for information."""
return f"Results for: {query}"
print(search.name) # web_search
복잡한 스키마 정의
Pydantic 모델이나 JSON 스키마로 복잡한 입력을 정의할 수 있어요. args_schema=에 넘기면 돼요.
from pydantic import BaseModel, Field
from typing import Literal
class WeatherInput(BaseModel):
"""Input for weather queries."""
location: str = Field(description="City name or coordinates")
units: Literal["celsius", "fahrenheit"] = Field(default="celsius", description="Temperature unit preference")
@tool(args_schema=WeatherInput)
def get_weather(location: str, units: str = "celsius") -> str:
"""Get current weather."""
return f"Current weather in {location}"
예약된 인자 이름
다음 파라미터 이름은 도구 인자로 쓸 수 없어요. 쓰면 런타임 오류가 나요.
| 파라미터 이름 | 용도 |
|---|---|
config |
RunnableConfig를 도구에 내부 전달 |
runtime |
ToolRuntime 파라미터(상태·컨텍스트·스토어 접근) |
런타임 정보에 접근하고 싶다면 config나 runtime이라는 이름 대신 ToolRuntime 파라미터를 쓰는 게 맞아요.
컨텍스트 접근하기
도구가 커뮤니케이션 히스토리, 사용자 데이터, 영구 메모리 같은 런타임 정보에 접근할 수 있게 하려면 ToolRuntime 파라미터를 쓰면 돼요. ToolRuntime은 다음과 같은 구성 요소를 제공해요.
- State (단기 메모리): 현재 대화에서 존재하는 변경 가능한 데이터 (메시지, 카운터, 커스텀 필드)
- Context (불변 설정): 호출 시점에 전달되는 불변 설정 (사용자 ID, 세션 정보)
- Store (장기 메모리): 대화를 넘어서는 영구 데이터 (사용자 선호, 지식 베이스)
- Stream Writer: 도구 실행 중 실시간 업데이트 전송
- Execution Info: 현재 실행의 ID·재시도 정보
- Server Info: LangGraph Server 실행 시 서버 메타데이터
- Config: 실행용
RunnableConfig - Tool Call ID: 현재 도구 호출의 고유 식별자
단기 메모리(State)에 접근하려면 도구 시그니처에 runtime: ToolRuntime을 추가하고 runtime.state로 읽으면 돼요.
from langchain.tools import tool, ToolRuntime
from langchain.messages import HumanMessage
@tool
def get_last_user_message(runtime: ToolRuntime) -> str:
"""Get the most recent message from the user."""
messages = runtime.state["messages"]
for message in reversed(messages):
if isinstance(message, HumanMessage):
return message.content
return "No user messages found"
더 알아보기
- LangChain Agents 문서:
create_agent에서 도구 연결 - LangChain Models 문서: 도구 호출 처리 방식
- LangChain 구조화 출력 문서: 모델 응답 스키마 제약