写在前面:为什么我想做一个「音乐旅程」推荐器?

日常我们用的音乐应用,大多停留在「单首歌推荐 / 歌单推荐」层面:
今天想听点轻松的、来点运动节奏、或者按歌手/风格随便刷一刷。

但很多场景,其实更接近一段「旅程」而不是一个静态列表,比如:

  • 一天的情绪曲线:通勤 → 工作专注 → 下班放松 → 夜晚窗边发呆
  • 一场展览或活动:开场铺垫 → 氛围拉满 → 收尾平静
  • 一期播客/视频:从讲述故事,到情绪爆点,再到余韵回落

这次更新,我给项目加上了一个全新的能力——音乐旅程编排(Music Journey)
它不只是推荐几首歌,而是按照故事 / 情绪曲线自动分段,为每一段生成一小段「配乐章节」

下面基于这次重构后的项目,整理一篇完整介绍,也顺便推荐一下 GitHub 仓库。


一、项目简介:音乐推荐 Agent

这个项目的定位是一个开源的 「音乐推荐 Agent」

用一句自然语言,串起心情、场景与故事的整条音乐旅程。

你可以像和朋友聊天一样对它说:

  • 「给我一份适合深夜加班写代码的歌单」
  • 「我想在雨天窗边听些治愈的独立民谣」
  • 「根据周杰伦,帮我找一些同样浪漫的中文 R&B」
  • 「帮我为一个展览设计 60 分钟的音乐旅程,从好奇到平静,再到感动」

系统会通过 LLM + LangGraph 工作流理解你的意图,再联动 Spotify、网络搜索和本地数据,给出带解释的推荐结果


二、核心功能一览

当前版本已经支持以下几个核心能力:

  • 自然语言驱动的音乐推荐
    心情 / 场景 / 歌手 / 流派,一句话描述需求即可。
    在这里插入图片描述

  • 可解释推荐
    不只是「给你一堆歌」,还会用一小段自然语言解释:
    为什么是这些风格、为什么是这个艺术家、为什么放在这个位置。

  • 歌曲网络推荐 / 搜索

    • 优先通过 Spotify MCP + 在线乐库 搜索歌曲
    • 失败时回退到 Tavily 网络搜索 提取歌曲信息
    • 还可以退回到本地示例库做模糊匹配
      这一层已经从简单「本地搜索」升级成真正意义上的 网络级音乐检索 +推荐
      在这里插入图片描述
  • 音乐旅程编排(Music Journey)(本次重点):

    • 输入一个故事或情绪时间线(mood timeline)
    • 自动划分为多个阶段(Segments)
    • 每个阶段给出情绪标签、文字描述与对应推荐歌曲
    • 前端通过 SSE 流式展示整个旅程的结构和配乐
      在这里插入图片描述
  • SSE 流式体验

    • 推荐说明逐词输出,像「打字机」一样
    • 歌曲逐首添加到列表里
    • 状态(思考中 / 获取推荐中 / 完成)实时刷新
  • RESTful API + 前后端分离

    • 后端:FastAPI + LangGraph
    • 前端:Next.js 14 + TypeScript
    • 提供 /api/recommendations/api/search/api/journey 等接口,方便二次集成。

三、重点展开:音乐旅程编排(Music Journey)

1. 使用场景

这个功能特别适合这些场景:

  • 播客 / 视频创作者
    想要一条「叙事感」很强的配乐线,跟着故事起伏走。

  • 展览 / 装置艺术 / 线下空间
    希望在一定时间内,音乐跟着观众情绪变化而变化:
    从好奇 → 沉浸 → 共鸣 → 平静。

  • 长时间专注 / 学习 / 写作
    不想只是重复一首 BGM,而是情绪有规划地缓慢演进。

2. 你需要提供什么?

