成语接龙 · AI 对话

一个基于 HTML5 + CSS3 + 原生 JavaScript 实现的成语接龙 AI 对话小游戏。
通过与智谱/DeepSeek 兼容的 GitCode AI 对话接口(OpenAI 流式协议)实时对话,
AI 会以成语「尾字开头」的规则与玩家接龙,并返回成语的拼音、释义、出处、例句,
在游戏中潜移默化地积累成语知识。

功能特性

  • 双向接龙:AI 出成语,你按最后一个字来接,AI 再继续接,你来我往。
  • 流式输出:基于 fetch + ReadableStream 解析 SSE 流,AI 逐字返回(对应参考 Python 的 stream=True 迭代)。
  • JSON 结构化返回:通过系统提示词要求 AI 只输出合法 JSON,前端解析后渲染为精美的「成语卡片」(含读音、释义、出处、例句)。
  • 同音放宽:允许以同音字接龙,降低难度、便于教学。
  • 国风界面:宣纸底色、朱砂与鎏金配色、卷轴式标题,纯 CSS 实现,无任何外部依赖。
  • 移动端适配:响应式布局,支持手机浏览。

目录结构

ruanjianjishu6/
├── index.html      # 主页面
├── style.css       # 国风样式
├── config.js       # AI 接口配置(地址 / 令牌 / 模型 / 系统提示词)
├── api.js          # Python 流式调用的 JavaScript 版(fetch + SSE 解析)
├── app.js          # 接龙游戏交互与成语卡片渲染
└── README.md       # 项目说明

快速开始

  1. 下载/克隆本项目,直接双击打开 index.html 即可运行(纯前端,无需构建)。

    若浏览器对 https://api-ai.gitcode.com 存在跨域限制,可先在本目录启动本地静态服务:

    python3 -m http.server 8080
    # 然后访问 http://localhost:8080
    
  2. 在输入框输入「开始」或任意一个字 / 一个成语,按回车或点击「发送」。
  3. AI 会立即接出一个成语并以卡片形式展示,末尾会提示你该以哪个字继续接龙。
  4. 持续输入,直到对局结束(AI 提示无法接龙),再输入「开始」即可重新开局。

配置说明

所有接口配置集中在 config.js 的 AI_CONFIG 中,与参考 Python 代码逐项对应:

config.js 字段参考 Python 代码中的对应位置说明
API_URLAPI_URL对话接口地址
API_KEYheaders["Authorization"]Bearer 鉴权令牌
MODELpayload["model"]模型名称
MAX_TOKENSpayload["max_tokens"]最大生成字数
TEMPERATUREpayload["temperature"]采样温度
TOP_Ppayload["top_p"]核采样参数
FREQUENCY_PENALTYpayload["frequency_penalty"]频率惩罚
THINKING_BUDGETpayload["thinking_budget"]思考预算
SYSTEM_PROMPTmessages[0](新加入)系统提示词,约定 JSON 返回格式

系统提示词与 JSON 返回格式

在 config.js 的 SYSTEM_PROMPT 中,我们要求 AI 只输出一个合法的 JSON 对象,
这样前端 app.js 就能直接 JSON.parse 出结构化字段并渲染成语卡片,而不再只是显示一段对话文字。

成功接龙时的返回格式:

{
  "status": "success",
  "last_word": "上一个成语的最后一个字",
  "idiom": "你接出的成语",
  "pinyin": "成语的完整拼音",
  "meaning": "成语释义",
  "source": "成语出处",
  "example": "一个自然的使用例句",
  "next_hint": "让用户接着接的字"
}

无法接龙(对局结束)时的返回格式:

{
  "status": "game_over",
  "reason": "无法接龙的原因说明",
  "suggestion": "可以重新开始的提示语"
}

前端在 app.js 的 extractJson() 中还做了容错解析:即使 AI 使用
markdown 代码块(json ... )包裹、或附带少量说明文字,也能提取出其中的 JSON。

技术实现:Python → JavaScript 转换对照

参考的 Python 调用核心逻辑如下:

def query(payload):
    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() in (b"data:[DONE]", b"data: [DONE]"):
            return
        yield json.loads(line.decode("utf-8").lstrip("data:"))

在 api.js 中与之对应的 JavaScript 实现:

Python(参考代码)JavaScript(本项目)
requests.post(..., stream=True)fetch(API_URL, { method: "POST", headers, body })
json=payload 自动序列化body: JSON.stringify(payload)
response.iter_lines()response.body.getReader() + TextDecoder 按 \n 切行
line.startswith(b"data:")line.trim().startsWith("data:")
line.strip() == b"data:[DONE]" 结束判定data === "[DONE]"
json.loads(line.decode("utf-8").lstrip("data:"))JSON.parse(data),再经 extractDeltaText() 取出内容
chunk["choices"]chunk.choices[0].delta.content(兼容 message.content)

注意事项

  • API Key 安全:本项目为教学演示,密钥直接写在 config.js 中;正式部署请收紧密钥权限或改为服务端代理转发,避免泄露。
  • 跨域 CORS:若浏览器直连被跨域策略拦截,可在服务端配置允许跨域,或将请求转发到本地代理后访问。
  • 内容真实性:AI 生成的释义、出处可能不准确,仅供参考,请以权威词典为准。
  • 在这里插入图片描述
Logo

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

更多推荐