Gradio gr.HTML 自定义前端:AI写作界面怎么搭
默认组件适合快速验证功能,但当 AI 写作工具需要更灵活的布局、说明区和结果展示时,页面结构往往不够用。本文以“主题输入、写作要求、生成按钮、结果展示”为例,说明如何使用 Gradio gr.HTML 自定义前端,并保留 Gradio 后端…
先确定写作任务和页面字段
不要一开始就写页面样式。先把一次生成任务拆成输入、动作和输出三类字段,避免界面完成后才发现后端缺少参数。
- 输入字段:文章主题、目标读者、写作要求。
- 动作字段:生成、清空或重新生成。
- 输出字段:生成状态、标题建议和正文结果。
- 验收字段:空输入提示、生成中状态、失败提示和结果保留。
本例只做最小原型,后端函数接收三个字符串,返回一段可展示的 HTML 内容。真实项目接入模型时,应把模型调用、异常处理和敏感配置放在服务端。
规划页面结构和元素职责
使用 gr.HTML 时,建议把它当作页面容器和视觉层,而不是把所有业务逻辑都塞进一段 HTML。输入仍交给 Gradio 组件管理,页面布局由 HTML 和 CSS 组织。
- 顶部放工具名称和任务说明,帮助用户确认当前用途。
- 左侧或上方放主题、受众和要求输入区。
- 中间放唯一的主要动作按钮,降低误操作。
- 下方放生成状态和结果区域,保证长文本有足够空间。
一个可复用的布局可以先用 gr.HTML 输出结构和样式,再通过 gr.Textbox、gr.Button 与 gr.Markdown 完成数据交互。不要在 HTML 中直接写会改变服务端状态的代码,也不要把密钥放进页面源码。
按步骤连接 Gradio 后端函数
下面的示例演示一个不依赖具体模型的最小闭环。生成函数先返回固定格式文本,等页面交互确认后,再替换为真实内容生成调用。
import gradio as gr
def generate_article(topic, audience, requirement):
if not topic.strip():
return "请输入文章主题"
audience = audience.strip() or "普通读者"
requirement = requirement.strip() or "表达清楚,分段展示"
return (
f"主题:{topic}\n\n"
f"面向:{audience}\n\n"
f"写作要求:{requirement}\n\n"
"这是用于验证页面连接的示例结果。"
)
with gr.Blocks() as demo:
gr.HTML("""
<section class='writer-shell'>
<div class='writer-header'>
<h2>AI 写作工作台</h2>
<p>填写任务信息后生成一份可编辑草稿</p>
</div>
</section>
""")
topic = gr.Textbox(label="文章主题", placeholder="例如:团队如何整理产品资料")
audience = gr.Textbox(label="目标读者", value="内容运营新手")
requirement = gr.Textbox(label="写作要求", lines=4)
generate = gr.Button("生成草稿")
result = gr.Markdown()
generate.click(
fn=generate_article,
inputs=[topic, audience, requirement],
outputs=result
)
demo.launch()- 先创建
gr.Blocks,让页面组件处于同一个界面上下文中。 - 用
gr.HTML放置页面头部、布局容器或说明区域。 - 用输入组件保存用户实际提交的数据,不要从页面文本中反向解析参数。
- 让按钮事件通过
click指向后端函数,并按输入顺序传递字段。 - 把函数返回值绑定到结果组件,先验证数据能否完整到达页面。
用一个写作场景检查输出展示
假设用户要生成一篇“AI 写作工具的资料整理流程”,目标读者是内容运营新手,要求输出分步骤说明。提交后,页面至少应能看到主题、受众和要求被后端接收,并在结果区显示对应内容。
| 测试输入 | 预期结果 |
|---|---|
| 主题为空 | 提示补充主题,不调用生成逻辑 |
| 只填写主题 | 使用默认读者和默认写作要求 |
| 三个字段完整 | 结果区显示完整的示例草稿 |
| 长篇要求 | 输入区保持可编辑,结果区不挤压按钮 |
当固定示例运行正常后,再把函数内部替换为模型请求。替换时保持函数参数和返回类型稳定,页面层就不必反复调整。
常见故障和修正动作
- 页面有结构但按钮没有反应:原因通常是按钮没有绑定事件,或事件没有指定输出组件。检查
generate.click的输入、输出和函数名称。 - 结果区一直为空:原因可能是后端函数没有返回值,或者返回值类型与结果组件不匹配。先返回固定字符串,再逐步加入模型调用。
- 输入顺序错乱:原因是函数参数顺序与 inputs 数组不一致。逐项对照字段名称、函数参数和 inputs 列表。
- 自定义样式没有生效:原因可能是 CSS 选择器没有命中页面元素,或样式写在错误的 HTML 范围内。先给外层容器设置唯一 class,再用浏览器检查实际结构。
- 生成时页面像卡住:原因是同步模型调用占用请求。先显示生成中状态,长任务再考虑队列、异步处理或后台任务方案。
- 用户输入被当成页面结构:原因是把不可信输入直接拼进 HTML。结果展示优先使用 Markdown 或文本组件,并对确需渲染的内容做严格清理。
发布前交互验收清单
- 页面首次打开时,输入框、按钮和结果区都能正常显示。
- 空主题提交时有明确提示,且不会产生空白结果。
- 完整输入可以准确传到后端函数,字段没有错位。
- 生成过程中按钮状态、等待提示和异常提示符合预期。
- 短结果和长结果都能阅读,结果区不会遮挡输入区。
- 刷新页面后,页面结构仍然稳定,没有依赖浏览器临时状态。
- 移动端查看时,输入框、按钮和结果区域不会横向溢出。
- 页面源码中没有 API 密钥、内部路径或不必要的敏感信息。
- 真实模型接入后,至少用空输入、普通输入、超长输入和失败响应各测试一次。
- 确认结果展示、日志记录和错误提示不会泄露用户原始资料。
完成这些检查后,再继续增加历史记录、导出、模板选择等功能。先保持页面字段、后端参数和结果组件一一对应,后续扩展会更容易维护。相关的 Gradio 资料表交互可以参考Gradio Dataframe 字段编辑方法。
下一步
把这篇的方法练一遍
提示词和步骤可以带到创作里直接试做一版。