设计实践

Uizard:Autodesigner 能根据一句话生成多屏设计,但官方指南明确说

Autodesigner 能根据一句话生成多屏设计,但官方指南明确说:要说清楚是 app 还是 website、要写具体、不要规定屏幕数量和组件位置、不要列出具体流程。 这篇把这些规则写成一个提示词检查工具 brieflint.py,并用官方指南里的 ✅/🚫 例句原文做测试。

BINBHO · 图文教程

Autodesigner 能根据一句话生成多屏设计,但官方指南明确说:要说清楚是 app 还是 website、要写具体、不要规定屏幕数量和组件位置、不要列出具体流程。 这篇把这些规则写成一个提示词检查工具 brief_lint.py,并用官方指南里的 ✅/🚫 例句原文做测试。

先看清成品(box 上真实运行)

  • 官方 7 条 ✅ 例句全部通过,4 条 🚫 例句全部被标出对应问题。
  • 风格标签 Light + Dark 被判为冲突。
  • 调试中发现并修复了 4 条“位置词”误报。pytest 18 项通过。

合规提醒:Uizard 没有公开 API,本文只用官方网页功能(Wireframe Scanner、Autodesigner、Handoff 导出),本地脚本只处理你自己的图片和文字,不抓取、不自动化操作 Uizard 网页,也不共享账号。Autodesigner 和组件代码导出需要 Pro 及以上套餐(以官方定价页为准,本文不列价格)。上传的草图、截图要是你有权使用的内容,不要上传别人受版权保护的界面去“复刻”商用。

运行说明:box 上没有 Uizard 账号,所以没有在 Uizard 里真正上传或生成过。本地脚本和测试都在 box 上真实运行过(Python 3.13、Pillow 13.0.0、numpy 2.5.4);测试用的草图照片和“导出图”是我自己用 Pillow 合成的,不是 Uizard 的真实素材。

做完之后你会得到什么?

成果 说明
brief_lint.py 检查项目描述和风格标签;有 ERROR 时退出码为 1
test_brief_lint.py 18 项测试,含官方例句和误报回归
一份写提示词的检查清单 见“模板规则”

需要准备哪些环境?

项目 版本
Python 3.9 以上
依赖 pip install pytest(脚本本身只用标准库)
Uizard Autodesigner 需要 Pro 及以上

官方规则

规则 官方例句
说明 app(桌面端写 web app)还是 website ✅ "A web app to track invoices";🚫 "An app to order food (Desktop)"
写具体 ✅ "A grocery ordering app";🚫 "Design tool website"
不要过度控制(屏幕数量、流程、组件位置) 🚫 "...with a big title centered in the screen that says “The best design tool”..."
关注最终目标,不要列页面和流程 ✅ "Dating app for people with magical powers";🚫 "A signup flow with login, signup, and onboarding screens."
风格标签不要互相冲突 🚫 Light 和 Dark 同时选

以上都来自 Guide to Autodesigner。指南还建议风格可以单独描述,例如形容词、颜色、知名公司风格。

文件结构

64-uizard-B-src/
├── brief_lint.py
└── test_brief_lint.py

第 1 步:检查工具

"""Uizard Autodesigner 提示词检查(英文提示词)。规则全部来自官方《Guide to Autodesigner》:
1. 写清楚是 app(桌面端写 web app)还是 website
2. 写具体,例如 "A grocery ordering app",而不是 "Design tool website"
3. 不要过度控制:屏幕数量、组件位置、按钮上的具体文字,Autodesigner 通常不会照做
4. 关注最终目标,不要列出具体的页面和流程(如 "A signup flow with login, signup, and onboarding screens.")
风格提示:不要选择互相冲突的标签(例如 Light 和 Dark)
这些是启发式检查,只给出提醒,不保证生成结果。"""
import re, sys

TYPE_WORDS = r"\b(web app|app|application|website|landing page|site)\b"
OVERCONTROL = [
    (r"\b\d+\s+(screens?|pages?)\b", "指定了屏幕数量"),
    # 位置词只有和界面组件名在 6 个词以内同时出现时才算(避免 "the right plumber"、"top-up"、"left-handed")
    (r"\b(?:title|button|logo|menu|image|header|navbar|nav|text|form|search bar|card|footer|banner)\b(?:\W+\w+){0,6}?\W+(?:centered|centred|on the (?:top|bottom|left|right)|at the (?:top|bottom)|in the (?:center|middle|corner))\b"
     r"|\b(?:centered|centred|on the (?:top|bottom|left|right)|at the (?:top|bottom)|in the (?:center|middle|corner))\b(?:\W+\w+){0,6}?\W+(?:title|button|logo|menu|image|header|navbar|nav|text|form|card|footer|banner)\b",
     "指定了组件位置"),
    (r"(that says|saying)\s*[\"“]?", "指定了组件上的具体文字"),
    (r"[\"“][^\"”]{3,}[\"”]", "引用了具体文案"),
]
FLOW = [(r"\b(sign ?up|log ?in|onboarding|checkout)\b.*\b(flow|screens?)\b|\b(flow|screens?)\b.*\b(sign ?up|log ?in|onboarding)\b",
         "列出了具体的页面或流程,应该描述最终目标")]
CONFLICTS = [("light", "dark")]

