一次识图任务的完整流程
会话代表一段多轮上下文,Run 代表其中一次业务任务。第三方系统保存两个 ID,就能持续查询任务。
- 01创建 vision 会话获得
session_id,会话固定绑定 vision-only 能力。 - 02提交图片和目标获得
run_id,任务先进入 queued 状态。 - 03按游标轮询每秒查询一次;出现问题时提交回答。
- 04读取文字结果status 进入 completed 后读取
result.text。
1. 验证访问密钥
向管理员申请 vision-only Key,并在每个请求的 Authorization Header 中携带。管理员可在 /admin/keys 即时签发独立 Key,无需重新部署。可以先调用检查接口确认权限。
/v1/auth/check检查 Key 权限curl https://agent.example.com/v1/auth/check \
-H "Authorization: Bearer $VISION_AGENT_KEY"
{"ok":true,"mode":"api_key","capabilities":["vision"],"user":null}2. 创建识图会话
capability 必须为 vision。client_reference 可用于关联你自己的订单、用户或任务编号,最长 200 个字符。
/v1/sessions创建会话curl -X POST https://agent.example.com/v1/sessions \
-H "Authorization: Bearer $VISION_AGENT_KEY" \
-H "Content-Type: application/json" \
-d '{
"capability": "vision",
"client_reference": "order-1001"
}'
{
"id": "7a34...",
"created_at": "2026-08-17T10:00:00.000Z",
"status": "idle",
"capability": "vision",
"legacy": false,
"client_reference": "order-1001"
}
3. 提交图片任务
图片内容使用纯 Base64,不要带 data:image/...;base64, 前缀。一次最多 4 张,单张最大 10MB,请求体最大 16MB。
/v1/sessions/{session_id}/messages创建 Runcurl -X POST \
https://agent.example.com/v1/sessions/SESSION_ID/messages \
-H "Authorization: Bearer $VISION_AGENT_KEY" \
-H "Content-Type: application/json" \
-d '{
"mode": "queue",
"text": "识别商品名称、价格和主要宣传文字",
"images": [{
"media_type": "image/jpeg",
"name": "product.jpg",
"data": "BASE64_DATA"
}]
}'
{"accepted":true,"session_id":"...","run_id":"..."}image/png、image/jpeg、image/webp、image/gif4. 轮询阶段和最终结果
运行期间建议每秒轮询一次。把响应中的 next_cursor 用作下一次 after,终态后立即停止轮询。
/v1/sessions/{session_id}/runs/{run_id}读取 Runcurl "https://agent.example.com/v1/sessions/SESSION_ID/runs/RUN_ID?after=0&limit=50" \
-H "Authorization: Bearer $VISION_AGENT_KEY"
{
"session_id": "...",
"run_id": "...",
"capability": "vision",
"status": "running",
"stage": "analyzing",
"events": [{
"id": 3,
"time": "2026-08-17T10:00:02.000Z",
"stage": "analyzing",
"state": "active",
"message": "正在分析图片内容"
}],
"next_cursor": 3,
"has_more": false,
"input_required": null,
"result": null,
"error": null
}
{
"status": "completed",
"stage": "completed",
"result": {
"text": "商品名称为……,标价为……"
},
"error": null
}
after 必须是非负整数;limit 默认 50,最大 100。5. 回答补充问题
当 status 为 waiting_input 时,读取 input_required.question_id 和问题数组。提交答案后继续轮询原来的 run_id。
{
"status": "waiting_input",
"input_required": {
"question_id": "...",
"questions": [{
"id": "subject",
"question": "需要识别图片中的哪个商品?",
"options": ["左侧商品", "右侧商品"]
}]
}
}
/v1/sessions/{session_id}/questions/{question_id}提交回答curl -X POST \
https://agent.example.com/v1/sessions/SESSION_ID/questions/QUESTION_ID \
-H "Authorization: Bearer $VISION_AGENT_KEY" \
-H "Content-Type: application/json" \
-d '{
"answers": [{
"id": "subject",
"selected": ["右侧商品"]
}]
}'
6. 给当前任务追加指令
mode: "steer" 不创建新业务 Run,而是关联当前正在执行的 Run,响应会返回相同的 run_id。
curl -X POST \
https://agent.example.com/v1/sessions/SESSION_ID/messages \
-H "Authorization: Bearer $VISION_AGENT_KEY" \
-H "Content-Type: application/json" \
-d '{
"mode": "steer",
"text": "重点识别图片右下角的小字"
}'
7. 取消任务
取消请求接受后 Run 会先进入 cancelling,随后变为 cancelled。进入终态后停止轮询。
/v1/sessions/{session_id}/cancel取消当前任务curl -X POST \
https://agent.example.com/v1/sessions/SESSION_ID/cancel \
-H "Authorization: Bearer $VISION_AGENT_KEY"
可直接改造的完整后端示例
这段 Node.js 代码可直接从本地文件读取图片并执行一次完整任务。生产代码应设置请求超时,并把 session_id、run_id 与你的业务记录一起保存。
import { readFile } from 'node:fs/promises'
const BASE_URL = process.env.IMAGE_AGENT_URL
const API_KEY = process.env.VISION_ONLY_API_KEY
const imageBase64 = (await readFile('./product.jpg')).toString('base64')
async function request(path, options = {}) {
const response = await fetch(`${BASE_URL}${path}`, {
...options,
headers: {
Authorization: `Bearer ${API_KEY}`,
'Content-Type': 'application/json',
...options.headers,
},
})
const body = await response.json()
if (!response.ok) throw new Error(body.error?.code || 'api_error')
return body
}
const session = await request('/v1/sessions', {
method: 'POST',
body: JSON.stringify({
capability: 'vision',
client_reference: 'order-1001',
}),
})
const accepted = await request(`/v1/sessions/${session.id}/messages`, {
method: 'POST',
body: JSON.stringify({
mode: 'queue',
text: '提取图片中的商品名称、价格和文案',
images: [{
media_type: 'image/jpeg',
name: 'product.jpg',
data: imageBase64,
}],
}),
})
let cursor = 0
while (true) {
const run = await request(
`/v1/sessions/${session.id}/runs/${accepted.run_id}` +
`?after=${cursor}&limit=50`
)
cursor = run.next_cursor
for (const event of run.events) console.log(event.message)
if (run.status === 'completed') {
console.log(run.result.text)
break
}
if (run.status === 'waiting_input') {
console.log('需要回答:', run.input_required)
break
}
if (['failed', 'cancelled'].includes(run.status)) {
throw new Error(run.error?.code || run.status)
}
await new Promise(resolve => setTimeout(resolve, 1000))
}
状态说明
queued已接受,等待执行继续轮询running正在规划、识图或整理结果继续轮询waiting_input需要调用方回答问题提交 answerscancelling正在处理中断请求继续轮询completed任务完成读取 result.text 并停止failed任务失败读取 error.code 并停止cancelled任务已取消停止轮询常见错误码
HTTP 错误统一使用 { "error": { "code": "...", "message": "..." }, "request_id": "..." },同一个 ID 也会出现在 X-Request-Id 响应头。运行时 Agent 错误位于 Run 的 error 字段,并带可供服务端查日志的 incident_id。
unauthorizedKey 缺失或无效invalid_capabilitycapability 不是 image 或 visionunsupported_field调用方传入了 agent_presetcapability_forbiddenvision-only Key 请求了 imageinvalid_image_input图片格式、数量、Base64 或大小无效worker_busy单 Worker 正在处理其他会话steer_unavailable当前没有可追加指令的 Runlegacy_session旧会话只读,需要创建新会话run_not_foundRun 不存在或不属于此会话invalid_cursorafter 不是非负整数invalid_limitlimit 不在 1 到 100 之间transport_forbiddenvision-only Key 请求原始 SSEmodel_not_configured服务端模型凭据缺失,联系管理员处理agent_errorAgent 异步失败,向管理员提供 incident_idservice_restarted任务被 Gateway 重启中断vision-only 返回什么,不返回什么
- 受控阶段状态
- 需要回答的问题
- 最终文字结果
- 安全错误码
- 隐藏思维链
- 工具参数
- 工具原始输出
- Shell、文件或 Web 能力
vision-only Key 不能创建 image 会话,也不能访问原始 /events SSE。识图工具只能读取当前会话目录中的本地图片。最终文本最多 16,000 字符。