⚡ Создание языковых агентов в виде графиков ⚡
Примечание
Ищете версию JS? Нажмите здесь (документация JS).
LangGraph — это библиотека для создания многоакторных приложений с отслеживанием состояния и LLM, используемая для создания агентных и многоагентных рабочих процессов. По сравнению с другими структурами LLM, он предлагает следующие основные преимущества: циклы, управляемость и постоянство. LangGraph позволяет определять потоки, включающие циклы, необходимые для большинства агентных архитектур, что отличает их от решений на основе DAG. Будучи инфраструктурой очень низкого уровня, он обеспечивает детальный контроль над потоком и состоянием вашего приложения, что имеет решающее значение для создания надежных агентов. Кроме того, LangGraph включает в себя встроенную функцию сохранения, обеспечивающую расширенные функции управления человеком и памяти.
LangGraph вдохновлен Pregel и Apache Beam. Публичный интерфейс черпает вдохновение из NetworkX. LangGraph создан компанией LangChain Inc, создателями LangChain, но может использоваться без LangChain.
Платформа LangGraph — это инфраструктура для развертывания агентов LangGraph. Это коммерческое решение для развертывания агентских приложений в рабочей среде, созданное на базе платформы LangGraph с открытым исходным кодом. Платформа LangGraph состоит из нескольких компонентов, которые работают вместе для поддержки разработки, развертывания, отладки и мониторинга приложений LangGraph: Сервер LangGraph (API), LangGraph SDK (клиенты для API), LangGraph CLI (инструмент командной строки для создания сервера). ), LangGraph Studio (пользовательский интерфейс/отладчик),
Чтобы узнать больше о LangGraph, посетите наш первый курс Академии LangChain «Введение в LangGraph» , который доступен бесплатно здесь.
LangGraph Platform — это коммерческое решение для развертывания агентских приложений в рабочей среде, созданное на базе платформы 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
в качестве нашего LLM. ПРИМЕЧАНИЕ. Нам необходимо убедиться, что модель знает, что у нее есть эти инструменты, доступные для вызова. Мы можем сделать это, преобразовав инструменты LangChain в формат для вызова инструментов OpenAI с помощью метода .bind_tools()
.StateGraph
), передавая схему состояний (в нашем случае MessagesState
)MessagesState
— это заранее созданная схема состояния, которая имеет один атрибут — список объектов Message
LangChain, а также логику для объединения обновлений с каждого узла в состояние.Нам нужны два основных узла:
agent
: отвечает за принятие решения о том, какие действия предпринять (если таковые имеются).tools
, который вызывает инструменты: если агент решает выполнить действие, этот узел затем выполнит это действие. Во-первых, нам нужно установить точку входа для выполнения графа — узел agent
.
Затем мы определяем одно нормальное и одно условное ребро. Условное ребро означает, что пункт назначения зависит от содержимого состояния графа ( MessageState
). В нашем случае пункт назначения неизвестен, пока не примет решение агент (LLM).
.invoke()
, .stream()
и .batch()
с вашими входными данными.MemorySaver
— простой контрольный указатель в памяти. LangGraph добавляет входное сообщение во внутреннее состояние, затем передает состояние узлу точки входа "agent"
.
Узел "agent"
выполняется, вызывая модель чата.
Модель чата возвращает AIMessage
. LangGraph добавляет это в состояние.
График циклически выполняет следующие шаги до тех пор, пока в AIMessage
больше не останется tool_calls
:
AIMessage
tool_calls
, выполняется узел "tools"
"agent"
выполняется снова и возвращает AIMessage
Выполнение переходит к специальному значению END
и выводит конечное состояние. И в результате мы получаем список всех наших сообщений чата.
Дополнительную информацию о том, как внести свой вклад, можно найти здесь.