Coze案例-油画换脸智能体

完整项目

学习目标:

  • 掌握提示词加图片,生成图片这类多模态搭建方式
  • 嵌套调用工作流,掌握模块化的搭建方式
  • 掌握代码节点的基本使用 图片

工作流搭建

2.1 开始节点

图片

2.2 意图分析节点

意图分析节点使用大模型节点,模型使用豆包工具调用。输入和输出配置如下:

图片

图片

系统提示词的配置:

## 角色
你是意图分析专家。请根据{{input}},分析出用户想要使用的名画,并输出对应的名画{query}和对应的{number}。

## 名画名称
支持的名画有:
1=维米尔《戴珍珠耳环的少女》
2=达芬奇《蒙娜丽莎的微笑》
3=拉斐尔《自画像》
4=梵高《戴灰毡帽的自画像》
5=达芬奇《抱貂的女子》
6=梵高《梵高耳朵缠着绷带、拿着烟斗的自画像》
7=哈尔斯《笑容骑士》
8=拉斐尔《戴头纱的女子》


## 限制
1. 你输出的内容必须为8幅名画中的一幅。
2. 你必须确保输出和支持名画的内容一模一样,例如“ 维米尔《戴珍珠耳环的少女》”。
2. 不得返回其他无关内容。

2.3 根据需求抽取图片

这是一个代码节点,输入和输出配置如下:

图片

代码为:

async function main({ params }: Args): Promise<{ image_url: string }> {
    const cases = [
        {
            case: 1,
            painting: "https://p9-bot-workflow-sign.byteimg.com/tos-cn-i-mdko3gqilj/519d672931d746d08c587f66202a7842.jpg~tplv-mdko3gqilj-image.image?lk3s=fff2e91a&x-expires=1781936066&x-signature=wxdxQ20jDdZHodSI0uY3Hw6HvsM%3D",
        },
        {
            case: 2,
            painting: "https://p9-bot-workflow-sign.byteimg.com/tos-cn-i-mdko3gqilj/1884585d8fc94d398748a236913afa74.jpg~tplv-mdko3gqilj-image.image?lk3s=fff2e91a&x-expires=1781935968&x-signature=GP%2F0YvgwSVQevkSKXUQTkqevkqw%3D",
        },
        {
            case: 3,
            painting: "https://p9-bot-workflow-sign.byteimg.com/tos-cn-i-mdko3gqilj/64cfc0fdaf71422787f3b426f06c5212.jpg~tplv-mdko3gqilj-image.image?lk3s=fff2e91a&x-expires=1781936101&x-signature=Mmi1givYhNqCiC6JUy4v95JWEbI%3D",
        },
        {
            case: 4,
            painting: "https://p9-bot-workflow-sign.byteimg.com/tos-cn-i-mdko3gqilj/51816a64aee84c559c93dbf81710974b.jpg~tplv-mdko3gqilj-image.image?lk3s=fff2e91a&x-expires=1781936197&x-signature=vgom%2FcGkImt%2BLTraYGTE7PwFhMM%3D",
        },
        {
            case: 5,
            painting: "https://p9-bot-workflow-sign.byteimg.com/tos-cn-i-mdko3gqilj/1bec591f64b9419bb5b6563bf22fb2a8.jpg~tplv-mdko3gqilj-image.image?lk3s=fff2e91a&x-expires=1781936252&x-signature=Lj9klw4dlYyxy0vlgGqD5ZAdQ1A%3D",
        },
        {
            case: 6,
            painting: "https://p26-bot-workflow-sign.byteimg.com/tos-cn-i-mdko3gqilj/9fb41cf653ac45d48589a02dbe518a4b.jpg~tplv-mdko3gqilj-image.image?rk3s=81d4c505&x-expires=1749892493&x-signature=hwG0FqyBd%2BKk%2FaVpkA%2BfUd5zIgo%3D",
        },
        {
            case: 7,
            painting: "https://p9-bot-workflow-sign.byteimg.com/tos-cn-i-mdko3gqilj/d9ee8e4824fc4a748979169c981fcd37.jpg~tplv-mdko3gqilj-image.image?lk3s=fff2e91a&x-expires=1781936311&x-signature=9ECGKXzVOaZ8Q9vRaD18Ol%2Fss4A%3D",
        },
        {
            case: 8,
            painting: "https://p9-bot-workflow-sign.byteimg.com/tos-cn-i-mdko3gqilj/f8143ee85cfc48ecb5800de890c57ada.jpg~tplv-mdko3gqilj-image.image?lk3s=fff2e91a&x-expires=1781936346&x-signature=BsUn0PLr5z76LXUF3E0e779eaDk%3D",
        }
    ];

    // 使用params.input 而不是params.query
    const inputQuery = params.input;
    if (isNaN(inputQuery)) {
        // 如果输入不是有效的数字,随机返回一个图片链接
        const randomCase = cases[Math.floor(Math.random() * cases.length)];
        return { image_url: randomCase.painting };
    }

    // 直接匹配查询的数字和名画的case字段
    const matchedCase = cases.find(caseItem => caseItem.case === inputQuery);

    // 如果匹配到名画,则返回对应的图像链接;否则随机返回一个
    if (matchedCase) {
        return { image_url: matchedCase.painting };
    } else {
        const randomCase = cases[Math.floor(Math.random() * cases.length)];
        return { image_url: randomCase.painting };
    }
}
import random

