1
0
Files
ollama/rag

Базовый RAG для локального запуска

Этот проект представляет собой систему RAG, которая позволяет преобразовывать документацию из Confluence или других источников в формат, пригодный для работы с локальной Ollama, и задавать вопросы по содержимому документов.

Быстрый старт

cd ..; ./up; cd -
python3 -m venv .venv
source .venv/bin/activate
pip install beautifulsoup4 markdownify sentence-transformers qdrant-client langchain transformers
pip install torch torchvision --index-url https://download.pytorch.org/whl/cpu
./download.sh 123456789 # <<== pageId страницы в Confluence
python3 convert.py
python3 vectorize.py
python3 rag.py --interactive

Что такое RAG?

RAG (Retrieval-Augmented Generation) — это архитектура, которая расширяет возможности генеративных языковых моделей (LLM) за счет интеграции внешних источников знаний. Вместо того, чтобы полагаться исключительно на информацию, полученную во время обучения, RAG сначала извлекает релевантные фрагменты из внешней базы знаний, а затем использует их для генерации более точных и информативных ответов.

Основные шаги подготовки RAG:

  • Индексация: Документы преобразуются в векторные представления (эмбеддинги) и сохраняются в векторной базе данных
  • Поиск: При поступлении запроса система ищет наиболее релевантные фрагменты из индексированной базы
  • Генерация: Найденные фрагменты используются как контекст для генерации ответа с помощью языковой модели

Преимущества RAG:

  • Повышает точность ответов засчёт использования актуальной и специфической информации
  • Позволяет отвечать на вопросы, требующих знаний, не входящих в обучающие данные модели
  • Дает возможность проверить источник информации в сгенерированном ответе
  • Может работать с проприетарными или конфиденциальными данными без дообучения модели

Прочесть подробнее можно здесь: https://habr.com/ru/articles/904032/

Структура проекта

rag/
├── input_html/         # Входные файлы HTML, загруженные из Confluence
├── data/               # Входные (конвертированные) Markdown и прочие текстовые файлы
├── chats/              # Директория для сохранения чатов
├── download.sh         # Скрипт для загрузки страниц из Confluence
├── convert.py          # Скрипт конвертации HTML в Markdown
├── vectorize.py        # Скрипт векторизации Markdown
├── rag.py              # Основной скрипт RAG системы
├── clear.sh            # Скрипт очистки html/md файлов
└── README.md           # Этот файл

Стек

Предварительные требования

  1. Запустить среду из корня репозитория: ../README.md
  2. Установить ПО: curl, jq, python3, pip
  3. Установить зависимости python:
python3 -m venv .venv
source ./venv/bin/activate
pip install beautifulsoup4 markdownify sentence-transformers qdrant-client langchain transformers
pip install torch torchvision --index-url https://download.pytorch.org/whl/cpu
  1. Установить в ollama генеративную модель -- читай ниже.

Подготовка данных

1. Выгрузка из Confluence

Открыть одну или несколько страниц (разделов) Confluence, которые необходимо получить, и обратить внимание на наличие pageId, например:

https://conf.company.ltd/pages/viewpage.action?pageId=123456789
https://conf.company.ltd/pages/viewpage.action?pageId=987654321

Если URL страницы не содержит pageId, можно открыть историю изменений этой страницы, например:

https://conf.company.ltd/pages/viewpreviousversions.action?pageId=123456789
https://conf.company.ltd/pages/viewpreviousversions.action?pageId=987654321

Скопировать значения pageId и подставить в команду ./download.sh <pageId1> [<pageId2>...], например:

./download.sh 123456789 987654321

В результате указанные страницы и все их дочерние будут сохранены в директорию ./input_html/. Файлы будут названы по заголовкам страниц.

Important

В начале каждого файла будет сохранена исходная ссылка в формате @@https://conf.company.ltd/pages/viewpage.action?pageId=123456789@@. Это сделано для того, чтобы в диалоге с моделью источники информации отображались в виде ссылок, а не названий файлов.

Important

Confluence не позволяет получить готовые макросы в HTML-виде. Хотя в макросах часто есть очень полезная информация, но её приходится выбрасывать просто потому, что загрузка макросов происходит при загрузке страницы браузером. В файлах будет находиться HTML-текст с готовыми к загрузке макросами, но не загруженными. Поэтому, например, содержания, списки дочерних страниц, встраиваемые диаграммы и пр. плюшечки будут вырезаны.

