Реализовать prompt diff
ТЕХНИЧЕСКОЕ ЗАДАНИЕ: Реализовать prompt diff
1. Цель задачи
Научиться инженерно подходить к версионированию промптов и автоматизировать процесс код-ревью изменений в них. Вы разработаете утилиту для сравнения двух версий промпта с подсветкой изменений, интегрируете её в Git-рабочий процесс и обеспечите удобный просмотр диффа в пул-реквестах.
Ключевой результат Рабочая команда prompt-diff, которая принимает два файла промптов (или ссылки на коммиты) и выводит цветной diff в консоль/HTML, а также GitHub Action, автоматически публикующий diff в комментарии к PR.
2. Исходные данные
| Что нужно | Откуда взять |
|---|---|
Репозиторий с промптами (версионированные .prompt или .yaml / .md файлы) | Создать локально или использовать существующий проект |
| Python 3.9+ | Установлен в системе |
| Git | Установлен и настроен |
| Доступ к GitHub / GitLab (опционально) | Личный аккаунт |
Если нет реального репозитория с промптами — симулируем:
- Создайте пустой Git-репозиторий: mkdir prompt-demo && cd prompt-demo && git init
- Создайте пару файлов промптов в разных версиях:
- v1.yaml — базовая версия промпта для суммаризации
- v2.yaml — изменённая версия с другим тоном и примерами
- Закоммитьте оба файла в разные ветки или в виде последовательных коммитов в master
- Убедитесь, что можно выполнить git diff v1.yaml v2.yaml
3. Технологический стек
| Компонент | Инструменты | Назначение |
|---|---|---|
| Язык | Python 3.9+ | Реализация утилиты diff |
| Библиотека diff | difflib (stdlib), termcolor, diff2html-cli | Алгоритмы сравнения и подсветка |
| Формат вывода | Терминал (цветной) / HTML / Markdown | Визуализация для code review |
| Автоматизация | GitHub Actions или GitLab CI | Публикация diff в PR |
| Тестирование | pytest | Проверка корректности диффа |
| Линтинг | flake8, black | Качество кода |
4. Этапы выполнения
Этап 1: Проектирование интерфейса и выбор алгоритма (30 минут)
Действия
-
Определите команду и аргументы
-
Сравните алгоритмы diff
-
Напишите спецификацию в SPEC.md в репозитории:
- Формат входных данных (файлы, текст)
- Правила отображения: строки с удалением красным, добавлением зелёным, контекст серым
- Поведение при пустых или несуществующих файлах
Ожидаемый результат этапа Документ SPEC.md с чётким описанием интерфейса и поведения утилиты.
Этап 2: Реализация базовой утилиты (1.5–2 часа)
Действия
-
Создайте структуру проекта
prompt-diff/ ├── prompt_diff/ │ ├── __init__.py │ ├── cli.py │ ├── differ.py │ ├── formatters.py ├── tests/ │ ├── test_differ.py ├── sample_prompts/ │ ├── v1.yaml │ └── v2.yaml ├── setup.py / pyproject.toml └── SPEC.md -
Реализуйте
differ.py— основной классPromptDiffer:import difflib from pathlib import Path from typing import List, Tuple class PromptDiffer: def __init__(self, context_lines: int = 3): self.context_lines = context_lines def load(self, path: Path) -> str: return path.read_text(encoding='utf-8') def compute_diff(self, text1: str, text2: str) -> str: lines1 = text1.splitlines(keepends=True) lines2 = text2.splitlines(keepends=True) diff = difflib.unified_diff( lines1, lines2, fromfile='version1', tofile='version2', n=self.context_lines ) return ''.join(diff) -
Реализуйте
formatters.py— цветной вывод в терминал:from termcolor import colored def format_terminal(diff_text: str) -> str: output = [] for line in diff_text.splitlines(keepends=True): if line.startswith('+'): output.append(colored(line, 'green')) elif line.startswith('-'): output.append(colored(line, 'red')) elif line.startswith('@@'): output.append(colored(line, 'cyan')) else: output.append(line) return ''.join(output) -
Реализуйте cli.py:
import argparse from pathlib import Path from .differ import PromptDiffer from .formatters import format_terminal, format_html def main(): parser = argparse.ArgumentParser(description='Prompt Diff Tool') parser.add_argument('file1', type=Path) parser.add_argument('file2', type=Path) parser.add_argument('--html', action='store_true', help='Output as HTML') args = parser.parse_args() differ = PromptDiffer() text1 = differ.load(args.file1) text2 = differ.load(args.file2) diff = differ.compute_diff(text1, text2) if args.html: with open('diff.html', 'w') as f: f.write(format_html(diff)) else: print(format_terminal(diff)) -
Настройте pyproject.toml с точкой входа.
Ожидаемый результат этапа Работающая команда prompt-diff (после pip install -e .) выводит цветной diff в терминал.
Этап 3: Интеграция с Git и code review (1–1.5 часа)
Действия
- Создайте Git-хук (pre-push) для автоматической проверки — опционально
- Напишите GitHub Action для публикации diff в комментарии PR:
- Триггер:
pull_requestс изменением .prompt/.yaml/.md - Шаги:
- Пример
.github/workflows/prompt-diff.yml:name: Prompt Diff on: [pull_request] jobs: diff: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 with: fetch-depth: 2 - name: Set up Python uses: actions/setup-python@v5 with: python-version: '3.10' - name: Install prompt-diff run: pip install . - name: Generate HTML diff run: | git diff HEAD^ --name-only -- '*.prompt' '*.yaml' '*.md' | while read f; do if git diff HEAD^ -- "$f" | grep -q .; then prompt-diff --html <(git show HEAD^:"$f") "$f" > "${f}.diff.html" fi done - name: Upload artifacts uses: actions/upload-artifact@v4 with: path: '*.diff.html' - name: Comment PR uses: actions/github-script@v7 with: script: | const fs = require('fs'); const files = fs.readdirSync('.').filter(f => f.endsWith('.diff.html')); for (const f of files) { const content = fs.readFileSync(f, 'utf-8'); await github.rest.issues.createComment({ ...context.repo, issue_number: context.issue.number, body: `## Prompt diff: ${f}\n\n<details><summary>Show diff</summary>\n\n${content}\n\n</details>` }); }
- Триггер:
- Проверьте работу Action на тестовом PR в вашем репозитории.
Ожидаемый результат этапа При создании PR с изменением промпта в комментариях появляется свёрнутый блок с цветным diff (HTML).
Этап 4: Тестирование и обработка граничных случаев (1 час)
Действия
- Напишите тесты в
tests/test_differ.py: - Добавьте тесты для CLI с использованием subprocess или CliRunner из Click (если используете Click)
- Покройте тестами форматтеры — проверьте, что цвета содержат ANSI-коды (для терминала) или корректный HTML
- Запустите pytest, добейтесь 100% прохождения
Ожидаемый результат этапа pytest проходит минимум 8 тестов, coverage > 85%.
Этап 5: Документация и финальная упаковка (30 минут)
Действия
- Напишите README.md:
- Установка: pip install prompt-diff (или
pip install -e .) - Примеры использования
- Скриншот/описание цветного вывода
- Интеграция с Git (хук)
- Ссылка на GitHub Action
- Установка: pip install prompt-diff (или
- Добавьте CONTRIBUTING.md с правилами форматирования (black, flake8)
- Обновите pyproject.toml — укажите автора, лицензию, ссылки
Ожидаемый результат этапа Готовый репозиторий с документацией, который можно использовать и передать коллегам.
5. Критерии приемки (Definition of Done)
- Утилита prompt-diff установлена и работает через CLI
- Цветной diff в терминале: зелёный для добавлений, красный для удалений, голубой для заголовков
- HTML-вывод генерируется корректно и может быть вставлен в Markdown (с экранированием)
- GitHub Action автоматически публикует diff в комментарии PR
- Все тесты проходят, coverage > 85%
- Документация содержит примеры для разных случаев (добавление, удаление, изменение)
- Поддерживаются файлы с расширениями .prompt, .yaml,
.md,.txt - Утилита корректно обрабатывает Unicode (эмодзи, кириллицу)
- Скрипт не падает при отсутствии одного из файлов, выводит понятную ошибку
- В README есть инструкция по быстрой установке и использованию
6. Ожидаемый результат
Основной артефакт Python-пакет prompt-diff (как локальный репозиторий) со следующей структурой:
prompt-diff/
├── prompt_diff/
│ ├── __init__.py
│ ├── cli.py
│ ├── differ.py
│ ├── formatters.py
├── tests/
│ ├── test_differ.py
│ ├── test_formatters.py
├── sample_prompts/
│ ├── v1.yaml
│ └── v2.yaml
├── .github/
│ └── workflows/
│ └── prompt-diff.yml
├── README.md
├── CONTRIBUTING.md
├── pyproject.toml
├── SPEC.md
Содержание ключевых файлов
differ.py— класс с методамиload,compute_diff,compare_commits(опционально)formatters.py— функцииformat_terminal,format_html.github/workflows/prompt-diff.yml— рабочий Action- README.md — полное описание
Опционально pre-commit hook скрипт, Makefile
7. Возможные сложности и их решение
| Сложность | Решение |
|---|---|
| Цвета в терминале не отображаются (Windows) | Использовать библиотеку colorama для инициализации ANSI-поддержки |
| HTML diff слишком большой и ломает комментарий PR (ограничение GitHub – 65536 символов) | Обрезать diff до 60000 символов и добавить ссылку на артефакт; или выводить только сводку изменений с детальной ссылкой |
| Нужно сравнивать промпты из разных коммитов, а не только файлы | Добавить опцию --commit и реализовать git show внутри Python (через subprocess) |
| diff показывает только строки, но не символьные изменения внутри строки (например, изменённое слово) | Использовать difflib.ndiff для посимвольного сравнения; затем сгруппировать в строки с подсветкой слов |
GitHub Action не может найти prompt-diff (не установлен) | Установить пакет внутри шага: pip install git+https://github.com/your-org/prompt-diff.git или создать Docker-образ |
| При большом количестве изменённых промптов в одном PR генерируется много комментариев | Объединить все diff в один комментарий, используя <details> для каждого файла |
8. Бюджет времени (оценка)
| Этап | Время |
|---|---|
| Этап 1: Проектирование интерфейса | 30 мин |
| Этап 2: Реализация базовой утилиты | 1 ч 30 мин |
| Этап 3: Интеграция с Git и code review | 1 ч 30 мин |
| Этап 4: Тестирование | 1 ч |
| Этап 5: Документация | 30 мин |
| Итого (без учёта отладки) | 5 ч |
| С учётом типичных задержек (×1.5) | ~7.5 ч |
Примечание: Для первого раза рекомендуется выделить 2 рабочих дня с возможностью доработок.
9. Связанные вопросы из базы знаний
| Вопрос | Тема |
|---|---|
| 15 | Управление версиями промптов |
| 42 | Форматы хранения промптов (yaml, md, txt) |
| 73 | Инструменты сравнения текстов (diff) |
| 104 | GitHub Actions для промптов |
| 157 | Дифф промптов и его визуализация |
| 208 | Подсветка изменений в code review |
| 259 | Ревью промптов: критерии и процесс |
| 310 | Версионирование промптов с помощью Git |
| 401 | CI/CD для промптов: автоматизация проверок |
| 503 | Лучшие практики хранения промптов в репозитории |
10. Чек-лист самопроверки
- Я создал SPEC.md до начала кодирования и утвердил его с командой
- Утилита запускается без ошибок на пустых и несуществующих файлах с понятными сообщениями
- Цвета работают и в терминале, и в HTML-версии
- GitHub Action корректно обрабатывает изменения только в файлах промптов
- Я написал минимум 8 unit-тестов, покрытие > 85%
- README содержит команды установки, примеры и скриншоты
- Я проверил, что diff не нарушает лимит длины комментария GitHub (если используется)
- Я просмотрел пул-реквест с реальным изменением промпта и убедился, что ревьювер сразу видит изменения