<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Embeddings on kenji.blog</title><link>http://kenji.blog/ru/tags/embeddings/</link><description>Recent content in Embeddings on kenji.blog</description><generator>Hugo -- gohugo.io</generator><language>ru</language><copyright>kenjinote</copyright><lastBuildDate>Fri, 11 Sep 2026 13:00:00 +0900</lastBuildDate><atom:link href="http://kenji.blog/ru/tags/embeddings/index.xml" rel="self" type="application/rss+xml"/><item><title>【Введение в реализацию RAG】Как заставить локальный ИИ читать ваши документы</title><link>http://kenji.blog/ru/p/rag-local-ai-implementation-guide/</link><pubDate>Fri, 11 Sep 2026 13:00:00 +0900</pubDate><guid>http://kenji.blog/ru/p/rag-local-ai-implementation-guide/</guid><description>&lt;img src="http://kenji.blog/p/rag-local-ai-implementation-guide/img/eyecatch.jpg" alt="Featured image of post 【Введение в реализацию RAG】Как заставить локальный ИИ читать ваши документы" />&lt;h1 id="введение">Введение
&lt;/h1>&lt;p>В последние годы развитие больших языковых моделей (LLM) поражает воображение: множество ИИ, во главе с ChatGPT и Claude, проникают в нашу жизнь и работу. Однако у обычных LLM есть очевидная слабость: они знают только &amp;ldquo;публичную информацию на момент обучения&amp;rdquo;. Естественно, они не могут ответить на вопросы, касающиеся &amp;ldquo;приватных документов&amp;rdquo;, таких как внутренние правила компании, личные заметки или неопубликованные проектные материалы. Если попытаться заставить их ответить, возрастает риск генерации правдоподобной лжи, не соответствующей действительности (галлюцинаций).&lt;/p>
&lt;p>В связи с этим сегодня в мире взрывными темпами распространяется технологическая архитектура &lt;strong>RAG (Retrieval-Augmented Generation: генерация с дополненной выборкой)&lt;/strong>. Использование RAG позволяет динамически предоставлять LLM собственные знания из внешней базы данных, на основе которых можно генерировать точные и обоснованные ответы.&lt;/p>
&lt;p>Кроме того, при работе с корпоративными данными или личной конфиденциальной информацией передача данных в облачные API, такие как OpenAI, часто недопустима с точки зрения политики безопасности. Именно здесь возникает потребность в создании &amp;ldquo;Локального RAG&amp;rdquo; в сочетании с &lt;strong>локальным ИИ&lt;/strong> (LLM, полностью работающей на вашем ПК или локальном сервере).&lt;/p>
&lt;p>В этой статье мы подробно рассмотрим все: от базовой теории RAG до конкретных методов реализации локального RAG с использованием Python, математической основы (механизм векторного поиска) и продвинутых методов запуска системы в рабочую среду.&lt;/p>
&lt;hr>
&lt;h1 id="1-общая-архитектура-rag">1. Общая архитектура RAG
&lt;/h1>&lt;p>RAG — это не единая модель ИИ, а системная архитектура, в которой взаимодействуют несколько компонентов. Она условно делится на две фазы: &amp;ldquo;фаза поглощения (загрузка данных)&amp;rdquo; и &amp;ldquo;фаза поиска и генерации&amp;rdquo;.&lt;/p>
&lt;p>Следующая диаграмма Mermaid показывает общую картину системы RAG.&lt;/p>
&lt;div class="mermaid">graph TD
subgraph "Фаза поглощения (Предварительная подготовка)"
Doc["Собственные документы (PDF, TXT и т.д.)"] --> Loader["Загрузчик документов"]
Loader --> Splitter["Разделение текста (Чанкинг)"]
Splitter --> EmbedModel1["Модель встраивания (Embedding)"]
EmbedModel1 --> VectorDB["Векторная база данных"]
end
subgraph "Фаза вывода (При запросе пользователя)"
User["Вопрос пользователя (Запрос)"] --> EmbedModel2["Модель встраивания (Embedding)"]
EmbedModel2 --> QueryVector["Вектор запроса"]
QueryVector --> Search["Поиск по сходству (Векторный поиск)"]
VectorDB --> Search
Search --> Context["Извлечение связанных фрагментов (Контекст)"]
User --> PromptBuilder["Построение промпта"]
Context --> PromptBuilder
PromptBuilder --> LocalLLM["Локальная LLM"]
LocalLLM --> Answer["Генерация окончательного ответа"]
end&lt;/div>
&lt;h2 id="фаза-поглощения-предварительная-подготовка">Фаза поглощения (Предварительная подготовка)
&lt;/h2>&lt;ol>
&lt;li>&lt;strong>Загрузка документов&lt;/strong>: Загрузка неструктурированных данных, таких как PDF, Word, текстовые файлы и т.д.&lt;/li>
&lt;li>&lt;strong>Чанкинг (разделение текста)&lt;/strong>: Разделение длинных текстов на осмысленные фрагменты (чанки) для того, чтобы они поместились в ограничение на ввод LLM (контекстное окно) и для повышения точности поиска.&lt;/li>
&lt;li>&lt;strong>Эмбеддинг (векторизация)&lt;/strong>: Передача разделенных чанков в модель встраивания (Embedding Model) и преобразование их в массивы чисел (векторы) размерностью от сотен до тысяч.&lt;/li>
&lt;li>&lt;strong>Сохранение в базу данных&lt;/strong>: Сохранение преобразованных векторов и связывание их с исходными текстовыми данными в векторной базе данных (Vector DB).&lt;/li>
&lt;/ol>
&lt;h2 id="фаза-вывода-во-время-выполнения">Фаза вывода (Во время выполнения)
&lt;/h2>&lt;ol>
&lt;li>&lt;strong>Векторизация запроса&lt;/strong>: Векторизация вопроса пользователя с использованием той же модели встраивания, что и при предварительной подготовке.&lt;/li>
&lt;li>&lt;strong>Поиск по сходству&lt;/strong>: Расчет сходства между вектором запроса и векторами документов в базе данных для получения нескольких наиболее семантически близких (релевантных) фрагментов текста.&lt;/li>
&lt;li>&lt;strong>Построение промпта&lt;/strong>: Объединение полученных связанных текстов в качестве &amp;ldquo;контекста (фоновых знаний)&amp;rdquo; с вопросом пользователя для создания промпта ввода в LLM.&lt;/li>
&lt;li>&lt;strong>Генерация ответа&lt;/strong>: Получив расширенный промпт, LLM генерирует ответ на основе предоставленной контекстной информации.&lt;/li>
&lt;/ol>
&lt;hr>
&lt;h1 id="2-глубокое-понимание-векторного-поиска-и-встраиваний-embeddings">2. Глубокое понимание векторного поиска и встраиваний (Embeddings)
&lt;/h1>&lt;p>В основе RAG лежит &amp;ldquo;векторный поиск (семантический поиск)&amp;rdquo;. В отличие от традиционного поиска по ключевым словам (например, BM25), который основан на точном совпадении и частоте слов, векторный поиск основан на &amp;ldquo;смысловом сходстве&amp;rdquo;. Например, даже если используются разные слова, такие как &amp;ldquo;собака&amp;rdquo; и &amp;ldquo;щенок&amp;rdquo;, &amp;ldquo;ПК&amp;rdquo; и &amp;ldquo;компьютер&amp;rdquo;, они будут найдены, если их значения близки.&lt;/p>
&lt;h2 id="что-такое-модель-встраивания-embedding-model">Что такое модель встраивания (Embedding Model)?
&lt;/h2>&lt;p>Модель встраивания — это нейронная сеть, которая принимает на вход текст на естественном языке и выводит плотный вектор (Dense Vector) фиксированной длины. Обычные модели (например, &lt;code>text-embedding-3-small&lt;/code> или модель с открытым исходным кодом &lt;code>multilingual-e5-large&lt;/code>) отображают текст в векторы вещественных чисел размерностью 384 или 1024.&lt;/p>
&lt;p>В этом многомерном пространстве (скрытом пространстве) они обучены так, что чем ближе по смыслу предложения, тем меньше расстояние между ними в координатном пространстве.&lt;/p>
&lt;h2 id="математическая-основа-расчета-сходства-косинусное-сходство">Математическая основа расчета сходства: Косинусное сходство
&lt;/h2>&lt;p>Когда векторная база данных ищет связанные документы, наиболее часто используемой метрикой расстояния является &lt;strong>косинусное сходство (Cosine Similarity)&lt;/strong>. В отличие от евклидова расстояния (абсолютного расстояния в пространстве), косинусное сходство фокусируется на &amp;ldquo;угле между двумя векторами&amp;rdquo;. Поскольку оно менее подвержено влиянию длины предложения (нормы вектора), оно очень хорошо подходит для расчета сходства текстов.&lt;/p>
&lt;p>В виде формулы косинусное сходство между векторами $\mathbf{A}$ и $\mathbf{B}$ выглядит следующим образом:&lt;/p>
$$ \text{Cosine Similarity}(\mathbf{A}, \mathbf{B}) = \cos(\theta) = \frac{\mathbf{A} \cdot \mathbf{B}}{\|\mathbf{A}\| \|\mathbf{B}\|} = \frac{\sum_{i=1}^{n} A_i B_i}{\sqrt{\sum_{i=1}^{n} A_i^2} \sqrt{\sum_{i=1}^{n} B_i^2}} $$
&lt;ul>
&lt;li>$\mathbf{A} \cdot \mathbf{B}$ обозначает скалярное произведение (Dot Product).&lt;/li>
&lt;li>$\|\mathbf{A}\|$ обозначает L2-норму (длину) вектора $\mathbf{A}$.&lt;/li>
&lt;li>$n$ — это размерность вектора.&lt;/li>
&lt;/ul>
&lt;p>Косинусное сходство принимает значения от -1 до 1.&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Ближе к 1&lt;/strong>: направления двух векторов почти совпадают (очень схожи по смыслу)&lt;/li>
&lt;li>&lt;strong>Ближе к 0&lt;/strong>: два вектора перпендикулярны (не связаны)&lt;/li>
&lt;li>&lt;strong>Ближе к -1&lt;/strong>: два вектора указывают в противоположные стороны (противоположные по смыслу)&lt;/li>
&lt;/ul>
&lt;p>Современные векторные БД (Chroma, FAISS, Qdrant и т.д.) используют алгоритм приближенного поиска ближайших соседей (ANN), называемый HNSW (Hierarchical Navigable Small World), который оптимизирован для поиска документов с высоким косинусным сходством среди миллионов векторных данных за миллисекунды.&lt;/p>
&lt;hr>
&lt;h1 id="3-технологический-стек-для-создания-локального-rag">3. Технологический стек для создания локального RAG
&lt;/h1>&lt;p>Для создания полностью локального RAG, не зависящего от облака, мы будем использовать экосистему с открытым исходным кодом. Ниже представлен рекомендуемый технологический стек.&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Языковая модель (LLM)&lt;/strong>
&lt;ul>
&lt;li>Инструмент: &lt;code>Ollama&lt;/code> или &lt;code>Llama.cpp&lt;/code>&lt;/li>
&lt;li>Модель: легкие и высокопроизводительные открытые модели, такие как &lt;code>Llama-3-8B-Instruct&lt;/code>, &lt;code>Gemma-2-9B-It&lt;/code>, &lt;code>Qwen2-7B-Instruct&lt;/code>. Для задач на японском языке подходят модели, настроенные на японский язык, такие как &lt;code>Llama-3-ELYZA-JP-8B&lt;/code>.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>&lt;strong>Модель встраивания (Embedding)&lt;/strong>
&lt;ul>
&lt;li>Модель: &lt;code>intfloat/multilingual-e5-large&lt;/code> или &lt;code>BAAI/bge-m3&lt;/code>. При локальном запуске обычно их скачивают с Hugging Face и запускают с помощью Sentence-Transformers.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>&lt;strong>Векторная база данных (Vector DB)&lt;/strong>
&lt;ul>
&lt;li>&lt;code>ChromaDB&lt;/code>: основана на Python, очень проста в настройке. Идеально подходит для локальной разработки.&lt;/li>
&lt;li>&lt;code>FAISS&lt;/code>: высокоскоростная библиотека векторного поиска, разработанная Meta.&lt;/li>
&lt;li>&lt;code>Qdrant&lt;/code> / &lt;code>Milvus&lt;/code>: для более масштабных проектов и рабочих сред.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>&lt;strong>Фреймворк оркестрации&lt;/strong>
&lt;ul>
&lt;li>&lt;code>LangChain&lt;/code>: фактический стандарт для связывания (Chain) компонентов.&lt;/li>
&lt;li>&lt;code>LlamaIndex&lt;/code>: фреймворк для подключения данных, специально ориентированный на RAG.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ol>
&lt;p>В этот раз мы реализуем систему, используя самую простую в освоении комбинацию: &lt;strong>LangChain + ChromaDB + Ollama + HuggingFaceEmbeddings&lt;/strong>.&lt;/p>
&lt;hr>
&lt;h1 id="4-учебное-руководство-по-реализации-создание-полного-локального-rag-на-python">4. Учебное руководство по реализации: Создание полного локального RAG на Python
&lt;/h1>&lt;p>Начиная с этого момента, мы будем создавать локальный RAG, написав фактический код на Python. Пожалуйста, предварительно установите Ollama на свой ПК и запустите его в фоновом режиме. Также загрузите модель в Ollama (например: &lt;code>ollama run llama3&lt;/code>).&lt;/p>
&lt;h2 id="шаг-1-установка-необходимых-библиотек">Шаг 1: Установка необходимых библиотек
&lt;/h2>&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">pip install langchain langchain-community langchain-huggingface
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">pip install chromadb sentence-transformers pypdf
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h2 id="шаг-2-обзор-кода-реализации">Шаг 2: Обзор кода реализации
&lt;/h2>&lt;p>Ниже представлен полный Python-скрипт для загрузки PDF-файла, его векторизации и ответов на вопросы с помощью локальной LLM.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;span class="lnt">21
&lt;/span>&lt;span class="lnt">22
&lt;/span>&lt;span class="lnt">23
&lt;/span>&lt;span class="lnt">24
&lt;/span>&lt;span class="lnt">25
&lt;/span>&lt;span class="lnt">26
&lt;/span>&lt;span class="lnt">27
&lt;/span>&lt;span class="lnt">28
&lt;/span>&lt;span class="lnt">29
&lt;/span>&lt;span class="lnt">30
&lt;/span>&lt;span class="lnt">31
&lt;/span>&lt;span class="lnt">32
&lt;/span>&lt;span class="lnt">33
&lt;/span>&lt;span class="lnt">34
&lt;/span>&lt;span class="lnt">35
&lt;/span>&lt;span class="lnt">36
&lt;/span>&lt;span class="lnt">37
&lt;/span>&lt;span class="lnt">38
&lt;/span>&lt;span class="lnt">39
&lt;/span>&lt;span class="lnt">40
&lt;/span>&lt;span class="lnt">41
&lt;/span>&lt;span class="lnt">42
&lt;/span>&lt;span class="lnt">43
&lt;/span>&lt;span class="lnt">44
&lt;/span>&lt;span class="lnt">45
&lt;/span>&lt;span class="lnt">46
&lt;/span>&lt;span class="lnt">47
&lt;/span>&lt;span class="lnt">48
&lt;/span>&lt;span class="lnt">49
&lt;/span>&lt;span class="lnt">50
&lt;/span>&lt;span class="lnt">51
&lt;/span>&lt;span class="lnt">52
&lt;/span>&lt;span class="lnt">53
&lt;/span>&lt;span class="lnt">54
&lt;/span>&lt;span class="lnt">55
&lt;/span>&lt;span class="lnt">56
&lt;/span>&lt;span class="lnt">57
&lt;/span>&lt;span class="lnt">58
&lt;/span>&lt;span class="lnt">59
&lt;/span>&lt;span class="lnt">60
&lt;/span>&lt;span class="lnt">61
&lt;/span>&lt;span class="lnt">62
&lt;/span>&lt;span class="lnt">63
&lt;/span>&lt;span class="lnt">64
&lt;/span>&lt;span class="lnt">65
&lt;/span>&lt;span class="lnt">66
&lt;/span>&lt;span class="lnt">67
&lt;/span>&lt;span class="lnt">68
&lt;/span>&lt;span class="lnt">69
&lt;/span>&lt;span class="lnt">70
&lt;/span>&lt;span class="lnt">71
&lt;/span>&lt;span class="lnt">72
&lt;/span>&lt;span class="lnt">73
&lt;/span>&lt;span class="lnt">74
&lt;/span>&lt;span class="lnt">75
&lt;/span>&lt;span class="lnt">76
&lt;/span>&lt;span class="lnt">77
&lt;/span>&lt;span class="lnt">78
&lt;/span>&lt;span class="lnt">79
&lt;/span>&lt;span class="lnt">80
&lt;/span>&lt;span class="lnt">81
&lt;/span>&lt;span class="lnt">82
&lt;/span>&lt;span class="lnt">83
&lt;/span>&lt;span class="lnt">84
&lt;/span>&lt;span class="lnt">85
&lt;/span>&lt;span class="lnt">86
&lt;/span>&lt;span class="lnt">87
&lt;/span>&lt;span class="lnt">88
&lt;/span>&lt;span class="lnt">89
&lt;/span>&lt;span class="lnt">90
&lt;/span>&lt;span class="lnt">91
&lt;/span>&lt;span class="lnt">92
&lt;/span>&lt;span class="lnt">93
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="kn">import&lt;/span> &lt;span class="nn">os&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">from&lt;/span> &lt;span class="nn">langchain_community.document_loaders&lt;/span> &lt;span class="kn">import&lt;/span> &lt;span class="n">PyPDFLoader&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">from&lt;/span> &lt;span class="nn">langchain_text_splitters&lt;/span> &lt;span class="kn">import&lt;/span> &lt;span class="n">RecursiveCharacterTextSplitter&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">from&lt;/span> &lt;span class="nn">langchain_huggingface&lt;/span> &lt;span class="kn">import&lt;/span> &lt;span class="n">HuggingFaceEmbeddings&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">from&lt;/span> &lt;span class="nn">langchain_community.vectorstores&lt;/span> &lt;span class="kn">import&lt;/span> &lt;span class="n">Chroma&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">from&lt;/span> &lt;span class="nn">langchain_community.llms&lt;/span> &lt;span class="kn">import&lt;/span> &lt;span class="n">Ollama&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">from&lt;/span> &lt;span class="nn">langchain_core.prompts&lt;/span> &lt;span class="kn">import&lt;/span> &lt;span class="n">PromptTemplate&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">from&lt;/span> &lt;span class="nn">langchain.chains&lt;/span> &lt;span class="kn">import&lt;/span> &lt;span class="n">RetrievalQA&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">def&lt;/span> &lt;span class="nf">main&lt;/span>&lt;span class="p">():&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># 1. Загрузка документов&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;Загрузка документов...&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># Укажите путь к PDF, который нужно загрузить&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">file_path&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s2">&amp;#34;sample_company_policy.pdf&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">loader&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">PyPDFLoader&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">file_path&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">documents&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">loader&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">load&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># 2. Разделение на чанки (Text Splitting)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># Разделение на фрагменты подходящего размера, не нарушая смысла текста&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">text_splitter&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">RecursiveCharacterTextSplitter&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">chunk_size&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="mi">500&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="c1"># Максимальное количество символов в одном чанке&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">chunk_overlap&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="mi">50&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="c1"># Количество перекрывающихся символов между чанками (предотвращает потерю контекста)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">separators&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="se">\n\n&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="se">\n&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;。&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;、&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34; &amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;&amp;#34;&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">chunks&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">text_splitter&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">split_documents&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">documents&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sa">f&lt;/span>&lt;span class="s2">&amp;#34;Разделено на &lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="nb">len&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">chunks&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2"> чанков.&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># 3. Инициализация модели встраивания (Local HuggingFace Model)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># Использование мультиязычной модели&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;Загрузка модели встраивания...&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">embeddings&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">HuggingFaceEmbeddings&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">model_name&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;intfloat/multilingual-e5-large&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">model_kwargs&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="p">{&lt;/span>&lt;span class="s1">&amp;#39;device&amp;#39;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s1">&amp;#39;cpu&amp;#39;&lt;/span>&lt;span class="p">}&lt;/span> &lt;span class="c1"># Используйте &amp;#39;cuda&amp;#39; или &amp;#39;mps&amp;#39;, если есть GPU&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># 4. Создание векторной базы данных (Chroma)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;Создание векторной базы данных...&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">persist_directory&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s2">&amp;#34;./chroma_db&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">vectorstore&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">Chroma&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">from_documents&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">documents&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="n">chunks&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">embedding&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="n">embeddings&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">persist_directory&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="n">persist_directory&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># Создание ретривера (поисковика). Настройка на получение топ-3 связанных документов&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">retriever&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">vectorstore&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">as_retriever&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">search_kwargs&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="p">{&lt;/span>&lt;span class="s2">&amp;#34;k&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="mi">3&lt;/span>&lt;span class="p">})&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># 5. Инициализация локальной LLM (Ollama)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;Подключение к локальной LLM...&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># Предварительно загрузите модель, например, с помощью &amp;#39;ollama pull llama3&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">llm&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">Ollama&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">model&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;llama3&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># 6. Определение шаблона промпта&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">prompt_template&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s2">&amp;#34;&amp;#34;&amp;#34;Вы - превосходный ассистент, хорошо разбирающийся в правилах и внутренней информации компании.
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2">Используя ТОЛЬКО следующий контекст (фоновую информацию), подробно ответьте на вопрос пользователя.
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2">Если ответ не может быть найден в контексте, не стройте догадок и честно ответьте «Я не могу найти ответ в предоставленной информации».
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2">【Контекст】
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2">&lt;/span>&lt;span class="si">{context}&lt;/span>&lt;span class="s2">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2">【Вопрос】
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2">&lt;/span>&lt;span class="si">{question}&lt;/span>&lt;span class="s2">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2">【Ответ】:
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2">&amp;#34;&amp;#34;&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">PROMPT&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">PromptTemplate&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">template&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="n">prompt_template&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">input_variables&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s2">&amp;#34;context&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;question&amp;#34;&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># 7. Создание цепочки RAG&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">qa_chain&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">RetrievalQA&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">from_chain_type&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">llm&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="n">llm&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">chain_type&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;stuff&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">retriever&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="n">retriever&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">return_source_documents&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="kc">True&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="c1"># Настройка возврата источников информации&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">chain_type_kwargs&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="p">{&lt;/span>&lt;span class="s2">&amp;#34;prompt&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="n">PROMPT&lt;/span>&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># 8. Выполнение вопроса&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">query&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s2">&amp;#34;Расскажите об условиях оплаты транспортных расходов при удаленной работе.&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sa">f&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="se">\n&lt;/span>&lt;span class="s2">Вопрос: &lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">query&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="se">\n&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">result&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">qa_chain&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">invoke&lt;/span>&lt;span class="p">({&lt;/span>&lt;span class="s2">&amp;#34;query&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="n">query&lt;/span>&lt;span class="p">})&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;【Ответ】&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">result&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s1">&amp;#39;result&amp;#39;&lt;/span>&lt;span class="p">])&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="se">\n&lt;/span>&lt;span class="s2">---&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;【Использованные источники】&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">for&lt;/span> &lt;span class="n">doc&lt;/span> &lt;span class="ow">in&lt;/span> &lt;span class="n">result&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s1">&amp;#39;source_documents&amp;#39;&lt;/span>&lt;span class="p">]:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sa">f&lt;/span>&lt;span class="s2">&amp;#34;- Страница &lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">doc&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">metadata&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">get&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;page&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s1">&amp;#39;неизвестно&amp;#39;&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2">: &lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">doc&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">page_content&lt;/span>&lt;span class="p">[:&lt;/span>&lt;span class="mi">50&lt;/span>&lt;span class="p">]&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2">...&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">if&lt;/span> &lt;span class="vm">__name__&lt;/span> &lt;span class="o">==&lt;/span> &lt;span class="s2">&amp;#34;__main__&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">main&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h2 id="объяснение-ключевых-моментов-кода">Объяснение ключевых моментов кода
&lt;/h2>&lt;ol>
&lt;li>&lt;strong>RecursiveCharacterTextSplitter&lt;/strong>:
Это наиболее рекомендуемый разделитель для естественного языка. Он пытается разделить текст в порядке: абзац (&lt;code>\n\n&lt;/code>), строка (&lt;code>\n&lt;/code>), точка (&lt;code>。&lt;/code>), чтобы разделить текст таким образом, чтобы он уместился в заданный &lt;code>chunk_size&lt;/code>, сохраняя при этом смысловые блоки насколько это возможно. Установив &lt;code>chunk_overlap&lt;/code>, вы предотвращаете потерю информации на границах контекста.&lt;/li>
&lt;li>&lt;strong>HuggingFaceEmbeddings&lt;/strong>:
&lt;code>intfloat/multilingual-e5-large&lt;/code> — это очень мощная многоязычная модель встраивания с открытым исходным кодом. Вы можете векторизовать текст оффлайн в локальной памяти, не используя облачные API (например, &lt;code>text-embedding-ada-002&lt;/code> от OpenAI).&lt;/li>
&lt;li>&lt;strong>ChromaDB&lt;/strong>:
Она работает в оперативной памяти или локальном хранилище (на базе SQLite), поэтому вам не нужно настраивать сложный сервер базы данных. Указав &lt;code>persist_directory&lt;/code>, вы можете пропустить процесс векторизации при повторном выполнении и загрузить базу данных с диска.&lt;/li>
&lt;/ol>
&lt;hr>
&lt;h1 id="5-продвинутые-методы-rag-advanced-rag-techniques">5. Продвинутые методы RAG (Advanced RAG Techniques)
&lt;/h1>&lt;p>Базовая система RAG (Naive RAG), созданная в приведенном выше руководстве, также будет работать, но если в рабочей среде требуется высокая точность ответов, необходимо внедрить следующие продвинутые методы.&lt;/p>
&lt;h2 id="51-гибридный-поиск-hybrid-search">5.1 Гибридный поиск (Hybrid Search)
&lt;/h2>&lt;p>Векторный поиск хорошо справляется с пониманием &amp;ldquo;смысла&amp;rdquo;, но он может плохо справляться со строгим поиском по ключевым словам, таким как &amp;ldquo;определенные имена собственные&amp;rdquo;, &amp;ldquo;номера моделей продуктов&amp;rdquo; и &amp;ldquo;идентификаторы сотрудников&amp;rdquo;.
Следовательно, параллельно выполняя &lt;strong>семантический поиск&lt;/strong> (с помощью векторного поиска) и &lt;strong>поиск по ключевым словам&lt;/strong> (с использованием алгоритмов типа BM25), а затем оценивая и объединяя результаты обоих подходов (используя методы типа Reciprocal Rank Fusion, RRF), можно радикально сократить количество пропусков в поиске.&lt;/p>
&lt;h2 id="52-повторное-ранжирование-re-ranking">5.2 Повторное ранжирование (Re-ranking)
&lt;/h2>&lt;p>Векторный поиск работает быстро, но он не обязательно оценивает точную контекстную релевантность. Общий конвейер для повышения точности поиска выглядит следующим образом:&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Начальный поиск (First-stage Retrieval)&lt;/strong>: Широкий и поверхностный поиск из векторной БД, извлечение примерно 20–30 связанных чанков.&lt;/li>
&lt;li>&lt;strong>Повторная оценка (Re-ranking)&lt;/strong>: Использование другой, более &amp;ldquo;тяжелой&amp;rdquo; модели машинного обучения, называемой Cross-Encoder (например, &lt;code>bge-reranker&lt;/code>), для подачи пар запроса пользователя и извлеченного чанка и пересчета баллов семантической релевантности.&lt;/li>
&lt;li>&lt;strong>Отбор&lt;/strong>: Только верхние 3–5 с наивысшими баллами передаются в промпт LLM в качестве окончательного контекста.&lt;/li>
&lt;/ol>
&lt;p>Этот метод предотвращает передачу нерелевантной шумовой информации в LLM и может значительно повысить точность (Precision) ответов.&lt;/p>
&lt;div class="mermaid">graph LR
Query["Запрос"] --> VSearch["Векторный поиск (топ 20)"]
VSearch --> Reranker["Модель реранкера (Cross-Encoder)"]
Query --> Reranker
Reranker --> TopK["Высокоточные топ 3"]
TopK --> LLM["Генерация LLM"]&lt;/div>
&lt;h2 id="53-семантический-чанкинг-и-поиск-родительского-документа">5.3 Семантический чанкинг и поиск родительского документа
&lt;/h2>&lt;p>Существует метод под названием &amp;ldquo;Semantic Chunking&amp;rdquo; (Семантический чанкинг), который использует ИИ для обнаружения изменений в смысле предложений и разделяет текст на их основе, а не механически разбивает текст на фиксированное количество символов.
Кроме того, существует метод &amp;ldquo;Parent Document Retriever&amp;rdquo; (Поиск родительского документа), в котором векторизация выполняется на очень маленьких единицах (например, предложениях) для высокоточного поиска, но при передаче в LLM передается &amp;ldquo;исходный большой абзац (родительский документ)&amp;rdquo;, содержащий это предложение, что обеспечивает LLM достаточным контекстом.&lt;/p>
&lt;hr>
&lt;h1 id="6-проблемы-и-решения-при-эксплуатации-локального-rag">6. Проблемы и решения при эксплуатации локального RAG
&lt;/h1>&lt;p>При создании и эксплуатации RAG в локальной среде существуют специфические препятствия.&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Нехватка VRAM (видеопамяти)&lt;/strong>:
Чтобы запустить локальную LLM с практичной скоростью (десятки токенов в секунду), вам необходимо загрузить модель в VRAM вашего GPU. Для работы модели класса 8B в формате fp16 (16-битная плавающая запятая) требуется около 16 ГБ VRAM, но с использованием технологии &lt;strong>квантования (Quantization)&lt;/strong> (сжатие до 4 или 8 бит, например, в форматах GGUF или AWQ), ее можно заставить работать достаточно быстро даже на 8 ГБ VRAM (например, на стандартном игровом ПК). Llama.cpp и Ollama поддерживают эти форматы квантования из коробки.&lt;/li>
&lt;li>&lt;strong>Ограничение контекстного окна&lt;/strong>:
Если объем полученного контекста слишком велик, он может превысить лимит ввода LLM (лимит токенов) или модель может &amp;ldquo;забыть&amp;rdquo; среднюю часть информации (феномен Lost in the middle). Важно настраивать количество извлекаемых чанков и тщательно отбирать их с помощью вышеупомянутых технологий реранжирования.&lt;/li>
&lt;li>&lt;strong>Управление свежестью данных&lt;/strong>:
Если исходные документы обновляются, соответствующие векторы документов в векторной базе данных также должны быть обновлены или удалены (операции CRUD). Поскольку ChromaDB поддерживает обновление на основе идентификаторов документов, практично управлять хеш-значениями файлов и настраивать пакетную обработку для синхронизации только изменений.&lt;/li>
&lt;/ul>
&lt;hr>
&lt;h1 id="заключение">Заключение
&lt;/h1>&lt;p>RAG (Retrieval-Augmented Generation) — это мощная парадигма, которая превращает ИИ из обычного универсального ассистента в вашего «персонального эксперта» или «эксперта, специализирующегося на ваших внутренних задачах».&lt;/p>
&lt;p>Мы увидели, что даже с высокими требованиями к конфиденциальности, не позволяющими использовать облачные сервисы, можно относительно легко создать полноценную среду «локального RAG», комбинируя элементы экосистемы с открытым исходным кодом, такие как Ollama, LangChain и ChromaDB.&lt;/p>
&lt;p>Основываясь на математическом понимании векторных пространств и продвинутых подходах, таких как разделение текста и реранжирование, рассмотренных в этой статье, попробуйте разработать собственную оригинальную систему ИИ, используя свои данные. Скорость эволюции локального ИИ поразительна, и система, которую вы построили сегодня, может быть мгновенно обновлена по производительности завтра, просто заменив ее на еще более умную легкую модель.&lt;/p>
&lt;hr>
&lt;p>&lt;em>В этом блоге мы продолжим публиковать подробные статьи о технологиях ИИ и RAG. Если у вас есть какие-либо вопросы или отзывы, пожалуйста, оставьте их в разделе комментариев.&lt;/em>&lt;/p></description></item></channel></rss>