# QQ 游戏 AI 频道智能匹配 Demo

> 理解玩家需求，匹配更合适的游戏频道。
> 面向「QQ 游戏开放生态产品经理」岗位的作品 Demo，演示一个 AI 产品的最小完整闭环。
> 当前版本：**V1.3**（V1.0 + 否定句检测、触发词扩充、游戏别名扩充、XSS 防护、自动化测试；V1.2 新增「赛事观赛」意图与电竞频道；V1.3 频道库大扩充至 52 个）

---

## 1. 项目背景

QQ 游戏开放生态中沉淀了大量游戏频道（新手组队、攻略讨论、开黑大厅等），但玩家常常不知道"我该去哪个频道"。本 Demo 验证一个 AI 产品方案：**让玩家用一句自然语言描述需求，AI 自动理解意图并推荐最合适的频道**。

## 2. 用户问题

- 玩家侧：想找队友 / 求攻略，但面对几十个频道不知道选哪个，发帖石沉大海。
- 生态侧：频道流量分配粗放，优质内容与目标用户错配，频道活跃率受损。

## 3. 产品目标

- 玩家：**一句话输入 → 一次点击 → 得到一个可解释的频道推荐**。
- 产品：跑通"问题定义 → 模型链路 → 评估 → 数据反馈 → Bad Case → 迭代"的完整 AI 产品闭环，而不是单纯调用大模型。

## 4. 核心流程

```
用户输入聊天内容
  → 点击「开始智能匹配」
  → AI 分析动画（识别游戏 → 理解意图 → 提取标签 → 匹配频道）
  → 生成结构化用户画像（游戏 / 意图 / 阶段 / 社交需求 / 标签）
  → 两阶段匹配：游戏硬过滤 → 候选排序 → 阈值判定
  ├── 有高匹配频道 → 正常推荐
  └── 覆盖不足 / 游戏不存在 → AI Discovery 频道扩充
        → Web 搜索 → 结果过滤 → 生成频道画像 → 人工审核 → 重新匹配
  → 推荐结果（含来源标识与匹配依据）
  → 用户反馈（👍 匹配准确 / 👎 匹配不准确）
  → Bad Case 更新匹配策略 / 频道画像权重
  → 完成反馈闭环
```

### AI 频道库扩充（AI Discovery）

当已识别游戏但频道库覆盖不足时，系统自动触发频道扩充，而不是推荐其他游戏或简单显示"暂无匹配"：

- **频道空缺检测** `checkChannelCoverage()`：游戏无任何频道 → `not_found`；有频道但最高匹配 <60 → `insufficient`；两者均触发扩充；有高匹配（≥60）→ `sufficient`，不触发搜索。
- **Web Discovery**：按游戏 + 意图动态生成搜索词（玩家社区 / 游戏讨论 / 玩家评价 / 攻略社区，而非只搜 QQ 频道）；当前为内置模拟语料，真实环境可替换为搜索 API。
- **结果过滤**：只保留确实讨论目标游戏的结果，去广告、去其他游戏、去重。
- **频道画像生成**：把搜索结果抽象为结构化画像（频道名 / 类型 / 标签 / 主题 / 目标用户 / 置信度）。**这是 Demo 生成的频道画像，不是真实 QQ 频道**；真实 AI 模式下可由 LLM 提取，失败自动回退本地生成。
- **人工审核**：画像默认"AI 自动发现 · 待人工审核"，点击「加入频道库」才写入 `discoveredChannels`（localStorage 持久化，可一键清空，不影响原始频道库）；「忽略」则弃用并重新匹配。
- **拒绝生成**：公开信息不足时明确提示"暂未找到足够可靠的公开信息，无法生成频道画像"，不编造频道，避免 AI 幻觉。
- **与 Bad Case 联动**：AI 发现频道被反馈错误时按次降权（-15 分/次），≥2 次标记"低置信频道"并降低优先级。

三个可演示场景：

