Ниже — текущий порядок подготовки и отправки данных в LLM при анализе одного юнита кода.
- Воркер получает задачу анализа (
AnalysisTask) с набором файлов, списком норм и пользовательскими настройками. - Код разбивается на единицы анализа (unit) с метаданными: файл, тип (procedure/function), диапазон строк, изменённые строки, признаки (tags), статические находки.
- До LLM‑вызовов применяются пользовательские настройки:
- если
disable_patterns = true, паттерн‑этап пропускается полностью.
- если
Цель: выбрать ограниченный список норм, которые имеют смысл для проверки данного юнита.
- Формируется сокращённый список норм: передаются ID + заголовки + секция + категория (без текста нормы и без подсказок).
- Если включена настройка «Использовать все нормы», в список добавляются нормы из
norms.yaml. - В подсказке для модели строго указан формат ответа: JSON‑массив
norm_id. - В LLM отправляется:
- краткое описание юнита (файл, диапазон строк, изменённые строки, признаки),
- фрагмент кода (см. п. 3.1 ниже),
- список норм (ID + title + section + category),
- инструкция “выбери нормы, потенциально релевантные этому фрагменту”.
- Ответ разбирается; остаются только norm_id, которые реально есть в исходном наборе.
- Если список выбранных норм пустой — дальнейший код‑этап для этого юнита пропускается.
Цель: проверить только выбранные нормы для текущего юнита.
- На вход берутся только нормы, выбранные на шаге 1 из
critical_norms.yaml+custom_norms.yaml. - Формируется полный промт:
- сведения об юните + исходный код;
- список статических нарушений (если есть), чтобы LLM их не дублировала;
- подробные тексты выбранных норм (title, norm_text, rationale, detection_hint, scope и т.д.);
- инструкция: вернуть строго JSON‑массив с находками (norm_id, section, category, evidence...).
- LLM возвращает JSON‑массив находок по выбранным нормам.
- Результат сохраняется в
ai_findingsи пишется в артефакты.
Цель: отдельно проверить архитектурные/паттерновые нормы.
- Шаг выполняется только если
disable_patterns = false. - Формируется промт со списком паттернов и инструкции искать нарушения только по паттернам.
- LLM возвращает JSON‑массив находок по паттернам.
- Результат сохраняется в
ai_findingsи пишется в артефакты.
- Выполняется только если включена настройка «Использовать все нормы».
- На вход берутся нормы, выбранные на шаге 1 из
norms.yaml. - Формируется полный промт с текстами выбранных норм и отправляется в LLM.
- Результат сохраняется в
ai_findingsи артефакты.
- LLM получает три списка: паттерны, критические нормы, обычные нормы.
- Возвращает единый список без дублей (JSON‑массив).
- Если merge не удался, используются исходные списки.
Перед отправкой промта в LLM код проходит редактирование только для LLM:
- Строковые литералы заменяются на
<REDACTED>. - Комментарии заменяются на
<REDACTED_COMMENT>. - Маскирование применяется только к контенту, отправляемому в LLM.
- Для пользователя и UI исходный код не изменяется и показывается полностью.
- Отчёт о маскировании сохраняется в артефактах.
Для каждого шага сохраняются:
{run_id}_{stage}_llm_log_{n}_prompt.txt{run_id}_{stage}_llm_log_{n}_response.txt{run_id}_{stage}_llm_log_{n}.json(полная структура){run_id}_{stage}_llm_redaction_{n}.json(отчёт маскирования)
Где stage = select | critical | pattern | norms | merge | query.
Важно: *_select_llm_log_*_response.txt — это ответ LLM на этапе отбора применимых норм.
Он не является итоговым ответом с нарушениями. Финальные нарушения появляются только
после шагов critical / norms / query и попадают в ai_findings.
- На шаге selection суммарный размер списка норм ограничен лимитом
MAX_NORM_SELECTION_CHARS(сейчас 100_000). - На шаге code ограничения зависят от модели/провайдера (в коде жёсткого лимита нет).
- Выбор норм отделён в отдельный этап, чтобы минимизировать “шум”.
- Результаты по‑прежнему зависят от LLM (модель/температура/провайдер). Для строгой повторяемости лучше фиксировать модель и параметры.