openclaw造神记录-04:写了个图片生成skill,顺便聊聊产品和技术

0 阅读10分钟

上个周末,想在 自己的龙虾里生成一张图片。然后发现——居然没有图片生成的 Skill。行吧,那就vibe coding写一个。

🤔 为什么要自己做?

原因 1:OpenClaw 原生没有

OpenClaw 的 Skill 生态里,确实没有图片生成功能。

想生成图片?你有三个选择:

  1. 打开阿里云百炼控制台
  2. 用 Midjourney 或 Stable Diffusion
  3. 自己写脚本调 API

💡 但这些都跟 OpenClaw 没关系,你得切换工具,来回倒腾。

原因 2:现有的 Skill 太难用了

我也试过找别人写的图片生成 Skill,用了几个之后,沉默了。

具体表现:

  • ❌ 说"做个名片",它不理解,要你写完整的 Prompt
  • ❌ 只有一个引擎能用,想换模型?没门
  • ❌ 说"小红书配图",它不知道是 3:4,要你手动填尺寸
  • ❌ 生成效果看运气,同样的 prompt 今天好用明天不好用

💡 说白了,就是个"调 API 的壳",没有任何产品化思考。


🎯 做成什么样?

我就想要一个简单的交互:

"帮我做一张赛博朋克风格的名片"

然后它应该自动帮我完成:

  • ✅ 语义触发(听到"生成图片"、"做名片"自动调用 Skill)
  • ✅ 意图识别(哦,用户要名片,赛博朋克风格)
  • ✅ 模板匹配(用 biz_card 模板)
  • ✅ 引擎选择(名片用 wanx,文字渲染好)
  • ✅ Prompt 构建(把"赛博朋克"扩展成专业描述)
  • ✅ 尺寸适配(名片用 16:9 比例)
  • ✅ 生成并返回图片

💡 而不是让我自己去研究这些。

于是,Beauty Image 就这么诞生了。

🚀 核心功能

一句话总结

基于 OpenClaw 语义触发 + 本地意图识别,自动完成场景匹配、模板选择、引擎路由、Prompt 构建,输出专业级图片。

都能干什么?

场景分类具体场景OpenClaw 触发示例
📇 商务场景名片设计、商业海报、产品摄影"帮我做张名片"
👤 社交场景头像/IP 形象、表情包、金句卡片"生成个头像"
🎨 3D 创意水晶质感手办、毛绒玩具、微缩场景"画个水晶猫咪"
🛠️ 实用工具天气卡片、冰箱贴、电影分镜"上海天气卡片"

目前支持

  • 📦 40+ 场景模板
  • 🎨 30+ 风格词典
  • ⚙️ 3 个 引擎(wanx / seedream4 / seedream5)
  • 📐 15 种 尺寸比例

🔌 集成机制

SKILL.md 定义

OpenClaw Skills 通过 SKILL.md 文件定义触发条件和执行逻辑:

---
name: beauty-image
description: 商业化 AI 图片生成助手。40+ 场景模板,30+ 风格词典,智能意图识别...
version: 3.2.0
author: 圆规
metadata:
  openclaw:
    requires:
      env:
        - DASHSCOPE_API_KEY
        - ARK_API_KEY
    primaryEnv: DASHSCOPE_API_KEY
    emoji: "🎨"
---

# Beauty Image V3 — 商业化 AI 图片生成

**触发场景**:
- 名片设计  询问姓名、职称、公司、风格
- 海报创作  询问主题、配色、排版
- 头像/IP  询问人物描述、风格、表情
- 3D/材质  询问主体、材质类型
- 通用图片  画面描述、尺寸比例

两层意图识别

第一层:OpenClaw 语义触发

OpenClaw 根据用户消息的语义,自动判断是否需要调用 Beauty Image Skill:

用户:"帮我做一张赛博朋克风格的名片"
   ↓
OpenClaw 语义理解 → 触发 beauty-image skill
   ↓
执行 scripts/generate_image_v3.py --prompt "..."

第二层:本地规则引擎

Skill 内部的 image_intent_parser.py 进一步解析用户需求:

# 33 条场景规则
_SCENE_RULES = [
    (r"(名片|business\s*card)", "biz_card"),
    (r"(水晶|crystal|玻璃)", "3d_crystal"),
    # ... 共 33 条
]

# 21 条风格规则
_STYLE_RULES = [
    (r"赛博朋克|cyberpunk", "赛博朋克"),
    (r"吉卜力|ghibli", "吉卜力"),
    # ... 共 21 条
]

💡 OpenClaw 负责"什么时候调用",本地规则引擎负责"具体生成什么"。


🔧 技术细节(给感兴趣的同学)

1️⃣ 意图识别:写了 54 条规则

代码文件:scripts/image_intent_parser.py

一开始我想用 LLM...

但算了一笔账:

