Настроить prompt as code

ТЕХНИЧЕСКОЕ ЗАДАНИЕ: Настроить prompt as code

1. Цель задачи

Внедрить подход prompt as code — хранение, версионирование и управление промптами для LLM через систему контроля версий (Git). Настроить процесс code review для промптов и автоматическую проверку изменений в CI/CD. Это позволит обеспечить прозрачность изменений, возможность отката и воспроизводимости версий промптов.

Ключевой результат Все промпты команды хранятся в Git-репозитории, каждый merge request (MR) требует code review, CI-пайплайн автоматически проверяет валидность и стиль промптов.


2. Исходные данные

Что нужноОткуда взять
Репозиторий Git (GitHub / GitLab / Bitbucket)Создать новый или использовать существующий для промптов
Набор промптов (хотя бы 3-5)Из текущего проекта LLM-ассистента или тестовые примеры
Система CI/CD (GitHub Actions / GitLab CI / Jenkins)Включена в репозиторий
Инструмент валидации YAML/JSON (yamllint, ajv)Установить локально и в CI
Инструмент линтинга промптов (promptlint или свой скрипт)Написать или взять готовый (например, promptfoo lint)
Документация по соглашениям о промптахСоставить самостоятельно

Если нет реального инструмента — симулируем:

  1. Создайте пустой репозиторий prompts-repo на GitHub
  2. Добавьте несколько примеров промптов в формате YAML:
    • prompts/greeting.yaml
    • prompts/summarize.yaml
    • prompts/translate.yaml
  3. Настройте Actions с файлом .github/workflows/prompt-ci.yml
  4. Используйте yamllint и простой скрипт на Python (prompt_checker.py) для проверки наличия обязательных полей (system, user, temperature и т.д.)

3. Технологический стек

КомпонентИнструментыНазначение
Система контроля версийGit (GitHub / GitLab)Версионирование и хранение промптов
Шаблонизация промптовJinja2 / F-string / YAML с переменнымиГибкая подстановка параметров
Валидация форматаyamllint, jsonlint, ajvПроверка синтаксиса YAML/JSON
Линтинг промптовpromptfoo / Pydantic / кастомный скриптПроверка структуры, размера, полей
CI/CDGitHub Actions / GitLab CIАвтоматические проверки при каждом MR
Code reviewPull request / Merge requestРучное ревью изменений промптов
ДокументацияMarkdown внутри репозиторияСоглашения, примеры, инструкции

4. Этапы выполнения

Этап 1: Организация репозитория и структуры промптов (30 минут)

Действия

  1. Создайте репозиторий company-prompts и клонируйте локально
  2. Создайте директорию prompts/, внутри — поддиректории по назначению:
    prompts/
    ├── assistants/          # системные промпты ассистентов
    ├── agents/              # промпты для agent loop
    ├── evaluation/          # промпты для оценки (RAGAS, llm-as-judge)
    └── templates/           # шаблоны с переменными
    
  3. Определите единый формат файла промпта (рекомендуется YAML):
    # prompts/assistants/rag_assistant.yaml
    name: rag_assistant
    version: 1.0.0
    description: Помощник для RAG-ответов
    model: gpt-4o
    temperature: 0.2
    max_tokens: 1500
    system: |
      Ты  эксперт по документации компании. Отвечай на основе предоставленного контекста…
    user_template: |
      Контекст:
      {{context}}
    
      Вопрос пользователя:
      {{question}}
    required_variables: [context, question]
    
  4. Добавьте базовые файлы:

Ожидаемый результат этапа Чистая структура репозитория, 3-5 файлов-примеров промптов, файлы документации.


Этап 2: Перенос существующих промптов и шаблонизация (1–2 часа)

