Глава 10: Верификация и самопроверка
Принцип
Модель может проверять свой вывод. Встроенная верификация повышает качество результата без дополнительных запросов.
Самопроверка (Self-verification)
Базовый паттерн
"Выполни задачу.
После выполнения:
1. Проверь результат на корректность
2. Если нашёл ошибку — исправь
3. Верни финальный результат"
Примеры
Пример 1: Код
"Напиши функцию бинарного поиска.
После написания проверь:
1. Работает ли на пустом списке?
2. Работает ли для одного элемента?
3. Корректны ли граничные индексы (off-by-one)?
4. Завершается ли цикл?
Если нашёл проблемы — исправь и покажи финальную версию."
Пример 2: SQL
"Напиши SQL запрос: топ-10 пользователей по сумме заказов за месяц.
Проверка:
1. Обрабатываются ли NULL значения?
2. Корректна ли группировка?
3. Учитываются ли отменённые заказы?
4. Правильный ли порядок сортировки?
Результат: запрос + результат проверки."
Пример 3: Регулярные выражения
"Напиши regex для валидации email.
Проверь на примерах:
✓ Должны проходить: user@example.com, user.name@sub.domain.co.uk
✗ Не должны проходить: @example.com, user@, user@.com
Если regex не проходит все тесты — исправь."
Adversarial testing
Модель пытается "сломать" собственное решение.
Паттерн
"Шаг 1: Реши задачу
Шаг 2: Попытайся найти входные данные, которые сломают решение
Шаг 3: Если нашёл — исправь и повтори шаг 2
Шаг 4: Верни устойчивое решение"
Примеры
Пример 1: Валидатор
"Напиши функцию валидации пароля.
Требования: минимум 8 символов, буква, цифра, спецсимвол.
Затем:
1. Придумай 5 строк, которые должны пройти валидацию
2. Придумай 5 строк, которые НЕ должны пройти
3. Проверь функцию на всех 10 строках
4. Исправь, если есть ошибки
Формат:
\`\`\`python
$функция$
Тесты: | Вход | Ожидание | Результат | ✓/✗ |"
Пример 2: Парсер "Напиши парсер URL.
Adversarial inputs:
-
URL без протокола
-
URL с нестандартным портом
-
URL с encoded символами
-
URL с auth (user:pass@)
-
Пустая строка
-
Невалидная строка
-
Очень длинный URL (10000 символов)
Проверь каждый случай, исправь уязвимости."
Пример 3: Калькулятор "Напиши калькулятор выражений (+, -, *, /, скобки).
Попробуй сломать:
-
Деление на ноль
-
Несбалансированные скобки
-
Пустое выражение
-
Двойные операторы (++)
-
Очень глубокая вложенность скобок
Для каждой атаки: ожидаемое поведение и реализация защиты."
\#\# Формальная верификация
Доказательство корректности через инварианты и контракты.
\#\#\# Инварианты цикла
"Напиши функцию с доказательством корректности.
Задача: найти максимум в списке
Формат:
def find\_max(arr: list$int$) -\> int:
'''
Инвариант цикла:
После i-й итерации, max\_val содержит максимум arr$0:i+1$
Доказательство:
- База (i=0): max\_val = arr$0$, максимум одного элемента
- Шаг (i→i+1): max\_val = max(max\_val, arr$i+1$)
Если arr$i+1$ \> max\_val, то arr$i+1$ — новый максимум
Иначе max\_val остаётся максимумом
Post-condition: max\_val = max(arr)
Termination: цикл завершается после len(arr) итераций
'''
\`\`\`"
Design by Contract
Пример 1: Preconditions/Postconditions
"Напиши функцию с контрактами.
\`\`\`python
def binary\_search(arr: list$int$, target: int) -\> int:
'''
Preconditions:
- arr отсортирован по возрастанию
- len(arr) \> 0
Postconditions:
- Если return \>= 0: arr$return$ == target
- Если return == -1: target not in arr
Raises:
- ValueError: если preconditions нарушены
'''
\`\`\`"
Пример 2: Инвариант структуры данных
"Напиши класс с инвариантом.
\`\`\`python
class SortedList:
'''
Invariant: elements всегда отсортирован по возрастанию
Методы должны сохранять инвариант:
- add(x): вставка с сохранением порядка
- remove(x): удаление без нарушения порядка
'''
def \_check\_invariant(self) -\> bool:
'''Проверка инварианта для отладки.'''
return all(a \<= b for a, b in zip(self.elements, self.elements$1:$))
\`\`\`"
Пример 3: State machine
"Напиши класс с явными состояниями.
\`\`\`python
class Connection:
'''
States: CLOSED, CONNECTING, CONNECTED, CLOSING
Valid transitions:
CLOSED → CONNECTING (connect)
CONNECTING → CONNECTED (on\_connect)
CONNECTING → CLOSED (on\_error)
CONNECTED → CLOSING (close)
CLOSING → CLOSED (on\_close)
Invalid transitions raise InvalidStateError
'''
\`\`\`"
Проверка типов
Runtime проверки
"Напиши функцию с runtime валидацией типов.
\`\`\`python
from typing import get\_type\_hints
def validate\_types(func):
'''Декоратор для проверки типов в runtime.'''
hints = get\_type\_hints(func)
def wrapper(\*args, \*\*kwargs):
\# Проверка аргументов
for name, value in zip(func.\_\_code\_\_.co\_varnames, args):
if name in hints:
expected = hints$name$
if not isinstance(value, expected):
raise TypeError(f'\{name\}: expected \{expected\}, got \{type(value)\}')
result = func(\*args, \*\*kwargs)
\# Проверка возвращаемого значения
if 'return' in hints:
if not isinstance(result, hints$'return'$):
raise TypeError(f'return: expected \{hints$"return"$\}, got \{type(result)\}')
return result
return wrapper
\`\`\`"
Static analysis подсказки
"Добавь type hints для mypy --strict.
Требования:
1. Все аргументы типизированы
2. Возвращаемый тип указан
3. Нет Any (или явно обоснован)
4. Optional явно указан для nullable
5. TypeVar для generics
Код для типизации:
$код$"
Уровни уверенности
Confidence scoring
"Ответь на вопрос и укажи уровень уверенности.
Формат:
\`\`\`json
\{
'answer': '...',
'confidence': 0.0-1.0,
'reasoning': '...',
'caveats': $'...'$
\}
Уровни:
-
0.9-1.0: точно знаю, проверено
-
0.7-0.9: уверен, но не проверял
-
0.5-0.7: вероятно, нужна проверка
-
<0.5: не уверен, рекомендую уточнить
Вопрос: "
\#\#\# Примеры
Пример 1: Технический вопрос "Вопрос: Какова сложность dict.get() в Python?
Ответ: { 'answer': 'O(1) в среднем, O(n) в худшем случае', 'confidence': 0.95, 'reasoning': 'dict использует hash table, коллизии редки', 'caveats': }"
Пример 2: Рекомендация "Вопрос: Какую библиотеку выбрать для HTTP запросов?
Ответ: { 'answer': 'httpx для новых проектов', 'confidence': 0.75, 'reasoning': 'Современный API, поддержка async, HTTP/2', 'caveats': }"
Пример 3: Неопределённость "Вопрос: Будет ли эта оптимизация эффективна?
Ответ: { 'answer': 'Вероятно да, но нужен бенчмарк', 'confidence': 0.5, 'reasoning': 'Теоретически снижает сложность, но константы неизвестны', 'caveats': }"
\#\# Чеклисты верификации
\#\#\# Для кода
"После написания кода проверь:
□ Корректность
-
Работает ли на типичных входах?
-
Работает ли на граничных случаях?
-
Обрабатываются ли ошибки?
□ Безопасность
-
Есть ли injection уязвимости?
-
Валидируется ли пользовательский ввод?
-
Нет ли утечки чувствительных данных?
□ Производительность
-
Какова временная сложность?
-
Какова пространственная сложность?
-
Есть ли очевидные оптимизации?
□ Читаемость
-
Понятны ли имена?
-
Нужны ли комментарии?
-
Следует ли код PEP8?"
\#\#\# Для анализа
"После анализа проверь:
□ Полнота
-
Все ли аспекты рассмотрены?
-
Нет ли пропущенных случаев?
□ Точность
-
Факты верны?
-
Выводы следуют из фактов?
□ Объективность
-
Нет ли bias?
-
Рассмотрены ли альтернативы?
□ Практичность
-
Рекомендации выполнимы?
-
Учтены ли ограничения?"