你可以给系统两种输入方式(任选其一):

  • 故事文本story):
    比如「我想为一整天的工作设计音乐,从清晨通勤开始,到夜晚回家整理心情。」

  • 情绪时间点序列mood_transitions):
    例如:

    [
      { "time": 0.0, "mood": "好奇", "intensity": 0.4 },
      { "time": 0.3, "mood": "专注", "intensity": 0.7 },
      { "time": 0.7, "mood": "激动", "intensity": 0.8 },
      { "time": 1.0, "mood": "平静", "intensity": 0.5 }
    ]
    

另外可以指定一个总时长(比如 60 分钟),系统会据此进行分段。

3. 系统会做什么?

在后端,MusicJourneyService 会做这几件事:

  1. 情绪/故事分析

    • 如果传入 story,先用 LLM 根据文本抽取几个关键阶段和情绪基调。
    • 如果传入 mood_transitions,则直接使用你给的情绪时间线。
  2. 阶段划分(Segments)

    • 把总时长切分为若干阶段(一般 3–6 段),每一段有:
      • mood:这一段的主要情绪(如:放松、专注、激昂、平静)
      • description:简短的文字描述
      • duration:预计时长
      • intensity:情绪强度(0–1)
  3. 为每一段选歌

    • 基于这一段的情绪、描述及用户偏好,调用推荐工具为该段挑选合适的歌曲列表。
    • 保证同一段内部风格相对统一,而不同段之间有合理过渡。
  4. 流式输出(SSE)

    • /api/journey/stream 会以 SSE 形式,依次推送:
      • 整体旅程信息(总段数、总时长、总歌曲数)
      • 每一段的 segment_startsegment_complete
      • 每段中的歌曲 song 事件
    • 前端可以边接收边渲染,实时看到「旅程的结构」被构建出来。
4. 前端体验

在前端,项目提供了一个「音乐旅程」页面(对应 README 里的截图):

  • 顶部是你输入故事/情绪的区域;
  • 中间是阶段卡片(每段一个 card,展示 mood / 描述 / 预计时长);
  • 底部是每个阶段下的歌曲列表。

配合 SSE,整个过程很像实时“排片+配乐”的导演台
你能看到系统如何把一段模糊的体验,拆分成一条有结构的音乐时间线。


四、架构与技术栈(简述)

后端:

  • FastAPI:提供 REST & SSE 接口
  • LangGraph:负责任务编排(意图识别、搜索、推荐、解释)
  • MCP 工具层:对接 Spotify、SiliconFlow、Tavily 搜索等
  • Pydantic / asyncio:数据建模与异步执行

前端:

  • Next.js 14(App Router)+ TypeScript
  • React Hooks + 自定义组件(推荐页、搜索页、旅程页等)
  • 自己实现的 SSE 客户端(fetch + ReadableStream),兼容 POST 请求

数据与配置:

  • 本地示例数据:data/music_database.json
  • 外部配置:setting.json 或环境变量
  • 详细的数据流与节点说明在仓库的 SSE_DATAFLOW.md 中也有完整文档。

五、如何本地快速体验?

后端 & 前端分别启动:

# 后端
python run_api_server.py  # 默认 http://localhost:8501

# 前端
cd web
npm install
npm run dev              # 默认 http://localhost:3000

打开浏览器访问:

  • http://localhost:3000/recommendations —— 体验流式音乐推荐
  • http://localhost:3000/search —— 体验歌曲网络搜索 / 推荐
  • 音乐旅程页面(如果你已经打开 README 截图中对应路由)—— 体验故事驱动的音乐旅程编排

六、GitHub 仓库地址

仓库已经开源,代码和文档都在这里:

  • GitHub:https://github.com/imagist13/Muisc-Research

仓库里已经包含:

  • 完整的 README(本篇文章内容的代码版)
  • API 说明、SSE 数据流设计文档
  • MCP 工具与测试脚本(例如 test_music_mcp.py

如果你:

  • 正在做音乐相关产品、播客/视频配乐工具;
  • 想学习「LLM + LangGraph + MCP + SSE」这一整套落地链路;
  • 或者只是想有一个好玩的「情绪驱动音乐旅程」小玩具,

欢迎直接 clone 下来玩一玩,也非常欢迎在 GitHub 提 issue / PR 一起完善。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