Введение в LangGraph
LangGraph — это мощный фреймворк от LangChain, предназначенный для создания многопользовательских приложений с LLM (Large Language Models). Он предоставляет структуру и инструменты, необходимые для создания сложных ИИ-агентов с помощью графового подхода.
Представьте себе LangGraph как чертёжный стол архитектора — он даёт нам инструменты для проектирования того, как наш агент будет думать и действовать.
Ключевые особенности:
* Управление состоянием: сохранение постоянного состояния во время взаимодействий.
* Гибкая маршрутизация: определение сложных потоков между компонентами.
* Персистентность: сохранение и возобновление рабочих процессов.
* Визуализация: просмотр и понимание структуры вашего агента.
В этом руководстве мы продемонстрируем LangGraph, создав многоступенчатый конвейер анализа текста, который обрабатывает текст в три этапа:
1. Классификация текста: категоризация входного текста по заранее определённым категориям.
2. Извлечение сущностей: идентификация ключевых сущностей из текста.
3. Суммирование текста: генерация краткого содержания входного текста.
Настройка среды
Перед погружением в код давайте настроим нашу среду разработки.
Установка
“`
!pip install langgraph langchain langchain-openai python-dotenv
“`
Настройка API-ключей
Нам понадобится API-ключ OpenAI для использования их моделей. Если у вас ещё нет ключа, вы можете получить его на сайте https://platform.openai.com/signup.
Тестирование настройки
Давайте убедимся, что наша среда работает правильно, создав простой тест с моделью OpenAI:
“`
from langchain_openai import ChatOpenAI
Инициализируем экземпляр ChatOpenAI
llm = ChatOpenAI(model=”gpt-4o-mini”)
Тестируем настройку
response = llm.invoke(“Hello! Are you working?”)
print(response.content)
“`
Создание конвейера анализа текста
Теперь давайте импортируем необходимые пакеты для нашего конвейера анализа текста с помощью LangGraph:
“`
import os
from typing import TypedDict, List, Annotated
from langgraph.graph import StateGraph, END
from langchain.prompts import PromptTemplate
from langchain_openai import ChatOpenAI
from langchain.schema import HumanMessage
from langchain_core.runnables.graph import MermaidDrawMethod
from IPython.display import display, Image
“`
Проектирование памяти нашего агента
Как и человеческому интеллекту требуется память, нашему агенту нужен способ отслеживания информации. Мы создаём это с помощью TypedDict для определения структуры нашего состояния:
“`
class State(TypedDict):
text: str
classification: str
entities: List[str]
summary: str
“`
Создание основных возможностей нашего агента
Теперь мы создадим фактические навыки, которые будет использовать наш агент. Каждая из этих возможностей реализована как функция, выполняющая определённый тип анализа.
1. Узел классификации
“`
def classification_node(state: State):
”’Classify the text into one of the categories: News, Blog, Research, or Other”’
prompt = PromptTemplate(
input_variables=[“text”],
template=”Classify the following text into one of the categories: News, Blog, Research, or Other.\n\nText:{text}\n\nCategory:”
)
message = HumanMessage(content=prompt.format(text=state[“text”]))
classification = llm.invoke([message]).content.strip()
return {“classification”: classification}
“`
2. Узел извлечения сущностей
“`
def entityextractionnode(state: State):
”’Extract all the entities (Person, Organization, Location) from the text”’
prompt = PromptTemplate(
input_variables=[“text”],
template=”Extract all the entities (Person, Organization, Location) from the following text. Provide the result as a comma-separated list.\n\nText:{text}\n\nEntities:”
)
message = HumanMessage(content=prompt.format(text=state[“text”]))
entities = llm.invoke([message]).content.strip().split(“, “)
return {“entities”: entities}
“`
3. Узел суммирования
“`
def summarization_node(state: State):
”’Summarize the text in one short sentence”’
prompt = PromptTemplate(
input_variables=[“text”],
template=”Summarize the following text in one short sentence.\n\nText:{text}\n\nSummary:”
)
message = HumanMessage(content=prompt.format(text=state[“text”]))
summary = llm.invoke([message]).content.strip()
return {“summary”: summary}
“`
Объединение всего вместе
Теперь наступает самая интересная часть — соединение этих возможностей в согласованную систему с помощью LangGraph:
“`
Create our StateGraph
workflow = StateGraph(State)
Add nodes to the graph
workflow.addnode(“classificationnode”, classification_node)
workflow.addnode(“entityextraction”, entityextractionnode)
workflow.addnode(“summarization”, summarizationnode)
Add edges to the graph
workflow.setentrypoint(“classification_node”) # Set the entry point of the graph
workflow.addedge(“classificationnode”, “entity_extraction”)
workflow.addedge(“entityextraction”, “summarization”)
workflow.add_edge(“summarization”, END)
Compile the graph
app = workflow.compile()
“`
Структура рабочего процесса: наш конвейер следует этому пути:
classificationnode → entityextraction → summarization → END
Тестирование нашего агента
Теперь, когда мы создали нашего агента, давайте посмотрим, как он работает с реальным примером текста:
“`
sample_text = “”” OpenAI has announced the GPT-4 model, which is a large multimodal model that exhibits human-level performance on various professional benchmarks. It is developed to improve the alignment and safety of AI systems. Additionally, the model is designed to be more efficient and scalable than its predecessor, GPT-3. The GPT-4 model is expected to be released in the coming months and will be available to the public for research and development purposes. “””
stateinput = {“text”: sampletext}
result = app.invoke(state_input)
print(“Classification:”, result[“classification”])
print(“\nEntities:”, result[“entities”])
print(“\nSummary:”, result[“summary”])
“`
Понимание силы согласованной обработки
Что делает этот результат особенно впечатляющим, так это не просто отдельные выходные данные — это то, как каждый шаг опирается на другие для создания полного понимания текста.
Классификация предоставляет контекст, который помогает сформировать наше понимание типа текста. Извлечение сущностей идентифицирует важные имена и понятия. Суммирование дистиллирует суть документа.
Это отражает человеческое понимание прочитанного, где мы естественным образом формируем понимание того, какой это текст, отмечаем важные имена и понятия и формируем мысленное резюме — и всё это поддерживая отношения между этими различными аспектами понимания.
Попробуйте с вашим текстом
Теперь давайте попробуем наш конвейер с другим примером текста:
“`
Replace this with your own text to analyze your_text = “”” The recent advancements in quantum computing have opened new possibilities for cryptography and data security. Researchers at MIT and Google have demonstrated quantum algorithms that could potentially break current encryption methods. However, they are also developing new quantum-resistant encryption techniques to protect data in the future. “””
Process the text through our pipeline yourresult = app.invoke({“text”: yourtext}) print(“Classification:”, your_result[“classification”])
print(“\nEntities:”, your_result[“entities”])
print(“\nSummary:”, your_result[“summary”])
“`
Добавление дополнительных возможностей (расширенный уровень)
Одним из мощных аспектов LangGraph является то, насколько легко мы можем расширить нашего агента новыми возможностями. Давайте добавим в наш конвейер узел анализа тональности:
“`
First, let’s update our State to include sentiment
class EnhancedState(TypedDict):
text: str
classification: str
entities: List[str]
summary: str
sentiment: str
“`
Тестирование расширенного агента
“`
Try the enhanced pipeline with the same text
enhancedresult = enhancedapp.invoke({“text”: sample_text})
print(“Classification:”, enhanced_result[“classification”])
print(“\nEntities:”, enhanced_result[“entities”])
print(“\nSummary:”, enhanced_result[“summary”])
print(“\nSentiment:”, enhanced_result[“sentiment”])
“`
Добавление условных рёбер (расширенная логика)
Почему условные рёбра?
До сих пор наш граф следовал фиксированному линейному пути: classificationnode → entityextraction → summarization → (sentiment)
Но в реальных приложениях мы часто хотим запускать определённые шаги только при необходимости. Например:
* Извлекать сущности только если текст является новостью или исследовательской статьёй.
* Пропускать суммирование, если текст очень короткий.
* Добавлять пользовательскую обработку для блогов.
LangGraph упрощает это с помощью условных рёбер — логических вентилей, которые динамически маршрутизируют выполнение на основе данных в текущем состоянии.
Создание функции маршрутизации
“`
Route after classification
def routeafterclassification(state: EnhancedState) -> str:
category = state[“classification”].lower() # returns: “news”, “blog”, “research”, “other”
return category in [“news”, “research”]
“`
Определение условного графа
“`
from langgraph.graph import StateGraph, END
conditional_workflow = StateGraph(EnhancedState)
Add nodes
conditionalworkflow.addnode(“classificationnode”, classificationnode)
conditionalworkflow.addnode(“entityextraction”, entityextraction_node)
conditionalworkflow.addnode(“summarization”, summarization_node)
conditionalworkflow.addnode(“sentimentanalysis”, sentimentnode)
Set entry point
conditionalworkflow.setentrypoint(“classificationnode”)
Add conditional edge
conditionalworkflow.addconditionaledges(“classificationnode”, routeafterclassification, path_map={
True: “entity_extraction”,
False: “summarization”
})
Add remaining static edges
conditionalworkflow.addedge(“entity_extraction”, “summarization”)
conditionalworkflow.addedge(“summarization”, “sentiment_analysis”)
conditionalworkflow.addedge(“sentiment_analysis”, END)
Compile
conditionalapp = conditionalworkflow.compile()
“`
Тестирование условного конвейера
“`
test_text = “””
OpenAI released the GPT-4 model with enhanced performance on academic and professional tasks. It’s seen as a major breakthrough in alignment and reasoning capabilities.
“””
result = conditionalapp.invoke({“text”: testtext})
print(“Classification:”, result[“classification”])
print(“Entities:”, result.get(“entities”, “Skipped”))
print(“Summary:”, result[“summary”])
print(“Sentiment:”, result[“sentiment”])
“`
Заключение
В этом руководстве мы:
* Исследовали концепции LangGraph и его графовый подход.
* Создали конвейер обработки текста с классификацией, извлечением сущностей и суммированием.
* Расширили наш конвейер дополнительными возможностями.
* Представили условные рёбра для динамического управления потоком на основе результатов классификации.
* Визуализировали наш рабочий процесс.
* Протестировали нашего агента на реальных примерах текста.
LangGraph предоставляет мощную основу для создания ИИ-агентов, моделируя их как графы возможностей. Этот подход упрощает проектирование, модификацию и расширение сложных ИИ-систем.
1. Какие ключевые особенности LangGraph делают его подходящим инструментом для создания многопользовательских приложений с LLM?
Ответ: ключевые особенности LangGraph включают управление состоянием, гибкую маршрутизацию, персистентность и визуализацию. Эти функции позволяют сохранять состояние взаимодействий, определять сложные потоки между компонентами, сохранять и возобновлять рабочие процессы, а также просматривать и понимать структуру агента.
2. Какие этапы включает в себя конвейер анализа текста, созданный с помощью LangGraph, и какие задачи выполняются на каждом этапе?
Ответ: конвейер анализа текста включает в себя три этапа: классификация текста (категоризация входного текста по заранее определённым категориям), извлечение сущностей (идентификация ключевых сущностей из текста) и суммирование текста (генерация краткого содержания входного текста).
3. Как в LangGraph реализуется управление потоком выполнения в зависимости от результатов классификации текста?
Ответ: в LangGraph управление потоком выполнения реализуется с помощью условных рёбер. Эти логические вентили позволяют динамически маршрутизировать выполнение на основе данных в текущем состоянии. Например, можно настроить извлечение сущностей только для новостей или исследовательских статей, пропускать суммирование для коротких текстов или добавлять пользовательскую обработку для блогов.
4. Какие дополнительные возможности можно добавить в конвейер анализа текста с помощью LangGraph?
Ответ: в конвейер анализа текста можно добавить дополнительные возможности, такие как анализ тональности. Для этого необходимо обновить структуру состояния, добавив соответствующее поле, и добавить в граф соответствующий узел.
5. Какие преимущества предоставляет графовый подход в LangGraph для проектирования и расширения сложных ИИ-систем?
Ответ: графовый подход в LangGraph упрощает проектирование, модификацию и расширение сложных ИИ-систем. Он позволяет моделировать агентов как графы возможностей, что облегчает управление потоком выполнения, добавление новых функций и расширение системы.