通过将PAI-EAS部署的通义万相(ComfyUI)服务作为工具集成到Dify,可以将复杂的创作流程自动化。本文将介绍服务的部署与集成,实现从文本到多媒体内容的端到端生成。
方案概述
本方案的核心是利用Dify作为应用编排器,调用部署在PAI-EAS上的ComfyUI推理服务。ComfyUI的推理任务是异步执行的,因此整个调用链路如下:
提交任务:Dify向EAS服务发送一个POST请求,请求体中包含ComfyUI工作流的JSON描述。EAS接收任务后,会立即返回一个唯一的
prompt_id
。轮询状态:Dify使用上一步获取的
prompt_id
,通过GET请求循环查询(轮询)任务的执行状态。EAS会返回任务是否完成、成功或失败等信息。获取结果:判断任务成功执行后,再次发起GET请求获得最终结果,其中包含了生成文件在OSS上的文件名。Dify将文件名与OSS访问地址拼接,最终向用户展示完整的图片或视频链接。
完整工作流示例如下:
步骤一:(可选)部署Dify
若已有Dify环境,可跳过本节。本文以计算巢部署Dify社区单机版为例。
进入计算巢Dify社区版服务详情页,单击开始部署。
根据需求选择配置。对于基础演示,可选择单机版模板,实例类型选择
ecs.u1-c1m2.xlarge
,并设置实例密码,选择一个可用区。单击下一步:确认订单,在跳转页面单击立即创建。
服务部署完成后,单击详情,在概览页签的立即使用区域,找到dify访问链接。注册账号后登录就能创建dify应用。
步骤二:部署万相ComfyUI
进入ModelGallery,在搜索框中输入通义万相2.1-文生视频-1.3B,单击卡片进入模型详情页。
单击右上角部署,在配置页面进行以下设置,其余保持默认。
部署方式:选择
。服务配置:在JSON编辑器中,配置
storage.oss.path
参数,将其值修改为实际的OSS路径(例如:oss://examplebucket/wan
)。此路径将作为ComfyUI的工作目录用于存放生成的内容。关于OSS操作,请参见OSS控制台快速入门。
单击部署。等待约3分钟,当服务状态变为运行中,表示部署成功。
单击服务名称进入详情页,在概览页面的基本信息区域,单击查看调用信息。获取EAS服务的公网调用地址和访问Token,用于在Dify中调用服务。
步骤三:创建Dify应用
在Dify导入示例DSL文件wan-comfyui-dify.yml,本文以此说明调用ComfyUI的关键节点设置。
1. 设置环境变量
OSS_URL:生成文件的访问路径。本文ComfyUI工作目录为
oss://examplebucket/wan
,因此设为https://examplebucket.oss-cn-hangzhou.aliyuncs.com/wan/output
。其中oss-cn-hangzhou.aliyuncs.com
为OSS杭州的外网Endpoint,其他地域请参见OSS地域和访问域名。EAS_Token:步骤二中获取的服务Token。
EAS_URL:步骤二中获取的服务公网调用地址。
2. 开始节点设置输入变量
将正反向提示词等动态参数设为变量,供每次调用时输入。
3. 配置POST请求(获取Prompt ID)
3.1 设置请求地址
在EAS_URL后追加/prompt构成POST请求地址。
3.2 构造并发起POST请求
配置URL、HEADERS与BODY。其中BODY为导出的ComfyUI工作流JSON(创建及导出参见WebUI使用),并将需要动态修改的参数(如提示词、种子数等)替换为Dify中的变量。
3.3 获取Prompt ID
从返回结果中提取prompt_id
,用于后续轮询结果。
def main(arg: str) -> dict:
data = json.loads(arg)
return {"result": data["prompt_id"]}
4. 配置轮询逻辑(获取推理结果)
使用prompt_id循环发起GET请求,检查任务状态。
4.1 设置请求地址
在EAS_URL后追加history/<prompt_id>
构成GET请求地址。其中<prompt_id>
为上一步的结果。
4.2 根据prompt_id发起GET请求
4.3 延时等待
在每次轮询之间插入一个代码节点,执行time.sleep(12)
等操作,以避免过于频繁的请求。
import time
def main()-> dict:
time.sleep(12)
return {
"result": ""
}
4.4 判断执行结束
返回结果中有prompt_id表示推理已完成。
5. 拼接文件地址并展示结果
任务完成后,从最终的轮询结果中提取文件名,并与环境变量中的OSS_URL拼接,形成可公开访问的文件链接,并在Dify的“结束”节点中展示。
5.1 获取推理结果
该节点配置与4.2的节点配置相同。
5.2 提取文件名
import json
def main(input_str: str) -> dict:
data = json.loads(input_str)
images = []
image_names = []
first_key = next(iter(data))
status = data[first_key]["status"]
if status["completed"] and status["status_str"] == "success":
images = data[first_key]["outputs"]["28"]["images"]
for img in images:
image_names.append(img["filename"])
# 将列表转换为字符串
image_names_str = ",".join(image_names)
return {
"result": image_names_str,
}
5.3 拼接文件访问地址
将文件名拼接至OSS_URL,形成可访问的公网链接,并在Dify应用结果中展示。
需确保OSS bucket已设置为公共读权限,详情见Bucket ACL。
步骤四:测试应用
在Dify单击右上角预览,输入正反向提示词,对话框中输入1(工作流未使用该字段,可随意输入),发送之后,等待视频生成。
生产应用建议
安全性:在生产环境中,将OSS Bucket设置为公共读存在数据安全风险。建议限制只允许特定IP或VPC访问,详情见Bucket Policy。
稳定性与成本:合理设置轮询的等待时间。过短的间隔会增加API调用次数和服务器负载,可能产生不必要的费用;过长的间隔则会增加用户的等待时间。建议根据您任务的平均耗时进行调整。
常见问题
为什么无法访问生成的图片或视频链接?
请检查以下几点:
OSS Bucket是否已设置为公共读权限。
在Dify中配置的OSS_URL环境变量是否正确,特别是OSS访问域名是否与Bucket所在地域匹配。
工作流一直卡在轮询步骤怎么办?
这通常意味着EAS服务端的任务未能成功完成。请登录PAI控制台,查看对应EAS服务的实时日志,排查是否有运行时错误。