Домашка: промпт ревьюера
Домашка
У вашего devbuddy уже есть токен-калькулятор, но ревьюер пока не умеет собирать себе промпт. Сегодня появится модуль prompts.py: шаблон в константе, правила как данные, сборка одной функцией. А заодно вы на собственной шкуре почувствуете, почему str.format для промптов не годится — шаблон будет содержать JSON-пример с фигурными скобками.
Описание задачи
Файл prompts.py в devbuddy.
Основная функциональность
Константа
REVIEW_TEMPLATE— шаблон наstring.Template, обязательно содержащий:инструкцию роли («Ты — ревьюер кода...» — формулировка ваша);
секцию правил с плейсхолдером
$rules;дифф с плейсхолдером
$diff;секцию формата ответа с примером JSON, содержащим ключ
"comments"(пример из урока можно взять как есть);
Функция
build_review_prompt(diff: str, rules: list[str]) -> str:каждое правило вставляется отдельной строкой с префиксом
-(дефис и пробел);дифф подставляется как есть — без экранирования и обработок;
сборка не падает ни на каких символах диффа:
{,},$— обычные символы.
Дополнительные условия
Только стандартная библиотека.
Шаблон — константа уровня модуля; внутри
build_review_promptтекст промпта строками не собирается.
Как проверить себя
test_prompts.py, запуск python -m pytest test_prompts.py -v:
from prompts import build_review_prompt
DIFF = 'x = {"a": 1}\nprint(f"итого: ${x}")'
RULES = ["не используй global", "проверяй границы списков"]
def test_rules_as_list():
prompt = build_review_prompt(DIFF, RULES)
assert "- не используй global" in prompt
assert "- проверяй границы списков" in prompt
def test_diff_verbatim():
prompt = build_review_prompt(DIFF, RULES)
assert DIFF in prompt
def test_format_example_present():
prompt = build_review_prompt("a = 1", ["правило"])
assert '"comments"' in prompt
def test_survives_special_chars():
nasty = 'цена = ${x} и словарь {"k": "v"}'
prompt = build_review_prompt(nasty, ["правило"])
assert nasty in prompt
def test_multiple_rules_on_separate_lines():
prompt = build_review_prompt("a = 1", RULES)
lines = [line for line in prompt.splitlines() if line.startswith("- ")]
assert len(lines) >= 2Обратите внимание на test_survives_special_chars: дифф с $ и {} обязан пройти сквозь сборку нетронутым. Если ваш шаблон использует ${...}-синтаксис Template — самое время узнать, почему $diff и ${diff} — не одно и то же в разных ситуациях.
Пример работы программы
>>> from prompts import build_review_prompt
>>> print(build_review_prompt("total = total + vat", ["не пиши мутабельных глобалов"]))
Ты — ревьюер кода. Найди проблемы в диффе ниже.
Правила ревью:
- не пиши мутабельных глобалов
Дифф:
total = total + vat
Ответ дай строго в формате JSON:
{"comments": [{"file": "...", "line": 1, "severity": "warning", "message": "..."}]}
Если замечаний нет — отдай {"comments": []}.(точный текст вашего шаблона будет своим — тесты проверяют структуру, а не формулировки.)
Критерии готовности
Пять тестов зелёные.
В
prompts.pyнет сборки промпта строками внутри функции — только подстановка в шаблон.Коммит:
prompts.pyиtest_prompts.py.
Проверьте на живой модели (необязательно)
Соберите промпт для настоящего маленького диффа (пару строк из любого своего проекта) и отправьте его через LLMClient с ролями: системное сообщение — роль и формат, пользовательское — результат build_review_prompt. Посмотрите, держит ли модель формат "comments". Полноценно парсить ответ научимся в следующем занятии — пока просто посмотрите.
Как устроены LLM: токены, контекст, цена
10 мин
Домашка: токен-калькулятор
4 мин
Квиз: Как устроены LLM: токены, контекст, цена
8 мин
Промпты как код: шаблоны и переменные
8 мин
Домашка: промпт ревьюера
3 мин
Квиз: Промпты как код: шаблоны и переменные
7 мин
Структурированный вывод: JSON вместо прозы
6 мин
Домашка: парсер ревью
3 мин
Квиз: Структурированный вывод: JSON вместо прозы
7 мин
Выбор модели: GPT, Claude, открытые
7 мин
Домашка: бенчмарк вслепую
4 мин
Квиз: Выбор модели: GPT, Claude, открытые
7 мин
HARD-задача: смета агента
3 мин
Локальная модель: Ollama по-настоящему
8 мин
Квиз: Локальная модель: Ollama по-настоящему
6 мин