儿童成语学习卡片生成接口技术解析:异步接入、参数设计与多模态结果组装
一、技术简介
成语是汉语词汇中定型的短语,通常有出处、有典故,儿童在理解字面意思之外,还需要借助故事、画面和朗读才能真正掌握其含义。在儿童启蒙、亲子共读和语文教学场景中,单独提供一段释义文字往往不够:低龄儿童需要更浅白的语言、更直观的画面和可跟读的声音。
儿童成语学习卡片生成接口正是面向这一需求设计的多模态生成类 HTTP API:调用方传入一个成语、学习对象的年龄段和希望的画面比例,服务端先对成语进行合规校验与儿童化改编,再依次生成配图提示词、启动配图生成任务、启动读音音频生成任务,最后把释义、故事、造句、配图和音频融合为一张结构化学习卡片返回。
接口采用异步任务模型:提交请求后立即返回任务标识,调用方按间隔轮询任务状态,待任务成功后从结果中读取卡片的各个模块。本文从接入流程、参数设计、返回结构、多语言调用示例、错误处理和工程实践要点六个维度,完整介绍该接口的使用方式。

二、能力概览
接口的输入为三个参数,输出为一张融合完成的成语学习卡片。
输入参数
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| idiom | String | 是 | 要学习的成语,如「守株待兔」 |
| age_group | String | 是 | 学习对象年龄段,分三档:3-4岁启蒙、5-7岁基础、8-10岁进阶 |
| aspect_ratio | String | 否 | 配图画面比例,可选 1:1、3:4、4:3、16:9、9:16,默认 1:1 |
卡片输出模块
- 适龄释义:按年龄段把成语原意改写为儿童能听懂的解释,3-4岁档用词更浅、句子更短,8-10岁档可加入更完整的典故背景。
- 趣味故事:以角色、情节、道理三要素组织的小故事,把成语典故转化为儿童视角的叙述。
- 造句示范:贴近儿童日常生活的例句,帮助理解成语的使用语境。
- 成语配图:儿童插画风格,画面中央包含成语大字,便于视觉记忆。
- 读音音频:以适合儿童的慢速朗读故事与成语,支持反复收听与跟读。
工作流内部依次完成合规校验优化、成语内容儿童化改编、配图提示词生成、配图任务启动与状态轮询、读音音频任务启动与状态轮询、卡片数据融合共八个步骤。调用方无需关心内部编排,只需按「提交任务 → 轮询状态 → 读取结果」三步集成。
三、适用场景
3.1 儿童启蒙卡片
为低龄儿童提供图文声并茂的成语入门材料,把抽象成语转化为可看、可听、可跟读的卡片,降低理解门槛。
3.2 亲子共读
家长与孩子一起看画面、听朗读,在互动中完成传统文化启蒙,音频语速经过放缓处理,适合家长带读。
3.3 语文课堂素材
教师可按课文中的成语批量获取标准化多模态素材,用于课堂展示、板书配图和课后拓展。
3.4 早教与点读类应用
早教机、点读类应用可在用户选择成语后调用接口,把释义、配图和音频组装进自有卡片页面。
3.5 成语内容专栏
内容平台可按成语清单批量组织图文音频专栏,统一卡片画风与朗读节奏。
3.6 纸质教具印刷
导出配图后可用于印刷识字卡、启蒙挂图等纸质教具。

四、接入流程
4.1 获取访问凭证
在云市场控制台开通该接口后,控制台会分配一个专属的 AppCode。后续所有请求都需要在 HTTP Header 中携带该凭证:
Authorization: APPCODE <您的AppCode>
AppCode 等同于密钥,请勿泄露到前端、公开仓库或日志中。
4.2 确定调用地址
开通服务后,云市场控制台会提供两个 HTTPS 调用地址:一个用于提交执行任务,一个用于按任务标识查询状态。建议把两个地址分别配置为环境变量,不要硬编码在代码中。
4.3 提交执行任务
向提交端点发送 POST 请求,Content-Type 为 application/json,请求体包含成语、年龄段和画面比例。提交成功后立即返回任务标识 task_id,此时卡片尚未生成完成。
4.4 轮询任务状态
使用返回的 task_id 调用查询端点,建议按 1-2 秒间隔轮询。任务状态取值包括 PENDING(排队中)、RUNNING(执行中)、SUCCESS(成功)、FAILED(失败)。
4.5 读取卡片结果
任务成功后,从返回结构的 flow_result 中读取各步骤产物:释义与故事造句来自成语改编步骤,配图来自配图轮询步骤,音频来自读音音频轮询步骤,output 节点保存融合概述与语义分析,再由业务侧把这些模块组装为一张完整卡片。

