【全栈实践】第一个 AI Agent 项目:从零搭建 AI 音频创作助手【最终版】

从零到一,全栈手搓 AI 智能播客平台------我的完整开发手记

引言:这个项目是做什么的?

Smart Podcast Platform 是一个端到端的智能播客制作平台。它的核心能力很简单:用户上传一段视频或音频,AI 自动理解内容、设计音色、生成播客,全程无需人工干预。

传统的 AI 音频工具通常停留在"生成文字脚本"的层面------用户拿到脚本后,还需要自己找配音、做剪辑、调音效,整个流程割裂且低效。这个项目试图把整个链条打通:从内容理解音色设计 ,从语音合成专业混音,全部由 AI Agent 自动完成。

这是我个人独立开发的全栈项目,从后端 Python 到前端 Vue 3,从 LangGraph Agent 编排到 pydub 音频处理,完整覆盖了一个 AI 音频应用的方方面面。

代码库地址:github.com/XingtongCai...


0、相关细节说明文章

以下三篇是关于这个Agent更详细说明:

1.第一个 AI Agent 项目:从零搭建 AI 音频创作助手(入门篇) : 这个是第一版本,里面主要进行初期框架搭建,包含Vue3 + ai-elements-vue 搭前端界面,LangChain 1.0 × AG-UI 协议 × Qwen TTS 驱动后端,支持定制音色,复刻音色和配音功能。

2.第一个 AI Agent 项目:从零搭建 AI 音频创作助手(进阶篇) : 这个是第二版本,新增了完整的播客后期制作能力,包括音频拼接、智能BGM选择、音轨混音三大核心功能,同时新增了音频资源管理API和语音输入功能,实现了从前端上传、语音输入到后端处理的全链路闭环。

3.第一个 AI Agent 项目:从零搭建 AI 音频创作助手(高级篇): 这个是第三版本,新增了音频、视频识别能力、临时-永久双层存储架构、定时清理机制和更智能的提示词系统,让播客 Agent 从单纯的"语音合成工具"升级为"全链路音频内容创作平台"。

一、项目架构总览

1.1 技术栈一览

层级 技术选型 核心作用
前端框架 Vue 3 + TypeScript + Vite 提供流式对话界面与播客管理
UI 组件 shadcn-vue + Tailwind CSS 深色主题的现代化交互体验
AI 框架 LangChain + LangGraph Agent 编排与多轮对话记忆
后端服务 FastAPI + Uvicorn REST API + SSE 流式响应
通信协议 AG-UI Protocol 前后端 Agent 事件标准化通信
语音引擎 阿里云 DashScope (Qwen-TTS) 音色设计、语音克隆、语音合成
语音识别 阿里云 DashScope (Qwen-ASR) 高精度语音转文字,支持 ITN 标准化
多模态模型 qwen3.5-omni-plus 图片/视频/音频统一理解
音频处理 pydub + FFmpeg 音频拼接、混音、后期制作

1.2 系统架构图

css 复制代码
graph TB
    A[用户浏览器] --> B[Vue 3 前端]
    B --> C[FastAPI 后端]
    C --> D[LangGraph Agent]
    D --> E[LLM 推理引擎]
    D --> F[工具调用层]
    
    F --> G1[Qwen-TTS 音色设计]
    F --> G2[Qwen-TTS 语音克隆]
    F --> G3[Qwen-ASR 语音识别]
    F --> G4[Qwen-Omni 多模态理解]
    F --> G5[音频拼接与混音]
    
    C --> H[存储层]
    H --> H1[音频文件存储]
    H --> H2[音色索引管理]
    H --> H3[配置持久化]
    
    B --> I[AG-UI 协议]
    I --> C

二、核心技术深度解析

2.1 Agent 智能体:不只是"调用 API"

传统的 AI 应用通常是"用户输入 → 调用 API → 返回结果"的线性流程。但在播客制作场景中,这个流程要复杂得多:

  • 用户可能上传视频(需要多模态理解)
  • 用户可能上传音频(需要语音识别)
  • 用户可能要求特定音色(需要音色设计)
  • 最终需要混音输出(需要音频后期处理)

我们的 Agent 系统通过 LangGraph 实现了智能编排:

ini 复制代码
# backend/app/services/agent_service.py

agent = create_agent(
    name="tts_agent",
    model=model,          # LLM 推理引擎
    tools=tools,          # 注册 9 个专业工具
    system_prompt=full_prompt,  # 播客专家角色定义
    checkpointer=InMemorySaver()  # 多轮对话记忆
)

核心设计理念:

  1. 自主决策:Agent 根据用户输入自动判断需要调用哪些工具,无需预设固定流程
  2. 链式调用:复杂任务自动编排多步骤工具调用(理解内容 → 设计音色 → 合成语音 → 混音输出)
  3. 上下文感知:自动从对话历史中提取信息,避免重复询问用户
  4. 记忆持久化 :基于 InMemorySaver 实现多轮对话状态保持

