LangGraph 공식문서를 번역한 내용입니다. 필요한 경우 부연 설명을 추가하였고 이해하기 쉽게 예제를 일부 변경하였습니다. 문제가 되면 삭제하겠습니다.
https://langchain-ai.github.io/langgraph/how-tos/recursion-limit/
런타임에서, 애플리케이션 로직에 의해 설정되어야 하는 값(예: 사용자 ID)을 도구에 전달해야 할 수 있다. 보안상의 이유로 LLM이 제어해서는 안된다. LLM은 오직 의도된 파라미터만 관리해야 한다.
LangChain 도구는 Runnable
인터페이스를 사용하며, invoke
와 같은 메서드는 RunnableConfig
인수를 통해 런타임 정보를 받는다.
다음 예제에서는 사용자의 즐겨 찾는 애완동물을 관리하는 에이전트를 설정한다. 엔트리 추가, 읽기, 삭제 작업을 수행하며, 사용자 ID는 애플리케이션 로직을 통해 고정하고, 채팅 모델은 다른 파라미터를 제어하도록 한다.
준비
우선, 필요한 패키지를 설치하자.
pip install langgraph langchain_openai
도구와 모델 정의
from typing import List
from dotenv import load_dotenv
from langchain_core.runnables.config import RunnableConfig
from langchain_core.tools import tool
from langchain_openai import ChatOpenAI
from langgraph.prebuilt import ToolNode
user_to_pets = {}
load_dotenv()
@tool(parse_docstring=True)
def update_favorite_pets(
# config는 함수 시그니처에 포함되지 않아야 하므로 docstring에 추가할 필요가 없다.
pets: List[str],
config: RunnableConfig,
) -> None:
"""Add the list of favorite pets.
Args:
pets: List of favorite pets to set.
"""
user_id = config.get("configurable", {}).get("user_id")
user_to_pets[user_id] = pets
@tool
def delete_favorite_pets(config: RunnableConfig) -> None:
"""Delete the list of favorite pets."""
user_id = config.get("configurable", {}).get("user_id")
if user_id in user_to_pets:
del user_to_pets[user_id]
@tool
def list_favorite_pets(config: RunnableConfig) -> None:
"""List favorite pets if any."""
user_id = config.get("configurable", {}).get("user_id")
return ", ".join(user_to_pets.get(user_id, []))
tools = [update_favorite_pets, delete_favorite_pets, list_favorite_pets]
tool_node = ToolNode(tools)
도구 호출이 가능한 채팅 모델을 사용하려면 먼저 모델이 사용 가능한 도구들을 인식할 수 있도록 해야 한다. 이를 위해 ChatOpenAI
모델에서 .bind_tools
메서드를 호출한다.
from langchain_anthropic import ChatAnthropic
from langgraph.graph import StateGraph, MessagesState
from langgraph.prebuilt import ToolNode
model_with_tools = ChatOpenAI(model="gpt-4o-mini", temperature=0).bind_tools(tools)
ReAct Agent
ReAct 에이전트의 그래프 구현을 설정해 보자. 이 에이전트는 쿼리를 입력으로 받아들여, 쿼리를 해결할 수 있는 충분한 정보가 얻어질 때까지 도구를 반복적으로 호출한다. 우리는 방금 정의한 도구들과 함께 사전 구축된 ToolNode
와 OpenAI 모델을 사용한다.
from langgraph.graph import StateGraph, MessagesState, START, END
def should_continue(state: MessagesState):
messages = state["messages"]
last_message = messages[-1]
if last_message.tool_calls:
return "tools"
return END
def call_model(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("agent", call_model)
builder.add_node("tools", tool_node)
builder.add_edge(START, "agent")
builder.add_conditional_edges("agent", should_continue, ["tools", END])
builder.add_edge("tools", "agent")
graph = builder.compile()
from IPython.display import Image, display
try:
display(
Image(
graph.get_graph().draw_mermaid_png(
output_file_path="how-to-pass-config-to-tools.png"
)
)
)
except Exception:
pass
사용
from langchain_core.messages import HumanMessage
user_to_pets.clear() # Clear the state
print(f"User information prior to run: {user_to_pets}")
inputs = {"messages": [HumanMessage(content="my favorite pets are cats and dogs")]}
for chunk in graph.stream(
inputs, {"configurable": {"user_id": "123"}}, stream_mode="values"
):
chunk["messages"][-1].pretty_print()
print(f"User information after the run: {user_to_pets}")
User information prior to run: {}
================================ Human Message =================================
my favorite pets are cats and dogs
================================== Ai Message ==================================
Tool Calls:
update_favorite_pets (call_zYlpngJKNHBmeNHgMo6h58VK)
Call ID: call_zYlpngJKNHBmeNHgMo6h58VK
Args:
pets: ['cats', 'dogs']
================================= Tool Message =================================
Name: update_favorite_pets
null
================================== Ai Message ==================================
Your favorite pets have been updated to cats and dogs!
User information after the run: {'123': ['cats', 'dogs']}
from langchain_core.messages import HumanMessage
print(f"User information prior to run: {user_to_pets}")
inputs = {"messages": [HumanMessage(content="what are my favorite pets")]}
for chunk in graph.stream(
inputs, {"configurable": {"user_id": "123"}}, stream_mode="values"
):
chunk["messages"][-1].pretty_print()
print(f"User information prior to run: {user_to_pets}")
User information prior to run: {'123': ['cats', 'dogs']}
================================ Human Message =================================
what are my favorite pets
================================== Ai Message ==================================
Tool Calls:
list_favorite_pets (call_gzCGJanTSYTaqyTT1IkmRmZP)
Call ID: call_gzCGJanTSYTaqyTT1IkmRmZP
Args:
================================= Tool Message =================================
Name: list_favorite_pets
cats, dogs
================================== Ai Message ==================================
Your favorite pets are cats and dogs.
User information prior to run: {'123': ['cats', 'dogs']}
print(f"User information prior to run: {user_to_pets}")
inputs = {
"messages": [
HumanMessage(content="please forget what i told you about my favorite animals")
]
}
for chunk in graph.stream(
inputs, {"configurable": {"user_id": "123"}}, stream_mode="values"
):
chunk["messages"][-1].pretty_print()
print(f"User information prior to run: {user_to_pets}")
User information prior to run: {'123': ['cats', 'dogs']}
================================ Human Message =================================
please forget what i told you about my favorite animals
================================== Ai Message ==================================
Tool Calls:
delete_favorite_pets (call_qaYhQYgaEqQzmI0XuCDYYWyF)
Call ID: call_qaYhQYgaEqQzmI0XuCDYYWyF
Args:
================================= Tool Message =================================
Name: delete_favorite_pets
null
================================== Ai Message ==================================
I've forgotten your favorite animals. If you need anything else, just let me know!
User information prior to run: {}
LangGraph 참고 자료
- Controllability
- Persistence
- Memory
- Human-in-the-loop
- Streaming
- Tool calling
- Subgraphs
- State Management
- Other
- Prebuilt ReAct Agent
반응형