五、调用示例与返回结构
5.1 请求参数
| 参数名 | 类型 | 必填 | 描述 |
|---|---|---|---|
| idiom | String | 是 | 要学习的成语 |
| age_group | String | 是 | 年龄段:3-4岁 / 5-7岁 / 8-10岁 |
| aspect_ratio | String | 否 | 画面比例:1:1、3:4、4:3、16:9、9:16,默认 1:1 |
请求 Header:
| Header | 值 | 说明 |
|---|---|---|
| Authorization | APPCODE <您的AppCode> | 云市场统一鉴权 |
| Content-Type | application/json | JSON 请求体 |
5.2 cURL 示例(提交任务)
curl -X POST "$EXECUTE_ENDPOINT" \
-H "Authorization: APPCODE <您的AppCode>" \
-H "Content-Type: application/json" \
-d '{
"idiom": "为虎作伥",
"age_group": "5-7岁",
"aspect_ratio": "1:1"
}'
其中 $EXECUTE_ENDPOINT 替换为云市场控制台提供的提交地址。提交成功返回任务标识:
{
"showapi_res_code": 0,
"showapi_res_body": {
"task_id": "69ddd187e13823d1d500015b"
}
}
5.3 Python 示例(提交 + 轮询 + 取结果)
import os
import time
import requests
EXECUTE_ENDPOINT = os.environ["EXECUTE_ENDPOINT"]
QUERY_ENDPOINT = os.environ["QUERY_ENDPOINT"]
APP_CODE = os.environ["APP_CODE"]
HEADERS = {
"Authorization": f"APPCODE {APP_CODE}",
"Content-Type": "application/json",
}
def submit_task(idiom: str, age_group: str, aspect_ratio: str = "1:1") -> str:
resp = requests.post(
EXECUTE_ENDPOINT,
headers=HEADERS,
json={
"idiom": idiom,
"age_group": age_group,
"aspect_ratio": aspect_ratio,
},
timeout=10,
)
resp.raise_for_status()
body = resp.json().get("showapi_res_body", {
})
return body["task_id"]
def poll_task(task_id: str, interval: int = 2, max_wait: int = 300) -> dict:
deadline = time.time() + max_wait
while time.time() < deadline:
resp = requests.get(
QUERY_ENDPOINT,
headers=HEADERS,
params={
"task_id": task_id},
timeout=10,
)
resp.raise_for_status()
body = resp.json().get("showapi_res_body", {
})
status = body.get("status")
if status == "SUCCESS":
return body
if status == "FAILED":
raise RuntimeError(f"任务失败: {body.get('remark')}")
time.sleep(interval)
raise TimeoutError("轮询超时,任务未在限定时间内完成")
if __name__ == "__main__":
task_id = submit_task("为虎作伥", "5-7岁", "1:1")
result = poll_task(task_id)
flow = result["flow_result"]
# 释义与故事、造句来自成语改编步骤
adapter = flow["step_1_idiom_content_adapter"]
definition = adapter["result"]
variants = {
v["style"]: v["content"] for v in adapter["content_variants"]}
story = variants.get("趣味故事")
sentence = variants.get("生活造句")
# 配图地址、音频地址分别位于配图轮询与音频轮询步骤的结果对象中
image_url = flow["step_4_poll_image_status"].get("result_url")
audio_url = flow["step_6_poll_audio_status"].get("result_url")
print("释义:", definition)
print("故事:", story)
print("造句:", sentence)
print("配图:", image_url)
print("音频:", audio_url)
5.4 Java 示例(提交任务)
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
public class IdiomCard {
public static void main(String[] args) throws Exception {
String executeEndpoint = System.getenv("EXECUTE_ENDPOINT");
String appCode = System.getenv("APP_CODE");
String body = "{"
+ "\"idiom\":\"为虎作伥\","
+ "\"age_group\":\"5-7岁\","
+ "\"aspect_ratio\":\"1:1\"}";
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(executeEndpoint))
.header("Authorization", "APPCODE " + appCode)
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(body))
.build();
HttpResponse<String> response = client.send(
request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
}
}
5.5 返回结构
提交接口返回任务标识;查询接口返回任务整体状态与各步骤结果。业务数据位于 showapi_res_body 对象内,flow_result 保存输入、融合概述与各步骤产物。
{
"showapi_res_code": 0,
"showapi_res_error": "",
"showapi_res_id": "67905216fb638c23e1849490",
"showapi_res_body": {
"ret_code": 0,
"status": "SUCCESS",
"progress": 100,
"used_time": 114,
"remark": "",
"step_status_list": [
{
"step_id": "step_1_idiom_content_adapter", "step_name": "成语内容儿童化改编", "status": "SUCCESS" }
],
"flow_result": {
"input": {
"idiom": "为虎作伥", "age_group": "5-7岁", "aspect_ratio": "1:1" },
"output": {
"result": "成语学习卡片融合完成",
"structured_analysis": {
"semantic_structure": {
"core_theme": "为虎作伥",
"logical_flow": "标题-读音-释义-故事-配图-造句"
}
},
"merge_readiness": {
"fusion_compatible": true }
},
"step_1_idiom_content_adapter": {
"result": "为虎作伥的意思是比喻充当坏人的帮凶,帮助坏人做坏事。",
"content_variants": [
{
"variant_id": "v1_story", "style": "趣味故事", "content": "从前有个叫伥鬼的小妖怪……", "score": 0.95 },
{
"variant_id": "v2_sentence", "style": "生活造句", "content": "我们要有明辨是非的能力,不能为虎作伥。", "score": 0.90 }
]
},
"step_4_poll_image_status": {
"result_url": "https://.../idiom-card.jpg" },
"step_6_poll_audio_status": {
"result_url": "https://.../reading.wav" }
}
}
}
查询返回的主要字段:
| 字段 | 类型 | 说明 |
|---|---|---|
| ret_code | Integer | 任务返回码,0 表示成功 |
| status | String | 任务整体状态:PENDING / RUNNING / SUCCESS / FAILED |
| progress | Integer | 执行进度百分比 |
| used_time | Integer | 任务已用时间(秒) |
| remark | String | 失败时的错误描述 |
| step_status_list | Array | 八个内部步骤的状态列表,用于定位失败环节 |
| flow_result.output | Object | 融合概述、语义分析与融合就绪状态 |
| flow_result.step_1_idiom_content_adapter | Object | 儿童化释义(result)与故事、造句(content_variants) |
| flow_result.step_4_poll_image_status | Object | 配图轮询结果,内含配图地址 |
| flow_result.step_6_poll_audio_status | Object | 读音音频轮询结果,内含音频地址 |
读取要点:释义文本取 step_1_idiom_content_adapter.result;故事与造句在 content_variants 数组中,按 style 字段区分「趣味故事」「生活造句」;配图地址与音频地址分别从配图轮询、音频轮询步骤的结果对象中读取。不同成语生成的文本长度存在差异,业务侧应把各模块视为可空字段并做容错。