async def main(args: Args) -> Output:
    
    cases = [
        {"case": 1, "painting": "https://p9-bot-workflow-sign.byteimg.com/tos-cn-i-mdko3gqilj/519d672931d746d08c587f66202a7842.jpg~tplv-mdko3gqilj-image.image?lk3s=fff2e91a&x-expires=1781936066&x-signature=wxdxQ20jDdZHodSI0uY3Hw6HvsM%3D"},
        {"case": 2, "painting": "https://p9-bot-workflow-sign.byteimg.com/tos-cn-i-mdko3gqilj/1884585d8fc94d398748a236913afa74.jpg~tplv-mdko3gqilj-image.image?lk3s=fff2e91a&x-expires=1781935968&x-signature=GP%2F0YvgwSVQevkSKXUQTkqevkqw%3D"},
        {"case": 3, "painting": "https://p9-bot-workflow-sign.byteimg.com/tos-cn-i-mdko3gqilj/64cfc0fdaf71422787f3b426f06c5212.jpg~tplv-mdko3gqilj-image.image?lk3s=fff2e91a&x-expires=1781936101&x-signature=Mmi1givYhNqCiC6JUy4v95JWEbI%3D"},
        {"case": 4, "painting": "https://p9-bot-workflow-sign.byteimg.com/tos-cn-i-mdko3gqilj/51816a64aee84c559c93dbf81710974b.jpg~tplv-mdko3gqilj-image.image?lk3s=fff2e91a&x-expires=1781936197&x-signature=vgom%2FcGkImt%2BLTraYGTE7PwFhMM%3D"},
        {"case": 5, "painting": "https://p9-bot-workflow-sign.byteimg.com/tos-cn-i-mdko3gqilj/1bec591f64b9419bb5b6563bf22fb2a8.jpg~tplv-mdko3gqilj-image.image?lk3s=fff2e91a&x-expires=1781936252&x-signature=Lj9klw4dlYyxy0vlgGqD5ZAdQ1A%3D"},
        {"case": 6, "painting": "https://p26-bot-workflow-sign.byteimg.com/tos-cn-i-mdko3gqilj/9fb41cf653ac45d48589a02dbe518a4b.jpg~tplv-mdko3gqilj-image.image?rk3s=81d4c505&x-expires=1749892493&x-signature=hwG0FqyBd%2BKk%2FaVpkA%2BfUd5zIgo%3D"},
        {"case": 7, "painting": "https://p9-bot-workflow-sign.byteimg.com/tos-cn-i-mdko3gqilj/d9ee8e4824fc4a748979169c981fcd37.jpg~tplv-mdko3gqilj-image.image?lk3s=fff2e91a&x-expires=1781936311&x-signature=9ECGKXzVOaZ8Q9vRaD18Ol%2Fss4A%3D"},
        {"case": 8, "painting": "https://p9-bot-workflow-sign.byteimg.com/tos-cn-i-mdko3gqilj/f8143ee85cfc48ecb5800de890c57ada.jpg~tplv-mdko3gqilj-image.image?lk3s=fff2e91a&x-expires=1781936346&x-signature=BsUn0PLr5z76LXUF3E0e779eaDk%3D"}
    ]
    params = args.params
    # 获取输入参数
    input_query = params.get("input")
    
    # 验证输入是否为数字
    try:
        input_num = int(input_query)
    except (ValueError, TypeError):
        # 如果输入不是有效的数字,随机返回一个图片链接
        random_case = random.choice(cases)
        return {"image_url": random_case["painting"]}
    
    # 直接匹配查询的数字和名画的case字段
    matched_case = next((case for case in cases if case["case"] == input_num), None)
    
    # 如果匹配到名画,则返回对应的图像链接;否则随机返回一个
    if matched_case:
        return {"image_url": matched_case["painting"]}
    else:
        random_case = random.choice(cases)
        return {"image_url": random_case["painting"]}

