本指南介绍如何通过 Aidge API 提交门店陈列图片、查询异步任务,并解析空位检测结果。
空位检测用于定位零售门店商品陈列中的空位、不饱满及商品倒塌区域,帮助业务系统开展缺货发现、补货提醒和人工复核。客户提交一张公网可访问的图片后,通过任务 ID 查询检测结果,将返回坐标映射到原图展示。
控制台入口 智能巡检
一、接口说明
1. 适用场景
门店货架巡检,发现前排空位及局部不饱满区域。
展示盒、框篮、堆位及冻柜独立陈列格的缺量检查。
商品倾倒、滑落或堆体失稳区域定位。
客户自建业务系统接入,展示异常框并开展补货和复核。
2. 功能介绍
功能 | API 名称 | 说明 |
提交检测 |
| 每次提交一张图片,受理后返回任务 ID |
查询结果 |
| 按任务 ID 查询状态及最终结果 |
接口版本为 2026-04-28,通过 HTTPS、POST 调用,认证方式为 AccessKey。调用域名和地域使用实际开通服务提供的配置,北京接入点为 aidge.cn-beijing.aliyuncs.com。建议通过阿里云 SDK 或 OpenAPI 调用工具完成签名及参数序列化。
3. 调用流程
检测采用异步任务方式,提交后进入排队调度。提交成功后保存 Data.TaskId,再通过查询接口获取结果。
调用
VacancyDetection,通过ImageUrl提交一张公网可访问的 HTTPS 图片。提交成功后,保存返回的
Data.TaskId,任务进入排队调度并执行检测。使用该任务 ID 调用
QueryAsyncTaskResult。任务尚未结束时,间隔至少 1 秒后继续查询。任务结束后,检查任务状态及
Data.Result中的业务成功标识和错误信息。检测成功时,解析坐标数组并在原图上展示异常区域。图片陈列饱满、无异常时返回空数组
[ ],按正常成功处理。检测失败时,根据错误信息处理,并保留
TaskId和RequestId以便排查。
二、流控信息与授权信息
QPS 阈值请向智能巡检团队咨询。平台默认会为单个客户预留一定的 QPS 配额,保障日常调用。如需提升配额或开展集中批量检测,请提前联系智能巡检团队,提供预期峰值 QPS、调用规模及使用时段,以便评估服务容量并协调扩容。轮询建议至少间隔 1 秒,遇到限流后延长间隔。
调用身份需具备
aidge:VacancyDetection及查询接口的访问权限。RAM 子账号由管理员授予相应权限。AccessKey 在客户服务端通过凭据配置使用。配置方式见 身份验证配置。
三、请求参数
字段区分大小写。下列 JSON 展示业务参数结构,实际调用通过 SDK 或 OpenAPI 工具完成公共参数、签名及序列化。
1. VacancyDetection
参数 | 类型 | 要求与说明 |
| string | 必填,单张图片的公网可访问 HTTPS URL |
| string | 选填,为空时使用内置完整空位检测提示词。支持纯文本及仅含文本的 messages/content JSON |
| string | 选填,系统提示词 |
ImageUrl 直接填写图片地址字符串。图片链接应在任务排队、下载及执行期间保持有效,并返回有效图片内容。
建议默认仅传入 ImageUrl,UserPrompt 和 SystemPrompt 均留空或省略。 服务会自动使用空位检测模型及配套的完整推荐提示词,按统一检测标准返回异常坐标。
{
"ImageUrl": "https://example.com/shelf.jpg"
}如需显式传入提示词,建议使用下方完整推荐版本,以保持检测范围、异常判定标准及坐标输出格式一致。
{
"ImageUrl": "https://example.com/shelf.jpg",
"UserPrompt": "你是一个零售门店陈列异常检测助手。你的任务是检查图像中所有可见的商品陈列区域,定位符合以下业务标准的空位、不饱满或商品倒塌区域,只输出每处异常的边界框坐标。\n只返回 JSON 数组,不要输出解释、分析、Markdown 标记或其他文字。\n\n一、异常判定标准(仅用于判断检测范围,不输出类别)\n\n1. 首排不饱满:常规货架最靠近顾客一侧的横向前沿排面存在清晰可见的商品缺位,导致首排未形成完整陈列排面。\n2. 盒装商品不饱满:商品直接陈列在可独立搬运、通常随商品配送且具有商品专属性的开口展示盒或托盒中,商品整体陈列高度明显低于盒体的可容纳高度。\n3. 框中商品不饱满:商品直接陈列在门店长期复用、与货架或陈列设备结构绑定的固定框、篮、筐、槽或分隔仓中,商品整体陈列高度明显低于框体或篮体的可容纳高度。\n4. 叠放不饱满:相邻同类商品已形成清晰、规则的多层堆码结构,但目标堆位存在完整一层商品未码放。只有确认完整一层缺失时才判定为该异常;局部缺少单件、零散空隙或轻微高低不齐均不符合该条件。\n5. 商品倒塌:商品出现清晰可见的姿态失稳或结构失稳,偏离同一区域同类商品的正常陈列姿态,表现为倾倒、滑落、无支撑压覆或堆体失稳。\n6. 冻柜单格不饱满:冷冻柜或冷藏柜中,由隔板、篮筐或柜体结构划分出的独立陈列格内,商品整体陈列高度明显低于该格框体或篮体的可容纳高度,或者冰槽底部可摆放商品的位置露出白色底槽网格。\n\n二、检测与框选要求\n\n1. 检查整张图像的各层货架、展示盒、框篮、堆位和冻柜单格,输出所有可确认且符合上述标准的异常区域。\n2. 按实际陈列形态应用相应标准。开口展示盒或托盒与固定框篮应按其容器性质判断;冻柜独立陈列格按冻柜单格标准判断,不能仅因位于陈列前沿就一律套用首排不饱满的标准。\n3. 框选局部异常区域:缺位时围住可见缺位区域;盒、框、堆位或冻柜缺量时围住体现该处不饱满的局部区域;商品倒塌时围住发生倾倒、滑落或失稳的商品区域。必要时可包含用于界定该异常的少量容器边界,不要机械扩大为整层货架、整个容器或整个陈列架。\n4. 同一处连续异常输出一个框,不要按想象中缺少的商品件数拆框;不同位置、被正常商品或陈列结构分开的异常分别输出。同一异常即使符合多项标准也不要重复报框;同一陈列单元内相互独立的异常可以分别输出。\n5. 仅依据图像中可见的证据判断。不要将正常商品间隙、货架结构空隙、背景、阴影、反光、价签或遮挡造成的不可见区域当作缺位;不要推测被遮挡部分缺货。正常的平放、斜放陈列不等于商品倒塌。\n6. 边界框应尽量贴合可见异常区域,不凭空补全图像外或遮挡后的范围,不框选无关的正常商品、地面、通道或广告区域。\n\n三、输出要求\n\n1. 只输出由坐标数组组成的 JSON 数组,每处异常对应一个 [x1, y1, x2, y2],即 [左上角x, 左上角y, 右下角x, 右下角y]。不要使用对象或字段名,不要输出类别、置信度或其他信息。\n2. 坐标以整张输入图像为基准,宽和高分别归一化到 0–1000。四个值均为整数,满足 0 <= x1 < x2 <= 1000、0 <= y1 < y2 <= 1000;不要输出像素坐标、百分比或 0–1 小数坐标。\n3. 按框左上角从上到下排序;纵坐标相同时从左到右排序。\n4. 如果整张图像没有可确认的上述异常,包括符合标准的饱满陈列图片,只输出空数组 [ ]。不要输出“饱满”文字或整图框。\n\n以下示例仅说明输出格式,实际坐标必须依据当前图像:\n[\n [138, 406, 230, 463],\n [353, 526, 471, 622]\n]",
"SystemPrompt": "You are a helpful assistant."
}示例地址请替换为实际可下载图片 URL。
2. QueryAsyncTaskResult
参数 | 类型 | 要求与说明 |
| string | 必填,提交接口返回的任务 ID |
{
"TaskId": "提交接口返回的任务ID"
}四、响应参数
1. 顶层字段
两个接口的顶层字段如下。Code、Message 的具体取值及是否返回以接口响应为准,查询接口定义中这两个字段主要用于错误信息。
字段 | 类型 | 含义 |
| string | 本次请求 ID,用于排查问题 |
| string | 调用错误码或状态码 |
| boolean | 本次 API 调用是否成功 |
| string | 返回信息或调用失败说明 |
| object | 业务数据 |
2. 提交接口的 Data
字段路径 | 类型 | 含义 |
| string | 异步任务 ID,用于后续查询 |
| map<string, int64> | 用量明细,异步提交时留空,任务终态后补充 |
| boolean | 工作流处理是否成功,异步提交时可为空 |
| string | 工作流错误码,失败时有值 |
| string | 工作流错误信息,失败时有值 |
提交阶段以调用成功且取得有效 TaskId 判断任务是否受理。通过查询接口获取最终检测结果。
3. 查询接口的 Data
字段路径 | 类型 | 含义 |
| string | 任务状态,完成状态示例为 |
| string | 任务结果文本 |
| string | 任务 ID |
| map<string, any> | 用量信息 |
| string | 业务 ID,按实际响应读取 |
接入时按现有异步任务约定处理 QUEUED、COMPLETED、FAILED。QUEUED 时等待后继续查询,COMPLETED 时读取结果,FAILED 时读取错误信息。接口页面对 Status 仅提供了 COMPLETED 示例,其他状态及扩展值以服务实际返回为准。
4. 检测业务结果
图片陈列饱满、未检测到异常时,返回空数组[ ],属于正常调用成功。此时业务success=true,result为字符串"[ ]",解析后得到空数组。请将其视为“无异常”,按成功结果处理。
对 Data.Result 执行 JSON 解析后,读取检测业务字段。
字段 | 类型 | 含义 |
| boolean | 检测业务是否成功 |
| string | 业务错误码,成功时为空 |
| string | 业务错误说明,成功时为空 |
| string | 坐标数组的 JSON 字符串 |
将 result 再解析一次,获得坐标数组。
[
[138, 406, 230, 463],
[353, 526, 471, 622]
]每个框对应一处异常,格式为 [左上角x, 左上角y, 右下角x, 右下角y]。坐标以整图为基准,宽、高分别归一化为 0–1000 的整数,满足 0 <= x1 < x2 <= 1000、0 <= y1 < y2 <= 1000。像素横坐标为 x / 1000 × 原图宽度,像素纵坐标为 y / 1000 × 原图高度。
没有可确认异常时,业务 success 为 true,result 为字符串 "[ ]"。失败时结合 errorCode 和 errorMessage 处理。使用自定义提示词时,请继续约束上述坐标输出格式。
判断顺序为顶层 API 调用成功、任务状态到达终态、检测业务成功,最后解析坐标。
五、响应示例及调用代码
以下 ID、坐标、错误文案和状态码用于展示结构,实际响应以服务返回为准。结果文本的坐标结构按现有空位检测工作流契约说明。
1. 提交成功
{
"RequestId": "request-example",
"Code": "success",
"Success": true,
"Message": "Success",
"Data": {
"TaskId": "task-example",
"UsageMap": {}
}
}2. 检测完成
{
"RequestId": "request-example",
"Success": true,
"Data": {
"TaskId": "task-example",
"Status": "COMPLETED",
"UsageMap": {
"ProcessingCount": 1
},
"Result": "{\"result\":\"[[138,406,230,463],[353,526,471,622]]\",\"success\":true,\"errorCode\":\"\",\"errorMessage\":\"\"}"
}
}3. 业务失败结果
下面为 Data.Result 解析后的业务错误示例。
{
"result": "",
"success": false,
"errorCode": "InvalidParameter",
"errorMessage": "图片不可达或不是有效图片。"
}4. Python 提交与轮询示例
安装依赖
pip install alibabacloud-tea-openapi alibabacloud-openapi-util alibabacloud-tea-util alibabacloud-credentials通过阿里云凭据链配置身份后执行,图片地址替换为实际公网 HTTPS URL。示例使用通用 RPC 调用,ImageUrl 直接传字符串。
import json
import time
from alibabacloud_credentials.client import Client as CredentialClient
from alibabacloud_tea_openapi.client import Client as OpenApiClient
from alibabacloud_tea_openapi import models as open_api_models
from alibabacloud_openapi_util.client import Client as OpenApiUtil
from alibabacloud_tea_util import models as util_models
config = open_api_models.Config(credential=CredentialClient())
config.endpoint = "aidge.cn-beijing.aliyuncs.com"
config.region_id = "cn-beijing"
client = OpenApiClient(config)
runtime = util_models.RuntimeOptions()
def call(action, business_params):
params = open_api_models.Params(
action=action,
version="2026-04-28",
protocol="HTTPS",
pathname="/",
method="POST",
auth_type="AK",
style="RPC",
req_body_type="formData",
body_type="json",
)
request = open_api_models.OpenApiRequest(
query=OpenApiUtil.query(business_params)
)
body = client.call_api(params, request, runtime)["body"]
if body.get("Success") is not True:
raise RuntimeError(
f"{body.get('Code')}: {body.get('Message')} "
f"RequestId={body.get('RequestId')}"
)
return body
submitted = call("VacancyDetection", {
"ImageUrl": "https://example.com/shelf.jpg"
})
task_id = submitted["Data"]["TaskId"]
print("TaskId", task_id)
deadline = time.monotonic() + 300 # 客户端等待示例,可按业务调整
while time.monotonic() < deadline:
queried = call("QueryAsyncTaskResult", {"TaskId": task_id})
data = queried["Data"]
status = data.get("Status")
if status in ("COMPLETED", "FAILED"):
if status == "FAILED":
raise RuntimeError(
f"任务失败,TaskId={task_id},Result={data.get('Result')}"
)
business = json.loads(data["Result"])
if business.get("success") is not True:
raise RuntimeError(
f"{business.get('errorCode')}: "
f"{business.get('errorMessage')},TaskId={task_id}"
)
boxes = json.loads(business["result"])
print("检测坐标", boxes)
break
time.sleep(1)
else:
print("等待超时,请保存任务ID后续查询", task_id)六、错误处理
调用失败查看顶层 Code、Message 及 SDK 异常信息。检测业务失败查看 Data.Result 中的 errorCode、errorMessage。排查问题时请保存 RequestId 和 TaskId。
场景 | 处理方式 |
图片地址无效或公网不可访问 | 修复 URL,确认返回有效图片后重新提交 |
必填参数缺失或格式错误 | 核对 |
提交请求超时 | 核对是否已受理并保存已取得的任务 ID,再决定是否重新提交 |
查询尚未完成 | 间隔后继续查询,客户端设置总等待时间 |
提交或查询限流 | 降低频率并延迟重试 |
查询返回终态失败 | 根据任务结果中的具体错误处理 |
结果解析失败 | 保留原始结果、任务 ID 和请求 ID,联系服务方排查 |
接口页面未列出专属业务错误码。当前空位检测工作流使用 InvalidParameter 和 DownstreamUnavailable 表达入参及下游错误,Aidge 最终透出以实际响应为准。
七、计费方式
空位检测为涉及费用的接口。提交阶段的 UsageMap 留空,由调度器在任务终态后补充。用量信息按 Data.UsageMap 读取,示例键为 ProcessingCount,具体价格和计费规则以开通服务及商务约定为准。
八、变更历史
变更时间 | 变更内容概要 |
2026-11-10 | 初版文档 |