Самое важное из мира AI — в канале MAX AgentLabОтдельные разборы, инструменты и практические схемы Читайте Agent Lab в Telegram Разборы, кейсы и новости о практических AI-агентах без лишней воды.

Проверяем Specification Frame на реальной задаче

Проверяем Specification Frame на реальной задаче
Temporary fallback cover; replace in editorial pass.

Уровень: с нуля · Чтение: до 12 минут · Опубликовано:

Зачем это нужно

Запрос «напиши функцию импорта платежей из CSV» выглядит понятным, но в нём нет почти ничего важного: как хранить суммы, что делать с дублями, какую ошибку вернуть на битой строке и как понять, что код готов. Модель заполняет эти пробелы сама. Код получается правдоподобным, запускается и при этом может нарушать требования, о которых вы просто не написали.

Specification Frame — это способ структурировать промпт в четыре блока: контекст, ограничения, контракт результата и проверки. В этой статье мы возьмём одну учебную задачу, сформулируем её двумя способами — коротко и через рамку — и сравним ответы по одному и тому же чек-листу. В итоге у вас будет шаблон промпта и чек-лист, которые можно переиспользовать на своих задачах.

Важно: задача ниже — пример, придуманный для статьи. Мы не приводим «замеров» и процентов улучшения: результат зависит от модели, её версии и настроек. Вместо этого вы проведёте сравнение сами и запишете собственные наблюдения.

Учебная задача

Нужна функция на Python, которая читает CSV-файл с платежами и возвращает итог по каждому клиенту. Формат файла (пример):

payment_id,customer_id,amount,currency
p-001,c-10,1250.50,RUB
p-002,c-11,99.99,RUB
p-001,c-10,1250.50,RUB
p-003,c-10,abc,RUB

В этих четырёх строках уже спрятаны три ловушки: дубль p-001, некорректная сумма abc и денежные значения, которые опасно считать через float. Короткий промпт ни одну из них не упоминает.

Шаг 1. Подготовьте рабочую папку

Все команды безопасны: они создают файлы только внутри новой папки и ничего не устанавливают глобально.

mkdir sf-check && cd sf-check
python3 -m venv .venv
source .venv/bin/activate
python -m pip install pytest

Сохраните пример выше в файл payments.csv:

cat > payments.csv <<'EOF'
payment_id,customer_id,amount,currency
p-001,c-10,1250.50,RUB
p-002,c-11,99.99,RUB
p-001,c-10,1250.50,RUB
p-003,c-10,abc,RUB
EOF

Шаг 2. Вариант A — короткий промпт

Отправьте модели буквально такой запрос, в новом диалоге без предыстории:

Напиши функцию на Python, которая считает сумму платежей
по каждому клиенту из CSV-файла.

Сохраните ответ в variant_a.py, не редактируя его.

Шаг 3. Вариант B — промпт по Specification Frame

Теперь та же задача, но разложенная на четыре блока. Откройте ещё один новый диалог с той же моделью:

<context>
Сервис сверки платежей. На вход приходит CSV с колонками
payment_id, customer_id, amount, currency. Файл формирует внешняя
система, она иногда повторяет строки и присылает мусор в amount.
Python 3.11, только стандартная библиотека.
</context>

<constraints>
- Деньги не храни во float: используй decimal.Decimal.
- Строки с одинаковым payment_id считай одним платежом
  (учитывай первую встреченную).
- Принимай только currency = RUB; другие валюты — ошибка строки.
- Некорректные строки не роняют обработку: собирай их в список ошибок.
- Не используй сторонние пакеты.
</constraints>

<output_contract>
Функция: summarize(path: str) -> tuple[dict[str, Decimal], list[str]]
- первый элемент: customer_id -> сумма, округлённая до 0.01;
- второй элемент: сообщения об ошибках вида "line N: причина",
  где N — номер строки файла, считая заголовок первой строкой.
Верни один файл summarize.py и отдельно файл test_summarize.py.
</output_contract>

<checks>
Тесты pytest должны покрывать: дубль payment_id, нечисловую сумму,
чужую валюту, пустой файл с одним заголовком, точность 0.1 + 0.2.
Перед ответом перечисли, какое требование закрывает каждый тест.
</checks>

Сохраните код в summarize.py и тесты в test_summarize.py.

Шаг 4. Запустите проверки

Сначала прогоните тесты, которые написала сама модель:

python -m pytest -q test_summarize.py

Тесты от модели — не доказательство. Добавьте свою независимую проверку на нашем файле. Это ожидаемое поведение по спецификации, а не результат какого-то прогона:

cat > test_independent.py <<'EOF'
from decimal import Decimal
from summarize import summarize

def test_sample_file():
    totals, errors = summarize("payments.csv")
    assert totals == {"c-10": Decimal("1250.50"), "c-11": Decimal("99.99")}
    assert len(errors) == 1
    assert errors[0].startswith("line 5:")
EOF
python -m pytest -q test_independent.py

Для варианта A такой тест обычно нельзя запустить напрямую: у функции другое имя и другая сигнатура. Это уже наблюдение — без контракта результата ответ нельзя проверить автоматически. Оцените вариант A вручную по чек-листу ниже.

Шаг 5. Оцените оба ответа по чек-листу

Каждый пункт — «да» или «нет», без «почти». Чек-лист воспроизводим: другой человек, глядя на тот же код, должен поставить те же отметки.

#КритерийКак проверитьAB
1Суммы не проходят через floatПоиск float( в коде; есть ли Decimal
2Дубль payment_id учтён один разИтог c-10 равен 1250.50
3Битая строка не роняет обработкуФункция завершается на payments.csv
4Ошибка содержит номер строкиСообщение начинается с line 5:
5Чужая валюта отклоняетсяДобавьте строку с USD и запустите
6Сигнатура совпадает с контрактомsummarize(path) -> (dict, list)
7Только стандартная библиотекаНет импортов pandas и т. п.
8Тесты запускаются и проходятpython -m pytest -q

Запишите итог как «N из 8» для каждого варианта, вместе с названием модели и датой. Если повторяете эксперимент, делайте это в новых диалогах: история переписки влияет на ответ.

Как собрать рамку для своей задачи

  1. Контекст — кто будет использовать результат, откуда берутся данные, версия языка и окружения. Только то, что меняет решение.
  2. Ограничения — запреты и обязательные правила. Хороший признак: каждое ограничение можно проверить по коду.
  3. Контракт результата — точные имена, типы, формат ошибок, список файлов. Это то, на что опирается ваш независимый тест.
  4. Проверки — какие случаи должны быть покрыты и как доказать соответствие. Попросите модель связать каждый тест с требованием.

Практическое правило: каждый пункт чек-листа должен вытекать из какого-то пункта рамки. Если в чек-листе есть критерий, которого нет в промпте, — вы проверяете то, чего не просили.

Типовые ошибки

Ограничения подхода

Что дальше

Сохраните шаблон рамки и чек-лист рядом с проектом и используйте их как стартовую точку для следующих задач. Больше практических разборов — в разделе руководств, а определения терминов из статьи — в глоссарии.