大模型辅助的 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)
一个终于不用再写"点击确定"这种废话的前端匠人