结构化输出
传入输出结构,即可在 data 中得到经过校验的 JSON,数据只取自智能体访问过的页面。
每次运行都会返回文本 answer。添加 output_schema 后,运行还会在 data 中返回符合该结构的 JSON。JSON 根据智能体访问过的页面的文本和链接以及它的回答生成,绝不靠猜测,因此其中的链接 URL 都是页面上真实的地址。结构化输出不额外收费。
用 output_schema 获取 JSON#
传入你想要的结构。简写形式把每个字段映射到一个类型:
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 KB。不是有效 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 之前,先检查 data_error:
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" }
]
}
}