В конце мая 2026 года инженер Дмитрий К. выложил в репозиторий Claude Code подробный разбор своей архитектурной ошибки. Ошибка стоила ему двух недель работы и финального вывода: «Модель не виновата. Виноват промпт». История — идеальный анекдот про embedded-деплой, где Claude Opus 4.6 (на тот момент последняя версия) вместо лёгкого прошивочного решения сгенерировал архитектуру с полноценным HTTP-сервером, микросервисными слоями и юнит-тестами на 300 страниц. Для чипа с 32 КБ оперативной памяти.
Что попросили (и как НЕ надо)
Вот промпт, который отправил Дмитрий (он дал разрешение на публикацию):
prompt = """
Спроектируй архитектуру беспроводного деплоя прошивок
для IoT-устройства. Устройство имеет сенсоры, OTA-модуль
и лимитированный объём памяти. Опиши схему развёртывания,
протоколы и обработку ошибок.
"""
Звучит логично? Нет. Это ловушка №1: модель не знает, что для неё очевидно. Фраза «лимитированный объём памяти» — абстракция. Для Claude 32 КБ и 32 ГБ — одинаково «лимитированные». Поэтому Opus 4.6 нарисовал красивую диаграмму с:
- REST API на базе Flask (на embedded — это кирпич)
- База данных SQLite для хранения метаданных (нет, на 32 КБ не влезет)
- Очередь сообщений через MQTT с брокером (требует отдельный сервер)
- Полноценный CI/CD pipeline с отдельными стейджами тестирования
🛑 Результат: архитектура, которая физически не могла запуститься на целевом устройстве. Claude не ошибся — он просто сделал то, что обычно считает «деплоем». Проблема в том, что LLM понимают цель, но игнорируют её, если не задать жёсткие рамки.
Разбор: почему модель сделала «не то»
Разберём три ошибки промпта, которые превратили embedded-архитектуру в карго-культ enterprise.
1 Отсутствие числовых ограничений
Слова «лимитированный» и «ограниченный» для LLM — синонимы «чуть меньше, чем обычно». Нужны конкретные числа: RAM 32 КБ, Flash 256 КБ, частота CPU 48 МГц. Без чисел модель экстраполирует из своего обучения, где «деплой» — это Unix-подобная система с сотнями мегабайт памяти.
2 Жаргонная ловушка «OTA-модуль»
Термин OTA (Over-The-Air) в embedded-среде означает конкретный механизм обновления прошивки с верификацией подписи и минимальным bootloader. Но в корпусе обучения Claude слово OTA часто встречается в контексте Google/Firebase OTA-апдейтов для приложений — там и REST, и базы данных, и очереди. Модель выбрала наиболее частотный контекст, а не наиболее уместный.
3 Неявная ролевая модель
Промпт не сказал: «Ты — embedded-инженер, который проектирует для микроконтроллера STM32». Без ролевой привязки Claude использует универсальный «архитектор корпоративных систем». Как показано в статье «Архитектура Claude Code», модель склонна к шаблонным ответам без контекстного калибрования под область.
Исправленный промпт: как надо было
После разбора ошибки Дмитрий переписал промпт, и модель выдала рабочую embedded-архитектуру за одну итерацию. Вот финальная версия:
prompt = """
Ты — embedded-инженер с 15-летним стажем, проектирующий
системы для микроконтроллеров STM32L0 с RAM: 32 КБ, Flash: 256 КБ.
Задача: спроектировать протокол беспроводного обновления прошивки
(деплой) для этого устройства.
Технические ограничения:
- Сеть: LoRa (скорость 0.3-50 кбит/с)
- Питание: батарея CR2032 (необходимо минимальное энергопотребление)
- Bootloader: уже есть, занимает 8 КБ Flash
- Критично: целостность образа (подпись ECDSA), rollback при сбое
Формат ответа:
1. Схема обновления (количество фаз, тайминги)
2. Структура пакета (заголовок, данные, подпись)
3. Обработка ошибок (таймауты, ретраи, fallback)
4. Оценка размера кода (bytes)
Не используй: HTTP, TCP, SQL, очереди сообщений,
отдельные серверы, файловые системы.
"""
Что из этого следует: практические уроки промптинга
- Числа — не опциональны. Если в задаче есть ограничения, дай их в цифрах. «Мало памяти» — бессмыслица, «32 КБ RAM» — контекст.
- Отрицательный список обязателен. Прямо перечисли, чего не должно быть. Иначе модель добавит всё, что знает (см. реальные кейсы — там та же проблема с лишними зависимостями).
- Роль — не декорация. «Ты — embedded-инженер» меняет распределение вероятностей в выводе. Без этого модель — универсальный солдат, который воюет танком, даже если задача — проникнуть в тыл пешком.
- Уточняй среду выполнения. Если модель генерирует код — укажи компилятор, архитектуру CPU, линковщик. Для архитектурных задач — названия конкретных чипов, протоколов, библиотек.
| Плохой промпт | Хороший промпт |
|---|---|
| «Ограниченная память» | «RAM 32 КБ, Flash 256 КБ» |
| «Спроектируй деплой» | «Спроектируй embedded-деплой для микроконтроллера STM32L0 с LoRa-радио» |
| «Без фреймворков» | «Не используй HTTP, TCP, SQL, очереди, файловые системы» |
А что, если модель всё равно ошибается?
Иногда даже с идеальным промптом архитектура оказывается нерабочей. В таких случаях полезно:
- Показать Claude его же предыдущий ответ и попросить найти ошибки (self-refine). Это работает почти всегда.
- Использовать автономную итерацию — дать модели несколько циклов на улучшение.
- Проверить, не переполнилось ли контекстное окно — длинные промпты с примерами могут вытеснить ключевые инструкции.
Но в 90% случаев корень проблемы — промпт. Как говорил тот инженер на своей странице: «Я потратил две недели, чтобы понять, что Claude умнее, чем я думал. Он просто ждал, пока я дам ему нормальное задание».
📌 Запомните: модель не читает ваши мысли. Всё, что не записано в промпте — для неё не существует. «Очевидные» для вас ограничения — для неё шум. Если вы не скажете «не используй веб-сервер», она его использует.
Этот случай наглядно показывает, почему архитектура как код с помощью LLM работает только при дисциплинированном промптинге. Без него вы получите красивый, но непригодный проект. И обвините модель. А она просто сделала то, что вы попросили — буквально.
Совет на будущее: прежде чем ругать Claude, перечитайте свой промпт. Если в нём нет цифр, нет «нельзя» и нет роли — вы сами создали ошибку.