Действия

  1. Соберите все текущие промпты из приложения (код, конфиги, .env)
  2. Унифицируйте их в YAML с обязательными полями (name, version, description, model, temperature, system, user_template, required_variables)
  3. Для каждого промпта определите переменные (например, {{context}}, {{query}}, {{language}}) и укажите их в required_variables
  4. Напишите скрипт загрузки промпта из YAML в Python (как будет использоваться):
    # loader.py
    import yaml
    from jinja2 import Template
    import os
    
    PROMPTS_DIR = "prompts"
    
    def load_prompt(name: str, variables: dict) -> dict:
        path = os.path.join(PROMPTS_DIR, f"{name}.yaml")
        with open(path) as f:
            data = yaml.safe_load(f)
        system = data["system"]
        user_template = data["user_template"]
        user_prompt = Template(user_template).render(**variables)
        return {
            "system": system,
            "user": user_prompt,
            "model": data["model"],
            "temperature": data["temperature"],
            "max_tokens": data["max_tokens"],
        }
    
  5. Добавьте тестовый сценарий, который проверяет корректную подстановку переменных для каждого промпта

Ожидаемый результат этапа Все промпты перенесены в YAML, написана функция загрузки, тесты проходят.


Этап 3: Настройка code review и CI (1 час)

Действия

  1. Включите branch protection на ветке main (GitHub: Settings → Branches)
    • Require a pull request before merging
    • Require approvals (минимум 1)
    • Dismiss stale reviews
  2. Создайте GitHub Actions workflow .github/workflows/prompt-ci.yml:
    name: Prompt CI
    
    on:
      pull_request:
        paths:
          - 'prompts/**'
          - '**.yaml'
          - '**.yml'
    
    jobs:
      validate:
        runs-on: ubuntu-latest
        steps:
          - uses: actions/checkout@v4
          - name: Install yamllint
            run: pip install yamllint
          - name: Lint YAML
            run: yamllint prompts/
          - name: Install dependencies
            run: pip install pyyaml jsonschema
          - name: Validate schema
            run: python scripts/validate_schema.py prompts/
          - name: Run prompt tests
            run: python -m pytest tests/
    
  3. Напишите скрипт валидации схемы scripts/validate_schema.py, который:
  4. Добавьте тесты tests/test_prompts.py для проверки:
    • Все ли обязательные поля присутствуют
    • Не превышают ли промпты лимит токенов (можно грубо 2000 слов)
    • Корректность подстановки переменных

Ожидаемый результат этапа При создании PR с изменением промпта автоматически запускаются линтинг, валидация схемы и юнит-тесты. Без прохождения всех проверок merge невозможен.


Этап 4: Внедрение линтинга качества промптов (30–45 минут)

Действия

  1. Установите promptfoo (инструмент для тестирования и оценки промптов) в окружение CI:
    npm install -g promptfoo
    
    Примечание: можно также использовать кастомный Python-скрипт.
  2. Создайте конфиг promptfoo promptfooconfig.yaml в корне репозитория:
    prompts:
      - file://prompts/assistants/rag_assistant.yaml
    providers:
      - openai:gpt-4o
    tests:
      - vars:
          context: "Документация по продукту X"
          question: "Как настроить Y?"
        assert:
          - type: contains
            value: "шаги"
          - type: latency
            maxMs: 2000
    
  3. Добавьте шаг в CI для запуска promptfoo на каждом PR:
    - name: Run promptfoo
      run: npx promptfoo eval --maxConcurrency 2
    
    (Для первого раза используйте фиктивные тесты, не требующие реального API‑ключа, или используйте eval с fake provider.)
  4. Добавьте скрипт проверки на наличие нежелательного содержимого (например, хардкод ключей API):
    # scripts/check_secrets.py
    import yaml, sys, re
    with open(sys.argv[1]) as f:
        data = yaml.safe_load(f)
    for key in data.get("system", "") + data.get("user_template", ""):
        if re.search(r'sk-[a-zA-Z0-9]{32,}', key):
            print("Ошибка: обнаружен API-ключ в промпте")
            sys.exit(1)
    
  5. Включите этот скрипт в CI

Ожидаемый результат этапа В CI добавлена проверка качества промптов (латенси, ключевые слова, отсутствие секретов).


Этап 5: Интеграция с рантаймом и документация (30 минут)

Действия

  1. Опишите в README.md процесс работы с промптами:
    • Как создать новый промпт (скопировать шаблон, заполнить поля)
    • Как внести изменение (branch → commit → PR → review → merge)
    • Как использовать промпты в коде (ссылка на loader.py)
  2. Добавьте в репозиторий Makefile с командами:
    lint:
    	yamllint prompts/
    test:
    	pytest tests/
    validate:
    	python scripts/validate_schema.py prompts/
    ci: lint validate test
    
  3. Протестируйте полный workflow:
    • Создайте новую ветку, измените промпт
    • Откройте PR, дождитесь CI
    • Запросите code review
    • Слейте изменения
    • Убедитесь, что новый промпт доступен в main

