Что такое «prompt as code» (промпты в Git, code review)?
Краткий тезис
Prompt as code — это практика управления промптами (текстовыми инструкциями для LLM) как программным кодом: хранение в системе контроля версий (Git), code review через Pull Request, автоматическое тестирование (CI) и деплой (CD) в Prompt Registry. Цель — обеспечить воспроизводимость, версионирование, коллаборацию и надёжность при работе с промптами, особенно в масштабируемых agentic RAG-системах. Без этой практики промпты часто редактируются «на лету» в ноутбуках или продакшн-конфигах, что ведёт к неконтролируемым изменениям и сложности отката.
1. Термин: «Prompt as code» — происхождение и аналогия
Практика заимствована из Infrastructure as Code (IaC) и Data as Code. Идея: промпт — это не статичный текст, а сущность, которая должна проходить формальный жизненный цикл:
- Разработка → Ревью → Тестирование → Релиз → Мониторинг.
Термин «Prompt as code» ввёл в широкий обиход OpenAI в своих рекомендациях по безопасному развёртыванию LLM (2023). Ключевые принципы:
- Хранение в Git — каждый промпт — файл (YAML, JSON, Markdown) с метаданными.
- Версионирование — семантическое версионирование (semver) для промптов.
- Code Review — изменения промпта проходят ревью, как и обычный код.
- CI/CD — при изменении запускаются тесты на регрессию и метрики качества.
- Регистрация — утверждённый промпт публикуется в централизованное хранилище (Prompt Registry).
2. Проблемы ad-hoc управления промптами (почему это важно)
До внедрения prompt as code команды часто сталкиваются с хаосом:
| Проблема | Описание | Последствие |
|---|---|---|
| Неявные изменения | Промпт правят в интерфейсе LLM или в коде на лету | Невозможно отследить, когда и кем изменён |
| Отсутствие версий | Нет истории изменений | Сложно откатить к рабочей версии |
| Ручное тестирование | Промпты проверяют вручную | Риск регрессии после небольшого изменения |
| Конфликт при мерже | Два разработчика меняют один промпт | Потеря изменений |
| Разные окружения | dev/staging/prod имеют разные версии | Ошибки из-за несоответствия |
Prompt as code решает эти проблемы через стандартные DevOps-практики.
3. Жизненный цикл промпта как кода
3.1 Разработка и формат
Промпт хранится в файле с метаданными. Пример структуры:
# prompts/agentic_rag/v1.2.3.yaml
version: "1.2.3"
name: "agentic_rag_system_prompt"
model: "gpt-4-turbo"
template: |
You are an AI assistant that helps answer questions using the provided context.
Always cite sources in the format [1], [2], etc.
If the context does not contain the answer, say "I don't know" – do not make up information.
Context:
{context}
Question: {question}
variables:
- name: context
type: string
description: "Retrieved documents concatenated"
- name: question
type: string
description: "User query"
tests:
- name: "test_grounded_answer"
input:
context: "Paris is the capital of France. [1]"
question: "What is the capital of France?"
expected_response_contains: "Paris"
expected_citation: true
- name: "test_no_context_refusal"
input:
context: ""
question: "Who invented the telephone?"
expected_response_contains: "I don't know"
metadata:
author: "alice.ml-team"
created: "2025-03-01"
description: "System prompt for agentic RAG with citation requirement"
3.2 Code Review
- Разработчик создаёт ветку
feature/update-prompt-v1.3.0. - Открывает Pull Request с изменениями в
prompts/agentic_rag/. - Ревьюеры проверяют:
- Корректность семантики промпта.
- Добавлены ли тесты для нового сценария.
- Не нарушена ли обратная совместимость (например, не удалены обязательные переменные).
3.3 CI — Автоматическое тестирование
GitHub Actions (или аналоги) при создании PR запускают конвейер:
# .github/workflows/prompt-tests.yml
name: Prompt CI
on: [pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Install dependencies
run: pip install openai pytest pyyaml
- name: Run prompt tests
run: |
for file in prompts/*.yaml; do
python validate_and_test.py --prompt-file "$file" --test-suite
done
validate_and_test.py загружает промпт, подставляет переменные из тестовых случаев, вызывает LLM и проверяет условия (expected_response_contains, наличие цитат и т.п.).
3.4 CD — Деплой в Prompt Registry
После мержа в main (или master) происходит деплой:
- Промпт загружается в Prompt Registry (например, S3 + DynamoDB или LangSmith Hub).
- Реестр хранит все версии, текущая отмечается как latest.
- Система (агент или RAG-пайплайн) при запуске загружает промпт по имени и версии (или подписывается на обновления).
Пример загрузки в реестр (Python-скрипт):
import yaml
import boto3
from datetime import datetime
def deploy_prompt(prompt_file):
with open(prompt_file) as f:
prompt = yaml.safe_load(f)
registry = boto3.client('s3')
key = f"prompts/{prompt['name']}/{prompt['version']}.yaml"
registry.put_object(Bucket='my-prompt-registry', Key=key, Body=yaml.dump(prompt))
print(f"Deployed {prompt['name']} version {prompt['version']}")
4. Prompt Registry — централизованное хранилище
Prompt Registry — это сервис (или просто бакет), который позволяет:
- Регистрировать новые версии.
- Получать промпт по имени и версии (или latest).
- Версионировать и отслеживать изменения.
- Проводить A/B тестирование — два параллельных промпта (контроль и эксперимент).
Пример архитектуры:
┌─────────────┐ CI/CD ┌──────────────────┐
│ Git (main) │ ────────>│ Prompt Registry │
│ prompts/* │ │ (S3 + index) │
└─────────────┘ └──────────────────┘
│
▼
┌──────────────────┐
│ Agent/RAG system │
│ загружает промпт │
│ при инициализации│
└──────────────────┘
Популярные готовые решения:
- LangSmith Hub — встроенный реестр от LangChain.
- PromptLayer — коммерческий сервис для управления промптами.
- Agenta — open-source платформа для разработки и версионирования промптов.
- Собственный реестр на FastAPI + PostgreSQL для полного контроля.
5. Связь с тестированием и метриками
Для prompt as code критически важно иметь регрессионные тесты. Они могут включать:
- Семантические проверки (содержит ли ответ конкретную фразу).
- Проверку фактов (faithfulness) — ответ не противоречит контексту.
- Метрики качества (answer relevance, context recall) через фреймворки вроде RAGAS или DeepEval.
Пример теста с pytest:
import pytest
import openai
import yaml
def load_prompt(path):
with open(path) as f:
return yaml.safe_load(f)
prompt_data = load_prompt("prompts/rag_system/v1.yaml")
def test_citation_present():
client = openai.OpenAI()
response = client.chat.completions.create(
model=prompt_data['model'],
messages=[
{"role": "system", "content": prompt_data['template'].format(
context="Earth is round [1].", question="What shape is Earth?")},
]
)
assert "[1]" in response.choices[0].message.content
6. Интеграция с Agentic RAG
В agentic RAG промпты ещё сложнее: они содержат описание инструментов (tools), структуру планирования (planning) и правила принятия решений. Практика prompt as code особенно полезна здесь:
- Системный промпт — задаёт поведение агента.
- Промпты для инструментов — описание каждого tool (function calling).
- Планировщик — промпт, который разбивает задачу на шаги.
- Правила рефлексии — промпт для самооценки (Self-RAG).
Все эти промпты должны быть версионированы и тестироваться совместно. Изменение одного может повлиять на всё поведение агента.
7. Инструменты и лучшие практики
| Инструмент | Описание | Когда выбрать |
|---|---|---|
| LangSmith Hub | Встроенный реестр, интеграция с LangChain | Используете LangChain |
| PromptLayer | Платформа с мониторингом, A/B, версиями | Нужна аналитика |
| Agenta | Open-source, веб-интерфейс для редактирования | Команда не разработчиков |
| Собственный реестр | Полный контроль, низкая стоимость | Стартап/enterprise |
Лучшие практики
- Используйте семантическое версионирование
major.minor.patch:- major — изменение поведения (breaking change).
- minor — добавление нового теста или незначительное улучшение.
- patch — исправление опечатки.
- Всегда указывайте модель (model) и параметры (temperature, max_tokens).
- Храните тесты в отдельной директории
prompts/tests/рядом с файлами. - Настройте автоматический откат при провале тестов.
Пет-проект для закрепления
Задача Создать репозиторий с тремя версиями промпта для RAG-системы, настроить CI/CD (GitHub Actions) для тестирования и деплоя в локальный Prompt Registry на FastAPI.
Инструменты
Шаги:
- Создайте структуру репозитория:
prompts/ rag_assistant/ v1.0.0.yaml v1.1.0.yaml v2.0.0.yaml tests/ test_prompts.py registry/ (FastAPI приложение) .github/workflows/ prompt-ci.yml prompt-cd.yml - Напишите минимальный реестр на FastAPI с эндпоинтами
POST /promptsиGET /prompts/{name}/{version}. - В GitHub Actions:
- CI: при пул-реквесте запускать
pytest tests/для каждого изменённого промпта. - CD: при мерже в main деплоить промпты в реестр (выполнить POST-запрос).
- CI: при пул-реквесте запускать
- Добавьте тесты на:
- Наличие ответа с фактами из контекста.
- Корректное игнорирование нерелевантного контекста.
Ожидаемый результат
- Репозиторий, в котором истории изменений промптов полностью прозрачна.
- При каждом PR автоматически проверяются регрессионные тесты.
- После мержа промпт сразу доступен через API реестра для использования в приложении.
Связь с другими вопросами
| Вопрос | Тема |
|---|---|
| 801 | Что такое Agentic RAG? |
| 803 | Как проектировать пайплайны промптов? |
| 804 | Что такое динамический выбор промптов? |
| 805 | Как оценивать агентов? |
| 808 | Инструменты (tools) в агентах |
| 809 | Память в агентах |
Навигация
- Предыдущий: 801
- Следующий: 803
- Индекс: 00. Индекс разборов