2026-06-18 Обзор сброса работы Godot RAG
Текущее состояние
Вчера в кафе я выпил примерно 1 литр кофе, и сегодня состояние оказалось очень плохим. Поэтому я не смог нормально заниматься кодированием. Тем не менее, даже сейчас я записываю то, что пришло в голову, и почему я упорядочил вчерашнюю работу.
Недостающие части в текущей архитектуре
В текущей архитектуре Godot LLM/RAG есть следующие недостающие элементы. Их необходимо улучшить в дальнейшем.
Слабый слой статического анализа
Отсутствует проверка на основе AST/парсера GDScript
Слабый граф зависимостей проекта Godot
Слабая проверка выполнения/синтаксиса
Таксономия меток пока грубая
Слабое различие между результатами LLM и проверенными ответами по происхождению
Слабый дизайн устранения утечек/дублирования данныхОсобенно есть аспекты, которые нельзя решить только с помощью RAG. Определение кода Godot — это не только задача поиска по документам, но и необходимость учитывать реальный синтаксис GDScript, зависимости scene/resource, структуру проекта и различия API Godot 3/4. Вчерашний процесс заключался в том, что официальную документацию разбивали на части (чангинг), а полученный результат снова передавали LLM для получения обратной связи. Этот подход выглядел быстрым внешне, но на практике критерии проверки постоянно колебались.
Причина подведения итогов работы 17 июня
17 июня я поручил LLM выполнить чангинг и затем передал полученный материал обратно в GPT для получения обратной связи. Однако, как бы я ни пытался, этот метод оказался неподходящим.
Официальную документацию мы собирали с помощью краулинга, чтобы использовать её полностью в качестве основы. Однако в процессе работы, пока LLM ещё не успел правильно проанализировать документы, он стал считать некоторые API важными, помечая их как «ключевые MVP», и начал жёстко кодировать определённые ключевые слова или чрезмерно усиливать контекст вокруг них. В результате вместо RAG, основанного на всей официальной документации, получился поисковик, настроенный лишь на несколько ключевых слов.
Проблема заключалась не только в том, что результаты не устраивали. LLM сам создавал критерии, генерировал файлы по этим критериям и затем, основываясь на полученных результатах, принимал дальнейшие решения, не проверяя их вручную. В итоге, не видя оригинальную структуру документа, он начал включать галлюцинации, и позже сам не знал, по каким правилам был создан каждый файл.
Более широко рассматривая, проявилось сильное явление, когда ChatGPT или Codex самостоятельно уменьшали или изменяли область без моего указания. Я хотел увидеть структуру, основанную на всей официальной документации, а не давал указаний «выбрать несколько ключевых API MVP» и захардкодить их. Однако LLM сам посчитал «если это MVP, то это достаточно ключевое», и создал следующий результат, хотя шаг ещё не был завершён.
Особенно проблематичной оказалась следующая модель поведения.
Пользователь хочет анализа структуры на основе полной официальной документации
-> LLM произвольно определяет диапазон MVP
-> Считается, что некоторые API являются ключевыми
-> Сначала выполняется хардкодинг/усиление/создание каталога
-> Создаются артефакты следующего этапа до проверки
-> Результат упаковывается в убедительные цифры
-> На самом деле оригинальная структура и критерии разметки загрязненыЭто не просто ошибка реализации, а проблема подхода к работе. И ChatGPT, и Codex имели тенденцию предполагать, что ответ уже известен, даже когда ответ ещё не получен, и переходить к следующему шагу, не завершив текущий. Казалось, что они следуют инструкциям, но на самом деле переосмысливали их диапазон, полностью игнорировали их или пытались сначала создать «хорошо выглядящую окончательную форму».
Особенно опасным в этой работе было то, что LLM не смог правильно различать надёжность промежуточных результатов, которые он сам генерировал. Факты, подтверждённые официальной документацией, случайно найденные слова с помощью regex, правила, одобренные пользователем, и предположительная дополнительная информация, выведенная LLM, смешались вместе. Когда LLM снова попросили оценить результат, получился цикл, в котором LLM оправдывал собственные выводы.
Причина очистки результатов чанкинга
Сегодня я привёл в порядок файлы, связанные с RAG‑чанкингом, которые создавал вчера.
Отсортированные элементы относятся к следующей категории.
v1 docs_chunks.jsonl
v2 docs_chunks_v2.jsonl
v3/v3.1 catalog/index/mapping результаты
Чанкинг/постобработка/проверка черновика скрипта
Начальный черновик RAG chat/indexСначала я думал, что проблема только в v3/v3.1, но при более тщательном рассмотрении понял, что v1 и v2 тоже требуют полного пересмотра с нуля. На самом деле нужно было анализировать сами чанки. Например, как именно построена справка по классам Godot, как в оригинальном документе представлены единицы — методы/свойства, и как результаты преобразования Sphinx «ломаются».
Однако на практике генерация результатов чанкинга шла раньше, чем анализ оригинального документа. В результате v1 оказался близок к фрагментам по количеству символов, а v2 — к этому же с наложенной постобработкой. На поверхности появлялись такие цифры, как количество чанков, успешный парсинг JSONL, распределение doc_type, но на самом деле не проверялось, «можно ли использовать этот чанк как основание для определения Godot 3/4».
Особенно важно было убедиться, что такие структуры, как CharacterBody2D.move_and_slide в справке по классам, стабильно сохраняются, что свойства вроде velocity точно разделяются, и как извлекать отношения «старое/новое» из миграционной документации. Если этого не сделать, то такие названия, как trusted_api_symbols, syntax_symbols, api_mapping, будут лишь звучными, но загрязнёнными данными.
Поэтому сегодня я очистил результаты чанкинга, включив в работу v1/v2. Это не отказ от задачи, а упорядочивание, чтобы больше не называть ошибочную базовую линию «базовой линией».
Сегодняшний вывод
Сегодняшний вывод прост.
Нужно начать с чанкования заново.
Сначала нужно проанализировать структуру оригинальных документов `outputs/godot_docs_full/pages`.
Нельзя использовать промежуточные результаты, созданные LLM, в качестве основания для следующего шага без проверки.Я не проверял, но LLM самостоятельно принимает решения, и, не посмотрев внимательно на оригинал, добавляет галлюцинации; в итоге LLM оказывается в состоянии, когда не знает, что именно он сделал. Если в таком состоянии продолжать создавать файлы, будет только расти количество отладочных файлов, и станет непонятно, что является критерием.
В дальнейшем я не буду доверять тому, что ChatGPT или Codex «самостоятельно» расширяют и реализуют всё в «хорошем направлении». Особенно в задачах, где важны критерии, таких как наборы данных, разметчики, RAG‑детекторы, необходимы следующие принципы.
LLM если произвольно определит диапазон MVP, то остановка
Если в коде появится хардкодинг без одобрения пользователя, то остановка
Если создавать артефакты без анализа исходной структуры, то остановка
Если переходить к следующему этапу без проверочного отчёта, то остановка
Если provenance LLM‑созданных материалов и проверенных ответов будет смешан, то остановкаЕсли завтра делать это снова, первая задача — не создание нового каталога. Сначала нужно проанализировать сам godot_docs_full. То есть проверить, какова фактическая структура официальных Markdown‑файлов, находящихся в outputs/godot_docs_full/pages, и, исходя из этой структуры, заново продумать, какие единицы следует разбивать на чанки.
Сейчас нужный вопрос — не «какое API добавить первым», а ближе к следующему.
Какой шаблон используется в документе class reference внутри godot_docs_full?
Можно ли надёжно отделить список методов/свойств/сигналов/констант из исходного Markdown?
В каком виде представлена структура таблиц/списков/предложений в документе migration?
Нельзя ли использовать те же критерии чанкинга для документа tutorial, что и для class reference?
Следует ли задавать разные единицы чанков в зависимости от типа документа?
Что следует использовать в качестве базового чанка: страница, раздел или API‑член?
Какой отчёт проверки необходимо определить перед чанкингом?В конце концов, задача состоит не в том, чтобы «пересоздать RAG», а в том, чтобы проанализировать godot_docs_full и заново спроектировать единицы‑чанки, соответствующие официальной документации Godot. Только после этого можно будет заново выполнять чанкование.