| 场景 | 输入示例 | 预期行为 |
|---|---|---|
| A：本地高匹配 | 案例 1（逆水寒新手副本） | 直接推荐「逆水寒手游｜新手组队」约 90%，日志提示"无需扩充" |
| B：游戏存在但主题不足 | "异环有没有新手群？刚入坑求带" | 本地最高约 28% → 触发 Discovery → 生成「异环｜新手互助」（待审核）→ 重新匹配约 90% |
| C：游戏不存在 | "最近在玩一个叫幻塔的游戏，想交流一下" | 本地候选 0 → Discovery 生成「幻塔｜玩家讨论区」→ 推荐约 75% |
| 兜底：拒绝生成 | "XX 是什么游戏？" | 公开信息不足 → 明确拒绝生成频道画像 |

## 5. AI 产品逻辑

Demo 采用**双层架构**，体现"模型层可替换，产品决策层稳定"：

```
用户输入 → LLM 理解层 → 结构化用户意图 → 本地频道匹配策略 → 推荐结果 → 用户反馈 → Bad Case
```

**理解层（可替换）**，两种模式可在页面右上角「⚙ AI 模型配置」中切换：

- **本地 Demo 模式**（默认）：本地规则 + 标签提取，无需 API Key，离线可运行。
  - 游戏识别：标准名 + 别名词表命中（如"王者"→ 王者荣耀）。
  - 意图识别：触发词规则（"一起玩/开黑"→ 寻找队友；"攻略/怎么/搭配"→ 求攻略）。
  - 阶段识别：触发词规则（"刚玩/萌新"→ 新手；"排位/深渊"→ 进阶玩家）。
  - 标签抽取：游戏 + 意图标签 + 阶段标签 + 补充关键词词表。
- **真实 AI 模式**：支持 OpenAI / DeepSeek / 通义千问 / 豆包 / 智谱 / 自定义 OpenAI Compatible。模型**只负责**输出结构化 JSON（游戏 / 意图 / 阶段 / 标签），不直接生成推荐频道；频道匹配仍由本地策略完成。所有提供商通过统一接口 `callLLM(config, prompt)` 调用，更换模型不改匹配逻辑。

**安全与兜底设计**：

- API Key 默认仅保存在页面运行内存中，不写入任何源码文件；勾选「记住配置」（默认关闭）才存入浏览器 localStorage，并有明确提示。
- 「测试连接」会真实请求一次模型并校验 JSON 结构，失败时给出可定位原因（API Key 无效 / Base URL 错误 / 模型名称错误 / 网络或跨域限制）。
- **任何情况下兜底**：无 API Key、配置不完整、API 失败或网络异常时，自动回退本地模式并提示"模型调用失败，已自动切换至本地 Demo 模式"，Demo 永远可以完整演示。

## 6. 匹配算法

不做复杂机器学习，采用**两阶段可解释匹配**（配置在 `app.js` 的 `WEIGHTS` / `MATCH_THRESHOLD` 中可直接修改）：

**第一阶段：候选过滤（硬过滤，不打分）**

- 游戏实体优先：识别出 `game = 异环` 时，候选频道只能是异环频道，跨游戏频道禁止进入排序。
- 游戏名先经 `GAME_ALIASES` 标准化（如"王者 / 农药"→ 王者荣耀、"ANANTA"→ 异环）。
- 频道库无该游戏频道时**不强行推荐其他游戏**，直接返回"暂无该游戏频道"（识别游戏 / 候选 0 / 建议扩充频道）。
- 叠加 Bad Case 排除规则：被用户标记过的错误频道在同游戏推荐中直接出局。

**第二阶段：候选排序（0~100 分）**

| 维度 | 权重 | 判定方式 |
|---|---|---|
| 意图匹配 | 35% | 频道标签命中意图核心标签（11 类意图各有映射） |
| 标签重合 | 30% | 用户标签与频道标签的 Dice 重合系数 |
| 用户阶段匹配 | 15% | 频道标签命中阶段标签（新手/进阶/长期玩家倾向） |
| 频道主题匹配 | 20% | 频道名「｜」后缀主题与意图的亲和度 |

