AI серія інтерв'ю 16: Яким має бути хороший spec coding?
Хороший Spec Coding (специфікаційно-орієнтоване програмування) полягає в тому, щоб перетворити "туманні ідеї" на "точний, перевірений та виконуваний контракт". Це не просто написання документа, а створення однозначної мови спілкування між людиною та AI (або між людьми). Далі я розгляну чотири аспекти: структура вмісту специфікації, принципи написання, процес співпраці з AI, перевірка якості, щоб показати, як виглядає хороша специфікація.
1. Стандартна структура документа специфікації (на прикладі функціонального модуля)
| Розділ | Обов'язковий вміст | Приклад |
|---|---|---|
| 1. Мета та обсяг | Одне речення, що описує, що робити, чітко вказує чого не робити | "Реалізувати API реєстрації користувача, не включаючи верифікацію електронної пошти" |
| 2. Контракт введення/виведення | Структура даних, типи, обов'язкові/необов'язкові поля, приклади значень | POST /register тіло запиту {email: string, password: string}, відповідь 201 або 400 з кодом помилки |
| 3. Поведінка та логіка | Бізнес-правила, граничні умови, переходи станів | "Довжина пароля 8-20 символів, мінімум одна цифра; якщо електронна пошта вже існує, повернути 409" |
| 4. Обробка помилок | Усі можливі виняткові сценарії та відповідні коди/повідомлення помилок | "Помилка підключення до бази даних → повернути 503, не розкриваючи стек" |
| 5. Нефункціональні вимоги | Продуктивність (час відповіді < 200 мс), безпека (параметризовані запити), логування, спостережуваність | "Усі SQL мають бути попередньо скомпільовані; записувати email, але не password" |
| 6. Тестові випадки (ключові) | Щонайменше 3 типових введення + 2 граничних/виняткових введення, із зазначенням очікуваного результату | Див. таблицю нижче |
| 7. Залежності та обмеження | Які бібліотеки використовувати, версії, змінні середовища | "Python 3.10+, FastAPI, змінна середовища DB_URL" |
Приклад тестових випадків (вбудованих у специфікацію)
| Сценарій | Введення | Очікуваний вивід |
|---|---|---|
| Звичайна реєстрація | email: a@b.com, пароль: Pass1234 |
201, повернути user_id |
| Занадто короткий пароль | пароль: Ab1 |
400, код помилки WEAK_PASSWORD |
| Електронна пошта вже існує | той самий email | 409, код помилки EMAIL_EXISTS |
Хороша специфікація спочатку містить тестові випадки, оскільки AI може на їх основі безпосередньо згенерувати модульні тести, а потім автоматично перевірити.
2. Основні принципи написання специфікації (варіація SMART)
| Принцип | Пояснення | Контрприклад |
|---|---|---|
| Точність (Precise) | Використовувати конкретні числа, типи, булеві умови, уникати "по можливості", "зазвичай" | ❌ "Пароль має бути достатньо безпечним" → ✅ "Пароль мінімум 8 символів, містить велику літеру, малу літеру, цифру" |
| Перевірюваність (Verifiable) | Кожна вимога має бути перевірена автоматичним тестом або ручною перевіркою (пройшов/не пройшов) | ❌ "Код має бути елегантним" → ✅ "Цикломатична складність функції ≤ 10, відсутні повторювані блоки коду" |
| Однозначність (Unambiguous) | Один і той самий термін має однакове значення у всьому тексті; за потреби надати глосарій | ❌ "Якщо користувач не існує, повернути помилку" → ✅ "Користувач не існує → повернути 404 та {code: 'USER_NOT_FOUND'}" |
| Повнота (Complete) | Охоплювати щасливий шлях, усі виняткові шляхи, нефункціональні вимоги | ❌ Тільки успішний сценарій → ✅ Включає тайм-аут бази даних, недостатні права тощо |
| Атомарність (Atomic) | Одна специфікація описує лише одну незалежно реалізовану функцію (для зручності виконання AI) | ❌ Одна специфікація для "всієї платіжної системи" → ✅ Розділити на "генерація платіжного доручення", "перевірка підпису зворотного виклику", "повернення коштів" |
3. Процес Spec Coding при співпраці з AI
- Людина пише специфікацію (за вищезазначеною структурою, особливо тестові випадки та сигнатури функцій).
- Специфікація передається AI одразу (без додаткових вимог у діалозі, щоб уникнути забруднення).
- AI генерує код + модульні тести (AI має створити виконувані тести відповідно до тестових випадків у специфікації).
- Запуск тестів: якщо всі пройшли, переходити до наступного кроку; якщо ні, виправити специфікацію або безпосередньо код (у цьому випадку можна увійти в малий цикл, але зміни мають бути зафіксовані).
- Ручна перевірка: перевірити, чи не додано функціонал поза специфікацією (scope creep), чи відповідає вимогам безпеки/продуктивності.
- Фіксація: зберегти документ специфікації разом із фінальним кодом у репозиторії як постійну документацію.
Ключова практика: кодіфікація специфікації — використовувати
spec.md+test_spec.py, де тестовий файл безпосередньо походить із прикладів у специфікації. Таким чином, при подальшій модифікації коду достатньо запустити тести, щоб перевірити, чи не порушена специфікація.
4. Ефекти хорошої специфікації (можна використовувати як критерії приймання)
- Визначеність: однакова специфікація, надана різним AI (або різним людям), дає схожі реалізації.
- Тестованість: після написання коду можна негайно автоматично перевірити 90% правильності.
- Підтримуваність: через півроку будь-хто, подивившись на специфікацію, зрозуміє початковий задум.
- Низька вартість комунікації: під час обговорень у команді обговорюють лише специфікацію, а не окремі рядки коду.
- Безпека/якість вбудовані: вимоги безпеки (наприклад, параметризовані запити) та граничні умови прописані в специфікації, AI зобов'язаний їх дотримуватися.
5. Приклад хорошої специфікації (спрощена версія)
# Специфікація: API реєстрації користувача
## Обсяг
- Приймає email, password
- Не надсилає лист для підтвердження, не перевіряє реальність email
## Контракт
POST /register
Content-Type: application/json
Запит: { "email": string, "password": string }
Відповідь 201: { "user_id": string }
Відповідь 400: { "code": "INVALID_PASSWORD" | "INVALID_EMAIL" }
Відповідь 409: { "code": "EMAIL_ALREADY_EXISTS" }
## Поведінка
- email має відповідати базовому формату RFC 5322 (a@b.c)
- password: довжина 8-20, мінімум одна цифра та одна велика літера
- Використовувати bcrypt для хешування, вартість солі 10
- Якщо перед збереженням у БД виявлено, що email вже існує → 409
## Тестові випадки (введення -> очікуваний статус + поле відповіді)
| Введення email | password | Очікування |
|----------------|----------|-------------|
| test@x.com | Pass1234 | 201, user_id існує |
| test@x.com | pass | 400, INVALID_PASSWORD |
| bad | Pass1234 | 400, INVALID_EMAIL |
| (вже існуючий email) | Pass1234 | 409, EMAIL_ALREADY_EXISTS |
## Нефункціональні вимоги
- SQL має використовувати параметризовані запити (захист від ін'єкцій)
- Логувати IP джерела реєстрації, не логувати пароль
- Час відповіді 95% запитів < 100 мс (без bcrypt)
## Залежності
- Python 3.10+, FastAPI, bcrypt, asyncpg
Хороший Spec Coding = перетворення "дизайнерських рішень" людини на "тестові випадки + сигнатури типів + обмеження поведінки" для машини, дозволяючи AI лише заповнювати реалізацію, тоді як людина завжди контролює якість і напрямок.
评论
暂无已展示的评论。
发表评论(匿名)