2.2 流式通信:AG-UI 协议的妙用

我们采用了 AG-UI 协议(Agent-User Interaction Protocol),将 Agent 的各种行为标准化为事件流:

python 复制代码
# backend/app/services/stream_processor.py

class StreamProcessor:
    async def process_stream(self, agent, messages):
        # 1. 发送运行开始事件
        yield RunStartedEvent(...)
        
        # 2. 流式处理 Agent 输出
        async for chunk in agent.astream(...):
            if isinstance(chunk, AIMessage):
                # 文本内容 → TextMessageContentEvent
                yield TextMessageContentEvent(delta=content)
            elif hasattr(chunk, 'tool_calls'):
                # 工具调用 → ToolCallStartEvent + ToolCallArgsEvent
                yield ToolCallStartEvent(tool_call_name=name)

协议事件类型:

事件 含义 前端展示
RUN_STARTED Agent 开始运行 加载动画
TEXT_MESSAGE_START/CONTENT/END 文本流式输出 打字机效果
TOOL_CALL_START/ARGS/END 工具调用过程 工具卡片展开
TOOL_CALL_RESULT 工具返回结果 结果展示

前端通过 ai-elements-vue 组件库,将这些事件渲染为丰富的交互界面:思维链展示、工具调用卡片、代码块高亮等。

2.3 音色设计:让 AI "开口说话"

这是整个系统最核心的功能模块。我们基于阿里云 DashScope 的 Qwen-TTS 引擎,实现了两种音色生成方式:

方式一:文本描述生成音色(Voice Design)

用户只需用文字描述想要的音色特征:

python 复制代码
# backend/app/tools/qwen_tts.py

@tool("qwen_voice_design", args_schema=VoiceDesignInput)
def qwen_voice_design_tool(
    voice_description: str,  # 如:"沉稳的中年男性,音色低沉浑厚,富有磁性"
    text: str,              # 测试文本
    language: str = "zh"
) -> str:
    # 调用 DashScope API,传入音色描述文本
    # API 返回 voice_id 和预览音频
    ...

技术亮点:音色描述直接作为 API 参数,无需训练或微调,零样本生成。

方式二:参考音频复刻(Voice Cloning)

上传一段参考音频,AI 自动复刻其音色特征:

ini 复制代码
@tool("qwen_voice_cloning", args_schema=VoiceCloningInput)
def qwen_voice_cloning_tool(
    voice_id: str = "",      # 已设计的音色ID
    local_path: str = "",    # 本地音频路径
    reference_audio: str = "",  # 上传的参考音频
    text: str = ""
) -> str:
    # 优先级:voice_id > local_path > reference_audio
    # 1. 注册音色 → 2. 合成语音 → 3. 保存本地
    ...

参数优先级设计voice_id > local_path > reference_audio,确保已设计的音色可以复用,避免重复注册。

2.4 多模态理解:让 AI "看懂"和"听懂"

播客内容的来源不限于文字------用户可能上传视频、音频、图片等各种格式。我们集成了 qwen3.5-omni-plus 模型,提供统一的多模态理解能力:

python 复制代码
# backend/app/tools/qwen_multimodal.py

@tool("qwen_multimodal_tool")
def qwen_multimodal_tool(media: str, prompt: str) -> str:
    # 1. 智能解析媒体来源(URL / 本地路径 / base64)
    media_content = _resolve_media_source(media)
    
    # 2. 大视频自动分割(>21MB 自动切片)
    if isinstance(media_content, list):
        # 对每个片段分别调用 API,合并结果
    
    # 3. 调用多模态 API
    response = _call_multimodal_api(messages)
    return _extract_text_from_response(response)

关键设计决策:

  1. 大视频分割策略 :当文件超过 21MB 时,自动使用 moviepy 分割为多个片段,每段约 10MB,确保 base64 编码后不超过 API 限制
  2. 统一媒体抽象_resolve_media_source() 函数将 URL、本地路径、base64 统一转换为 API 所需的格式
  3. 格式智能识别 :根据文件扩展名自动选择 image_url / video_url / input_audio 类型
音频理解:不只是"听",而是"懂"

除了视频和图片,多模态模型同样支持音频内容理解。用户上传一段音频,模型可以直接分析其中的语义内容、情感色彩、甚至识别说话人的语气和节奏------这对于播客内容创作尤为重要,因为很多用户会直接上传录音素材作为播客的原始材料。

