@ 耳遇 · 音乐推荐器 AI 对话(EarMeet AI Music)
寻找你的专属vov

**场景 × 性格 · 双维度智能匹配你的专属歌单

耳遇是一款纯前端(HTML5 + CSS3 + JavaScript)的 AI 音乐推荐应用。它借助 GitCode AI 的 DeepSeek-V4-Flash 大模型能力,将用户选择的**「场景」(通勤/工作/运动/深夜/旅行/睡眠/雨天/聚会)与「性格」(外向/内敛/浪漫/理性/热血/洒脱/完美/探索)两个维度组合建模,通过流式对话生成结构化 JSON 歌单数据**,再由前端进行精美的卡片化渲染,打造"会聊天、懂心情、懂得推荐"的 AI 音乐顾问。

在这里插入图片描述
-在这里插入图片描述

✨ 核心特性

特性说明
🧭 双维度画像8 种场景 × 8 种性格,自由组合出 64 种个性化画像
💬 AI 流式对话基于 SSE 流式输出,逐字渲染对话内容(含深度思考过程提示)
📄 JSON 结构化返回大模型严格按约定 Schema 返回歌单 JSON,两端协议清晰
🎵 歌单卡片渲染歌单封面渐变、情绪标签、能量值、关键词云、双维匹配度进度条一应俱全
🤖 复合式对话推荐完成后 AI 继续以朋友口吻引导追问"换首更轻快的 / 换成粤语歌"
🛟 离线兜底内置 60+ 首本地精选曲库,AI 接口异常时自动降级为本地推荐
📱 响应式布局1440px 三栏工作台 → 1180px 两栏 → 移动端单栏流畅适配
🌌 沉浸视觉暗夜星空 × 玻璃拟态 × 律动光斑,深度沉浸的音乐氛围

🚀 快速开始

项目为零构建、零依赖的纯静态站点,任意静态服务器即可运行:

# 方式一:Python 静态服务器
python3 -m http.server 8080

# 方式二:Node 静态服务器
npx serve .

# 方式三:任意 IDE 的 Live Server 插件(VS Code 等)

浏览器打开 http://localhost:8080 即可使用。

