从接口设计来看,AI Skin Analysis 并不是一个"提交图片后同步返回分析结果"的单一 API。
根据 YCE Integration Guide,一次完整调用涉及两个主要 API:File API 和 AI Task API 。前者负责初始化文件上传,后者负责创建皮肤分析任务。任务创建后,还需要使用 task_id 轮询执行状态。
因此,开发时需要分别处理文件、任务和结果三个阶段。
1. 输入图片首先需要满足尺寸要求
调用 API 前,需要检查源图片尺寸。
YCE 文档分别规定了 SD 和 HD 的最低短边尺寸:
|----|-----------|------------|
| 模式 | 长边 | 短边 |
| SD | 最大 2560px | 至少 480 px |
| HD | 最大 2560px | 至少 1080 px |
拍摄方面,Integration Guide 要求使用正面自拍,用户直视镜头,并保持图片清晰。文档同时提到可以使用 JS Camera Kit 拍摄照片。
更完整的图片规格和相关错误需要参考 YCE 的 File Specs & Errors 。
2. File API 只初始化上传,不传输图片文件
文件处理是整个调用流程中比较容易产生误解的部分。
首先需要发送:
POST /s2s/v2.0/file
请求 Body 中包含文件 metadata,包括:
- content_type
- file_name
- file_size
File API 成功响应后,会返回 file_id,同时在 requests 中提供实际文件上传所需的信息,其中包括 method、url 和 headers。
这里需要特别区分两个操作:
调用 File API
用于初始化上传并取得 file_id 和预签名 URL。
向 requests.url 发送文件
用于真正传输图片数据。
因此,拿到 file_id 并不代表图片已经上传。
根据 Integration Guide,如果调用 File API 后没有继续将文件上传到返回的 URL,就直接调用 AI API,可能得到:
500 Server Error / unknown_internal_error
或者:
404 Not Found
这一点在实现上传逻辑和排查接口错误时尤其需要注意。
3. 图片实际通过预签名 URL 上传
File API 响应中的 requests.url 是图片实际上传地址。
文档示例使用 PUT 方法,并要求按照响应中提供的 Header 上传文件:
|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| bash curl --location --request PUT 'https://yce-us.s3-accelerate.amazonaws.com/demo/ttl30/...signature...' \ --header 'Content-Type: image/png' \ --header 'Content-Length: 547541' \ --data-binary @'./skin_analysis_01_3dbd1b6683.png' |
因此,从 HTTP 调用层面看,这里实际上存在两次独立请求。
第一次请求 YCE File API,取得上传信息;第二次使用返回的 URL 执行 PUT,传输图片二进制数据。
只有文件成功传输后,才能继续使用对应的 file_id 创建分析任务。
4. dst_actions 决定此次任务分析什么
图片上传完成后,通过:
POST /s2s/v2.0/task/skin-analysis
创建 Skin Analysis Task。
其中,src_file_id 指向前面已经上传的图片,而 dst_actions 用来指定此次任务需要执行的 skin concerns。
YCE 文档给出的示例为:
|------------------------------------------------------------------|
| json "dst_actions": "wrinkle", "pore", "texture", "acne" |
也就是在一个任务中请求 wrinkle、pore、texture 和 acne 分析。
具体可用的 skin concerns 需要以 Inputs & Outputs 文档为准。Integration Guide 没有在这一部分列出完整列表,因此不能根据示例推断只有这四种,也不应自行增加其他 dst_actions 值。
创建任务时还可以通过 miniserver_args 设置文档支持的参数。示例中包括:
enable_mask_overlay
enable_dark_background_hd_pore
color_dark_background_hd_pore
opacity_dark_background_hd_pore
由于 Integration Guide 示例明确注明还有其他参数被省略,因此具体参数定义仍应以 Inputs & Outputs 为准。
5. SD 与 HD 的 dst_actions 不能混用
任务参数存在一个明确限制:SD 和 HD skin concern 参数不能同时出现在一个任务中。
如果混用,API 返回:
|------------------------------------------------------------------------------------------------------------|
| json { "status": 400, "error": "cannot mix HD and SD dst_actions", "error_code": "InvalidParameters" } |
如果 dst_actions 拼写错误,或者传入 API 不支持的 skin concern,也会返回 InvalidParameters。
例如文档中的未知参数示例:
|-----------------------------------------------------------------------------------------------------------|
| json { "status": 400, "error": "Not available dst_action abc123", "error_code": "InvalidParameters" } |
因此,收到 400 InvalidParameters 时,可以先检查两个位置:dst_actions 是否为有效值,以及是否在同一个任务中混合了 SD 和 HD 参数。
6. Skin Analysis 使用异步 Task 模型
POST /task/skin-analysis 成功后,不会直接返回最终皮肤分析结果,而是返回:
|-----------------------------------------------------------------------------------------------------------------------|
| json { "status": 200, "data": { "task_id": "SaGaqpDgKwFrVBgMpQMA3HY0LeqdT9_13W5TOD8_u_GPi6NqQ3dhlmN-6ntFwhzT" } } |
接下来需要使用这个 task_id 调用:
GET /s2s/v2.0/task/skin-analysis/<YOUR_TASK_ID>
查询任务状态。
任务执行过程中,状态保持为 running。
Integration Guide 明确指出,AI 任务执行时间并不保证,因此仍然需要 polling 。与此同时,文档也说明没有必要进行短时间间隔的频繁轮询。
处理结果在任务完成后保留 24 小时 ,开发端可以在这个时间范围内安排查询。
7. success 与 error 的处理不同
任务成功完成后,状态变为:
success
如果引擎无法完成任务,则状态变为:
error
根据 Integration Guide,units 只会在任务成功处理时消耗。
任务处于 running 阶段不会消耗 units;任务最终处理失败,也不会消耗 units。
文档还说明,在 units 扣除时,会优先使用临近过期的 units;如果到期日期相同,则优先扣除较早获得的 units。
因此,在程序逻辑中,不应该仅根据任务是否已经创建来判断分析是否完成,而应以最终 task status 为准。
8. 如何解析 Skin Analysis 返回结果
任务成功后,可以从 data.results.output 中读取具体分析结果。
Integration Guide 给出的单项结果结构包括:
|-----------------------------------------------------------------------------------------------------------------------------------------------------------|
| json { "type": "texture", "ui_score": 68, "raw_score": 57.33, "mask_urls": "https://yce-us.s3-accelerate.amazonaws.com/...texture_output.jpg" } |
其中:
type 表示当前结果对应的 skin concern。
ui_score 是 user-friendly score。
raw_score 是 raw analysis score。
mask_urls 保存 detection masks 对应的 URL。
由于 output 是数组,一次请求包含多个 dst_actions 时,响应中可以包含多个分析结果。文档示例中就分别返回了 texture 和 pore。
因此,解析结果时可以根据 type 识别对应的分析项目,而不是依赖数组中的固定位置。
9. 也可以跳过 File API
File API 并不是唯一的图片输入方式。
Integration Guide 说明,如果已经有一个公开可访问的图片 URL ,创建 AI Task 时可以直接提供该 URL,而不需要重新执行文件上传流程。
需要注意的是,文档在这里明确限定为 publicly accessible image URL。
至于 URL 输入对应字段的完整格式以及其他输入参数,Integration Guide 要求参考 Inputs & Outputs 。因此,仅根据当前文档内容,不应自行推断具体字段名称。
结语
从技术实现来看,YCE AI Skin Analysis API 可以拆分成几个独立环节:源图片规格检查、File API 初始化、预签名 URL 文件上传、Skin Analysis Task 创建、task_id 状态轮询以及结果解析。
其中最需要区分的是两个状态:
获得 file_id 不代表文件已经上传成功;获得 task_id 也不代表分析已经完成。
前者还需要完成预签名 URL 的 PUT 上传,后者需要继续通过 GET 接口轮询,直到任务进入 success 或 error 状态。
在结果解析阶段,则可以通过 type 区分不同 skin concern,并分别读取 ui_score、raw_score 和 mask_urls。至于完整的 skin concern 列表、参数定义以及文件规格,应继续以 YCE 的 Inputs & Outputs 和 File Specs & Errors 文档为准。