六、在线调试实录
以成语「为虎作伥」、年龄段「5-7岁」、比例「1:1」为例,完整走一次调用流程。
第 1 步:提交任务
向提交端点发送 JSON 请求体,包含 idiom、age_group、aspect_ratio 三个字段。提交成功后返回 task_id,任务进入执行队列。
第 2 步:轮询任务状态
使用 task_id 调用查询端点,每 1-2 秒查询一次。状态依次经历 PENDING、RUNNING,配图与音频两个生成任务并行推进,最终变为 SUCCESS。
第 3 步:读取卡片
任务成功后,从 flow_result 中读取各模块:
- 适龄释义:
step_1_idiom_content_adapter.result,按 5-7 岁认知水平改写的成语解释; - 趣味故事与造句:
step_1_idiom_content_adapter.content_variants,按style区分故事与造句; - 配图地址:配图轮询步骤结果对象中的图片,画面中央含成语大字;
- 音频地址:读音音频轮询步骤结果对象中的慢速朗读音频。
第 4 步:媒体落库
配图与音频地址为临时资源,业务侧应在任务成功后立即把图片和音频下载到自有对象存储,替换为自己的永久地址,避免后续资源过期导致 404。
第 5 步:组装展示
把文本模块、配图和音频按自有产品的卡片版式组装,即可在启蒙页面、点读应用或课堂课件中使用。