Ожидаемый результат этапа Полностью рабочий процесс prompt as code, описанный в документации, с возможностью быстрого старта для новых разработчиков.


5. Критерии приемки (Definition of Done)

  • Все промпты хранятся в Git‑репозитории в виде YAML-файлов с единой структурой
  • Для каждого промпта определена версия (в YAML поле version)
  • В репозитории есть JSON Schema для валидации промптов
  • Настроен CI‑пайплайн, который при каждом PR в prompts/ запускает:
    • линтинг YAML (yamllint)
    • валидацию схемы
    • юнит-тесты на подстановку переменных
    • проверку на секреты
  • Ветка main защищена: требуется минимум одно approve и прохождение CI
  • Написана документация по процессу работы с промптами (CONTRIBUTING.md)
  • Существует Makefile для локального запуска всех проверок
  • Тестовый сценарий (например, изменение существующего промпта и создание нового) завершился успешно через полный цикл PR → review → merge

6. Ожидаемый результат

  • Артефакт Git-репозиторий company-prompts со структурой, описанной выше, файлами промптов, конфигами CI, скриптами и документацией.
  • Содержимое не менее 5 промптов в YAML, JSON Schema, GitHub Actions workflow, скрипты validate_schema.py, check_secrets.py, тесты test_prompts.py, Makefile, README.md, CONTRIBUTING.md.
  • Опционально интеграция с рантаймом (пример использования loader.py в простом FastAPI приложении) и настроенный promptfoo с несколькими тестовыми сценариями.

7. Возможные сложности и их решение

СложностьРешение
Наличие секретов (API‑ключи) в промптахДобавить в CI скрипт check_secrets.py; обязать разработчиков использовать переменные окружения, а не хардкод
Разрастание количества промптов, сложность навигацииИспользовать поддиректории по назначению; вести индекс INDEX.md с краткими описаниями
Промпты различаются по формату (JSON, Markdown, Python dict)Установить единый формат YAML; конвертировать существующие скриптом миграции
Code review становится узким местомНазначить двух ответственных за промпты; автоматизировать базовые проверки (CI); использовать шаблоны PR
Тесты промптов требуют реального вызова LLM (дорого, медленно)Использовать mock-провайдер в promptfoo или писать тесты на основе регулярных выражений без вызова LLM

8. Бюджет времени (оценка)

ЭтапВремя (часы)
Этап 1: Организация репозитория и структуры0.5
Этап 2: Перенос промптов и шаблонизация1.5
Этап 3: Настройка code review и CI1.0
Этап 4: Линтинг качества промптов0.5
Этап 5: Интеграция и документация0.5
Итого4.0

Примечание: Для первого раза (изучение инструментов, отладка CI) заложите +2 часа.


9. Связанные вопросы из базы знаний

ВопросТема
15Принципы Git Flow для промптов
42Разработка единого формата промптов
73Автоматизация линтинга YAML в CI
128Настройка code review для непрограммистов (промпт-инженеры)
204JSON Schema для конфигурационных файлов
315Работа с переменными в Jinja2
401promptfoo: введение и тестовые сценарии
512Стратегии версионирования промптов (semver)
618Защита веток и Branch protection rules
789Утилита yamllint: конфигурация и интеграция

10. Чек-лист самопроверки

  • Я создал репозиторий с правильной структурой prompts/ и файлами примерами.
  • Все промпты имеют обязательные поля (name, version, system, user_template и т.д.) и прошли yamllint.
  • Я написал validate_schema.py и JSON-схему; при запуске локально она не выдаёт ошибок.
  • Я настроил GitHub Actions с четырьмя шагами (yamllint, validate_schema, test, check_secrets) и убедился, что пайплайн падает при некорректном файле.
  • Я создал тестовый PR с изменением промпта, запросил ревью у коллеги и успешно слил изменения после одобрения и зелёного CI.