Хранилище промптов
Хранилище промптов — централизованное место для шаблонов AI-промптов в Mockarty. Каждый промпт имеет UUID, тело, опциональную модель, теги и, главное, историю версий FIFO-20 с откатом одним вызовом.
AI-кнопки в UI, шаги Test Case Management (TCM) и задачи агента ссылаются на промпты по ID, а не копируют их текст. Правка промпта распространяется на всех потребителей без изменений кода.
Содержание
- Зачем управляемые промпты
- Модель версионирования
- Привязка к AI-кнопкам и шагам TCM
- Примеры для SDK и CLI
Зачем управляемые промпты
Prompt engineering — итеративный процесс. Команда, выпустившая AI-фичу, обычно правит промпт десятки раз за первый месяц. Без хранилища каждая правка требует изменений в шаблонах и передеплоя.
С Prompts Storage:
- Один источник истины — все потребители ссылаются на один ID.
- Безопасные итерации — каждое сохранение создаёт версию; можно сравнить и откатить без потерь.
- Аудит — каждая версия фиксирует автора и время.
- Переносимость — промпты аккуратно экспортируются для air-gapped-деплоев.
Модель версионирования
- Первый
POST /api/v1/stores/promptsсоздаёт версию1. - Каждое последующее
PUTс изменённымbodyсоздаёт новую версию. - История ограничена FIFO-20: при 21-й правке самая старая версия удаляется. Текущая версия всегда доступна через верхнеуровневый
GET. - Откат (
POST /.../rollback?to=N) восстанавливает тело версииN. Текущее тело сначала заталкивается в историю — откат не уничтожает последний черновик.
Синтаксис плейсхолдеров
Тело промпта поддерживает плейсхолдеры в двойных фигурных скобках —
сервер парсит их при сохранении, а потребители (AI-кнопки, agent
chat, окружения API tester) подставляют значения в момент вызова.
- Форма: две открывающие фигурные, имя плейсхолдера, две
закрывающие — напримерHello, {{username}}, summarize {{report_id}}. - Допустимые символы: буквы, цифры,
_. Имена чувствительны к
регистру, по соглашению — нижний регистр. Пишите скобки без пробелов —
{{username}}. Пробелы внутри скобок ({{ username }}) не
распознаются как плейсхолдер. - parsedKeys: ответ create/update эндпоинтов содержит массив
parsedKeysсо всеми уникальными именами в теле. AI-кнопка
использует этот список, чтобы построить структурированную форму
перед вызовом. - Незаполненные значения: переменная, помеченная required, без
значения по умолчанию и без переданного значения — рендер падает с
ошибкой. Любой другой незаполненный плейсхолдер подставляется как пустая
строка (а не как<no value>).
Привязка к AI-кнопкам и шагам TCM
AI-кнопки в UI («Суммаризировать падения», «Объяснить мок») принимают promptId. Агент Mockarty подгружает текущую версию при вызове; откат промпта мгновенно меняет поведение кнопки.
Шаги TCM работают аналогично: шаг типа ai-assisted хранит promptId, а не inline-шаблон.
Примеры для SDK и CLI
CLI
mockarty-cli prompts create \
--name tcm-step-summarizer \
--body "Summarize the following test step in one sentence: {{.step}}" \
--model claude-opus-4-7 \
--tag tcm --tag summary
mockarty-cli prompts update "$PROMPT_ID" --body "Summarize in ≤15 words: {{.step}}"
mockarty-cli prompts versions list "$PROMPT_ID"
mockarty-cli prompts versions rollback "$PROMPT_ID" 1
Go SDK
p, _ := client.Prompts().CreatePrompt(ctx, mockarty.Prompt{
Name: "tcm-step-summarizer",
Body: "Summarize the following test step in one sentence: {{.step}}",
Model: "claude-opus-4-7",
Tags: []string{"tcm", "summary"},
})
_, _ = client.Prompts().UpdatePrompt(ctx, p.ID, mockarty.Prompt{Body: "Summarize in ≤15 words: {{.step}}"})
versions, _ := client.Prompts().ListVersions(ctx, p.ID)
_ = versions
_, _ = client.Prompts().Rollback(ctx, p.ID, 1)
Python SDK
p = client.prompts.create(
name="tcm-step-summarizer",
body="Summarize the following test step in one sentence: {{.step}}",
model="claude-opus-4-7",
tags=["tcm", "summary"],
)
client.prompts.update(p["id"], body="Summarize in ≤15 words: {{.step}}")
versions = client.prompts.list_versions(p["id"])
client.prompts.rollback(p["id"], to_version=1)
Java SDK
Map<String, Object> p = client.prompts().create(
"tcm-step-summarizer",
"Summarize the following test step in one sentence: {{.step}}",
Map.of("model", "claude-opus-4-7", "tags", List.of("tcm", "summary")));
client.prompts().update((String) p.get("id"),
Map.of("body", "Summarize in ≤15 words: {{.step}}"));
List<Map<String, Object>> versions = client.prompts().listVersions((String) p.get("id"));
client.prompts().rollback((String) p.get("id"), 1);
См. также: AI-функции, Хранилище секретов.