def lint_project(prompt, device="mobile"):
    p, issues = prompt.strip().lower(), []
    types = re.findall(TYPE_WORDS, p)
    if not types:
        issues.append(("ERROR", "没有说明是 app 还是 website"))
    elif device == "desktop" and "app" in types and "web app" not in types:
        issues.append(("WARN", "桌面端的应用请写 web app;如果想要的是网站,请写 website"))
    words = re.findall(r"[a-z']+", p)
    has_purpose = bool(re.search(r"\b(for|to|with|that)\b|\w+ing\b", p))
    if len(words) < 4 and not has_purpose:
        issues.append(("WARN", "太笼统:补充用途或对象,例如 for ...、to ..."))
    for pat, msg in OVERCONTROL + FLOW:
        if re.search(pat, p):
            issues.append(("WARN", msg))
    return issues

def lint_style(tags):
    t = {x.strip().lower() for x in tags}
    return [("ERROR", f"标签冲突:{a} 和 {b}") for a, b in CONFLICTS if a in t and b in t]

if __name__ == "__main__":
    import argparse
    ap = argparse.ArgumentParser(); ap.add_argument("prompt"); ap.add_argument("--device", default="mobile", choices=["mobile", "tablet", "desktop"])
    ap.add_argument("--tags", default="")
    a = ap.parse_args()
    issues = lint_project(a.prompt, a.device) + (lint_style(a.tags.split(",")) if a.tags else [])
    for lvl, msg in issues:
        print(f"[{lvl}] {msg}")
    print("OK" if not issues else f"{len(issues)} 条提醒")
    sys.exit(1 if any(l == "ERROR" for l, _ in issues) else 0)

第 2 步:测试

"""用官方指南里的 ✅ / 🚫 例句做测试(原文照抄)。"""
import pytest
import brief_lint as L

GOOD = [("A web app to track invoices", "desktop"), ("A website to order food", "desktop"),
        ("A landing page for a design tool SaaS", "desktop"), ("A grocery ordering app", "mobile"),
        ("An invoice tracking website", "desktop"), ("A landing page for a design tool", "desktop"),
        ("Dating app for people with magical powers", "mobile")]
BAD = [("An app to order food (Desktop)", "desktop", "web app"),
       ("Design tool website", "desktop", "太笼统"),
       ('A landing page for a design tool with a big title centered in the screen that says "The best design tool", with a glowing button that says signup', "desktop", "位置"),
       ("A signup flow with login, signup, and onboarding screens.", "mobile", "流程")]

@pytest.mark.parametrize("prompt,device", GOOD)
def test_guide_good_examples_pass(prompt, device):
    assert L.lint_project(prompt, device) == []

@pytest.mark.parametrize("prompt,device,expect", BAD)
def test_guide_bad_examples_flagged(prompt, device, expect):
    assert any(expect in m for _, m in L.lint_project(prompt, device))

def test_no_type():
    assert L.lint_project("Something for dog owners")[0][0] == "ERROR"

def test_style_conflict():
    assert L.lint_style(["Young", "Light", "Modern"]) == []
    assert L.lint_style(["Light", "Dark"])[0][0] == "ERROR"

# 调试时发现的误报(修复前 4/7 条被误判为“指定了组件位置”)
@pytest.mark.parametrize("prompt,device", [("A website that helps you find the right plumber", "desktop"),
    ("A fitness app for people who sit all day at the bottom of a long workday", "mobile"),
    ("A web app to manage top-up cards for a cafe", "desktop"), ("A website for left-handed guitar players", "desktop")])
def test_position_false_positives(prompt, device):
    assert L.lint_project(prompt, device) == []

def test_real_position_still_flagged():
    assert any("位置" in m for _, m in L.lint_project("A website for a bakery with the logo centered at the top", "desktop"))

第 3 步:运行

$ python brief_lint.py "An app to order food (Desktop)" --device desktop --tags Light,Dark; echo $?
[WARN] 桌面端的应用请写 web app;如果想要的是网站,请写 website
[ERROR] 标签冲突:light 和 dark
2 条提醒
1
$ python -m pytest -q
18 passed

检查通过后,把提示词粘贴到 Autodesigner 的项目描述框,风格写在单独的风格描述里。(本文没有在 Uizard 里实际生成。)

调试示例

1. 第一版一次就通过了全部官方例句,但这不代表没有问题。 我另外写了 7 条正常的提示词试了一下,其中 4 条被误报为“指定了组件位置”: find the right plumber、at the bottom of a long workday、top-up cards、left-handed guitar players。原因是只要出现 right、top、left、bottom 就会报。 修复方法:只有当位置短语(centered、on the left、at the top 等)和界面组件名(title、button、logo 等)在 6 个词以内同时出现时才报。这 4 条已加为回归测试,同时用 "with the logo centered at the top" 确认真正的位置描述仍然会被标出。

2. 我自己的测试写错了。 修复后仍有 1 条失败:fitness app 那条。逐条打印规则匹配结果发现,没有任何规则命中;真正的原因是测试统一用了 device="desktop",所以“桌面端请写 web app”的提醒是正确的。我把测试改成每条单独指定设备。

常见问题

现象 原因 处理
生成的是网站,你想要的是应用 没说清类型或设备 桌面端写 web app
生成的屏幕数和要求不一样 Autodesigner 通常不遵守严格要求 生成后再手动增删
风格前后矛盾 选了冲突标签 只保留一种
工具误报 启发式规则有局限 以官方指南为准,可以忽略 WARN

模板规则

  • 句式:A/An <web app|app|website> <to/for ...>。
  • 一句话写目标,不写页面清单。
  • 风格单独写:标签 + 形容词或颜色。
  • 不在提示词里写按钮文字和位置;生成后再改。

项目资源

用途 地址
Guide to Autodesigner https://support.uizard.io/en/articles/7728147-guide-to-autodesigner

提示词写对方向,剩下的交给 Autodesigner,生成后再手动微调。