LangGraph

LangGraph 5강

[도구] ToolNode & ReAct 루프

에이전트의 핵심은 도구 호출이다. LLM에 bind_tools로 도구를 알려 주면, LLM은 필요할 때 tool_calls를 만들어 낸다. 이 호출을 ToolNode가 실제로 실행하고, 결과를 다시 LLM에게 돌려주는 순환이 바로 ReAct 루프다. LangGraph는 ToolNodetools_condition 프리빌트로 이 패턴을 간단히 만든다.

LangGraph 5강 구성도

이 강의 목표는 도구를 붙인 에이전트 그래프를 직접 조립하는 것이다.

1. 도구 정의 & 바인딩

@tool 데코레이터로 함수를 도구로 만들고, bind_tools로 LLM에 스키마를 알린다.

from langchain_core.tools import tool
from langchain_openai import ChatOpenAI

@tool
def add(a: int, b: int) -> int:
    "두 수를 더한다"
    return a + b

llm = ChatOpenAI(model="gpt-4o").bind_tools([add])

2. ToolNode 와 tools_condition

ToolNode는 메시지의 tool_calls를 실행해 결과를 ToolMessage로 돌려준다. tools_condition은 마지막 메시지에 도구 호출이 있으면 "tools", 없으면 END로 분기하는 프리빌트 라우팅 함수다.

from langgraph.prebuilt import ToolNode, tools_condition
from langgraph.graph import StateGraph, START

def chat(state): return {"messages": [llm.invoke(state["messages"])]}

g = StateGraph(State)
g.add_node("chat", chat)
g.add_node("tools", ToolNode([add]))
g.add_edge(START, "chat")
g.add_conditional_edges("chat", tools_condition)  # 도구 있으면 tools
g.add_edge("tools", "chat")                       # 결과 후 다시 chat
app = g.compile()

3. 실행 흐름

chat이 도구 호출을 만들면 → tools가 실행 → 결과가 chat으로 → LLM이 최종 답을 낼 때까지 반복한다.

핵심 명령·용어

이름
@tool 함수를 도구로 등록
bind_tools([...]) LLM에 도구 스키마 전달
ToolNode tool_calls 실행 노드
tools_condition 도구 유무 분기 프리빌트

예제

res = app.invoke({"messages": [("user", "17 더하기 25는?")]})
for m in res["messages"]:
    m.pretty_print()
# user → AI(tool_calls: add) → Tool(42) → AI("42입니다")

해설) LLM은 직접 계산하지 않고 add 도구를 호출해 정확한 값을 얻는다. 이 그래프 전체를 한 줄로 만들어 주는 것이 다음 강의의 create_react_agent다.

댓글 0