2.4 历史撰写

历史撰写节点使用大模型节点,输入输出配置如下:

图片

图片

系统提示词和用户提示词分别为:

## 角色
你是名画历史解读专家。请根据名画名称生成这幅名画历史的一句话概括{brief_intro}和详细解读{context},并以JSON格式输出。

## 输出案例
{
    "brief_intro": "《戴珍珠耳环的少女》是荷兰画家约翰内斯·维米尔的名作,描绘了一位戴着头巾和珍珠耳环的年轻女性。",
    "context": "《戴珍珠耳环的少女》是一幅充满神秘和优雅的肖像画,创作于1665年左右。画中的少女以其深邃的眼神和含蓄的微笑著称,她头戴蓝黄色的头巾,耳饰一颗闪亮的珍珠。维米尔巧妙地运用光影效果,突出了少女的面部表情和配饰的质感,使画面充满了细腻的层次感和真实感。这幅画被誉为“北方的蒙娜丽莎”,展现了维米尔卓越的艺术技巧和对人物内心世界的深刻洞察。"
}

## 限制
1. 必须确保输出的{brief_intro}和{context}有内容,且{brief_intro}仅有一句话概括,{context}为详细解读,不得包含其他内容。
2. 必须以JSON格式输出。
请根据{{topic}}生成这幅名画历史的一句话概括{brief_intro}和详细解读{context},并以JSON格式输出。

2.5 图像处理节点

图像处理节点是自定义的工作流,包括图像生成、画质提升、智能换脸等功能。已经封装好了节点,直接使用就行。输入如下:

图片

2.6 消息节点

根据生成的名画介绍,生成消息。

图片

### 💡 关于“{{topic}}”
---
***一句话总结***<br>
{{brief_intro}}
<br>
---
***详细介绍***<br>
{{context}}
<br>
---
![image]({{imageurl}})

2.7 输出节点

输出节点为图像处理节点的输出

图片

图像处理子节点

图片

3.1 开始节点:

开始节点需要配置

  • user_photo
  • painting_photo
  • Prompt
  • gender 图片

3.2 图像生成节点

图片

添加插件,图像生成,配置如下:

  • 风格融合 painting_photo
  • 人物一致 user_photo
  • 空间深度 painting_photo 图片

图片

正向和负向提示词

((1 {{gender}})),{{prompt}},{{prompt}}的服饰,油画

多人,雕塑,ugly hands, ugly fingers, bad body

3.3 画质提升节点

对上一步的输出data,进行画质提升。选择画质提升插件。

图片

3.4 智能换脸节点

智能换脸,需要配置换脸图和底图。换脸图就是用户的图片,底图是画质提升的图片。

图片

3.5 结束节点

图片

运行案例

图片

图片