LLM 意图识别:¥0.02/次
图片生成:¥0.15/次
────────────────
总成本:¥0.17/次

每天 100 次:
LLM 成本:¥2/天 → ¥60/月
图片成本:¥15/天 → ¥450/月

💡 LLM 占了 12% 的成本,而且只是中间步骤。

于是我写了规则引擎

# 33 条场景规则
_SCENE_RULES = [
    (r"(名片|business\s*card)", "biz_card"),
    (r"(海报|poster|宣传图)", "biz_poster"),
    (r"(水晶|crystal|玻璃)", "3d_crystal"),
    (r"(毛绒|plush|蓬松)", "3d_plush"),
    # ... 共 33 条
]

# 21 条风格规则
_STYLE_RULES = [
    (r"赛博朋克|cyberpunk", "赛博朋克"),
    (r"浮世绘|ukiyo", "浮世绘"),
    (r"吉卜力|ghibli", "吉卜力"),
    # ... 共 21 条
]

效果对比

方案响应时间单次成本覆盖率
规则引擎(默认)<1ms¥0.00~85%
LLM 深度解析(--use-llm)~500ms¥0.02~95%

2️⃣ Prompt 不是拼接,是"美化"

代码文件:scripts/image_prompt_templates.py

6 层结构化 Prompt

很多人以为我就是简单拼接了一下关键词,其实不是。

我研究了 110+ 高质量图片生成模板,总结了一个6 层结构:

layers = {
    "core": "核心主体",           # 这是什么?
    "subject": "主体描述",         # 长什么样?
    "style": "风格特征",          # 什么艺术风格?
    "lighting": "光照氛围",       # 什么光线条件?
    "composition": "构图视角",    # 什么视角和布局?
    "technical": "技术参数"       # 什么质量要求?
}

风格词典:三个维度

每个风格都有三个维度的描述:

STYLE_DICT = {
    "赛博朋克": {
        "keywords": "赛博朋克风格,霓虹灯光,深色背景,蓝紫粉渐变",
        "lighting": "霓虹灯混合光,彩色边缘光,逆光剪影",
        "negative": "白天,明亮,自然光,田园",
    },
    "水晶": {
        "keywords": "透明玻璃或水晶材质,高抛光,折射效果",
        "lighting": "明亮干净的专业棚拍光,锐利高光",
        "negative": "哑光,粗糙,木质,金属",
    },
}

实际效果

用户输入: "赛博朋克名片"(5 个字)

输出 Prompt:(约 200 个字)

个人名片设计,专业商务场景,包含姓名职位公司信息,简洁现代的版式设计,
赛博朋克风格,霓虹灯光,深色背景,蓝紫粉渐变,全息投影,
霓虹灯混合光,彩色边缘光,逆光剪影,
正面视角,居中布局,标准名片比例,
8K 渲染,细节丰富,专业质量

负面 Prompt:

白天,明亮,自然光,田园,过度装饰,复杂排版

💡 从 5 个字,扩展到 200 个字的专业级 Prompt。


3️⃣ 引擎路由:我测了N 张图

代码文件:scripts/generate_image_v3.py

发现的问题

一开始我只用了万相,后来发现有些场景真搞不定。

比如 3D 水晶,万相生成的跟塑料似的。但 Seedream 5 就可以。

实测数据(500+ 张图)

场景类型wanx 胜率seedream4 胜率seedream5 胜率推荐引擎
名片/文字78%15%7%wanx
3D 水晶12%35%53%seedream5
毛绒玩具8%42%50%seedream5

路由逻辑

def select_engine(scene_id, style_name):
    # 商务场景(文字多)→ wanx
    if scene_id.startswith("biz_"):
        return "wanx"
    
    # 3D 场景 → seedream5
    if scene_id.startswith("3d_"):
        return "seedream5"
    
    # 艺术创作 → seedream5
    if scene_id.startswith("art_"):
        return "seedream5"
    
    # 默认 → seedream4(性价比)
    return "seedream4"

故障转移机制

seedream5 额度用完  → 自动切 seedream4
seedream 全挂了    → 自动切 wanx
都不可用          → 提示用户配置 API Key

4️⃣ 尺寸适配:你说"小红书",它知道是 3:4

代码文件:scripts/generate_image_v3.py

这个功能我自己用得最爽。

15 种标准比例

WANX_SIZE_MAP = {
    "1:1": "1280*1280",
    "3:4": "1104*1472",  # 小红书
    "16:9": "1696*960",
    "2:3": "1048*1568",  # 海报
    # ... 共 15 种
}

用户友好别名

SIZE_ALIASES = {
    "正方": "1:1", "头像": "1:1",
    "小红书": "3:4", "xhs": "3:4",
    "横版": "16:9", "电影": "21:9",
    "海报": "2:3",
}

实际使用

# 你说"小红书"
uv run scripts/generate_image_v3.py --prompt "小红书配图" --size 小红书

# 它自动转成 3:4

