⚡ 그래프로 언어 에이전트 구축 ⚡
메모
JS 버전을 찾고 계십니까? 여기를 클릭하세요(JS 문서).
LangGraph는 에이전트 및 다중 에이전트 워크플로우를 생성하는 데 사용되는 LLM을 사용하여 상태 저장 다중 행위자 애플리케이션을 구축하기 위한 라이브러리입니다. 다른 LLM 프레임워크와 비교하여 주기, 제어 가능성 및 지속성이라는 핵심 이점을 제공합니다. LangGraph를 사용하면 대부분의 에이전트 아키텍처에 필수적인 주기와 관련된 흐름을 정의하여 DAG 기반 솔루션과 차별화할 수 있습니다. 매우 낮은 수준의 프레임워크로서 애플리케이션의 흐름과 상태 모두에 대한 세밀한 제어를 제공하며, 이는 안정적인 에이전트를 만드는 데 중요합니다. 또한 LangGraph에는 지속성이 내장되어 있어 고급 인간 참여형(Human-In-The-Loop) 및 메모리 기능을 사용할 수 있습니다.
LangGraph는 Pregel과 Apache Beam에서 영감을 받았습니다. 공개 인터페이스는 NetworkX에서 영감을 얻었습니다. LangGraph는 LangChain을 만든 LangChain Inc에 의해 제작되었지만 LangChain 없이도 사용할 수 있습니다.
LangGraph Platform은 LangGraph 에이전트를 배포하기 위한 인프라입니다. 이는 오픈 소스 LangGraph 프레임워크를 기반으로 구축된 에이전트 애플리케이션을 프로덕션에 배포하기 위한 상용 솔루션입니다. LangGraph 플랫폼은 LangGraph 응용 프로그램의 개발, 배포, 디버깅 및 모니터링을 지원하기 위해 함께 작동하는 여러 구성 요소로 구성됩니다. LangGraph 서버(API), LangGraph SDK(API용 클라이언트), LangGraph CLI(서버 구축을 위한 명령줄 도구) ), LangGraph Studio(UI/디버거),
LangGraph에 대해 자세히 알아보려면 여기에서 무료로 제공되는 첫 번째 LangChain Academy 과정인 LangGraph 소개를 확인하세요.
LangGraph 플랫폼은 오픈 소스 LangGraph 프레임워크를 기반으로 구축된 에이전트 애플리케이션을 프로덕션에 배포하기 위한 상용 솔루션입니다. 다음은 LangGraph 플랫폼이 해결하는 복잡한 배포에서 발생하는 몇 가지 일반적인 문제입니다.
pip install -U langgraph
LangGraph의 핵심 개념 중 하나는 상태입니다. 각 그래프 실행은 실행 시 그래프의 노드 간에 전달되는 상태를 생성하며, 각 노드는 실행 후 반환 값으로 이 내부 상태를 업데이트합니다. 그래프가 내부 상태를 업데이트하는 방식은 선택한 그래프 유형이나 사용자 정의 함수에 의해 정의됩니다.
검색 도구를 사용할 수 있는 에이전트의 간단한 예를 살펴보겠습니다.
pip install langchain-anthropic
export ANTHROPIC_API_KEY=sk-...
선택적으로, 최고의 관찰성을 위해 LangSmith를 설정할 수 있습니다.
export LANGSMITH_TRACING=true
export LANGSMITH_API_KEY=lsv2_sk_...
from typing import Annotated , Literal , TypedDict
from langchain_core . messages import HumanMessage
from langchain_anthropic import ChatAnthropic
from langchain_core . tools import tool
from langgraph . checkpoint . memory import MemorySaver
from langgraph . graph import END , START , StateGraph , MessagesState
from langgraph . prebuilt import ToolNode
# Define the tools for the agent to use
@ tool
def search ( query : str ):
"""Call to surf the web."""
# This is a placeholder, but don't tell the LLM that...
if "sf" in query . lower () or "san francisco" in query . lower ():
return "It's 60 degrees and foggy."
return "It's 90 degrees and sunny."
tools = [ search ]
tool_node = ToolNode ( tools )
model = ChatAnthropic ( model = "claude-3-5-sonnet-20240620" , temperature = 0 ). bind_tools ( tools )
# Define the function that determines whether to continue or not
def should_continue ( state : MessagesState ) -> Literal [ "tools" , END ]:
messages = state [ 'messages' ]
last_message = messages [ - 1 ]
# If the LLM makes a tool call, then we route to the "tools" node
if last_message . tool_calls :
return "tools"
# Otherwise, we stop (reply to the user)
return END
# Define the function that calls the model
def call_model ( state : MessagesState ):
messages = state [ 'messages' ]
response = model . invoke ( messages )
# We return a list, because this will get added to the existing list
return { "messages" : [ response ]}
# Define a new graph
workflow = StateGraph ( MessagesState )
# Define the two nodes we will cycle between
workflow . add_node ( "agent" , call_model )
workflow . add_node ( "tools" , tool_node )
# Set the entrypoint as `agent`
# This means that this node is the first one called
workflow . add_edge ( START , "agent" )
# We now add a conditional edge
workflow . add_conditional_edges (
# First, we define the start node. We use `agent`.
# This means these are the edges taken after the `agent` node is called.
"agent" ,
# Next, we pass in the function that will determine which node is called next.
should_continue ,
)
# We now add a normal edge from `tools` to `agent`.
# This means that after `tools` is called, `agent` node is called next.
workflow . add_edge ( "tools" , 'agent' )
# Initialize memory to persist state between graph runs
checkpointer = MemorySaver ()
# Finally, we compile it!
# This compiles it into a LangChain Runnable,
# meaning you can use it as you would any other runnable.
# Note that we're (optionally) passing the memory when compiling the graph
app = workflow . compile ( checkpointer = checkpointer )
# Use the Runnable
final_state = app . invoke (
{ "messages" : [ HumanMessage ( content = "what is the weather in sf" )]},
config = { "configurable" : { "thread_id" : 42 }}
)
final_state [ "messages" ][ - 1 ]. content
"Based on the search results, I can tell you that the current weather in San Francisco is:nnTemperature: 60 degrees FahrenheitnConditions: FoggynnSan Francisco is known for its microclimates and frequent fog, especially during the summer months. The temperature of 60°F (about 15.5°C) is quite typical for the city, which tends to have mild temperatures year-round. The fog, often referred to as "Karl the Fog" by locals, is a characteristic feature of San Francisco's weather, particularly in the mornings and evenings.nnIs there anything else you'd like to know about the weather in San Francisco or any other location?"
이제 동일한 "thread_id"
전달하면 대화 컨텍스트가 저장된 상태(예: 저장된 메시지 목록)를 통해 유지됩니다.
final_state = app . invoke (
{ "messages" : [ HumanMessage ( content = "what about ny" )]},
config = { "configurable" : { "thread_id" : 42 }}
)
final_state [ "messages" ][ - 1 ]. content
"Based on the search results, I can tell you that the current weather in New York City is:nnTemperature: 90 degrees Fahrenheit (approximately 32.2 degrees Celsius)nConditions: SunnynnThis weather is quite different from what we just saw in San Francisco. New York is experiencing much warmer temperatures right now. Here are a few points to note:nn1. The temperature of 90°F is quite hot, typical of summer weather in New York City.n2. The sunny conditions suggest clear skies, which is great for outdoor activities but also means it might feel even hotter due to direct sunlight.n3. This kind of weather in New York often comes with high humidity, which can make it feel even warmer than the actual temperature suggests.nnIt's interesting to see the stark contrast between San Francisco's mild, foggy weather and New York's hot, sunny conditions. This difference illustrates how varied weather can be across different parts of the United States, even on the same day.nnIs there anything else you'd like to know about the weather in New York or any other location?"
ChatAnthropic
사용합니다. 참고: 호출할 수 있는 도구가 있음을 모델이 알고 있는지 확인해야 합니다. .bind_tools()
메서드를 사용하여 LangChain 도구를 OpenAI 도구 호출 형식으로 변환하면 이 작업을 수행할 수 있습니다.MessagesState
)를 전달하여 그래프( StateGraph
)를 초기화합니다.MessagesState
는 LangChain Message
개체 목록과 각 노드의 업데이트를 상태에 병합하기 위한 논리라는 하나의 속성을 갖는 사전 구축된 상태 스키마입니다.우리에게 필요한 두 가지 주요 노드가 있습니다:
agent
노드: 취할 조치(있는 경우)를 결정합니다.tools
노드: 에이전트가 작업을 수행하기로 결정하면 이 노드가 해당 작업을 실행합니다. 먼저 그래프 실행을 위한 진입점인 agent
노드를 설정해야 합니다.
그런 다음 하나의 일반 모서리와 하나의 조건부 모서리를 정의합니다. 조건부 가장자리는 대상이 그래프 상태( MessageState
)의 내용에 따라 달라짐을 의미합니다. 우리의 경우 에이전트(LLM)가 결정할 때까지 목적지를 알 수 없습니다.
.invoke()
, .stream()
및 .batch()
호출을 자동으로 활성화합니다.MemorySaver
사용합니다. LangGraph는 입력 메시지를 내부 상태에 추가한 다음 상태를 진입점 노드 "agent"
에 전달합니다.
"agent"
노드가 실행되어 채팅 모델을 호출합니다.
채팅 모델은 AIMessage
를 반환합니다. LangGraph는 이를 상태에 추가합니다.
그래프는 AIMessage
에 더 이상 tool_calls
없을 때까지 다음 단계를 순환합니다.
AIMessage
에 tool_calls
가 있으면 "tools"
노드가 실행됩니다."agent"
노드가 다시 실행되고 AIMessage
반환합니다. 특수한 END
값까지 실행이 진행되어 최종 상태를 출력합니다. 결과적으로 모든 채팅 메시지 목록이 출력됩니다.
기여 방법에 대한 자세한 내용은 여기를 참조하세요.