ini 复制代码
# 音频理解调用示例
messages = [
    {"role": "user", "content": [
        {"input_audio": "https://example.com/podcast-raw.mp3"},
        {"text": "请分析这段音频的主要内容和情感基调"}
    ]}
]
response = client.chat.completions.create(
    model="qwen3.5-omni-plus",
    messages=messages
)
# 返回:内容摘要 + 情感分析 + 关键信息提取

2.5 音频后期制作:从"语音片段"到"专业播客"

生成语音只是第一步,真正的播客需要专业的后期处理。我们基于 pydub 实现了完整的音频处理管线:

python 复制代码
# backend/app/tools/audio_mixing.py

# 工具1:音频拼接
@tool("concatenate_audio")
def concatenate_audio_tool(
    audio_files: List[str],
    crossfade_duration: int = 200,  # 交叉淡入淡出
    silence_duration: int = 1200   # 片段间静音
) -> str:
    # 按顺序拼接多个音频片段
    ...

# 工具2:智能BGM选择
@tool("select_background_music")
def select_bgm_tool(
    scene_description: str,  # 如"欢快的开场"
    duration_seconds: float = None
) -> str:
    # 基于文件名关键词匹配 BGM
    # 自动循环/裁剪以匹配时长
    ...

# 工具3:专业混音
@tool("mix_audio_with_bgm")
def mix_audio_with_bgm_tool(
    voice_audio: str,
    bgm_audio: str,
    bgm_volume: float = -26,   # BGM 约 5% 音量
    intro_duration: float = 3.0  # 开场原声时长
) -> str:
    # BGM 开场(原音量)→ 过渡(渐变)→ 背景(5%音量)
    ...

混音策略设计:

shell 复制代码
BGM 音量曲线:
  100% ┤     ┌────── 开场(原声 BGM)
       │     │
   5%  ┤─────┼──────────────────── 背景(-26dB)
       │     │
       └─────┴────────────────────→ 时间
       0s   3s  淡入过渡 2s

这种设计模拟了专业播客的听觉体验:开场时 BGM 烘托氛围,过渡后降低为背景音,确保人声清晰。

2.6 配置管理:多层级优先级策略

项目采用 配置文件 > 环境变量 > 默认值 的三级配置优先级:

ini 复制代码
# backend/app/utils/config_manager.py

def get_config_value(key: str, env_key: str, default: str = "") -> str:
    # 1. 先读 config.json(前端可视化配置)
    config = load_config()
    value = config.get("llm", {}).get("openai_api_key")
    
    # 2. 再读环境变量
    if not value:
        value = os.getenv("OPENAI_API_KEY")
    
    # 3. 最后用默认值
    return value or default

设计意图 :用户可以通过前端界面(VisualConfig.vue)直接修改配置,无需手动编辑 .env 文件。配置自动持久化到 storage/config.json,降低使用门槛。

2.7 音频索引系统:轻量级的资源管理

我们没有引入数据库,而是用 JSON 文件实现了轻量级的音频资源索引:

less 复制代码
// storage/voice_index.json
[  {    "id": "uuid",    "local_path": "storage/audios/xxx.wav",    "voice_id": "voice-xxx",    "model_name": "cosyvoice-v3.5-plus",    "path": "audios",    "createTime": "2026-07-10 14:30:00"  }]

关键设计:

  • 文件锁并发控制 :使用 fcntl.flock 保证多请求并发写入安全
  • path 字段分类audios(定制音色)/ bgm(背景音乐)/ podcasts(播客成品),便于前端分类展示
  • 临时文件自动清理storage/temp/ 目录下的文件定期清理,避免磁盘堆积

三、前端交互设计

3.1 深色主题的沉浸式体验

前端采用深蓝紫的色调主题,深空背景 + 蓝紫光晕 + 亮蓝高亮,配置提取style.css中:

css 复制代码
/* ------ 光晕装饰色 ------ */
  --brand-glow-blue:      #3a5cff;
  --brand-glow-purple:    #7c3aed;
  --brand-glow-deep-blue: #1e40ff;

  /* ------ 品牌高亮蓝 ------ */
  --brand-blue:        #4f7cff;
  --brand-blue-light:  #4f9dff;
  --brand-blue-strong: #2b6ef7;
  --brand-blue-soft:   #7ea3ff;
  --brand-blue-pale:   #9ec2ff;

  /* ------ 卡片封面渐变 ------ */
  --brand-cover-from: #1e3a8a;
  --brand-cover-via:  #2a1e5f;
  --brand-cover-to:   #0d0524;

3.2 流式对话体验

基于 ai-elements-vue 组件库,前端实现了丰富的 Agent 交互界面:

  • 思维链展示:Agent 的推理步骤以可折叠卡片形式展示
  • 工具调用可视化:每个工具调用显示名称、参数、结果
  • 音频播放器:生成的音频直接在对话中嵌入播放
  • 文件上传:支持拖拽上传音频/视频文件

