English translation is not available yet. Showing Russian content.

Реализовать dependency management промптов

ТЕХНИЧЕСКОЕ ЗАДАНИЕ: Реализовать dependency management промптов

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

Разработать систему управления зависимостями между промптами в AI-приложении, которая гарантирует, что при изменении промпта‑компонента автоматически выполняются тесты для всех промптов, зависящих от него. Это предотвращает каскадные ошибки и снижает время на тестирование|регрессионное тестирование вручную.

Ключевой результат Рабочий инструмент, который строит граф зависимостей]] промптов]], детектирует изменения и запускает только необходимые тесты, выводя визуализированный граф и отчёт о выполнении.


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

Что нужноОткуда взять
Репозиторий с промптами (YAML/JSON)Создать тестовый набор или взять из существующего проекта
Описание зависимостей между промптамиРазметить вручную (например, поле depends_on в метаданных промпта)
Тестовая среда (Python 3.10+)Локальная установка или Docker-образ
Примеры тестов для промптов (pytest)Написать простые тесты на корректность формата, токенов и вызовов

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

  1. Создаём каталог prompts/ с 5–10 файлами вида prompt_*.yaml, каждый содержит:
    id: prompt_A
    text: "Ты — ассистент. Ответь на вопрос: {question}"
    depends_on: ["prompt_B", "prompt_C"]   # список зависимостей
    tests: ["test_A.py::test_output_length", "test_A.py::test_uses_B"]
    
  2. Создаём каталог tests/ с тестовыми файлами (pytest), проверяющими, что промпты корректно формируются и вызывают свои зависимости.
  3. Пишем скрипт для генерации случайных графов зависимостей (например, с помощью networkx.generators.random_graphs).

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

КомпонентИнструментыНазначение
ЯзыкPython 3.10+Основная разработка
Работа с графамиnetworkx, pyvisПостроение и визуализация графа зависимостей
Управление зависимостямиpip, poetryИзоляция окружения
Тестированиеpytest, pytest-xdistЗапуск тестов (в т.ч. параллельно)
CI/CD (опционально)GitHub ActionsАвтоматический запуск при пуше в репозиторий
Формат промптовYAML (PyYAML)Чтение метаданных промптов
Мониторинг измененийgit diff / watchdogОбнаружение изменений в файлах промптов

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

Этап 1: Анализ и проектирование (30 минут)

Действия

  1. Определить структуру метаданных промпта (обязательное поле depends_on).
  2. Спроектировать схему графа: узлы — id промптов, рёбра — зависимости (направленные от зависимого к базовому).
  3. Выбрать способ обнаружения изменений: сравнивать хэш содержимого файла (SHA256) с предыдущим состоянием.
  4. Набросать архитектуру модулей:
    • prompt_reader.py – загрузка и парсинг YAML-файлов.
    • dependency_graph.py – построение графа, поиск транзитивных зависимостей.
    • change_detector.py – отслеживание изменений (git diff или кэш хэшей]]).
    • test_runner.py – запуск тестов для затронутых промптов.
    • visualizer.py – визуализация графа (HTML/PNG).

Ожидаемый результат этапа Документ (Markdown или draw.io) с описанием архитектуры и примером структуры промпта.


Этап 2: Реализация ядра (2–3 часа)

Действия

  1. Создать класс PromptGraph на основе networkx.DiGraph:

    • Метод build_from_directory(path) – обходит все .yaml файлы, читает id и depends_on, добавляет узлы и рёбра.
    • Метод get_affected_prompts(changed_prompts: list[str]) – возвращает множество всех промптов, которые зависят от изменённых (прямо или транзитивно). Использует BFS по обратным рёбрам.
    • Метод visualize(output_path) – генерирует HTML-файл с интерактивным графом (pyvis) и сохраняет PNG (matplotlib).
  2. Реализовать ChangeDetector:

    • При первом запуске сохраняет SHA256 всех файлов в prompts/.hash_cache.json.
    • При последующих запусках сравнивает текущие хэши с кэшем; возвращает список changed_prompts.
    • Обновляет кэш после успешного выполнения тестов.
  3. Реализовать TestRunner:

    • Читает из метаданных промпта поле tests (список путей к тестовым функциям).
    • Вызывает pytest.main() с аргументами -k или явным списком тестовых функций.
    • Возвращает результат (успех/неудача) и логи.
  4. Объединить в основном скрипте main.py:

    def main():
        graph = PromptGraph()
        graph.build_from_directory("prompts/")
        changed = ChangeDetector.detect("prompts/")
        if not changed:
            print("No changes detected.")
            return
        affected = graph.get_affected_prompts(changed)
        print(f"Changed: {changed}, Affected: {affected}")
        test_result = TestRunner.run(affected)
        if test_result.failed:
            print("Tests failed. Abort merge.")
        else:
            ChangeDetector.update_cache("prompts/")
        graph.visualize("output/graph.html")
    

Ожидаемый результат этапа Рабочий скрипт, который при изменении prompt_B.yaml запускает тесты для prompt_B и всех промптов, на него ссылающихся, и выводит граф.