**最低阈值**：80~100 强匹配 / 60~79 一般匹配 / **低于 60 不推荐**（未识别到游戏时要求更高，需达 80）。推荐理由由真实命中维度动态生成，结果下方展示"匹配依据"逐项得分，可完整解释"为什么推荐它"。

示例：输入"异环不错啊，画面也真实，但是玩法空间、bug多……"
→ 画像：异环 / 体验评价 / 长期玩家倾向 / 标签[画面, 玩法, BUG, 运营, 长期游玩]
→ 游戏过滤后仅 3 个异环频道参与排序 → 推荐「异环｜游戏讨论」91%（强匹配）。

## 7. Bad Case 机制（反馈真实参与优化）

- 推荐结果下方提供 👍 / 👎 反馈按钮。
- 点击 👎 展开错误类型选择：游戏识别错误 / 意图识别错误 / 推荐频道不匹配 / 其他。
- 提交后记录为 Bad Case（含原始输入、识别游戏、错误频道），存储于浏览器 localStorage，刷新不丢失。
- **Bad Case 会改变后续推荐**：当反馈原因为"游戏识别错误"或"推荐频道不匹配"时，自动生成排除规则——同游戏的后续推荐中，被标记的错误频道直接排除，并在"匹配依据"中展示已生效的规则数。形成：推荐 → 用户反馈 → Bad Case → 本地策略更新 → 下一次推荐 的闭环。
- 页面底部「Demo 评估」区展示模拟评估数据（测试样本 30 / 正确 26 / 准确率 86.7%，已明确标记为模拟数据），并展示本机累计真实反馈。

## 8. Demo 运行方法

无需安装任何依赖、无需服务器、无需 API Key：

1. 双击打开 `index.html` 即可运行（推荐 Chrome / Edge）。
2. 点击任一"快捷案例"自动填充输入框，或在输入框中自由输入。
3. 点击「开始智能匹配」，查看分析过程、用户画像、推荐结果，并完成一次反馈。
4. （可选）点击右上角「⚙ AI 模型配置」，切换真实 AI 模式并填写 API Key；不配置时默认本地模式，功能完全不受影响。

文件结构：

```
/index.html   页面结构
/style.css    样式（腾讯系简洁风，主色 #1677FF）
/app.js       全部逻辑（频道数据内置，无跨域问题）
/README.md    本说明
/tests/       自动化测试（Bad Case / 模型差异 / 边界情况）
/package.json npm test 入口（仅用于跑测试；运行 Demo 本身无需 npm）
```

## 9. 后续可扩展方向

### V2 —— 接入真实大模型 API（当前版本已支持配置）
Demo 已内置「AI 模型配置」：模型负责用户意图识别、游戏实体识别、用户标签抽取，本地规则作为兜底策略。后续可优化 Prompt、增加 few-shot 示例、按 Bad Case 类型定向调优。

### V3 —— 建立真实频道画像
引入频道主题、频道活跃度、频道用户画像、历史匹配效果，匹配算法从"标签重合"升级为"供需匹配"。

### V4 —— 建立数据飞轮
打通"用户反馈 → Bad Case → 模型评估 → Prompt 优化 → 匹配策略优化"链路，形成：

```
用户需求 → AI 理解 → 频道匹配 → 用户反馈 → Bad Case → 策略迭代
```

的完整闭环，让匹配准确率随数据积累持续提升。

## 10. V1.1 健壮性改进与自动化测试

### 健壮性改进

| 改进项 | 说明 |
|---|---|
| 否定句检测 | "我不是想找队友，只想看看装备攻略"不再误判为组队；"不想打深渊"不计为进阶玩家；否定语境下的关键词不进入标签 |
| 触发词扩充 | 新增「带」「有人玩」「一起」「双排」「五排」等组队触发词，覆盖"有人带吗""有人玩LOL吗"等口语 |
| 游戏别名扩充 | 新增三角洲行动、幻塔、第五人格、我的世界、穿越火线、无畏契约、绝区零、星穹铁道、暗区突围、光遇等 |
| XSS 防护 | 所有进入 innerHTML 的动态内容（模型输出 / 用户输入 / localStorage）统一经 `escapeHTML()` 转义 |

