Вопрос или проблема
import logging
from neo4j import GraphDatabase
from neo4j_graphrag.indexes import upsert_vector
import openai
from PyPDF2 import PdfReader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from dotenv import load_dotenv
load_dotenv()
# Настройка логирования как в файл, так и в консоль
logging.basicConfig(
level=logging.INFO, # Уровень логирования
format="%(asctime)s - %(levelname)s - %(message)s", # Формат логов
handlers=[
logging.FileHandler("pdf_processing.log"), # Логировать в файл
logging.StreamHandler() # Логировать в консоль
]
)
URI = URI
AUTH = ("neo4j", "PWD")
# Установите здесь свой ключ API OpenAI
openai.api_key = openaikey
# Подключение к базе данных Neo4j
driver = GraphDatabase.driver(URI, auth=AUTH)
# Функция для извлечения текста из PDF-файла
def get_pdf_text(pdf_path):
logging.info(f"Начато извлечение текста из PDF: {pdf_path}")
text = ""
pdf_reader = PdfReader(pdf_path)
for page_num, page in enumerate(pdf_reader.pages):
extracted_text = page.extract_text() if page.extract_text() else ''
text += extracted_text
logging.info(f"Извлечён текст со страницы {page_num + 1}: {len(extracted_text)} символов")
logging.info(f"Завершено извлечение текста, общая длина: {len(text)} символов")
return text
# Функция для разбиения извлечённого текста на части
def get_text_chunks(text, chunk_size=1000, chunk_overlap=200):
logging.info(f"Начато разбиение текста на части, размер части: {chunk_size}, перекрытие: {chunk_overlap}")
text_splitter = RecursiveCharacterTextSplitter(chunk_size=chunk_size, chunk_overlap=chunk_overlap)
chunks = text_splitter.split_text(text)
logging.info(f"Завершено разбиение текста. Всего создано частей: {len(chunks)}")
return chunks
# Функция для генерации текстового эмбеддинга для данной части
def get_text_embedding(text_chunk):
logging.info(f"Генерация эмбеддинга для части размером {len(text_chunk)}")
response = openai.Embedding.create(
input=text_chunk,
model="text-embedding-ada-002" # Эмбеддинг-модель OpenAI (1536-мерный вектор)
)
embedding = response['data'][0]['embedding'] # Извлечение векторного представления
logging.info(f"Сгенерирован вектор эмбеддинга длиной {len(embedding)}")
return embedding
# Функция для обработки PDF, разбиения текста на части, генерации эмбеддингов и обновления векторов в Neo4j
def process_pdf_and_upsert_vectors(pdf_path):
logging.info(f"Начата обработка PDF: {pdf_path}")
# Этап 1: Извлечение текста из PDF
text = get_pdf_text(pdf_path)
# Этап 2: Разбиение текста на части
chunks = get_text_chunks(text)
# Этап 3: Проход по каждой части и генерация эмбеддингов
for i, chunk in enumerate(chunks):
embedding = get_text_embedding(chunk)
# Этап 4: Обновление вектора в Neo4j (node_id может быть динамическим)
logging.info(f"Обновление вектора для части {i + 1}")
upsert_vector(
driver,
node_id=i + 1, # Предполагается, что каждой части соответствует новый узел
embedding_property="vectorProperty",
vector=embedding,
)
logging.info(f"Обновлён вектор для узла {i + 1}")
logging.info(f"Завершена обработка PDF: {pdf_path}")
# Пример использования:
process_pdf_and_upsert_vectors(pdf_path)
Я прочитал официальную документацию Neo4j и попытался реализовать RAG, но не получаю никаких результатов. Я также пытался извлечь текст из PDF-документа, разбить его на части и затем обновить в Neo4j, но всё равно результаты отсутствуют, и в моем рабочем пространстве Neo4j нет эмбеддингов.
Может кто-то помочь мне решить эту проблему, чтобы я мог вставить свои эмбеддинги в Neo4j и затем выполнить векторный поиск на основе запроса пользователя!
Ответ или решение
Введение
Вы столкнулись с проблемой вставки векторов в Neo4j из PDF-документа с использованием библиотеки Neo4j GraphRAG. Несмотря на то, что вы следовали инструкциям из официальной документации, данные не отображаются в вашей рабочей области Neo4j. В данном ответе мы рассмотрим возможные причины этой проблемы и предложим шаги для их решения.
Общая структура кода
Прежде всего, давайте кратко рассмотрим основные этапы вашего кода:
- Извлечение текста из PDF.
- Разделение текста на фрагменты.
- Генерация векторов для каждого фрагмента текста.
- Вставка векторов в базу данных Neo4j.
Каждый этап кода включает важные операции, которые могут вызвать проблемы при выполнении.
Возможные причины и их решения
-
Проблемы с подключением к базе данных:
- Убедитесь, что правильно указаны
URI
иAUTH
для подключения к вашей базе данных Neo4j. - Проверьте, что база данных запущена и доступна (например, через браузер Neo4j).
- Убедитесь, что правильно указаны
-
Ошибки при извлечении текста из PDF:
- Убедитесь, что ваш PDF-файл не содержит защищённого контента или что библиотека
PyPDF2
может извлекать текст. - Проверьте журнал (
pdf_processing.log
) на наличие ошибок, связанных с извлечением текста из PDF.
- Убедитесь, что ваш PDF-файл не содержит защищённого контента или что библиотека
-
Разделение текста на фрагменты:
- Возможно, текст не был успешно извлечён, и в результате ваш список фрагментов будет пустым. Убедитесь, что после вызова
get_text_chunks
размер списка больше нуля. - Добавьте дополнительные логи, чтобы убедиться, что текст действительно делится на нужныеChunks.
- Возможно, текст не был успешно извлечён, и в результате ваш список фрагментов будет пустым. Убедитесь, что после вызова
-
Генерация векторов:
- Убедитесь, что вызов API OpenAI работает корректно. Проверьте наличие ошибок в ответе и в журнале.
- Проверьте, что сгенерированный вектор имеет корректный размер—это должен быть однородный массив, содержащий достаточное количество значений (например, 1536 для модели
text-embedding-ada-002
).
-
Вставка векторов в Neo4j:
- Убедитесь, что функция
upsert_vector
правильно работает и что вы передаёте все параметры должным образом. Например,node_id
должен быть уникальным для каждой вставки. - Проверьте, что свойство
embedding_property
указано правильно и соответствует вашей схеме данных в Neo4j.
- Убедитесь, что функция
-
Отсутствие индексов:
- Убедитесь, что для поля, в котором сохраняются векторы, создан необходимый индекс. Это необходимо для эффективного поиска по векторным данным.
Рекомендации по улучшению отладки
-
Логи: Добавьте дополнительные точки логирования в вашем коде, чтобы отслеживать состояние каждого этапа. Например, вы можете логировать результаты каждой операции.
-
Интерактивная проверка: Используйте Python интерактивную оболочку (например, Jupyter Notebook) для тестирования каждого этапа по отдельности. Это поможет локализовать источник проблемы.
-
Проверка в Neo4j: После выполнения кода попробуйте вручную выполнить запросы в Neo4j (например,
MATCH (n) RETURN n LIMIT 10
) для проверки, были ли векторы действительно вставлены.
Заключение
Работа с Neo4j и интеграция с OpenAI для векторного поиска может быть сложной задачей. Однако, следуя приведённым выше рекомендациям, вы сможете диагностировать и устранить возникшие проблемы. Помните, что систематический подход к отладке и улучшению логирования поможет в дальнейшем, если вы столкнётесь с подобными ситуациями. Успехов в вашей работе с Neo4j!