Да, можно запросить страницы простым curl/wget, но (1) будет сложнее получить мета-инфу о странице и (2) даже после очистки HTML-тегов в тексте останется очень много мусора (меню, футер, навигация...)

Да, можно комбинировать разные подходы и всё сильно усложнить, но я не хочу.

2. Конвертация страниц в Markdown

Этот формат наиболее хорошо подходит для цитирования, потому что не содержит лишних символов, которые будут мешать хорошей токенизации и векторизации.

Для конвертации следует выполнить команду:

python3 convert.py

В результате все html-файлы будут сохранены в директорию ./data/. Файлы будут названы по заголовкам страниц, внутри также сохранится ссылка на исходную страницу @@...@@.

Для получения справки по скрипту выполни команду:

python3 convert.py --help

3. Векторизация (индексирование)

Файлы ./data/* должны быть проиндексированы.

Для того, чтобы проиндексировать документы, выполнить команду:

python3 vectorize.py

Весь текст делится на отрезки (чанки) с некоторым перекрытием. Это делается для оптимизации количества информации, которое будет делиться на токены. Перекрытие обеспечивает смысловую связь между чанками.

Каждый чанк разбивается на токены, которые в виде векторов сохраняются в векторную СУБД Qdrant. При работе RAG, близость векторов токенов обеспечивает наибольшее смысловое совпадение разных слов => чанков => предложений => абзацев => документов. Как следствие:

  • наибольшее смысловое совпадение с вопросом пользователя;
  • молниеносный поиск по индексу чанков (частям документов);
  • корректное насыщение контекста для генеративной модели.

Для получения справки по скрипту выполни команду:

python3 vectorize.py --help

4. Запуск

Для работы с RAG в интерактивном режиме (симуляция диалога) следует выполнить команду:

python3 rag.py --interactive

Important

Модель не запоминает ничего, поскольку сам диалог не попадает в контекст! В целом, это похоже на гуглёж.

Для разового запуска RAG следует выполнить команду:

python3 rag.py --query "твой запрос здесь"

Для получения справки по скрипту выполни команду:

python3 rag.py --help

Note

У скрипта очень довольно аргументов для гибкой настройки.

Кастомный системный промпт

Если хочется уточнить роль генеративной модели, можно создать текстовый файл и прописать туда всё необходимое, учитывая следующие правила:

  1. Шаблон {{sources}} будет заменён на цитаты документов, найденных в qdrant
  2. Шаблон {{query}} будет заменён на запрос пользователя
  3. Если этих двух шаблонов не будет в промпте, результаты будут непредсказуемыми
  4. Каждая цитата в списке цитат формируется в формате:
    <source id="Z">
    Lorem ipsum dolor sit amet
    </source>
    
  5. При вызове rag.py указать путь к файлу промпта, используя аргумент --sys-prompt $путь_к_файлу
  6. Если указанного файла не существует, то будет применён промпт по умолчанию.

Посмотреть полный промпт можно указав аргумент --show-prompt при вызове rag.py.

Неплохие модели для экспериментов

Обозначения:

  • ☑️ — по умолчанию
  • 🧠 — размышляющая
  • 🏋️ — требуются ресурсы

Эмбеддинг

Ранжирование

Note

Другие можно найти здесь: https://github.com/AlexeyMalafeev/ruformers

Генеративные

Список по убыванию качества ответов и размера модели, по возрастанию скорости ответов на обычном домашнем ПК.

Также можно посмотреть на эти модели или свои собственные.

Дисклеймер

Проект родился на энтузиазме из личного любопытства.

Цель: изучить современные технологии.

Задачи:

  1. облегчить поиск информации о проекте среди почти 2000 тысяч документов в корпоративной Confluence, относящихся к нему;
  2. обеспечить минимум телодвижений для развёртывания RAG с нуля внутри команды;
  3. построить воспроизводимую среду для запуска проекта.

Здесь не было задачи сделать всё сложно и по красоте.

Этот проект -- пазл, который позволяет пошагово, по косточкам понять и настроить работу RAG.

Частично (в качестве агентов) в проекте участвовали модели семейств qwen, clause и chatgpt.

Дополнительные материалы