### 自动化测试（无需安装任何依赖）

| 测试文件 | 覆盖内容 | 断言数 |
|---|---|---|
| `tests/badcase_test.js` | Bad Case 反馈 → 本地频道排除 / AI 发现频道降权 / 阈值兜底 | 15 |
| `tests/model_test.js` | 不同模型厂家的理解层输出对匹配结果的影响（理解层可替换性演示） | 演示脚本 |
| `tests/edge_test.js` | 否定句、触发词、别名、无意义输入等边界情况回归 | 15 |

运行方式：项目目录下执行 `npm test`（或 `node tests/badcase_test.js` 单独运行）。

## 11. V1.2 更新：赛事观赛意图与电竞频道

### 背景问题

用户输入 *"去哪里看go职业选手打比赛呀"*（想看 CS:GO 职业比赛，问平台）时，旧版显示「当前暂无高度匹配频道」——原因有两个：

1. **意图分类缺失**：11 类意图中没有「观赛」，触发词表也不含"比赛/赛事/直播/职业选手"；
2. **频道库缺失**：没有 CS:GO 游戏别名，也没有任何电竞赛事频道。

### 本次新增

| 类型 | 内容 |
|---|---|
| 新意图 | **赛事观赛**（第 12 类）：触发词含 比赛/赛事/观赛/职业选手/战队/直播/总决赛/淘汰赛/回放；LLM 提示词同步更新 |
| 游戏别名 | CS:GO（CSGO / csgo / CS2 / cs2 / CS / cs / go） |
| 新频道 | CS:GO｜赛事观赛、CS:GO｜游戏讨论、CS:GO｜新手入门、英雄联盟｜赛事观赛（LPL）、无畏契约｜赛事观赛（VCT）、王者荣耀｜赛事观赛（KPL） |
| 快捷案例 | 新增「赛事观赛」："去哪里看CS:GO职业选手打比赛呀" |

实测：*"去哪里看go职业选手打比赛呀"* → 识别 CS:GO + 赛事观赛 → 推荐「CS:GO｜赛事观赛」70分；*"英雄联盟 LPL 有直播看吗"* → 推荐「英雄联盟｜赛事观赛」。相关断言已加入 `tests/edge_test.js`。

## 12. V1.3 更新：频道库扩充（19 → 52 个频道）

### 扩充原则

1. **别名表里的每个游戏至少 1~2 个频道**，避免"识别出了游戏却说无频道"；
2. **补齐意图覆盖**：氪金/商业化、活动讨论、社交交友此前没有对应频道，本次补上；
3. **刻意保留幻塔无频道**——它承担 AI Discovery 的演示场景 C（游戏不存在 → 自动扩充），不能把演示场景"优化没了"。

### 新增频道一览（33 个）

| 游戏 | 新增频道 |
|---|---|
| 逆水寒手游 | 庄园社交、外观时装 |
| 王者荣耀 | 攻略讨论、活动福利 |
| 三国杀 | 新手教学、开黑交友 |
| 原神 | 角色培养、抽卡氪金、版本活动 |
| 鸣潮 | 角色养成 |
| 英雄联盟 | 攻略进阶 |
| 蛋仔派对 | 地图工坊、新手入门 |
| 和平精英 | 组队吃鸡、战术攻略 |
| 穿越火线 | 组队开黑、赛事观赛（CFPL） |
| 三角洲行动 | 组队开黑、攻略交流 |
| 无畏契约 | 组队开黑、新手教学 |
| 绝区零 | 攻略交流、游戏讨论 |
| 崩坏：星穹铁道 | 攻略交流、剧情讨论 |
| 第五人格 | 组队开黑、攻略教学 |
| 我的世界 | 生存组队、建筑交流 |
| 暗区突围 | 组队开黑、装备攻略 |
| 光遇 | 社交交友、萌新互助 |

同步扩充：频道主题亲和表（社交/交友/氪金/抽卡/教学/养成/剧情/战术/吃鸡/互助/建筑/生存/庄园/时装/工坊）与补充关键词词表。新增 5 项频道覆盖断言，全部测试 30 项通过。
