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,生成后再手动微调。