260403_AI播客工作流与落地步骤
AI 播客工作流定义与落地步骤(P1)
日期:2026-04-03
范围:百炼工作流应用、后端字段与状态、脚本生成、TTS、≥5 触发与异步、小程序播放与通知。
一、百炼应用信息
| 项 | 值 |
|---|---|
| 应用名称(建议) | fm-AI播客 / 大事记 AI 播客 |
| 应用 ID | f67ab0c3880c4c4ab6fd116bf0486e83 |
| 说明 | 画布自建工作流;后端调用时使用该 ID 发起「工作流应用」执行(与智能体对话接口区分,以控制台实际调用方式为准)。 |
二、工作流拓扑(仅保留两种场景)
开始
→ 素材整理与场景选择(脚本)
→ 条件① 是否命中两种场景
├─ 否 → 脚本1:输出 INSUFFICIENT_MATERIAL → 结束
└─ 是 → 大模型:生成 dialogue_script + short_title
→ 脚本2:统一输出封装
→ 条件② 是否调用播客网关(命中场景)
├─ 否 → 结束
└─ 是 → 火山播客网关HTTP → 结束
场景规则(当前仅考虑以下两种)
- 场景1:最近5条合并播报
当素材清洗后总数 = 5 时,取最近5条合并为一期播客。 - 场景2:>5 且新增事件
当素材清洗后总数 > 5 且is_incremental=true时,取最近2条:第1条作为前置提示,第2条作为本期正文。 - 其它场景暂不处理,统一输出
INSUFFICIENT_MATERIAL。
组件说明(弱化原条件1/条件2/脚本1/脚本2)
| 步骤 | 画布组件 | 说明 |
|---|---|---|
| 素材整理与场景选择 | 脚本(Script) | 做轻量清洗 + 场景判定 + material_brief 拼装。 |
| 条件①/条件② | 条件(Judge) | 仅判断 scenario_supported,不再做复杂质检。 |
| 大模型 | LLM | 一次输出 dialogue_script + short_title。 |
| 脚本1/脚本2 | Script | 只做统一返回结构封装,不做复杂业务判断。 |
三、开始节点入参(与后端对齐)
本节描述的是工作流被调用时的「输入」(开始节点上的自定义变量),不是结束节点的「输出」。你截图里「开始 → 自定义变量」与下表一致即可。
后端向工作流传入时,建议至少包含以下字段(名称可与实现微调,但需在调用层固定映射)。
| 字段 | 类型 | 说明 |
|---|---|---|
event_id | Number | 大事记 ID |
community_id | Number | 小区 ID |
event_title | String | 标题 |
event_summary | String | 摘要,可空 |
dynamic_count | Number | 原始动态条数(业务入参) |
dynamics | Array | 动态列表;元素建议含 dynamic_id、title、content_text、occur_time |
is_incremental | Boolean | 是否新增事件(场景2开关) |
previous_transcript | String | 上一版逐字稿,可空(叙事衔接) |
target_duration_sec | Number | 目标时长(秒),默认如 90 |
style | String | 风格,如 warm_community |
lang | String | 如 zh-CN |
输入参考示例(JSON)
以下为联调/画布测试用示例:字段名与类型需与上表一致;dynamics 至少 5 条时才满足产品「≥5 条动态」口径(dynamic_count 与列表长度建议保持一致)。
后端 HTTP 调用百炼工作流时,通常放在请求体 input 下(与 DashScope apps/{appId}/completion 一致),结构形如:{ "input": { ...下述对象... }, "parameters": { "incremental_output": false } }。
统一输出结构示例(两段 JSON,结构固定) { “event_id”: 1987654321000123456, “title_for_audio”: “小区东门道闸升级改造”, “dialogue_script”: “A:嘿,你最近有没有注意到小区东门那块围挡? \nB:对,就是3月20号开始的——物业提前发了通知,说东门要半幅封闭施工,车辆得绕行西门。 \n\nA:其实这背后是一整套特别清晰的业主共决流程。最早3月1号,业委会就启动了征询,专门收集大家对道闸品牌和预算的意见。 \nB:没错,不是拍脑袋决定的。五天后,也就是3月5号,两套候选方案连同报价区间一起公示,整整7天,谁都能去看、去比、去提意见。 \n\nA:然后到了3月12号晚上9点,结果出来了:A方案获得过半数投票支持,正式通过。 \nB:这个“过半数”,指的是参与投票的业主里过半同意——不是全体业主,但也是实打实的民主决策。 \n\nA:紧接着3月15号一早,合同就准备签了;20号施工进场;到22号下午4点20分,新道闸已经装好,进入试运行阶段,现在正忙着录车牌白名单呢。 \nB:短短三周,从意见征询到设备上岗,节奏快,但每一步都留痕、有依据、可追溯。 \n\nA:你有没有试过把车开到东门,看它自己抬杆?那种“终于不用摇下车窗喊保安”的感觉,是不是有点小爽? \nB:但更值得留意的是——这背后没有临时起意,没有模糊地带,只有时间戳、动作节点和明确的责任主体。 \n\nA:所以啊,下次看到小区公告栏贴出一张新通知,别急着划走。它可能正悄悄改变你每天回家的那十几秒。 \nB:那最后想问问你:如果下一次征询轮到你家楼栋的加装电梯,你会希望提前知道哪些信息?”, “dynamic_count_used”: 5, “status”: “READY” } { “event_id”: “1987654321000123456”, “audio_url”: “https://intu-1353663652.oss-cn-heyuan.aliyuncs.com/2026/04/15/podcast/1987654321000123456_a010441a76474788a599321a6fea55c5.mp3”, “short_title”: “小区东门道闸升级改造纪实”, “status”: “OK” }
请求示例(场景1:最近5条)
{
"event_id": 1987654321000123456,
"community_id": 10001,
"event_title": "小区东门道闸升级改造",
"event_summary": "物业联合业委会推进东门道闸更换与车辆登记规则调整,以下为进展摘录。",
"dynamic_count": 5,
"dynamics_list": [
{
"dynamic_id": 1987654321000123401,
"title": "业主征询启动",
"content_text": "业委会发布征询说明,收集业主对道闸品牌与预算的意见。",
"occur_time": "2026-03-01 10:00:00"
},
{
"dynamic_id": 1987654321000123402,
"title": "方案公示",
"content_text": "公示两套候选方案及报价区间,公示期 7 天。",
"occur_time": "2026-03-05 18:30:00"
},
{
"dynamic_id": 1987654321000123403,
"title": "投票通过 A 方案",
"content_text": "参与投票业主过半数同意采用 A 方案,下一步签订合同。",
"occur_time": "2026-03-12 21:00:00"
},
{
"dynamic_id": 1987654321000123404,
"title": "施工进场通知",
"content_text": "物业通知 3 月 20 日起东门半幅封闭施工,请车辆绕行西门。",
"occur_time": "2026-03-15 09:00:00"
},
{
"dynamic_id": 1987654321000123405,
"title": "道闸试运行",
"content_text": "新道闸已安装完成,进入试运行与车牌白名单录入阶段。",
"occur_time": "2026-03-22 16:20:00"
}
],
"is_incremental": false,
"previous_transcript": "",
"target_duration_sec": 90,
"style": "warm_community",
"lang": "zh-CN"
}
输出: { “short_title”: “东门道闸升级完成试运行”, “event_id”: 1987654321000123456, “title_for_audio”: “小区东门道闸升级改造”, “dialogue_script”: “A:各位邻居好,欢迎收听本期社区播客!上期我们刚聊完东门道闸升级的业主征询和方案公示,今天这期,咱们直接跟进到落地阶段啦!\n\nB:没错!3月12号投票结果出炉——A方案以超半数支持率正式通过,业委会随即启动合同签订流程。\n\nA:紧接着,3月15号物业就发出了施工进场通知:3月20日起,东门将实行半幅封闭施工,车辆请统一绕行西门,为期约一周。\n\nB:而就在昨天,3月22号下午,新道闸已经安装完毕,正式进入试运行阶段!现在正同步开展车牌白名单录入工作,确保识别精准、通行顺畅。\n\nA:后续白名单登记方式和试运行反馈渠道,我们下期会第一时间同步,也欢迎邻居们在楼栋群留言提建议~”, “dynamic_count_used”: 5, “status”: “READY” } { “event_id”: “1987654321000123456”, “audio_url”: “https://intu-1353663652.oss-cn-heyuan.aliyuncs.com/2026/04/15/podcast/1987654321000123456_0db2804ba00b4d02af91876202b1338a.mp3”, “status”: “OK” }
postman输出 { “output”: { “finish_reason”: “stop”, “session_id”: “109b1d3e162d4b18a0e42af2c31c0a14”, “text”: ”{“short_title”:“东门道闸升级完成投票即将施工”,“event_id”:1987654321000123456,“title_for_audio”:“小区东门道闸升级改造”,“dialogue_script”:“A:各位邻居好,欢迎收听本期社区播报!上期我们刚聊完东门道闸升级的征询启动和方案公示,这周进展飞速——A方案已正式投票通过啦!\n\nB:没错!3月12日晚,业委会确认参与投票业主过半数支持A方案,合同签署进入倒计时。紧接着,物业在3月15日同步发出两条施工通知:3月20日起东门将半幅封闭施工,车辆请绕行西门;3月25日起还将面向全体住户开展集中告知。\n\nA:也就是说,改造已从“纸上方案”迈入“现场施工”阶段啦!提醒大家提前规划出行路线,尤其早高峰时段注意绕行西门。\n\nB:也别忘了,施工期间东门人行通道仍保持开放,非机动车和行人通行不受影响。后续安装调试、试运行及最终验收节点,我们也会持续同步更新~”,“dynamic_count_used”:5,“status”:“READY”}{“duration_seconds”:53,“event_id”:“1987654321000123456”,“audio_url”:“https://intu-1353663652.oss-cn-heyuan.aliyuncs.com/2026/04/15/podcast/1987654321000123456_635786ce186542beae23bf96621f4b6a.mp3\”,\“status\”:\“OK\”}” }, “usage”: { “models”: [ { “input_tokens”: 567, “model_id”: “qwen-plus-latest”, “output_tokens”: 236 } ] }, “request_id”: “2d5e0ace-90ff-973e-8b64-ff4b06439cbf” }
请求示例(场景2:>5 且新增)
{
"event_id": 1987654321000123456,
"community_id": 10001,
"event_title": "小区东门道闸升级改造",
"event_summary": "物业联合业委会推进东门道闸更换与车辆登记规则调整,以下为进展摘录。",
"dynamic_count": 6,
"dynamics_list": [
{
"dynamic_id": 1987654321000123402,
"title": "方案公示",
"content_text": "公示两套候选方案及报价区间,公示期 7 天。",
"occur_time": "2026-03-05 18:30:00"
}
],
"is_incremental": true,
"previous_transcript": "新道闸已安装完成,进入试运行与车牌白名单录入阶段。",
"target_duration_sec": 90,
"style": "warm_community",
"lang": "zh-CN"
}
场景2说明:该结构可由后端直接构造并传入;场景判断优先看
dynamic_count>5 && is_incremental=true,当前约定dynamics_list每次仅传 1 条新增素材。前情由previous_transcript提供,short_title仍需基于dynamics_list全量(即该次增量列表)title + content_text生成。
注意:不命中场景时,仍返回同一段首 JSON 结构(
status=INSUFFICIENT_MATERIAL),便于后端统一解析。
四、脚本节点(素材整理与场景选择):输入与输出
脚本输出(供后续条件/LLM使用)
| 字段 | 类型 | 说明 |
|---|---|---|
material_brief | String | 拼给 LLM 的素材正文 |
short_title_source_text | String | 由 dynamics_list 全量 title+content_text 拼成,专供生成 short_title |
dynamics_clean_count | Number | 清洗后总条数 |
dynamic_count_used | Number | 本次用于播客生成的条数(场景1=5,场景2=2) |
scenario_supported | Number | 1=命中两场景之一;0=不命中 |
fallback_reason | String | 不命中原因 |
五、条件表达式(与工作流内变量名一致)
条件① 是否命中两种场景
- 逻辑:
scenario_supported == 1时进入大模型;否则走脚本1输出INSUFFICIENT_MATERIAL。 - 表达式示例:
Number(outputs.<素材整理节点id>.scenario_supported || 0) >= 1
条件② 是否调用播客网关
- 逻辑:仍按
scenario_supported == 1判断,确保仅两种场景进入 HTTP 节点。 - 表达式示例:
Number(outputs.<素材整理节点id>.scenario_supported || 0) >= 1
六、工作流对外 JSON(Template 输出约定)
后端解析工作流返回时,固定为两段 JSON 串联(与你给的样例一致):
第一段为工作流结果;第二段为网关结果(含 audio_url、short_title)。
导出模板见:fm-AI播客(开发中)/template.yml;细节见 260404_百炼应用_双人对话结果.md。
6.1 素材不足
{
"status": "INSUFFICIENT_MATERIAL",
"event_id": 1987654321000123456,
"dynamic_count_used": 0,
"dialogue_script": "",
"title_for_audio": "小区东门道闸升级改造"
}
6.2 生成成功(统一双 JSON 结构)
{
"status": "READY",
"event_id": 1987654321000123456,
"dynamic_count_used": 5,
"dialogue_script": "<双人对话口播正文,A:/B:分段、段间空行>",
"title_for_audio": "小区东门道闸升级改造",
"short_title": "小区东门道闸升级改造纪实"
}
{
"event_id": "1987654321000123456",
"audio_url": "https://xxx/podcast_xxx.mp3",
"short_title": "小区东门道闸升级改造纪实",
"status": "OK"
}
short_title 规则:由大模型根据 dynamics_list 全量条目的 title + content_text 综合生成。
七、后端数据字段与状态(先定再开发)
建议在「大事记播客」扩展表或 t_publish_info 扩展字段中固化下列概念(名称可按库表规范调整)。
| 概念 | 建议枚举/字段 | 说明 |
|---|---|---|
| 播客生成状态 | PENDING / GENERATING / READY / FAILED / SKIPPED(素材不足) | SKIPPED 可与 INSUFFICIENT 对应 |
| 脚本来源 | 工作流返回 status | READY 与 INSUFFICIENT_MATERIAL |
| 音频 | audio_url 或对象存储 key | TTS 完成后写入 |
| 逐字稿 | transcript 或复用脚本字段 | 供下次 previous_transcript |
| 失败原因 | fail_reason | 便于排错与重试 |
与 P1 方案接口对齐(实现时核对路径与鉴权)
| 路径 | 方法 | 说明 |
|---|---|---|
/service/event-podcast/trigger-generate | POST | 触发播客生成(可含异步任务 ID) |
/service/event-podcast/status | GET | 查询生成状态 |
/service/event-podcast/audio-url | GET | 获取音频 URL |
/service/event-podcast/transcript | GET | 获取逐字稿 |
八、分阶段落地(按你给出的顺序执行)
阶段 A:数据字段与状态
- 定稿库表或字段:
event_id、状态、脚本文本、音频 URL、时间戳、失败原因。 - 定义与小程序、工作流 JSON 的字段映射(
status、reason等)。 - 实现
status/transcript等查询接口(可先 Mock,再接真实数据)。
阶段 B:脚本生成(LLM 工作流)
- 后端使用应用 ID
f67ab0c3880c4c4ab6fd116bf0486e83调用工作流(参数与第三节一致)。 - 解析第六节 JSON,写入
READY或INSUFFICIENT对应状态与文案。 - 将成功生成的正文写入「逐字稿」字段,供后续叙事衔接传入
previous_transcript。
阶段 C:接现有 TTS
- 以
dialogue_script(或兼容script_text)为输入,调用现有 TTS / 火山播客(与项目现状一致)。 - 上传音频至 OSS/CDN,回写
audio_url。 - 状态流转:
GENERATING→READY(音频就绪)或FAILED。
阶段 D:≥5 触发与异步
- 主阈值在 Java:动态数 ≥5(及业务规则)通过后再调用工作流;工作流内条件①作兜底。
- 生成任务异步化(线程池 / 消息队列 / 定时补偿),避免阻塞发帖接口。
- 记录任务 ID,便于
status轮询与重试。
阶段 E:小程序播放与通知
- 大事记详情页:播客区域(生成中 / 可播放 / 不足提示),
innerAudioContext播放audio_url。 - Feed/卡片:有音频时展示入口(与 P1 方案「发现页播客入口」一致)。
- 服务通知:生成成功后通知编辑者(模板 ID、跳转路径按微信规范配置)。
九、依赖与风险
| 项 | 说明 |
|---|---|
| 百炼侧 | 节点 id、LLM 输出字段名(text/result)须与表达式、后端解析一致。 |
| 并发 | 同一大事记重复触发时,建议幂等(版本号或「仅最新任务生效」)。 |
| 成本 | 工作流含多次 LLM,需在触发条件与缓存策略上可控。 |
十、修订记录
| 日期 | 说明 |
|---|---|
| 2026-04-03 | 初稿:工作流拓扑、字段、JSON、分阶段步骤与百炼应用 ID。 |
评论 (6)
豆包的播客
豆包播客
豆包
豆包播客
1
1
发表评论