3.3 四个核心页面

页面 功能 路由 效果描述
ChatAgent 流式对话 Agent,核心创作入口 / 深色主题对话界面,Agent 逐步展示思考过程、工具调用和生成结果,支持音频播放和文件拖拽上传
PodcastList 播客成品列表,展示和管理作品 /podcasts 卡片网格布局展示所有已生成的播客作品,每个卡片包含封面、标题、时长信息,悬停有微动效
ResourceLibrary 资源库管理,管理音色/BGM/素材 /resources 分类管理音色、BGM、播客素材,支持上传、预览、删除操作,左侧分类导航 + 右侧内容列表
VisualConfig 可视化配置 API Key 和模型参数 /config 表单式配置界面,分为"对话模型"和"语音播客"两个区块,支持密码可见性切换和自动持久化

四、工程实践与经验

4.1 工具设计的"单一职责"原则

我们将音频处理拆分为 9 个独立工具,每个工具只做一件事:

工具 职责 输入 输出
qwen_multimodal_tool 多模态内容理解 媒体文件 文本描述
qwen_asr_tool 语音识别 音频文件 文字转录
qwen_voice_design 音色设计 文本描述 音色ID+音频
qwen_voice_cloning 语音合成 音色ID+文本 音频文件
save_voice 音色保存 音频路径 永久存储
concatenate_audio 音频拼接 音频列表 拼接文件
select_background_music BGM 选择 场景描述 BGM 路径
mix_audio_with_bgm 专业混音 人声+BGM 最终播客

这种设计让 Agent 可以灵活组合工具,而不是被预设的"大而全"工具束缚。

4.2 临时文件与永久存储的分离

  • 临时目录storage/temp/):工具生成的中间产物,10 分钟自动清理
  • 永久目录storage/audios/):用户确认保存的音色,持久化存储
  • 成品目录storage/podcasts/):混音后的最终播客

这个设计避免了磁盘空间浪费,同时保证了用户主动保存的内容不会丢失。

4.3 流式输出的"真"流式

我们使用 stream_mode="messages" 模式,确保 Agent 的输出是逐 token 流式的,而非"生成完再发送"的伪流式:

csharp 复制代码
async for chunk in agent.astream(
    {"messages": langchain_messages},
    {"configurable": {"thread_id": self.thread_id}},
    stream_mode="messages"  # 关键:逐消息流式输出
):
    async for event in self._handle_chunk(chunk):
        yield event  # 立即发送,不等待

4.4 配置可视化:降低技术门槛

传统 AI 项目需要用户手动编辑 .env 文件,对非技术用户极不友好。我们通过 VisualConfig.vue 页面,将配置项以表单形式呈现:

  • API Key 输入框(支持密码可见性切换)
  • 模型选择下拉框
  • 配置自动持久化到 config.json
  • 前后端通过 /api/config 接口同步

五.结果展示


六、总结

这个项目展示了 AI Agent 在垂直内容创作领域 的完整实践:

  1. 端到端自动化:从内容理解到播客输出,全流程 AI 驱动
  2. 多模态融合:文字、图片、音频、视频统一处理
  3. 专业级音频质量:音色设计 + 智能混音,输出广播级品质
  4. 低门槛使用:可视化配置 + 自然语言交互,无需技术背景

附录:快速开始

bash 复制代码
# 1. 克隆项目
git clone <repo-url>

# 2. 启动后端
cd backend
python -m venv venv
source venv/bin/activate
pip install -r requirements.txt
cp .env.example .env  # 填写 API Key
python main.py

# 3. 启动前端
cd fronted
npm install
npm run dev

# 4. 访问 http://localhost:3000
相关推荐
12.=0.1 小时前
【REVIEW_C】【持续更新】
服务器·前端·javascript
Vuji1 小时前
Pi 插件解剖|todo.ts:297 行,拼出工具+命令+状态的完整插件
前端·agent
明月_清风1 小时前
开发者写PPT自救指南:4类对接场景,把技术讲清楚
前端·后端·面试
探索前端1 小时前
3dtiles加载时被地形遮挡问题研究及处理思路
前端·3d·cesium
Htr_1 小时前
Vercel 使用指南:框架、工作流与基础设施一体化的现代 Web 部署平台
前端
一颗烂土豆1 小时前
ECharts 太平面?试试这款 Vue 3D 图表库
前端·vue.js·echarts
anyup1 小时前
迁移uni-app x,我是如何让 AI 把我一步步搞崩溃的...
前端·uni-app·trae
用户921080262862 小时前
从读框架到搭项目:基于 Ant Design X Vue 和 RICH 范式搭建 AI 前端工作台
前端
Hilaku2 小时前
为什么同一段代码在 Safari 上永远有 Bug?
前端·javascript·程序员