Взаимодействие с документами с помощью DeepSeek и Ollama: локальный чатбот RAG для диалогов с учетом контекста

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.
Революционное взаимодействие с документами с помощью DeepSeek и Ollama: локальный чатбот RAG для диалогов с учетом контекста
Революционное взаимодействие с документами с помощью DeepSeek и Ollama: локальный чатбот RAG для диалогов с учетом контекста

С ростом популярности модели deepseek-r1:1.5b опасения по поводу конфиденциальности облачных решений становятся как никогда актуальными. Этот проект делает еще один шаг вперед, демонстрируя, как построить продвинутую систему RAG локально, используя DeepSeek, LangChain и Streamlit. Используя мощные возможности DeepSeek, эта система гарантирует, что ваши личные данные останутся на вашем компьютере, обеспечивая повышенную конфиденциальность и контроль.

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

Давайте рассмотрим, как создать этот безопасный, контекстно-ориентированный и ориентированный на конфиденциальность RAG-чатбот на вашем компьютере.

Github Repo: Полный код этого проекта доступен на GitHub. Читайте далее, чтобы разобраться в реализации проекта шаг за шагом.


Необходимые условия

  1. Python 3.10 или новее

Установите Python с сайта python.org. Для совместимости со всеми библиотеками рекомендуется использовать Python 3.10 или новее.

  1. Необходимые библиотеки

Установите необходимые библиотеки, используя команду:

pip install -r requirements.txt

  1. Для работы DeepSeek требуется установить Ollama

Инструкция по установке для Ollama и deepseek-r1:1.5b

  1. Скачайте Ollama

Перейдите на сайт Ollama, чтобы загрузить ее на свой компьютер.

  1. Распакуйте Zip-файл

Распакуйте загруженный zip-файл и найдите исполняемый файл Ollama.

  1. Запустите Ollama

После установки Ollama появится на панели задач, что указывает на то, что она работает через HTTP-порт 11434. Зайдите на сайт http://localhost:11434/, чтобы убедиться, что она работает.

  1. Запустите модель deepseek-r1:1.5b

Откройте командную строку и выполните команду:

ollama run deepseek-r1:1.5b


Описание кода

В этом разделе мы разберем код нашего чатбота RAG на основе PDF-файлов с использованием DeepSeek и Ollama, интегрированного со Streamlit для создания удобного пользовательского интерфейса. Давайте рассмотрим функциональность шаг за шагом:

1. Импорт и начальная настройка

import streamlit as st
from langchain.document_loaders import PyPDFLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.vectorstores import FAISS
from langchain.embeddings import HuggingFaceEmbeddings
from langchain_ollama import OllamaLLM
import os
import re
from langchain.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain_core.runnables.history import RunnableWithMessageHistory
from langchain_community.chat_message_histories import ChatMessageHistory
from langchain.chains import create_retrieval_chain
from langchain.chains.combine_documents import create_stuff_documents_chain
from langchain_core.chat_history import BaseChatMessageHistory
from langchain.chains import create_history_aware_retriever

Начнем с импорта необходимых библиотек. Ключевыми из них являются streamlit для пользовательского интерфейса, langchain для загрузки, разделения и встраивания документов, а также OllamaLLM для использования локально запускаемой модели DeepSeek.

Инициализация состояния сессии

# Initialize session state for chat history
if "messages" not in st.session_state:
    st.session_state.messages = []

Здесь мы инициализируем session_state для хранения истории чата, чтобы обеспечить сохранение диалога между взаимодействиями пользователей.

2. Обработка PDF

def process_pdf(pdf_path):
    st.info("Processing PDF... ⏳")
    loader = PyPDFLoader(pdf_path)
    docs = loader.load()

    text_splitter = RecursiveCharacterTextSplitter(chunk_size=512, chunk_overlap=256)
    split_docs = text_splitter.split_documents(docs)

    embedding_model = HuggingFaceEmbeddings(model_name="sentence-transformers/all-MiniLM-L6-v2")
    vectorstore = FAISS.from_documents(split_docs, embedding_model)

    return vectorstore

