4. Tool 호출
Graph에서 외부 Tool을 호출하는 방법에 대해서 알아보도록 하자.
먼저 Tool 함수를 정의해야 하는데,Tool을 일반적인 파이썬 함수로 정의한다. 이때 중요한 부분은 함수 첫줄에 툴에 대한 설명을 주석으로 달아줘야 한다. LLM AI 모델이 어떤 툴을 사용해야할지 판단할때 이 정보를 이용해서, 툴의 기능을 파악한 후에, 툴 호출 여부를 결정한다.
아래는 get_weather라는 툴을 정의한 코드로, 특정 지역의 날씨를 리턴하는 테스트 코드이다. (지역명이 sf나 san francisco인 경우에는 온도를 60도로, 아니면 90도 온도로 리턴한다.)
이렇게 툴을 호출하는 노드를 ToonNode라고 하는데, 인자로, 호출할 툴 함수를 정의한다.
아래 코드에서 보면 ToolNode([get_weather])로 툴 함수를 지정한것을 알 수 있다.
def get_weather(location: str):
"""Call to get the current weather."""
if location.lower() in ["sf", "san francisco"]:
return "It's 60 degrees and foggy."
else:
return "It's 90 degrees and sunny."
tool_node = ToolNode([get_weather])
툴 노드를 정의했으면, Graph에서 사용하는 LLM모델에게 이 그래프에 툴이 있으면 알리고, 툴이 어떤 기능을 할 수 있는지를 알려줘야 한다. 그래서, model을 생성한 후에, model.bind_tools 라는 함수를 이용하여, 현재 생성된 툴 함수들을 연결해줘야 한다. 이를 통해서 LLM은 툴의 기능을 파악하여 필요에 따라서 툴을 호출하도록 판단을 내리도록 할 수 있다.
model = init_chat_model(model="google_genai:gemini-2.5-flash")
model_with_tools = model.bind_tools([get_weather])
LLM이 툴을 사용하도록 판단을 내리면, 그 판단을 인식해서 ToolNode를 호출할 수 있도록 conditional_edge를 정의해야 한다.
아래 예제는 MessageState를 State 정보로 사용하는데, AI가 Tool 사용을 요청하면, message.tools_calls라는 부분에, 호출해야 하는 툴에 대한 정보가 전달된다.
그래서 아래 코드처럼 should_continue라는 conditional edge 함수에서, last_message.tools rㅏ 존재하면 리턴을 “tool”을 해서, edge에서 “tool”노드를 호출하도록 하였다.
def should_continue(state: MessagesState):
messages = state["messages"]
last_message = messages[-1]
if last_message.tool_calls:
print(last_message.tool_calls[0]["name"])
return "tools"
return END
이렇게 Tool Node와, Tool Node를 호출하기 위한 conditional edge 함수가 정의되면, 아래와 같이 그래프를 정의한다. node_1→ tools →node_1→tools 를 호출하는 구조를 가지고 되는데, AI LLM 모델이 판단하기에, 더이상 tools를 호출할 필요가 없을때 까지 반복하고, 호출할 필요가 없을 경우에는 END로 종료한다.
builder.add_edge(START, "node_1")
builder.add_conditional_edges("node_1", should_continue, ["tools", END])
builder.add_edge("tools", "node_1")
아래는 전체 내용을 구현한 예제코드이다.
from langchain.chat_models import init_chat_model
from langgraph.prebuilt import ToolNode
from langgraph.graph import StateGraph, MessagesState, START, END
import os
os.environ["GOOGLE_API_KEY"] = "{Your API Key}"
def get_weather(location: str):
"""Call to get the current weather."""
if location.lower() in ["sf", "san francisco"]:
return "It's 60 degrees and foggy."
else:
return "It's 90 degrees and sunny."
tool_node = ToolNode([get_weather])
model = init_chat_model(model="google_genai:gemini-2.5-flash")
model_with_tools = model.bind_tools([get_weather])
def should_continue(state: MessagesState):
messages = state["messages"]
last_message = messages[-1]
if last_message.tool_calls:
print(last_message.tool_calls[0]["name"])
return "tools"
return END
def node_1(state: MessagesState):
messages = state["messages"]
response = model_with_tools.invoke(messages)
return {"messages": [response]}
builder = StateGraph(MessagesState)
# Define the two nodes we will cycle between
builder.add_node("node_1", node_1)
builder.add_node("tools", tool_node)
builder.add_edge(START, "node_1")
builder.add_conditional_edges("node_1", should_continue, ["tools", END])
builder.add_edge("tools", "node_1")
graph = builder.compile()
result = graph.invoke({"messages": [{"role": "user", "content": "what's the weather in sf?"}]})
print("result")
print(result)
'빅데이타 & 머신러닝 > 생성형 AI (ChatGPT etc)' 카테고리의 다른 글
AI 자동화와 Zapier, n8n 소개 및 비교 (4) | 2025.07.17 |
---|---|
Langchain이 있는데, Langgraph가 왜 필요할까? (1) | 2025.07.17 |
고급 Agent를 위한 Langgraph 개념 이해 #3 - Edge (1) | 2025.07.10 |
고급 Agent를 위한 Langgraph - Multi State 사용시 주의해야할점 (1) | 2025.07.10 |
고급 Agent를 위한 Langgraph 개념 이해 #2 - Node (0) | 2025.07.08 |