⚠️ 请务必通过 HTTP 服务器访问(而非直接双击打开 file://),避免浏览器 CORS 与 fetch 限制。


🎮 使用说明

  1. 选择维度:在左侧分别点选一个「场景」和一个「性格」(各选其一,可重复更换)。
  2. 发起推荐:点击 ✨ 开始智能推荐,或使用快捷指令一键触发。
  3. 等待生成:耳遇会先进入"深度思考中…“状态,随后聊天区以流式显示"正在为你编织专属歌单…”。
  4. 查看结果:右侧自动渲染完整歌单卡片 —— 歌单名、情绪、能量、关键词、逐首歌曲的场景/性格匹配度与推荐理由。
  5. 自由对话:继续追问 AI,比如 为什么推荐《Eye of the Tiger》?换一首更温柔的,AI 会边聊边按需重新推荐。

🔌 AI 接口参考(Python → JavaScript 转换)

项目调用 GitCode AI 的 OpenAI 兼容 Chat Completions 接口:

POST https://api-ai.gitcode.com/v1/chat/completions

原始 Python 参考代码

import os
import requests

API_URL = "https://api-ai.gitcode.com/v1/chat/completions"
headers = {
    "Authorization": f"Bearer {os.environ['API_KEY']}",
}

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

for chunk in query({
    "model": "deepseek-ai/DeepSeek-V4-Flash",
    "messages": [{"role": "user", "content": "告诉我一个有关宇宙的有趣事实?"}],
    "stream": True,
    "max_tokens": 2048,
    "temperature": 0.6,
    "top_p": 0.95,
    "frequency_penalty": 0,
    "thinking_budget": 2048
}):
    print(chunk["choices"])

转换要点(js/api.js

PythonJavaScript 对应实现
requests.post(..., stream=True)fetch(url, { method: 'POST', body: JSON.stringify(payload) })
response.iter_lines()response.body.getReader() + TextDecoder 逐行切分
line.startswith(b"data:")parseSSELine()line.trim().startsWith('data:')
b"[DONE]" in line/\[DONE\]/i.test(data) → 结束标记
json.loads(line.lstrip("data:"))JSON.parse(data.slice(5)),逐块解出 choices[0].delta
yield 生成器回调机制 onReasoning / onText / onDone / onError

核心流读取逻辑:

const reader = response.body.getReader();
const decoder = new TextDecoder("utf-8");
let buffer = "";
while (true) {
  const { done, value } = await reader.read();
  if (done) break;
  buffer += decoder.decode(value, { stream: true });
  // 按 \n 切分,逐行解析 data: {...}
}

📦 歌单 JSON 返回格式

大模型收到系统提示词(js/config.jsSYSTEM_PROMPT)后,必须且仅输出一行可被 JSON.parse 直接解析的 JSON。结构如下:

{
  "playlist": {
    "name": "深夜仪式感·私享浪漫",
    "theme": "在深夜独处的时刻,为感性浪漫的你定制的声音旅程",
    "mood": "静谧温柔",
    "energy": 25,
    "cover_gradient": ["#7c5cff", "#3fb6ff"],
    "keywords": ["深夜", "独处", "浪漫", "仪式感"],
    "tracks": [
      {
        "title": "旅行的意义",
        "artist": "陈绮贞",
        "album": "华丽的冒险",
        "genre": ["民谣", "治愈"],
        "reason": "细腻的歌词与木吉他声,像在夜色中翻阅回忆的相册,完美契合深夜独处时感性浪漫的自我对话。",
        "scene_match": 95,
        "personality_match": 90
      }
    ]
  }
}

字段说明

字段类型说明
playlist.namestring歌单名称
playlist.themestring一句主题描述
playlist.moodstring情绪氛围标签(静谧/燃爆/治愈…)
playlist.energyint(0-100)能量值,决定视觉与氛围感知
playlist.cover_gradientstring[2]封面渐变色,前端动态应用
playlist.keywordsstring[]关键词云
tracks[].titlestring歌名
tracks[].artiststring歌手
tracks[].albumstring专辑/风格备注
tracks[].genrestring[]曲风标签
tracks[].reasonstring推荐理由(含场景×性格双向解释)
tracks[].scene_matchint(0-100)场景匹配度
tracks[].personality_matchint(0-100)性格匹配度

前端在 js/api.js 中通过 extractJSON()(支持整体解析 / ```json 代码块 / 花括号截取三级兜底)+ normalizePlaylist()(字段补全与钳制)对模型输出做容错归一化,确保无论模型如何输出都能稳定渲染。


🗂 项目结构

eryuyinyuetuijianqi_temp/
├── index.html              # 页面骨架(三栏布局)
├── css/
│   └── style.css           # 暗夜星空 × 玻璃拟态主题样式
├── js/
│   ├── config.js           # API 配置 / 场景×性格维度 / 系统提示词
│   ├── local_songs.js      # 60+ 首本地精选曲库(离线兜底)
│   ├── api.js              # Python→JS 转换的 SSE 流式调用 + JSON 解析
│   ├── render.js           # 消息渲染 / 歌单卡片渲染 / 匹配度进度条
│   └── app.js              # 主应用逻辑:维度状态、推荐流程、流式对话
├── README.md               # 本文档
└── BLOG 耳遇.md            # 项目展示博客文章

⚙️ 配置说明

所有可调参数集中在 js/config.js

配置项默认值说明
API_URLhttps://api-ai.gitcode.com/v1/chat/completionsGitCode AI 接口地址
API_KEY(项目内置示例 Key)建议替换为你自己的 GitCode AI Key
MODELdeepseek-ai/DeepSeek-V4-Flash模型名
TEMPERATURE0.6创造力(推荐场景可调低更稳定)
THINKING_BUDGET2048深度思考预算 token 数

🔐 安全提示

  • 本项目为纯前端演示,API Key 内置在 js/config.js,任何用户均可通过浏览器 DevTools 查看。
  • 如需对外公开部署,强烈建议在服务端做一层代理(Node/Python/Gateway),将 Key 保存在环境变量中,前端仅请求自己的代理地址。
  • 请勿将携带真实 Key 的仓库设置公开访问(示例 Key 请及时在 GitCode 控制台重置)。

🧪 已实现能力自测

  • ✅ 维度选择与 UI 状态同步
  • ✅ 真实 AI 流式对话(含推理思考过程提示)
  • ✅ 歌单 JSON 解析与卡片渲染(含双维匹配度进度条)
  • ✅ 推荐完成后的 AI 追问引导
  • ✅ 接口异常 → 本地曲库兜底推荐
  • ✅ 响应式布局(1440 / 1180 / 800 / 480px 四档断点)
  • ✅ 控制台零错误、页面零 XSS 注入点(所有动态文本均 HTML 转义)

📄 博客

项目展示博客:《码道 · 耳遇》见仓库根目录 BLOG 耳遇.md(5000 字以上),完整记录了产品理念、技术方案与开发心路。在这里插入图片描述


🧩 路线图(Roadmap)

  • 多选场景支持("通勤 + 雨天"组合推荐)
  • 歌单收藏 / 导出(分享链接、下载 JSON)
  • 接入音乐平台真实试听(需版权接口权限)
  • 服务端代理封装,隐藏 API Key
  • 用户画像库:多次对话后持久化性格偏好

📜 许可

仅供学习交流使用。歌曲信息由 AI 生成,版权归原作者所有。

Logo

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

更多推荐