Files
web/docs/plans/2026-05-04-challenge-ai-dialog-analysis.md
xuyueandClaude Opus 5.5 47d4679984 chore: 合并为单仓库,统一部署流程
- 根目录加入 docker-compose、Caddyfile、文档等原本不在仓库里的文件
- 前后端两份 GitHub Actions 合并成根目录的一个 deploy workflow:
  构建前端上传到 build/,再在服务器上 git pull 并重建容器

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-26 16:02:12 +08:00

7.9 KiB

挑战 AI 对话功能分析:如何更好地通过对话写出 Web 前端页面

日期: 2026-05-04

背景

WebPreview 的挑战页已经具备 AI 对话生成网页的基本闭环:学生输入需求,后端通过 WebSocket 流式调用大模型,提取 html/css/js,前端自动应用到预览区,并在生成完成后自动创建一次提交。提交可以反查提示词链,用于回看作品迭代过程。

相关核心文件:

  • client/src/pages/ChallengeDetail.vue:挑战页布局、AI 生成后自动提交。
  • client/src/store/prompt.ts:WebSocket 状态、消息列表、流式内容、代码应用。
  • client/src/components/ai/PromptPanel.vue:对话 UI、发送/停止、消息渲染。
  • api/prompt/consumers.py:WebSocket 连接、历史消息、流式生成、代码提取。
  • api/prompt/llm.py:系统提示词、模型调用、Markdown 代码块提取。
  • api/submission/api.py:提交创建、手动提交记录、提示词链查询。

当前能力

  1. 支持平台内 AI 对话,生成 HTML、CSS、JS。
  2. 支持流式输出,用户可以看到 AI 正在生成。
  3. 生成完成后自动把代码写入预览区。
  4. 生成完成后自动静默提交,保留每轮迭代结果。
  5. 支持停止生成,停止后重连 WebSocket。
  6. 支持删除一轮对话及其关联提交。
  7. 支持手动提交外部 AI 生成的代码,并记录对应提示词。
  8. 支持从提交查看提示词链,展示每轮 prompt、来源、层级和该轮页面预览。

主要问题

1. AI 缺少挑战上下文

当前 llm.build_messages() 只拼接系统提示词和历史消息,没有注入挑战标题、挑战描述、评分要求、素材列表。模型不知道学生正在完成哪个挑战,只能根据用户输入猜测目标。

影响:

  • 用户说“帮我完善这个页面”时,AI 不知道“这个”具体指什么挑战目标。
  • 生成结果容易偏离任务要求。
  • 如果挑战提供了图片素材,AI 不知道可用素材名称和路径。

2. AI 缺少当前代码状态

前端编辑器中的 html/css/js 会被 AI 生成结果覆盖,但下一轮对话时,后端只拿数据库里的历史消息作为上下文。用户手动修改、清空、粘贴外部代码后的真实代码状态不会进入模型上下文。

影响:

  • “在现在的基础上修改”不稳定。
  • 用户手改后的成果可能被下一轮 AI 覆盖。
  • AI 很难做精细迭代。

3. 输出协议依赖 Markdown 代码块