七、调用限制与规范
7.1 参数枚举约束
age_group只接受三档年龄段:3-4岁、5-7岁、8-10岁,传入其他写法可能被校验拒绝。aspect_ratio只接受 1:1、3:4、4:3、16:9、9:16 五种比例,不传时按默认 1:1 处理。idiom应为规范成语,不要传入俗语、短语或非成语内容。
7.2 轮询节奏控制
查询任务状态时控制轮询频率,建议 1-2 秒一次,并设置最大轮询时长(如 300 秒)。任务长时间停留在 RUNNING 时应记录日志并按超时处理,避免高频空转给服务端造成压力。
7.3 幂等与重试
提交阶段在网络超时或 5xx 错误时,可用相同参数有限次重试,重试间隔采用退避策略;查询阶段为只读操作,可安全重复调用。
7.4 超时与熔断
配图与音频生成需要一定时间,提交与查询请求都应设置合理超时;服务不可用时及时熔断降级,保护主业务流程,不要让用户长时间等待。
7.5 媒体资源落库
配图与音频为临时生成资源,有效期有限。任务成功后应立即下载到自有存储,前端不要直接引用返回的临时地址。
7.6 鉴权安全
AppCode 仅放在服务端请求 Header 中,不要在前端 JS、小程序前端代码中明文携带;若 AppCode 泄露,应立即在控制台重置。建议对失败请求记录 showapi_res_id 以便排查。
7.7 结果缓存
相同成语、相同年龄段、相同比例的卡片结果可在本地缓存,减少重复生成调用。
八、能力边界与免责
- 释义与故事由模型按年龄段改写,供儿童启蒙与教学参考,正式教材内容请以权威语文出版物为准。
- 配图为模型创作的儿童插画,可能存在细节偏差;涉及商用印刷时请自行确认授权范围。
- 接口为异步生成类服务,整体耗时受配图与音频生成环节影响,请勿设置过短超时。
- 配图与音频为临时资源,集成侧应在业务需要时及时保存到自有存储。
- 接口面向成语学习卡片生成,不提供成语词典查询、成语接龙或配图编辑等其他能力。
九、错误码排查
网关层通用返回码:
| showapi_res_code | 含义 | 处理建议 |
|---|---|---|
| 0 | 成功 | 正常读取结果 |
| -1 | 系统调用错误 | 检查请求参数与鉴权格式,稍后重试 |
| -2 | 可调用次数或额度为 0 | 确认账户状态与额度 |
任务级状态:
| status | 说明 | 处理建议 |
|---|---|---|
| SUCCESS | 任务成功 | 读取 flow_result.output 中的卡片 |
| RUNNING | 执行中 | 继续按间隔轮询 |
| PENDING | 排队中 | 继续等待,无需重复提交 |
| FAILED | 执行失败 | 查看 remark 错误信息与 step_status_list 定位失败步骤 |
排查顺序:先检查必填参数是否完整、年龄段与比例是否属于合法枚举,再确认 AppCode 格式是否为 APPCODE xxx、额度是否充足;任务失败时优先查看返回中的错误描述和各步骤状态。
十、技术 FAQ
Q1:为什么提交后没有立即返回卡片?
A:接口为异步生成模型,提交后先返回 task_id,配图和音频生成需要一定时间,必须通过轮询获取最终结果,不能把提交响应当作卡片内容使用。
Q2:年龄段有哪几档?
A:共三档:3-4岁启蒙、5-7岁基础、8-10岁进阶。不同档位的释义深度、叙事用词和配图画风会相应调整。
Q3:画面比例支持哪些值?
A:支持 1:1、3:4、4:3、16:9、9:16 五种比例,不传时默认 1:1。方形适合识字卡,竖版适合手机端与挂图,横版适合课堂投影。
Q4:配图和音频地址可以直接给前端用吗?
A:不建议。返回的是临时资源地址,有效期有限,应在任务成功后下载到自有对象存储,再把自己的永久地址提供给前端。
Q5:可以批量生成成语卡片吗?
A:当前接口为单成语提交。批量场景由业务侧循环调用,控制并发数,并对相同参数的结果做本地缓存。
Q6:任务一直 RUNNING 怎么办?
A:先按 1-2 秒间隔继续轮询,达到自设的最大等待时长(如 300 秒)仍未成功,则按超时处理并记录 showapi_res_id 与 task_id 用于排查,不要无限等待。
Q7:可以在前端浏览器直接调用吗?
A:不建议。AppCode 会暴露在客户端代码中,存在被盗用风险。正确做法是由业务后端中转提交与轮询,前端只拿到组装好的卡片字段。
十一、内容小结
本文介绍了儿童成语学习卡片生成接口的完整接入方式:从 APPCODE 鉴权、三参数提交、task_id 轮询,到 flow_result 各步骤产物的模块读取、多语言代码示例、媒体落库、错误码排查和工程实践要点。实际接入时建议重点关注四点:
- 异步模型:提交只拿任务标识,卡片必须轮询成功后读取;
- 枚举校验:年龄段三档、比例五种,调用前在业务侧拦截非法值;
- 媒体落库:配图与音频为临时地址,成功后及时下载到自有存储;
- 服务端中转:AppCode 仅在服务端使用,前端通过自有后端获取卡片。
按照上述流程接入后,即可在儿童启蒙、亲子共读、课堂教学、早教应用等场景中,把单个成语转化为释义、故事、造句、配图与音频一体化的学习卡片。
