在这里插入图片描述

在这里插入图片描述
码道英语短句AI情景会话台

一个基于情景对话练习英语口语的零依赖 Web 应用。AI 扮演情景中的角色(咖啡师、地勤、前台……),用一句句地道短句带你在真实场景里开口说英语;每句回复都自动配好中文翻译、音标、重点词拆解、口语贴士与接话建议,并支持一键朗读与收藏复读。

纯前端实现:HTML5 + CSS3 + JavaScript,无需构建,直接打开即可使用。


功能特性

  • 情景化角色扮演:内置 6 个高频生活情景(咖啡店、机场、酒店、餐厅、问路、面试),也支持自定义任意情景
  • JSON 结构化回复:AI 每次回复返回固定结构的 JSON,前端按「英文原句 → 中文翻译 → 音标 → 重点词 → 口语贴士 → 接话建议」分层渲染
  • 流式渐进刷新:SSE 流式输出,英文原句先浮现,随后各字段逐块补齐,等待感为零
  • 语音增强:
    • 朗读:speechSynthesis 朗读英文原句(en-US 音色)
    • 语音输入:Web Speech API 语音识别,说完自动上屏
  • 收藏夹:收藏地道短句,持久化到 localStorage,支持朗读 / 复制 / 移除
  • 完整交互状态:空状态引导、骨架屏加载、错误内联提示、Toast 反馈
  • 自适应布局:桌面双栏沉浸式、移动端单列降级

技术栈

层次方案
页面结构HTML5 语义化标签
样式CSS3 原生(CSS 变量、Grid、渐变、微动效),未引入任何 UI 框架
逻辑原生 JavaScript(Fetch API + ReadableStream 流式读取 + async generator)

快速开始

方式一:直接打开

用浏览器打开 index.html 即可,无需任何服务器。

方式二:本地 HTTP 服务(推荐)

# 任意静态服务器皆可
python3 -m http.server 8080 --directory .
# 然后访问 http://localhost:8080

语音输入(麦克风)仅在 https 或 localhost 环境下可用。


配置说明

所有接口参数集中在 js/config.js:

const CONFIG = {
  API_URL: "https://api-ai.gitcode.com/v1/chat/completions",
  API_KEY: "你的 API Key",
  MODEL: "deepseek-ai/DeepSeek-V4-Flash",
  PARAMS: {
    stream: true,
    max_tokens: 2048,
    temperature: 0.6,
    top_p: 0.95,
    frequency_penalty: 0,
    thinking_budget: 2048
  }
};

⚠️ 安全提醒:纯前端项目无法隐藏 API_KEY。演示场景直接使用即可;
生产环境务必改为「前端 → 你的后端代理 → 大模型 API」的架构,避免密钥泄露。


AI 回复 JSON 协议

系统提示词(见 js/config.js 的 SYSTEM_PROMPT)要求 AI 只输出一个纯 JSON 对象,禁止任何多余文字,结构如下:

{
  "speaker": "Barista",
  "speaker_cn": "咖啡师",
  "reply": "Hi there! What can I get started for you today?",
  "translation": "你好!今天想喝点什么?",
  "phonetic": "/haɪ ðeər | wɒt kæn aɪ get ˈstɑːtɪd fə jə təˈdeɪ/",
  "keywords": [
    { "word": "get started", "meaning": "开始,先来点什么" },
    { "word": "for you", "meaning": "为你" }
  ],
  "tip": "咖啡店常用开场白,比 order 更口语、亲切。",
  "suggestion": "你可以回答:I'd like a latte, please. 或者先问推荐。",
  "suggestion_en": "You can say: I'd like a latte, please.",
  "done": false
}
字段说明
speaker / speaker_cn当前说话的角色(中/英文名)
replyAI 角色的这句地道英语
translation中文翻译
phonetic参考国际音标
keywords本句重点词/短语及释义(1~3 个)
tip口语贴士(中文,≤40 字)
suggestion / suggestion_en引导学员接话的中文建议 + 英文提示
done学员表示结束时置 true,AI 道别收尾

渐进式 JSON 渲染

流式返回的是不断增量的 JSON 文本,前端并不等它完全结束,而是通过 tryParseJson() 实时尝试解析:

从文本尾部倒序扫描 },取最后一个合法完整的 JSON 前缀进行渲染。

因此用户会先看到英文突然浮现,随后翻译、音标、关键词、贴士逐块补齐,体验接近打字机效果,且不需要等待完整响应。


目录结构

.
├── index.html          # 页面结构
├── css/
│   └── style.css       # 全部样式(变量 / Grid / 动效)
├── js/
│   ├── config.js       # API 配置 + 系统提示词(JSON 协议)
│   ├── api.js          # 流式请求封装(Python 参考代码的 JS 移植)
│   └── app.js          # 应用逻辑(情景 / 对话 / 渲染 / 语音 / 收藏)
├── e2e_test.py         # Playwright 端到端验证脚本(可选)
└── README.md

Python 参考代码 → JavaScript 对照

原始 Python 通过 requests 的流式接口逐行消费 SSE 帧:

response = requests.post(API_URL, headers=headers, json=payload, stream=True)
for line in response.iter_lines():
    if not line.startswith(b"data:"):
        continue
    if line.strip() == b"data:[DONE]":
        return
    yield json.loads(line.decode("utf-8").lstrip("data:").rstrip("/n"))

js/api.js 中用 fetch + ReadableStream 实现了完全等价的能力:

const response = await fetch(CONFIG.API_URL, {
  method: "POST",
  headers: { "Content-Type": "application/json", Authorization: `Bearer ${CONFIG.API_KEY}` },
  body: JSON.stringify(payload),
  signal: options.signal          // 支持中止
});
const reader = response.body.getReader();   // ReadableStream
const decoder = new TextDecoder("utf-8");
// 按行扫描 "data:" 前缀 → 跳过空行 → "[DONE]" 结束 → 逐帧 yield

调用方以 async generator 形式消费:

for await (const chunk of chatStream(buildPayload(messages))) {
  const delta = chunk.choices[0].delta.content;   // 累积增量文本
}

本地测试

准备好 Python3 + Playwright 后可跑端到端验证(会真实调用一次 API,消耗少量配额):

python3 -m http.server 8123 --directory . &     # 先起服务
python3 e2e_test.py

脚本会依次断言:情景渲染 → 高亮 → AI 开场(流式)→ 结构化字段 → 两轮对话 → 收藏 → 收藏面板 → 情景切换重置,并收集 console 错误。


已知说明

  • 语音朗读与语音输入依赖浏览器能力(Chrome / Edge / Safari 支持较好)。
  • 收藏数据保存在当前浏览器 localStorage,跨设备不共享。
  • API 为 OpenAI 兼容格式,替换 API_URL、API_KEY、MODEL 即可接入其它同协议服务。
Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