chore: 合并为单仓库,统一部署流程

- 根目录加入 docker-compose、Caddyfile、文档等原本不在仓库里的文件
- 前后端两份 GitHub Actions 合并成根目录的一个 deploy workflow:
  构建前端上传到 build/,再在服务器上 git pull 并重建容器

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
xuyueandClaude Opus 5.5 committed 2026-10-26 16:02:12 +08:00
1 parent 70983a12a5
commit 47d4679984
40 files changed
+13723 -34

No files matched your search

@@ -0,0 +1,206 @@
# 挑战 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 输出,例如:
```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 前端页面。