Этап 3: Создание тестового набора и валидация (1 час)

Действия

  1. Сгенерировать 5–10 промптов с пересекающимися зависимостями (например, A -> B, A -> C, B -> D). Использовать скрипт-генератор.
  2. Написать тесты (pytest) для каждого промпта:
    • test_prompt_A_output_length – проверяет, что длина ответа для примера не превышает 1000 токенов.
    • test_prompt_A_includes_B – проверяет, что в теле промпта подставляется шаблон из B.
  3. Имитировать изменение: вручную изменить содержимое prompt_D.yaml и запустить main.py.
  4. Проверить, что affected включает D, B, A, и что тесты для всех трёх выполняются.
  5. Проверить корректность визуализации графа.

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


Этап 4: Интеграция в CI (1 час)

Действия

  1. Создать Dockerfile с Python-окружением.
  2. Настроить docker-compose.yml для запуска скрипта.
  3. Добавить GitHub Actions workflow (.github/workflows/check_prompts.yml):
    on:
      push:
        paths:
          - 'prompts/*.yaml'
          - 'tests/*.py'
    jobs:
      check:
        runs-on: ubuntu-latest
        steps:
          - uses: actions/checkout@v3
          - name: Run dependency manager
            run: |
              pip install -r requirements.txt
              python main.py
            env:
              PYTHONPATH: .
          - name: Upload graph artifact
            uses: actions/upload-artifact@v3
            with:
              name: dependency-graph
              path: output/graph.html
    
  4. Убедиться, что при сломанном тесте workflow завершается с ошибкой.

Ожидаемый результат этапа Автоматическая проверка зависимостей при каждом пуше в репозиторий, артефакт с графом.


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

Действия

  1. Написать README.md с примером использования, установкой и описанием метаданных.
  2. Привести пример вывода графа (скриншот).
  3. Описать, как добавить новый промпт в систему.
  4. Подготовить краткую демонстрацию для команды (5-10 минут).

Ожидаемый результат этапа Документация, готовая к передаче в ревью.


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

  • Реализован модуль построения графа зависимостей по YAML-файлам.
  • При изменении одного промпта автоматически определяются все транзитивно зависимые промпты.
  • Запускаются только тесты для изменённого и зависимых промптов.
  • Граф визуализируется в интерактивном HTML и статическом PNG.
  • Кэш хэшей файлов сохраняется и используется для детекции изменений.
  • Интеграционный тест (3+ промпта, каскадная зависимость) проходит успешно.
  • CI/CD workflow запускается при пуше в prompts/ и tests/.
  • Документация (README) описывает установку, настройку и пример использования.
  • Код покрыт unit-тестами (минимум 70% покрытие модуля dependency_graph.py).

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

Основной артефакт

  • Репозиторий с кодом, включающий:
    • prompt_reader.py, dependency_graph.py, change_detector.py, test_runner.py, visualizer.py, main.py.
    • Конфигурационные файлы (requirements.txt, Dockerfile, .github/workflows/check_prompts.yml).
    • Пример 5–10 промптов в prompts/.
    • Тесты в tests/.

Дополнительные результаты

  • Сгенерированный граф зависимостей (output/graph.html).
  • Отчёт о выполнении тестов (stdout/CI logs).
  • Документация (README.md).

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

СложностьРешение
Циклические зависимости в промптахВвести проверку при добавлении ребра: networkx.has_path(graph, child, parent); при обнаружении цикла выбрасывать исключение и останавливать сборку.
Изменение файла тестов (без изменения промпта)ChangeDetector должен отслеживать только файлы .yaml в prompts/. Тесты запускаются только если их имя указано в изменённом промпте.
Большое количество промптов (>1000)Использовать networkx с оптимизированными структурами; кэшировать хэши в SQLite вместо JSON для быстрого поиска.
Разные команды используют разные форматы промптовЗадать единый контракт метаданных (YAML с полями id, depends_on, tests); предоставить миграционный скрипт.

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

ЭтапВремя
Анализ и проектирование30 мин
Реализация ядра2,5 ч
Создание тестового набора и валидация1 ч
Интеграция в CI1 ч
Документирование и демонстрация30 мин
Итого~5,5 ч

Примечание Для первого выполнения время может увеличиться до 8 часов из-за доработки деталей и отладки.


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

ВопросТема
15Prompt versioning
23Template injection prevention
47Prompt testing strategies
68Dependency injection in LLM pipelines
112Change detection in configuration files
188CI/CD for ML pipelines
205Graph databases for prompt lineage
312Caching strategies in AI systems
401Pytest fixtures for LLM prompts
567Visualization of computational graphs

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

  • Я проверил, что main.py корректно обрабатывает случай отсутствия изменений.
  • Я написал хотя бы один юнит-тест для get_affected_prompts с графом из 5 узлов.
  • Я убедился, что кэш хэшей обновляется только после успешного прогона тестов.
  • Я протестировал, что при цикле в зависимостях выбрасывается исключение.
  • Я убедился, что артефакт графа загружается в CI и доступен для скачивания.