Движок разметки: CLI, REST API, инструменты MCP и SDK
Управляйте движком разметки через potato label, маршруты REST /api/engine/v1, пять инструментов MCP или класс Study в Python, всё над одним файлом engine.sqlite.
Сервер разметки, командная строка, REST API, инструменты MCP и Python SDK управляют одним и тем же движком разметки через один и тот же файл engine.sqlite в каталоге задачи. Можно начать исследование из командной строки, выдавать запросы людям через сервер и сертифицировать из ноутбука.
Исследованием одновременно управляет только один процесс. Планировщик запущенного сервера держит блокировку записи исследования, и пока он её держит, potato label run, potato label certify и Study.run() отказываются работать и сообщают об этом. Вместо этого сертифицируйте через сервер, с помощью POST /api/engine/v1/certify или админ-страницы. Блокировка нужна потому, что два управляющих процесса отобрали бы две калибровочные выборки и сертифицировали бы по меткам друг друга. Блокировка снимается, когда её владелец завершается. Владельца, убитого на той же машине, сразу заменяют, а владельца на другой машине заменяют после двух минут без сигнала жизни. Команды только для чтения (status, certificate, calls, export) работают в любое время.
Командная строка
Каждая команда движка принимает файл конфигурации исследования:
potato label <command> <config.yaml> [options]Девять команд покрывают исследование от первого вызова модели до экспортированного набора данных:
| Команда | Что делает |
|---|---|
run | Размечает каждый объект каскадом, отбирает слепую калибровочную выборку, сертифицирует и разрешает метки. --until predicted (по умолчанию) останавливается после одного прохода, а --until met продолжает, пока каждый контракт не будет выполнен или движок не будет ждать людей. Также принимает --max-items N, --budget-usd X (переопределяет budgets.model_usd для этого прогона), --max-ticks N (по умолчанию 20) и --json. Прерванный прогон продолжается с места остановки без повторных вызовов моделей. Завершается со статусом 1 и называет источник, если последний прогон источника завершился сбоем или все его ответы оказались ошибками, либо если ни один источник не может разметить схему, названную в контракте. |
status | Объекты, предсказания, запросы по целям, контракты, траты, объекты пока без метки и строка для каждого источника с ошибками либо со сбойным или приостановленным прогоном. --json. |
certify | Проверяет каждый контракт на новых cert-метках и новых предсказаниях. Если изменились только dev-метки, возвращается сохранённый результат с примечанием, а --retest проверяет правило, которое теперь выбирает dev, на следующей попытке (см. Попытки). --json. |
certificate | Сертификат качества. --format md (по умолчанию), html или json, и --out FILE. |
export | Метки с происхождением, сертификат (JSON, Markdown, HTML), карточка набора данных и журнал вызовов в --out DIR (по умолчанию <output_annotation_dir>/labeling_engine). |
calls | Журнал аудита вызовов моделей в виде строк JSON. --out FILE. |
distill | Обучает модель на уже собранных метках и ставит её первой в каскаде. |
optimize | Оценивает каждое подмножество каскада на dev-метках и сообщает самое дешёвое, которое сохраняет покрытие. Если ни одно подмножество не сохраняет покрытия, не рекомендует ничего. --prompts N также просит уровень LLM написать N перефразировок своего промпта и оценивает каждую на dev-объектах. Это вызовы моделей, они записываются в журнал, учитываются в бюджете и хранятся под собственными версиями источника, а текущий промпт оценивается по сохранённым предсказаниям. Каскад и сертификат не меняются. |
migrate-config | Записывает копию конфигурации с блоком labeling_engine, эквивалентным её старым ключам ИИ. --out FILE. См. Переход на движок разметки. |
Проверка прогресса ничего не тратит, потому что status, certificate и админ-страница читают сохранённые результаты. Каждый новый тест, будь то certify на новых метках или certify --retest, тратит часть бюджета ошибки контракта.
Файлы, которые записывает экспорт
potato label export записывает в выходной каталог файлы четырёх видов:
| Файл | Содержимое |
|---|---|
labels.jsonl, labels.csv | Одна строка на объект и схему, с меткой или без, с полями id, schema, label, label_origin (auto, human, adjudicated, ...), status (accepted, accepted_uncertified при threshold_legacy, pending, pending_recert), source, model, source_version, confidence, contract_version и request_ids. Машинная метка, источник которой изменился после её принятия, имеет статус pending_recert, пока следующий проход её не пересертифицирует. |
certificate.json, .md, .html | Сертификат. |
README.md | Карточка набора данных с front matter для Hugging Face, построенная по сертификату. |
model_calls.jsonl | Каждый вызов модели с моделью, хешами промпта и ответа, токенами, задержкой, стоимостью, попаданиями в кэш и категориями маскирования. |
Обычные экспортёры (python -m potato.export и экспорт из админ-панели) экспортируют разметку людей, а их список есть на странице форматов экспорта. Среди них формат labeling_engine записывает те же файлы, что и potato label export, и отказывается работать, если движок не включён. Когда движок включён, экспорт в CSV, Parquet и Hugging Face добавляет два столбца, которые говорят, на какой запрос движка отвечала каждая разметка. engine_purpose содержит цель, например calibration, а engine_request содержит JSON с целью, вероятностью включения, видимостью, частью выборки и id запроса. По этим столбцам слепую случайную выборку можно отделить от ответов на запросы проверки.
REST API
Все маршруты движка находятся под /api/engine/v1 и возвращают JSON. Аутентифицируйтесь ключом администратора в заголовке X-API-Key или сессией администратора. Для чтения нужно право на админ-панель, для certify и plan нужно управление распределением, а для сертификата нужно право на экспорт.
| Метод и путь | Возвращает |
|---|---|
GET /status | Объекты, предсказания, запросы, итоги вызовов, бюджеты, а для каждой схемы её каскад, контракты и число разрешённых меток |
GET /schemes/<name>/contracts | Последний результат каждого контракта на схеме, с пометкой stale, если каскад изменился |
GET /schemes/<name>/risk_coverage | Для каждого порога последнего уровня долю принятых, наблюдаемую ошибку и гарантированную верхнюю границу на cert-метках |
GET /schemes/<name>/reliability | Бины надёжности, ECE и оценку Брайера для каждого уровня на калибровочных метках |
GET /schemes/<name>/drift | Монитор аудитов для каждого контракта селективного риска |
GET /schemes/<name>/optimize | Отчёт о более дешёвом каскаде, оценённый на dev-метках |
GET /requests | Число запросов по целям и статусам и сами запросы. Фильтры: purpose, status (повторите параметр или перечислите значения через запятую), schema и limit (не больше 1000) |
GET /calls | Журнал вызовов, сначала новые, и итоги по источникам. limit (не больше 500), offset |
GET /certificate | Сертификат. format=json (по умолчанию), md или html, а save=1 также сохраняет его |
GET /crowd | Последний план планировщика по краудсорсингу, пробный запуск, если не включены реальные траты |
POST /certify | Проверить каждый контракт сейчас. ?retest=1 (или {"retest": true}) также проверяет правило, которое изменили только dev-метки |
POST /plan | Выполнить один проход планировщика сейчас |
Маршруты отвечают 404, когда движок для исследования выключен. Они отвечают 400 с ошибкой в JSON на недопустимый параметр, например limit, который не является числом, неизвестные purpose или status либо format, отличный от json, md или html.
Например, этот запрос получает текущий сертификат в формате Markdown с сервера на порту 8000:
curl -H "X-API-Key: $ADMIN_API_KEY" \
"http://localhost:8000/api/engine/v1/certificate?format=md"Инструменты MCP
MCP-сервер предоставляет пять инструментов движка с теми же правами, что и маршруты REST:
engine_statusengine_requestsengine_run, который выполняет один проход планировщикаengine_certify, который принимаетretestengine_certificateв форматахjson,mdилиhtml
Выдача этих инструментов при выключенном движке вызывает предупреждение валидации. Через potato mcp connect отклонённый вызов (нет права, неверный параметр) возвращается как ошибка инструмента с сообщением сервера. Выдача инструментов и подключение клиента описаны в документации MCP-сервера.
Python SDK
Класс Study управляет движком из Python, например в ноутбуке:
from potato.labeling_engine.sdk import Study
study = Study("examples/labeling-engine/text-certified-sentiment/config.yaml")
study.run() # label, sample, certify, resolve
for req in study.requests(status="open")[:5]:
study.label(req.item_id, req.schema, "positive", user="me")
study.certify()
print(study.certificate(fmt="md"))
study.export("out/")Каждый метод повторяет команду или маршрут:
| Метод | Что делает |
|---|---|
Study(config_path) | Загружает конфигурацию и объекты |
run(until="predicted", max_ticks=20) | Как potato label run, и берёт блокировку записи |
label(item_id, scheme, value, user, request_id=None) | Записывает метку человека. Закрывает request_id, а если его нет, запрос, который этот человек держит по объекту, иначе метка сохраняется как органическая и никогда не сертифицирует. Вторая метка того же человека на том же объекте обновляет первую |
status() | Как GET /status |
requests(status=None, purpose=None, ...) | Реестр запросов |
certify(retest=False) | Как potato label certify |
certificate(fmt="json") | json, md или html |
export(out_dir) | Как potato label export |
Пример размечает каждый открытый запрос как «positive» только для того, чтобы показать вызовы. Метка, записанная через Study.label и не отвечающая ни на один запрос, сохраняется как органическая, а органические метки никогда не сертифицируют, поэтому скрипт, размечающий объекты, которые движок не запрашивал, добавляет метки, которые не читает ни один контракт.
Дополнительные материалы
- Движок разметки
- Конфигурация движка разметки
- Контракты движка разметки
- Админ-панель, которая ссылается на админ-страницу движка
Подробности реализации смотрите в исходной документации.