Структурированный вывод
Передайте схему вывода и получите проверенный JSON в data, собранный только со страниц, которые посетил агент.
Каждый запуск возвращает текстовый answer. Добавьте output_schema, и запуск также вернёт в data соответствующий ей JSON. JSON собирается из текста и ссылок посещённых агентом страниц и из его ответа, а не из догадок, поэтому URL ссылок — настоящие, взятые со страницы. Структурированный вывод ничего не стоит сверх обычного.
JSON через output_schema#
Передайте нужную структуру. Краткая форма сопоставляет каждому полю тип:
curl https://lovelyrouter.com/v1/browser/runs \
-H "Authorization: Bearer $LOVELY_API_KEY" \
-H "content-type: application/json" \
-d '{
"goal": "Get the top 3 stories on the front page.",
"start_url": "https://news.ycombinator.com/",
"output_schema": {
"stories": [{"title": "string", "url": "string", "points": "integer"}]
}
}'Завершённый запуск содержит JSON в data, рядом с answer:
{
"id": "brun_8f3c2d1e0a9b8c7d6e5f4a3b",
"object": "browser_run",
"status": "succeeded",
"steps": 1,
"answer": "The top 3 stories are \"Bitwarden Dual License Model\" (95 points), \"Talorys – A self-hosted personal AI agent\" (57 points) and \"REA Reverse – Engineer Anything\" (498 points).",
"data": {
"stories": [
{ "title": "Bitwarden Dual License Model", "url": "https://community.bitwarden.com/…", "points": 95 },
{ "title": "Talorys – A self-hosted personal AI agent", "url": "https://github.com/rociiu/talorys", "points": 57 },
{ "title": "REA Reverse – Engineer Anything", "url": "https://rea.tools/", "points": 498 }
]
},
"charge_usd": 0.006
}Примеры на Python и Node.js используют настройку API, H и headers из раздела Запуск первой задачи.
Краткая схема#
Краткая схема — это обычный JSON, где каждое значение описывает поле:
| Вы пишете | Вы получаете |
|---|---|
"string", "number", "integer", "boolean", "array", "object", "null" | Значение этого типа или null, если на странице его нет |
Любой другой текст, например "price as shown, with currency" | Строку или null. Ваш текст подсказывает агенту, что туда поместить |
["string"], [{...}] | Список таких элементов. [] — список чего угодно |
{"field": ...} | Объект ровно с этими полями, все присутствуют |
Описание делает поле строкой: "price": "price in USD" вернёт "$19.99", а не число. Если нужно число, используйте "number".
Если на верхнем уровне схемы есть ключ type, properties, items или $schema, она читается как полная JSON Schema, а не как краткая форма. Чтобы вернуть поле с одним из этих имён, напишите полную JSON Schema.
Полная JSON Schema#
Для перечислений, форматов, обязательных полей или описаний типизированных полей передайте JSON Schema (draft 2020-12):
{
"goal": "Find the 2026 Toyota Camry trims on the build page with their starting MSRP and engine.",
"start_url": "https://www.toyota.com/camry/",
"output_schema": {
"type": "object",
"properties": {
"trims": {
"type": "array",
"items": {
"type": "object",
"properties": {
"name": { "type": "string" },
"msrp_usd": { "type": "number", "description": "Starting MSRP, without fees" },
"engine": { "type": "string" },
"hybrid": { "type": "boolean" }
},
"required": ["name", "msrp_usd"]
}
}
},
"required": ["trims"]
}
}Результат проверяется по схеме. Если первая попытка не проходит проверку, агент получает ошибки валидации и один раз исправляет результат. Размер схемы — до 20 КБ. Схема, не являющаяся корректной JSON Schema, при запуске возвращает 400: "output_schema" is not a usable JSON Schema: ….
Чтение data и data_error#
| Поле | Когда |
|---|---|
data | JSON после завершения запуска. null, пока запуск идёт, если вы не запрашивали структуру или если извлечь данные не удалось. |
data_error | Присутствует, только если извлечь данные не удалось, и содержит причину, например extracted data does not match the schema: … и затем поля, не прошедшие проверку. |
Значения, которых нет на страницах, возвращаются как null, а списки — пустыми; ничего не выдумывается. Значения секретов никогда не попадают в data: они заменяются на [secret:<name>].
Проверяйте data_error, прежде чем использовать data:
if run.get("data_error"):
raise RuntimeError(f"no data: {run['data_error']}")
trims = run["data"]["trims"]Формат в самой цели#
Структуру можно запросить и в самой цели, например: «Верни JSON-список открытых вакансий с названием, командой и местоположением». Когда цель просит структурированные данные определённой формы (JSON, именованные поля, список или таблицу с заданными столбцами), запуск тоже заполняет data в этой форме. Без схемы проверять не по чему, поэтому используйте output_schema, если ваш код зависит от точной структуры.
Если запуск завершился раньше#
- Лимит шагов. Запуск, достигший
max_steps, завершается какfailedсreached the step limit (N). Он всё равно пишетanswerпо последней странице и заполняетdataтем, что успел увидеть. - Ошибка или тайм-аут.
dataзаполняется по уже посещённым страницам, поэтому данные могут быть неполными. - Остановлен. Остановленный вами запуск не возвращает
data.
Как получить данные получше#
- Называйте поля так, как они названы на странице. Имена полей направляют извлечение, а имена верхнего уровня добавляются в инструкции агента, чтобы он заканчивал работу на страницах, где они показаны.
pointsиcommentsработают лучше, чемscoreиn. - Просите в цели всё, что есть в схеме. «Получи 5 главных историй с заголовком, ссылкой и очками» вместе с подходящей схемой работает лучше, чем одна схема.
- Не берите много страниц. Данные берутся с последних шести страниц, которые посетил агент. Если данные разбросаны по многим страницам, запускайте по одной задаче на страницу или группу страниц.
- Делайте необязательные поля необязательными. В полной схеме перечисляйте в
requiredтолько поля, которые нужны всегда. Поля краткой схемы всегда могут бытьnull. - Для длинных таблиц используйте точный режим. Он умеет читать длинную таблицу или список кодом на странице, а не только из видимого текста. См. Режимы.
Примеры#
Подтверждение заказа после отправки формы:
{
"goal": "Order one Blue Mug (size large) for Ada Lovelace, 12 Main St, Springfield, IL 62701, and tell me the order number and total.",
"start_url": "https://shop.example.com/mugs/blue",
"secrets": ["shop_user", "shop_password"],
"output_schema": { "order_number": "string", "total": "number", "currency": "string" }
}При значении по умолчанию "approve": "risky" этот запуск приостанавливается и ждёт вашего одобрения перед оформлением заказа. См. Человек в контуре.
Результаты поиска с вложенными полями:
{
"goal": "Search for 'noise cancelling headphones' and get the first 5 results with name, price, rating and number of reviews.",
"start_url": "https://www.example-store.com/",
"output_schema": {
"results": [
{ "name": "string", "price": "number", "rating": "number", "reviews": "integer", "url": "string" }
]
}
}