Функция process_pdf выполняет основную задачу по обработке загруженного PDF-файла:

  1. Загрузка PDF. PyPDFLoader считывает PDF-файл.

  2. Разбивка текста. Текст разбивается на более мелкие фрагменты с помощью RecursiveCharacterTextSplitter для эффективной обработки.

  3. Встраивание и хранение векторов. Мы используем модель HuggingFaceEmbeddings для встраивания фрагментов текста и хранения их в индексе FAISS, что позволяет быстро находить их при запросах.

3. Создание цепочки разговоров

def get_conversation_chain(retriever):
    llm = OllamaLLM(model=llm_model)

    contextualize_q_system_prompt = (
        "Given the chat history and the latest user question, "
        "provide a response that directly addresses the user's query based on the provided documents. "
        "Do not rephrase the question or ask follow-up questions."
    )

    contextualize_q_prompt = ChatPromptTemplate.from_messages(
        [
            ("system", contextualize_q_system_prompt),
            MessagesPlaceholder("chat_history"),
            ("human", "{input}"),
        ]
    )

    history_aware_retriever = create_history_aware_retriever(
        llm, retriever, contextualize_q_prompt
    )

    system_prompt = (
        "As a personal chat assistant, provide accurate and relevant information based on the provided documents. "
        "Limit answers to 2-3 sentences and 50 words max. "
        "Do not form standalone questions, suggest selections, or ask further questions."
        "\n\nContext:\n{context}"
    )

    qa_prompt = ChatPromptTemplate.from_messages(
        [
            ("system", system_prompt),
            MessagesPlaceholder("chat_history"),
            ("human", "{input}"),
        ]
    )

    question_answer_chain = create_stuff_documents_chain(llm, qa_prompt)

    rag_chain = create_retrieval_chain(history_aware_retriever, question_answer_chain)

    store = {}

    def get_session_history(session_id: str) -> BaseChatMessageHistory:
        if session_id not in store:
            store[session_id] = ChatMessageHistory()
        return store[session_id]

    conversational_rag_chain = RunnableWithMessageHistory(
        rag_chain,
        get_session_history,
        input_messages_key="input",
        history_messages_key="chat_history",
        output_messages_key="answer",
    )

    print("Conversational chain created ✅")
    return conversational_rag_chain

Эта функция создает цепочку генерации, дополненную извлечением (RAG), с возможностями учета истории:

  1. Извлечение контекста. History_aware_retriever гарантирует, что чатбот учтет всю историю разговора для получения контекста.

  2. Системные запросы. contextualize_q_system_prompt и system_prompt предоставляют чатботу инструкции для кратких и релевантных ответов.

  3. Управление историей. get_session_history помогает отслеживать историю чата, чтобы ответы были контекстными на основе прошлых сообщений.

Обработка тегов рассуждения

def extract_think_content(text):
    match = re.search(r'<think>(.*?)</think>', text, flags=re.DOTALL)
    return match.group(1).strip() if match else ""

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

Приведенная выше функция удаляет из окончательного ответа все рассуждения внутри тегов <think>, оставляя только очищенный ответ.

4. Пользовательский интерфейс Streamlit

st.set_page_config(page_title="Chat with Documents", layout="wide")
st.title("						
Источник: https://habr.com/ru/articles/879438/


Интересные статьи

Интересные статьи

Бытует мнение, что Битрикс прожорлив, и способен поглотить все ресурсы, которые есть на сервере. Убедимся, что это действительно так, и во всем виноват GeList. А потом попробуем разобраться, что с эти...
Евгений Шеленков — руководитель Университета Битрикс24 и тимлид команды «Коммуникации в реальном времени». В компании он с 2010 года — и до сих пор относится к работе как к любимому хобби
Был обычный жаркий летний день. Таких много бывает, когда ты работаешь, и почему-то крайне мало, когда у тебя выходной. Карантин в Научно-исследовательском институте Тепла и Холод...
В последние дни российские новостные СМИ пестрят сообщениями о том, что эксперты отмечают рост кибератак на фоне перехода людей на удаленку. Как говорится, кому война, а кому мать р...
В 2019 году люди знакомятся с брендом, выбирают и, что самое главное, ПОКУПАЮТ через интернет. Сегодня практически у любого бизнеса есть свой сайт — от личных блогов, зарабатывающих на рекламе, до инт...