IndexedDB — это боль. И точка.
Браузерное API для хранения данных на клиенте. Асинхронное, транзакционное, с индексами, курсорами и странными исключениями. Спецификация IndexedDB занимает сотни страниц. Реализовать её в браузере — задача не для слабонервных. И вот я сижу с Claude Code (последняя версия на июнь 2026) и думаю: а сможет ли LLM написать реализацию IndexedDB с нуля? Не часть, не прототип, а полноценный движок, который пройдёт WPT тесты?
Спойлер: смогла. 95% тестов Web Platform Tests (WPT) для IndexedDB зелёные. Один промпт, цикл генерации и исправления — и почти рабочая реализация. Ниже — хардкорная методика с Ralph loop, подводные камни и момент, когда я понял, что 95% — это не предел, а новая отправная точка.
Почему WPT, а не юнит-тесты
Многие думают: «Напишу свои тесты, прогоню через LLM — профит». Нет. Свои тесты часто повторяют ошибки имплементации. WPT — золотой стандарт. Это сотни тестов, написанных разработчиками браузеров. Они проверяют edge cases, которые вы даже не вообразите: что будет, если открыть транзакцию, удалить базу данных, а потом попытаться записать данные? А если индекс создан, но ключ — массив с null? WPT знает ответ.
Подход evals driven development, который мы разбирали в контексте пайплайнов, здесь работает как часы: тесты — это eval, генерация — это модель, а цикл — это мы с Claude Code.
Ralph loop: машина для итераций
Ralph loop — это простой, до безобразия, алгоритм:
- Сгенерировать код по промпту.
- Запустить тесты (WPT).
- Собрать ошибки.
- Скормить ошибки обратно в промпт.
- Повторить, пока не надоест или зелёная полоса не станет 100%.
Звучит как Test + Spec Driven Development? Абсолютно. Только вместо человека — LLM, а spec — это сотни тестов.
Ключевой нюанс: промпт с ошибками должен быть структурирован. Я не просто кидал лог — я просил Claude Code классифицировать ошибку: «ошибка транзакции», «ошибка индекса», «ошибка курсора». Это резко повысило качество исправлений.
Промпт, который заставил LLM написать IndexedDB
Я дал Claude Code один промпт. Без разделения на модули, без подсказок по архитектуре. Вот его суть (реальный промпт был длиннее, но идея та же):
Ты — эксперт по IndexedDB. Напиши полную реализацию браузерного API IndexedDB на JavaScript, которая проходит все WPT тесты. Используй структуру: IDBFactory, IDBDatabase, IDBObjectStore, IDBIndex, IDBTransaction, IDBCursor, IDBRequest, IDBOpenDBRequest, IDBVersionChangeEvent. Реализация должна быть самодостаточной, без внешних зависимостей, с поддержкой структурированного клонирования, транзакций (readonly, readwrite, versionchange), индексов (unique, multiEntry), курсоров (next, prev, nextunique, prevunique) и обработки ошибок. Пиши код по одному модулю за раз, после каждого модуля я буду запускать тесты и сообщать об ошибках.
Да, это «вайб-кодинг» высшей пробы. Но с системой. Промпт явно указывает что нужно реализовать, но не как. LLM сама выбирала паттерны.
Сравните с подходом маленькой LLM из другого эксперимента: там промпт содержал конкретные указания по архитектуре, и это дало двукратное улучшение. Здесь же модель большая, она сама разобралась.
Пошаговый план эксперимента
1 Подготовка WPT тестов
Скачал репозиторий web-platform-tests, выбрал директорию IndexedDB/. Отфильтровал тесты, которые зависят от других API (например, Service Workers). Оставил ~300 тестов, проверяющих ядро IndexedDB.
2 Запуск первой итерации
Скopмил промпт Claude Code. Получил ~2000 строк кода. Запустил WPT. Результат: 23% зелёных. Много ошибок в транзакциях и сериализации данных. Но ничего — Ralph loop only begins.
3 Цикл исправлений
Каждая итерация: я брал лог ошибок, форматировал (убирал дубли, группировал по типу), отправлял Claude Code. Модель исправляла код. После 5 итераций — 68%. После 12 — 91%. После 20 — 95%. Дальше модель упёрлась в потолок.
4 Анализ оставшихся ошибок
Оставшиеся 5% тестов падают из-за тонкостей структурированного клонирования (объекты с циклическими ссылками, ArrayBuffer с определёнными флагами) и некоторых багов с индексами multiEntry. LLM не хватило контекста спецификации. Как показало сравнение Claude Code с другой моделью, окно контекста — иллюзия. Даже 200K токенов не вмещают всю тонкость спецификации.
Результаты: что зелёное, что красное
| Категория тестов | Пройдено | Проблемы |
|---|---|---|
| Транзакции (readonly, readwrite, versionchange) | 98% | Редкий баг с блокировкой при abort |
| Индексы (unique, multiEntry, compound) | 92% | multiEntry с массивами ключей |
| Курсоры (continue, advance, direction) | 96% | Крайние случаи с delete и update |
| Структурированное клонирование | 85% | Blob, File, циклические ссылки |
| Версионирование и open/deleteDatabase | 97% | Конкуренция нескольких вкладок (не тестировалось) |
Нюансы и грабли, на которые я наступил
- Не кормите модель всей спецификацией сразу. Claude Code начинает галлюцинировать на середине документа. Лучше давать фрагменты — как советует эксперимент с RAG: извлеките только релевантные куски.
- WPT тесты могут быть несовместимы с вашей средой. Я запускал через Node.js с мок-браузерным окружением. Пришлось эмулировать Worker, DOMException и прочее.
- LLM не понимает порядок тестов. Иногда исправление одной ошибки ломало десять других. Поэтому после каждого цикла — полный прогон, а не точечная проверка.
- Лучше использовать структурированный лог ошибок. Не просто «тест X упал», а «в строке Y ожидалось Z, получено W». Коллекция промптов для LLM-тестирования подсказала, как форматировать такие логи.
Почему 95%, а не 100%
Потолок не в модели, а в данных. Тонкости структурированного клонирования — это страницы спецификации, которые LLM не видела ни в одном обучающем примере (или видела, но не запомнила). Чтобы пробить 95%, нужно либо дообучать модель на специфичных багах, либо подключать символический движок для клонирования. Как AI SAST не заменяет статический анализатор полностью, так и LLM не заменит эксперта по клонированию.
Главный вывод: LLM отлично генерирует базовую логику, но для крайних случаев нужен человек с отладчиком. Или ещё одна LLM, которая специализируется на структурированном клонировании. Sub-agents, как в методичке Test + Spec Driven Development, — логичное развитие.
Как повторить (или не повторять) мой опыт
Если вы хотите сгенерировать реализацию любого браузерного API через LLM, план такой:
- Выберите API и скачайте WPT тесты для него.
- Настройте среду выполнения (Node.js + моки).
- Напишите промпт, описывающий API поверхностно, но с указанием всех модулей.
- Запустите Ralph loop с автоматизацией (скрипт, который парсит лог и отправляет LLM).
- После каждой итерации анализируйте, какие тесты стали красными, и приоритизируйте исправления.
- Когда прогресс остановится — передайте специфические куски спецификации вручную.
Вся автоматизация цикла — это, по сути, Evals Driven Development в действии. Только eval — это WPT, а разработчик — LLM.
Неочевидный совет: не пытайтесь скормить LLM всю спецификацию IndexedDB сразу. Разбейте на модули: транзакции, индексы, курсоры. Иначе контекст захлебнется. А лучше — используйте агентный подход, где каждый под-агент отвечает за свой модуль. Тогда 95% превратятся в 99%.
Мир браузерной разработки меняется. Ещё год назад мы считали, что написать IndexedDB с нуля — это полгода работы команды. Теперь один инженер с Claude Code делает это за неделю. Не за день, но прогресс очевиден. 2026-й — год, когда LLM перестали быть игрушками и стали инструментом для продакшн-кода. Даже для такого сложного API, как IndexedDB.