💡 这就是"复杂留给自己,简单留给用户"。


5️⃣ 生成前确认:省得你浪费钱

代码文件:scripts/generate_image_v3.py

图片生成是要花钱的,¥0.1-0.5/次。

我不想用户稀里糊涂就生成了,结果发现不是自己想要的。

print(f"""
即将生成图片:
- 场景:biz_card
- 风格:赛博朋克
- 引擎:wanx
- 尺寸:16:9 (1696*960)
- 缺失字段:title, company

确认?(y/n): """)

confirm = input()
if confirm.lower() != 'y':
    print("已取消")
    sys.exit(0)

用户可以看到:

  1. 意图识别对不对
  2. 还有哪些字段没填
  3. 到底要用哪个引擎

💡 确认完再生成,省得浪费钱。


📈 开发历程

V1:MVP(1 天)

# 就一个脚本
prompt = input("请输入描述:")
result = call_wanx_api(prompt)
save_image(result)
✅ 优点❌ 问题
快,一天上线只能用万相
简单直接Prompt 得自己写

V2:模板化(1 周迭代)

templates = {
    "biz_card": {"prompt": "名片设计,{name},{title}", "engine": "wanx"},
    "3d_crystal": {"prompt": "3D 水晶质感,{subject}", "engine": "seedream5"},
}
✅ 进步❌ 问题
用户只需填字段还是得手动选模板
不用写完整 Prompt不够智能

V3:意图识别(当前版本)

# 33 条规则自动识别场景
scene_id = match_scene(user_input)
style = match_style(user_input)
fields = extract_fields(user_input)

💡 核心思路:用规则引擎模拟 LLM 的意图理解能力,但成本几乎为零。


V3.2:OpenClaw Skill 集成

  • 🔌 通过 SKILL.md 定义触发条件
  • 🧠 OpenClaw 语义理解 + 本地规则引擎,两层意图识别
  • 📋 5 个触发场景,每个场景有确认询问逻辑
  • 🎯 支持自然语言触发:"帮我做张名片"、"画个水晶猫咪"

💭 一些产品思考

思考 1:给用户选择权,还是帮用户做决定?

这是个经典的产品问题。

我的答案:

默认帮用户决定,但保留手动 override 的权利。

# 默认:自动路由(帮你选最优的)
uv run scripts/generate_image_v3.py --prompt "名片"

# 手动:强制指定(你想用哪个用哪个)
uv run scripts/generate_image_v3.py --prompt "名片" --engine wanx

理由:

  1. 大部分用户不知道什么是 wanx、什么是 Seedream
  2. 但专家用户可能就想用某个特定模型
  3. 所以默认帮你选,但也可以手动改

思考 2:成本 vs 体验的权衡

方案准确率单次成本
LLM 意图识别95%¥0.02
规则引擎85%¥0.00

我的选择: 规则引擎。

💡 因为 85% 够用了。

剩下的 15%,用户可以手动指定,或者加钱上 LLM。

这不是技术问题,是商业决策。


思考 3:为什么开源?

三个原因:

  1. 📢 40+ 场景肯定覆盖不全,我需要大家帮我提 PR
  2. 🌱 OpenClaw Skill 生态需要更多玩家,我抛个砖
  3. 💻 代码本身有点意思,值得分享

📁 项目结构

beauty-image/
├── SKILL.md                          # OpenClaw Skill 定义(触发条件 + 执行逻辑)
├── _meta.json                        # 技能元数据
├── README.md                         # 使用说明
├── scripts/
│   ├── generate_image_v3.py          # V3 主脚本(入口)
│   ├── image_intent_parser.py        # 意图识别引擎(54 条规则)
│   ├── image_prompt_templates.py     # 30+ 风格词典 + Prompt Builder
│   └── check.py                      # 健康检查
└── examples/
    └── README.md                     # 示例

🎬 最后

这个东西,说大了是"AI 图片生成工具",说小了就是"我懒得每次手动写 Prompt 所以写了个脚本"。

但做着做着,发现还挺有意思的:

  • 🤔 怎么设计交互才能让用户最省事?
  • ⚖️ 怎么在成本和效果之间找平衡?
  • 📐 怎么把"玄学"的 Prompt 变成可复用的工程?
  • 🛡️ 怎么做故障转移保证服务可用?

💡 这些都是产品问题,也是技术问题。


如果你也在做类似的东西,或者对这个项目有任何想法,欢迎来找我聊聊。

📬 GitHubgithub.com/xyva-yuangu…
👤 作者圆规
💬 反馈提 Issue 或直接联系我

觉得有用的话,帮忙点个 Star⭐ 呗!(重点,点个Star🌟)

另外,我也开源了我二次开发的龙虾:github.com/xyva-yuangu…

备注:V5版应该比市面上使用体验都好一些,起码不会忘记东西,token消耗也做了优化。目前最新版本是V11,还在养。