大模型辅助的 UI 文案生成:让每一个按钮都说“人话“
·
大模型辅助的 UI 文案生成:让每一个按钮都说"人话"
一、"点击确定代表您同意我们的服务条款和隐私政策以及数据收集协议"
你一定见过这种按钮文案。它的问题不是"写错了",而是"写得太正确了"——正确到用户根本不想读。
UI 文案(UX Writing)是设计中最容易被忽视的环节。设计师会把大量精力花在间距、色彩、动效上,但按钮上的文字往往是最后一分钟随手写的。而事实是:一段好的按钮文案,比一个精美的渐变背景更能提升转化率。
大语言模型(LLM)在这个领域的表现出人意料地好——因为它不需要理解设计,它只需要理解语言。这篇文章,我会讲如何用 AI 为你的 UI 组件生成"说人话"的文案,从单个按钮到完整页面的文案生成管线。
二、UI 文案的生成约束:不是"写得好",而是"写得对"
UI 文案的五种核心类型
| 类型 | 示例组件 | 文案要求 | 字数限制 |
|---|---|---|---|
| 操作按钮 | CTA、提交、确认 | 动词开头,结果明确 | ≤6 字 |
| 提示信息 | Tooltip、Toast | 一句话说清状态 | ≤20 字 |
| 错误提示 | 表单校验错误 | 说清楚"哪里错了"+"怎么办" | ≤40 字 |
| 空状态 | 空列表、无结果 | 安抚+引导下一步 | ≤30 字 |
| 占位文本 | Input placeholder | 给出具体示例 | ≤15 字 |
品牌语调的量化
不同品牌需要不同的文案语调。我定义了一个"语调三元组"来量化:
语调 = (亲和度, 专业度, 简洁度)
- 亲和度 0-10:0=冷漠, 10=像朋友聊天
- 专业度 0-10:0=通俗, 10=学术/法律腔
- 简洁度 0-10:0=啰嗦, 10=电报
不同场景的推荐语调:
| 场景 | 语调三元组 | 按钮示例 |
|---|---|---|
| 医疗健康 | (7, 8, 7) | "查看检查报告" |
| 金融理财 | (4, 9, 9) | "确认交易" |
| 社交娱乐 | (9, 3, 6) | "来找点好玩的!" |
| 企业办公 | (5, 7, 8) | "提交审批" |
| 教育学习 | (8, 6, 5) | "开始今天的学习之旅" |
三、AI 文案生成引擎的实现
/**
* AI UI 文案生成引擎
*/
interface CopyContext {
/** 组件类型 */
componentType: 'button' | 'toast' | 'error' | 'empty' | 'placeholder';
/** 业务场景描述 */
scenario: string;
/** 品牌语调 */
brandTone: {
warmth: number; // 亲和度 0-10
professionalism: number; // 专业度 0-10
conciseness: number; // 简洁度 0-10
};
/** 目标用户画像 */
audience?: string;
/** 操作的结果(用户点击后会发生什么) */
actionResult?: string;
}
interface CopyCandidate {
text: string;
score: number; // 综合评分
breakdown: {
lengthScore: number;
toneScore: number;
clarityScore: number;
};
}
class UXCopyGenerator {
/** 字数限制配置 */
private readonly LENGTH_LIMITS = {
button: { max: 6, ideal: 4 },
toast: { max: 20, ideal: 12 },
error: { max: 40, ideal: 20 },
empty: { max: 30, ideal: 15 },
placeholder: { max: 15, ideal: 8 },
};
/**
* 基于 Prompt 工程生成候选文案
*
* 调用的实际是 LLM API,这里展示的是 Prompt 构建逻辑
*/
buildPrompt(context: CopyContext): string {
const limits = this.LENGTH_LIMITS[context.componentType];
return `你是一个专业的 UI/UX 文案设计师。
请为以下场景生成 5 个候选文案:
**组件类型**:${context.componentType}
**业务场景**:${context.scenario}
**用户操作后发生什么**:${context.actionResult || '无特殊说明'}
**目标用户**:${context.audience || '普通用户'}
**文案约束**:
- 字数不超过 ${limits.max} 字,理想是 ${limits.ideal} 字
- 亲和度要求:${context.brandTone.warmth}/10(${this.describeWarmth(context.brandTone.warmth)})
- 专业度要求:${context.brandTone.professionalism}/10(${this.describeProfessionalism(context.brandTone.professionalism)})
- 简洁度要求:${context.brandTone.conciseness}/10(${this.describeConciseness(context.brandTone.conciseness)})
**排版要求**:
${this.getFormatRequirements(context.componentType)}
请直接输出 5 个候选文案,每行一个,不要编号。`;
}
/** 打分引擎:评估候选文案 */
scoreCandidate(text: string, context: CopyContext): CopyCandidate {
const limits = this.LENGTH_LIMITS[context.componentType];
// 评分维度一:长度评分
const length = text.length;
let lengthScore = 0;
if (length <= context.brandTone.conciseness * 0.8 + 1) {
lengthScore = 1.0;
} else if (length <= limits.ideal) {
lengthScore = 0.8;
} else if (length <= limits.max) {
lengthScore = 0.5;
} else {
lengthScore = 0.1; // 超长,严重扣分
}
// 评分维度二:清晰度评分
let clarityScore = 0.5;
// 有动词 → 加分
if (this.hasActionVerb(text)) clarityScore += 0.2;
// 有明确结果 → 加分
if (text.includes('成功') || text.includes('完成') ||
text.includes('已') || text.includes('请')) {
clarityScore += 0.15;
}
// 没有模糊词 → 加分
if (!text.includes('可能') && !text.includes('大概') &&
!text.includes('或许')) {
clarityScore += 0.15;
}
// 评分维度三:语调匹配度
const toneScore = this.calculateToneMatch(text, context.brandTone);
// 加权综合评分
const total = lengthScore * 0.25 + clarityScore * 0.4 + toneScore * 0.35;
return {
text,
score: total,
breakdown: { lengthScore, toneScore, clarityScore },
};
}
/**
* 语调匹配度计算
*
* 基于关键词和句式特征估算文本的语调
*/
private calculateToneMatch(text: string, target: CopyContext['brandTone']): number {
let estimatedWarmth = 5;
let estimatedProfessionalism = 5;
// 温暖度估计
if (/[!!~~]/.test(text)) estimatedWarmth += 1;
if (text.includes('吧') || text.includes('哦') || text.includes('呢')) estimatedWarmth += 1;
if (text.includes('您')) estimatedWarmth += 1;
if (text.includes('请')) estimatedProfessionalism += 1;
// 专业度估计
if (text.includes('确认') || text.includes('提交')) estimatedProfessionalism += 1;
if (text.includes('审核') || text.includes('验证')) estimatedProfessionalism += 1;
// 计算匹配度
const warmthDiff = Math.abs(target.warmth - estimatedWarmth) / 10;
const profDiff = Math.abs(target.professionalism - estimatedProfessionalism) / 10;
return 1 - (warmthDiff + profDiff) / 2;
}
private hasActionVerb(text: string): boolean {
const verbs = ['查看', '提交', '保存', '删除', '搜索', '分享',
'下载', '上传', '开始', '取消', '确认', '发送', '添加', '编辑'];
return verbs.some(v => text.includes(v));
}
private describeWarmth(score: number): string {
if (score >= 8) return '非常亲切,像朋友间的对话';
if (score >= 6) return '温和友好,保持适度的亲近感';
if (score >= 4) return '中性,不冷不热';
return '专业克制,避免情感表达';
}
private describeProfessionalism(score: number): string {
if (score >= 8) return '高度专业,使用行业术语';
if (score >= 6) return '半正式,兼顾专业和可读';
return '通俗易懂,避免专业术语';
}
private describeConciseness(score: number): string {
if (score >= 8) return '极度精简,能省则省';
if (score >= 6) return '适中,说清楚但不啰嗦';
return '详细说明,允许一定冗余';
}
private getFormatRequirements(type: string): string {
const formats: Record<string, string> = {
button: '动词开头(如"查看报告"),不使用"确定"这种泛化词',
toast: '陈述句,说清当前状态(如"保存成功"),不使用疑问句',
error: '先说"哪里错了",再说"怎么办"(如"邮箱格式不正确,请输入有效的邮箱地址")',
empty: '先安抚,再引导(如"还没有收藏内容,去发现好文章吧")',
placeholder: '给出一个具体的示例值(如"例如:张三"),不说"请输入"',
};
return formats[type] || '';
}
/**
* 批量生成 + 自动筛选
*
* 调用 LLM 生成 5 个候选 → 逐一打分 → 返回 Top 3
*/
async generateAndSelect(context: CopyContext): Promise<CopyCandidate[]> {
// 实际项目中使用 LLM API
const candidates = await this.callLLM(this.buildPrompt(context));
return candidates
.map(text => this.scoreCandidate(text, context))
.sort((a, b) => b.score - a.score)
.slice(0, 3); // 返回 Top 3
}
private async callLLM(prompt: string): Promise<string[]> {
// 实际调用 OpenAI / Claude / 本地模型
// 这里返回模拟数据
return [
'查看详情',
'了解更多',
'点击查看',
'前往查看',
'打开详情',
];
}
}
四、边界:AI 文案的三个"不能"
-
不能替代法律合规审核:涉及用户协议、隐私政策、金融交易确认等具有法律效力的文案,AI 生成的内容需要法务团队最终审核。一个字的偏差可能导致法律纠纷。
-
不能理解品牌的历史包袱:一个品牌可能刻意避免某些词汇(比如"优惠"听起来像打折),AI 不知道这些。品牌语调词典需要人工维护。
-
不能判断"场景敏感度":在医疗、金融、法律产品中,一句"轻松搞定"可能让用户觉得你在不尊重严肃的事情。场景敏感度需要人工判断。
五、总结
好的 UI 文案不是"写得漂亮",而是"写得准确"。它需要同时满足四个约束:字数合适、语调一致、动词明确、场景匹配。大语言模型的优势在于它可以同时考虑所有约束来生成候选文案,而传统做法通常只能一条一条人工调整。把 AI 定位为"文案初稿生成器",人在最后把关——这是目前 UI 文案生产的最佳实践。
作者:李慕杰(Leo / 8limujie)
一个终于不用再写"点击确定"这种废话的前端匠人
更多推荐

所有评论(0)