docs / promptPreprocessor.ru.md

Препроцессор промптов (Prompt Preprocessor)

Обзор

Препроцессор обрабатывает пользовательские запросы с файлами для RAG-системы (Retrieval-Augmented Generation). Он автоматически выбирает оптимальную стратегию внедрения контекста на основе размера файлов и доступного контекстного окна языковой модели.

Основная функция preprocess

Входные параметры:

  • ctl: PromptPreprocessorController — контроллер препроцессора
  • userMessage: ChatMessage — сообщение пользователя

Логика работы:

  • Извлекает текст сообщения пользователя
  • Загружает историю чата и добавляет новое сообщение
  • Фильтрует файлы из сообщения (исключает изображения)
  • Определяет стратегию обработки контекста:
    • Если есть новые файлы → выбирает стратегию через chooseContextInjectionStrategy()
    • Если есть только старые файлы → использует retrieval
  • Возвращает обработанный промпт

Стратегии обработки контекста

1. inject-full-content — Полная вставка

Когда используется:

  • Все файлы вместе с промптом помещаются в контекстное окно модели

Процесс:

1. Парсит каждый файл через ctl.client.files.parseDocument()
2. Извлекает полное содержимое
3. Форматирует с заголовками: ** filename full content **
4. Вставляет в промпт с инструкцией

Формат вывода:

This is a Enriched Context Generation scenario.

The following content was found in the files provided by the user.

** document.pdf full content **

[полное содержимое файла]

** end of document.pdf **

Based on the content above, please provide a response to the user query.

User query: [запрос пользователя]

2. retrieval — Семантический поиск

Когда используется:

  • Файлы слишком большие для полного размещения в контексте
  • Требуется найти только релевантные фрагменты

Процесс:

1. Загружает embedding-модель (nomic-embed-text-v1.5-GGUF)
2. Выполняет семантический поиск через ctl.client.files.retrieve()
3. Фильтрует результаты по retrievalAffinityThreshold
4. Добавляет найденные цитаты в промпт
5. Прикрепляет источники через ctl.addCitations()

Формат вывода (при наличии результатов):

The following citations were found in the files provided by the user:

Citation 1: "[текст цитаты]"

Citation 2: "[текст цитаты]"

Use the citations above to respond to the user query, only if they are relevant. Otherwise, respond to the best of your ability without them.

User Query:

[запрос пользователя]

Формат вывода (без результатов):

Important: No citations were found in the user files for the user query. In less than one sentence, inform the user of this. Then respond to the query to the best of your ability.

User Query:

[запрос пользователя]

3. none — Без контекста

Когда используется:

  • Файлы отсутствуют
  • Не найдено релевантных цитат (порог affinity не пройден)

Алгоритм выбора стратегии

Функция chooseContextInjectionStrategy() принимает решение на основе расчёта токенов:

Шаги алгоритма

ШагОписание
1Загружает LLM-модель через ctl.client.llm.model()
2Измеряет текущее заполнение контекста через measureContextWindow()
3Парсит файлы и подсчитывает общее количество токенов
4Рассчитывает доступные токены с целевым заполнением 70%
5Сравнивает: totalFilePlusPromptTokenCount > availableContextTokens

Формула расчёта

const contextOccupiedFraction = contextOccupiedPercent / 100;
const targetContextUsePercent = 0.7;
const targetContextUsage = targetContextUsePercent * (1 - contextOccupiedFraction);
const availableContextTokens = Math.floor(modelRemainingContextLength * targetContextUsage);

Критерий выбора

Если totalFileTokenCount + userPromptTokenCount > availableContextTokens
    → retrieval
Иначе
    → inject-full-content

Вспомогательные функции

measureContextWindow()

Измеряет заполнение контекстного окна:

Возвращает:

{
  totalTokensInContext: number,      // всего токенов в контексте
  modelContextLength: number,        // размер контекста модели
  modelRemainingContextLength: number, // доступно токенов
  contextOccupiedPercent: number     // процент заполнения
}

getEffectiveContextFormatted()

Применяет шаблон промпта модели:

  • Вызывает model.applyPromptTemplate(ctx)
  • При ошибке (нет user-сообщений) добавляет placeholder "?" и повторяет попытку

prepareRetrievalResultsContextInjection()

Обрабатывает стратегию retrieval:

  • Создаёт статусы для UI (загрузка, парсинг, embedding)
  • Обрабатывает файлы с прогрессом
  • Фильтрует результаты по retrievalAffinityThreshold
  • Форматирует цитаты в промпт

prepareDocumentContextInjection()

Обрабатывает стратегию inject-full-content:

  • Парсит файлы в кэше
  • Форматирует содержимое с заголовками
  • Заменяет текст сообщения через input.replaceText()

Конфигурация

Параметры из configSchematics:

ПараметрТипОписание
retrievalLimitnumberМаксимальное количество цитат для поиска
retrievalAffinityThresholdnumberПорог релевантности для фильтрации цитат (0.0–1.0)

Статусы для пользователя

Препроцессор отображает прогресс через PredictionProcessStatusController:

СтатусТекст
DecidingDeciding how to handle the document(s)...
Loading parserLoading parser for {filename}...
Parser loaded{library} loaded for {filename}...
ProcessingParsing file {filename}... ({progress}%)
RetrievalRetrieving relevant citations for user query...
DoneRetrieved {N} relevant citations for user query

Отладка

Препроцессор выводит отладочную информацию через ctl.debug():

  • Результаты retrieval
  • Обработанное содержимое
  • Метрики производительности (время чтения, токенизации)
  • Детали выбора стратегии

Зависимости

import {
  text,
  type Chat,
  type ChatMessage,
  type FileHandle,
  type LLMDynamicHandle,
  type PredictionProcessStatusController,
  type PromptPreprocessorController,
} from "@lmstudio/sdk";

Embedding-модель: nomic-ai/nomic-embed-text-v1.5-GGUF