에이전트의 핵심은 도구 호출이다. LLM에 bind_tools로 도구를 알려 주면, LLM은 필요할 때 tool_calls를 만들어 낸다. 이 호출을 ToolNode가 실제로 실행하고, 결과를 다시 LLM에게 돌려주는 순환이 바로 ReAct 루프다. LangGraph는 ToolNode와 tools_condition 프리빌트로 이 패턴을 간단히 만든다.
이 강의 목표는 도구를 붙인 에이전트 그래프를 직접 조립하는 것이다.
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
댓글은 운영자만 작성할 수 있어요.