Создание агента GraphRAG с Neo4j и Milvus
Этот блог изначально был опубликован на Neo4j и перепубликован здесь с разрешения
Обзор
В этой статье подробно рассказывается, как создать агента GraphRAG с использованием графовой базы данных Neo4j и векторной базы данных Milvus. Этот агент сочетает возможности графовых баз данных и векторного поиска, чтобы предоставлять точные и релевантные ответы на запросы пользователей. В этом примере мы будем использовать LangGraph, Llama 3.1 8B с Ollama и GPT-4o.
Традиционные системы генерации с расширенным поиском (RAG) полагаются исключительно на векторные базы данных для извлечения релевантных документов. Наш подход идет дальше, включая Neo4j для фиксации связей между сущностями и концепциями, что обеспечивает более тонкое понимание информации. Мы хотим создать более надежную и информативную систему RAG, объединив эти две техники.
Создание агента RAG
Наш агент следует трем ключевым концепциям: маршрутизации, механизмам резервного переключения и самокоррекции. Эти принципы реализованы через серию компонентов LangGraph:
Маршрутизация – Специальный механизм маршрутизации решает, использовать ли векторную базу данных, граф знаний или их комбинацию в зависимости от запроса.
Резервное переключение – В ситуациях, когда первоначального извлечения недостаточно, агент переключается на веб-поиск с использованием Tavily.
Самокоррекция – Агент оценивает собственные ответы и пытается исправить галлюцинации или неточности.
Также у нас есть другие компоненты, такие как:
Извлечение – Мы используем Milvus, векторную базу данных с открытым исходным кодом и высокой производительностью, для хранения и извлечения фрагментов документов на основе семантического сходства с запросом пользователя.
Усиление графом – Neo4j используется для построения графа знаний из извлеченных документов, обогащая контекст связями и сущностями.
Интеграция LLM – Llama 3.1 8B, локальная LLM, используется для генерации ответов и оценки релевантности и точности извлеченной информации, в то время как GPT-4o используется для генерации Cypher, языка запросов, используемого Neo4j.
Архитектура GraphRAG
Архитектуру нашего агента GraphRAG можно представить как рабочий процесс с несколькими взаимосвязанными узлами:
Маршрутизация вопросов – Агент сначала анализирует вопрос, чтобы определить лучшую стратегию извлечения (векторный поиск, поиск по графу или оба варианта).
Извлечение – На основе решения маршрутизации релевантные документы извлекаются из Milvus, либо информация извлекается из графа Neo4j.
Генерация – LLM генерирует ответ, используя извлеченный контекст.
Оценка – Агент оценивает сгенерированный ответ на релевантность, точность и потенциальные галлюцинации.
Уточнение (при необходимости) – Если ответ считается неудовлетворительным, агент может уточнить поиск или попытаться исправить ошибки.
Примеры агентов
Чтобы продемонстрировать возможности наших LLM-агентов, рассмотрим два разных компонента: Graph Generation и Composite Agent .
Хотя полный код доступен внизу этой статьи, эти фрагменты помогут лучше понять, как эти агенты работают в рамках фреймворка LangChain.
Генерация графа
Этот компонент предназначен для улучшения процесса вопросов и ответов за счет использования возможностей Neo4j. Он отвечает на вопросы, используя знания, встроенные в графовую базу данных Neo4j. Вот как это работает:
1. GraphCypherQAChain – Позволяет LLM взаимодействовать с графовой базой данных Neo4j. Он использует LLM двумя способами:
cypher_llm– Этот экземпляр LLM отвечает за генерацию Cypher-запросов для извлечения релевантной информации из графа на основе вопроса пользователя.Валидация – Убеждается, что Cypher-запросы проверены, чтобы гарантировать их синтаксическую корректность.
2. Извлечение контекста – Проверенные запросы выполняются в графе Neo4j для извлечения необходимого контекста.
3. Генерация ответа – Языковая модель использует извлеченный контекст для генерации ответа на вопрос пользователя.
### Generate Cypher Query
llm = ChatOllama(model=local_llm, temperature=0)
# Chain
graph_rag_chain = GraphCypherQAChain.from_llm(
cypher_llm=llm,
qa_llm=llm,
validate_cypher=True,
graph=graph,
verbose=True,
return_intermediate_steps=True,
return_direct=True,
)
# Run
question = "agent memory"
generation = graph_rag_chain.invoke({"query": question})
Этот компонент позволяет RAG-системе подключаться к Neo4j, что может помочь предоставлять более полные и точные ответы.
Композитный агент, граф и вектор 🪄
Именно здесь происходит магия: наш агент может объединять результаты из Milvus и Neo4j, обеспечивая лучшее понимание информации и приводя к более точным и нюансированным ответам. Вот как это работает:
Промпты – Мы определяем промпт, который инструктирует LLM использовать контекст как из Milvus, так и из Neo4j, чтобы ответить на вопрос.
Извлечение – Агент извлекает релевантную информацию из Milvus (с использованием векторного поиска) и Neo4j (с использованием Graph Generation).
Генерация ответа – Llama 3.1 8B обрабатывает промпт и генерирует краткий ответ, используя объединенные знания из векторной и графовой баз данных с помощью композитной цепочки.
### Composite Vector + Graph Generations
cypher_prompt = PromptTemplate(
template="""You are an expert at generating Cypher queries for Neo4j.
Use the following schema to generate a Cypher query that answers the given question.
Make the query flexible by using case-insensitive matching and partial string matching where appropriate.
Focus on searching paper titles as they contain the most relevant information.
Schema:
{schema}
Question: {question}
Cypher Query:""",
input_variables=["schema", "question"],
)
# QA prompt
qa_prompt = PromptTemplate(
template="""You are an assistant for question-answering tasks.
Use the following Cypher query results to answer the question. If you don't know the answer, just say that you don't know.
Use three sentences maximum and keep the answer concise. If topic information is not available, focus on the paper titles.
Question: {question}
Cypher Query: {query}
Query Results: {context}
Answer:""",
input_variables=["question", "query", "context"],
)
llm = ChatOpenAI(model="gpt-4o", temperature=0)
# Chain
graph_rag_chain = GraphCypherQAChain.from_llm(
cypher_llm=llm,
qa_llm=llm,
validate_cypher=True,
graph=graph,
verbose=True,
return_intermediate_steps=True,
return_direct=True,
cypher_prompt=cypher_prompt,
qa_prompt=qa_prompt,
)
Давайте посмотрим на результаты нашего поиска, объединяющего сильные стороны графовых и векторных баз данных для улучшения обнаружения научных статей.
Начнем с нашего графового поиска с использованием Neo4j:
# Example input data
question = "What paper talks about Multi-Agent?"
generation = graph_rag_chain.invoke({"query": question})
print(generation)
> Вход в новую цепочку GraphCypherQAChain...
Сгенерированный Cypher:
cypher
MATCH (p:Paper)
WHERE toLower(p.title) CONTAINS toLower("Multi-Agent")
RETURN p.title AS PaperTitle, p.summary AS Summary, p.url AS URL
> Цепочка завершена.
{'query': 'Какая статья рассказывает о Multi-Agent?', 'result': [{'PaperTitle': 'Collaborative Multi-Agent, Multi-Reasoning-Path (CoMM) Prompting Framework', 'Summary': 'В этой работе мы стремимся расширить верхнюю границу способности LLM к рассуждению, предлагая совместную многоагентную, многопутевую для рассуждений (CoMM) prompting framework. В частности, мы побуждаем LLM играть разные роли в команде по решению задач и поощряем разных агентов, играющих роли, совместно решать целевую задачу. В частности, мы обнаруживаем, что применение разных путей рассуждения для разных ролей является эффективной стратегией реализации подходов few-shot prompting в многоагентных сценариях. Эмпирические результаты демонстрируют эффективность предложенных методов на двух научных задачах уровня колледжа по сравнению с конкурентными базовыми подходами. Наш дальнейший анализ показывает необходимость побуждать LLM играть разные роли или экспертов независимо.', 'URL': 'https://github.com/amazon-science/comm-prompt'}]
Графовый поиск отлично справляется с поиском связей и метаданных. Он может быстро находить статьи по названиям, авторам или заранее заданным категориям, предоставляя структурированное представление данных.
Далее мы переходим к нашему векторному поиску, чтобы получить иной взгляд:
# Example input data
question = "What paper talks about Multi-Agent?"
# Get vector + graph answers
docs = retriever.invoke(question)
vector_context = rag_chain.invoke({"context": docs, "question": question})
> В статье обсуждается "Adaptive In-conversation Team Building for Language Model Agents" и говорится о Multi-Agent. В ней представлена новая адаптивная парадигма формирования команд, которая предлагает гибкое решение для создания команд LLM-агентов, способных эффективно решать сложные задачи. Подход, называемый Captain Agent, динамически формирует команды и управляет ими на каждом этапе процесса решения задачи, используя вложенные групповые беседы и рефлексию, чтобы обеспечить разнообразную экспертизу и предотвратить стереотипные ответы.
Векторный поиск действительно хорошо понимает контекст и семантическое сходство. Он может находить статьи, концептуально связанные с запросом, даже если они явно не содержат поисковые термины.
Наконец, мы объединяем оба метода поиска:
Это ключевая часть нашего RAG-агента, позволяющая использовать как векторные, так и графовые базы данных.
composite_chain = prompt | llm | StrOutputParser()
answer = composite_chain.invoke({"question": question, "context": vector_context, "graph_context": graph_context})
print(answer)
> Статья "Collaborative Multi-Agent, Multi-Reasoning-Path (CoMM) Prompting Framework" рассказывает о Multi-Agent. В ней предлагается фреймворк, который побуждает LLM играть разные роли в команде по решению задач и поощряет разных агентов, играющих роли, совместно решать целевую задачу. В статье представлены эмпирические результаты, демонстрирующие эффективность предложенных методов на двух научных задачах уровня колледжа.
Интегрируя графовый и векторный поиск, мы используем сильные стороны обоих подходов. Графовый поиск обеспечивает точность и навигацию по структурированным связям, а векторный поиск добавляет глубину за счет семантического понимания.
Этот комбинированный метод предлагает несколько преимуществ:
Улучшенный recall: Он находит релевантные статьи, которые могли бы быть пропущены при использовании любого из методов по отдельности.
Расширенный контекст: Он обеспечивает более нюансированное понимание того, как статьи связаны друг с другом.
Гибкость: Он может адаптироваться к разным типам запросов — от поиска по конкретным ключевым словам до более широких концептуальных исследований.
Подведем итог
В этой статье блога мы показали, как создать GraphRAG Agent с использованием Neo4j и Milvus. Объединяя сильные стороны графовых баз данных и векторного поиска, этот агент предоставляет точные и релевантные ответы на запросы пользователей.
Архитектура нашего RAG-агента с выделенной маршрутизацией, механизмами резервного варианта и возможностями самокоррекции делает его надежным и устойчивым. Примеры компонентов Graph Generation и Composite Agent демонстрируют, как этот агент может использовать как векторные, так и графовые базы данных, чтобы предоставлять исчерпывающие и нюансированные ответы.
Надеемся, это руководство было полезным и вдохновит вас изучить возможности объединения графовых баз данных и векторного поиска в ваших собственных проектах.
Текущий код доступен на GitHub.
Следуйте за нами
Читать далее

Announcing the General Availability of Single Sign-On (SSO) on Zilliz Cloud
SSO is GA on Zilliz Cloud, delivering the enterprise-grade identity management capabilities your teams need to deploy vectorDB with confidence.

Why Not All VectorDBs Are Agent-Ready
Explore why choosing the right vector database is critical for scaling AI agents, and why traditional solutions fall short in production.

8 Latest RAG Advancements Every Developer Should Know
Explore eight advanced RAG variants that can solve real problems you might be facing: slow retrieval, poor context understanding, multimodal data handling, and resource optimization.