后端用正则从模型回复里提取 html / css / ```js 代码块。如果模型少写一个代码块、语言标签不规范、把 CSS/JS 混进 HTML,提取就可能失败。

影响:

  • 预览区可能只更新部分代码。
  • 空代码块和提取失败不好区分。
  • 后端难以判断这次生成是否可安全应用。

4. 生成结果直接应用,缺少版本确认

AI 完成后前端立即执行 applyCode(),把代码应用到预览区,并自动提交。

影响:

  • 用户没有“接受 / 拒绝 / 对比差异”的机会。
  • 一次较差的生成会覆盖当前可用版本。
  • 自动提交会混合草稿版本和最终版本。

5. 缺少运行时诊断

预览 iframe 当前只渲染页面,没有把 window.onerror、console.error、资源加载失败等诊断信息反馈给对话系统。

影响:

  • JS 报错时学生不一定知道原因。
  • AI 无法基于真实错误自动修复。
  • 教师查看作品时也缺少失败原因记录。

6. 对话输入缺少教学引导

输入框只有“描述你想要的网页效果...”这类开放提示。学生容易发送低质量指令,例如“帮我做一个好看的页面”。

影响:

  • AI 生成质量依赖学生表达能力。
  • 难以引导学生从“命令 AI”过渡到“描述设计目标、布局、交互、约束”。
  • 已有的 L1-L6 prompt 分类结果没有反向用于提升学生提问质量。

改进目标

挑战 AI 对话应从“代码生成器”升级为“带上下文的前端迭代助手”:

  1. 理解挑战要求。
  2. 理解当前页面代码。
  3. 理解可用素材。
  4. 能发现运行错误。
  5. 能以可控版本方式修改页面。
  6. 能引导学生写出更高质量的 prompt。

优先改进建议

P0:注入完整上下文包

每次发送 prompt 时,前端或后端应构建一个上下文包:

  • 挑战标题。
  • 挑战描述 Markdown 的纯文本摘要。
  • 分值、及格线、评分目标。
  • 当前 html/css/js。
  • 可用素材列表:name、url、用途说明。
  • 最近一次预览错误。
  • 最近几轮对话摘要。

建议后端将这些内容作为 system/developer context 注入,而不是让用户自己描述。

P0:让模型基于当前代码做完整改写

发送消息时前端附带当前编辑器代码。后端提示模型:

  • 如果是修改需求,必须基于当前代码返回完整修改后代码。
  • 不允许只返回片段。
  • 不允许删除已有功能,除非用户明确要求。

这样可以减少“AI 不知道当前页面”的问题。

P1:改用结构化输出协议

从 Markdown 代码块改为 JSON 输出,例如:

{
  "summary": "本轮修改说明",
  "html": "...",
  "css": "...",
  "js": "...",
  "warnings": [],
  "questions": []
}

后端先解析 JSON,再校验字段完整性。解析失败时不要应用代码,而是要求模型重试一次或向前端返回可解释错误。

P1:增加版本确认与回滚

把每轮 AI 生成结果保存为一个版本:

  • 生成后先显示“待接受版本”。
  • 用户可以“应用”“撤销”“查看差异”“设为最终提交”。
  • 自动提交可以保留为过程记录,但最终成绩应区分 draft 和 final。

这样既能保留学习过程,又不会污染最终作品。

P1:把预览错误反馈给 AI

在 iframe 中捕获:

  • window.onerror
  • unhandledrejection
  • console.error
  • 图片资源加载失败

前端展示错误,并提供“让 AI 修复错误”按钮。发送修复请求时,把错误堆栈、当前代码和用户最近意图一起传给模型。

P2:加入 prompt 质量引导

结合已有 L1-L6 prompt 分类能力,给学生提供轻量反馈:

  • 当 prompt 过短时,提示补充“布局、颜色、交互、响应式、素材”。
  • 提供快捷按钮:“加交互”“优化样式”“适配手机”“修复错误”“解释代码”“按挑战要求检查”。
  • 在提交链中展示 prompt 层级趋势,鼓励学生从 L1/L2 走向 L4-L6。

P2:支持多轮目标拆解

当用户提出复杂需求时,AI 可以先生成简短计划,而不是马上写代码:

  1. 页面结构。
  2. 视觉风格。
  3. 交互行为。
  4. 响应式要求。
  5. 实现步骤。

用户确认后再生成代码。这适合复杂挑战和高质量作品创作。

推荐实施顺序

  1. 上下文包:挑战内容、素材、当前代码进入模型上下文。
  2. 预览错误捕获:让 AI 能修真实错误。
  3. 结构化输出:降低代码提取失败率。
  4. 版本确认:避免 AI 直接覆盖好版本。
  5. prompt 引导:提升学生对话质量。
  6. 最终提交标记:区分草稿过程和最终作品。

成功标准

  1. 学生输入模糊修改需求时,AI 能稳定基于当前页面迭代,而不是重写成无关页面。
  2. AI 生成结果更符合挑战描述和素材约束。
  3. 代码提取失败率显著下降。
  4. JS 报错能被捕获并可一键交给 AI 修复。
  5. 学生可以回滚到任意历史版本。
  6. 教师查看提示词链时,可以看出学生如何从需求、反馈、修复到最终作品。

一句话结论

下一步重点不是让 AI “更会写代码”,而是让 AI 在每轮对话里都拥有任务、当前作品、素材、错误和版本历史。只有这样,学生才能真正通过对话持续迭代出可用、贴合挑战要求的 Web 前端页面。