Paraformer-large结合LangChain:语音驱动Agent构建教程
1. 为什么需要语音驱动的Agent?
你有没有遇到过这样的场景:开会录音长达两小时,想快速整理成会议纪要却要手动听写;客户来电反馈问题,客服人员一边通话一边打字记录,效率低还容易遗漏关键信息;或者你只是想对着电脑说一句“把上周销售数据生成图表”,就自动完成整套操作——这些需求背后,都需要一个能“听懂话、理解意图、执行任务”的语音驱动Agent。
传统语音识别(ASR)只解决“把声音变成文字”这一步,但真正的智能在于:识别后的文本如何被理解、如何触发后续动作、如何与业务系统联动。Paraformer-large提供了高精度、长音频友好的语音转写能力,而LangChain则像一位聪明的调度员,把识别结果交给合适的工具、记忆上下文、调用API、生成响应。两者结合,就能搭建出真正可用的语音交互Agent。
本教程不讲抽象概念,不堆砌术语,而是手把手带你从零开始:先跑通Paraformer-large的离线语音识别界面,再把它接入LangChain框架,最后实现一个能听、能懂、能做的语音助手原型。整个过程全部本地运行,无需联网调用第三方API,隐私安全有保障,适合企业内网部署或个人研究使用。
2. 快速启动Paraformer-large语音识别服务
2.1 环境准备与一键部署
本镜像已预装所有依赖:PyTorch 2.5、FunASR、Gradio、ffmpeg,无需额外安装。你只需要确认两点:
- 实例配备NVIDIA GPU(推荐RTX 4090D或A10/A100),确保CUDA可用
- 存储空间充足(模型缓存约3GB,长音频处理需预留10GB以上临时空间)
如果服务未自动启动,请在终端执行以下命令检查并运行:
# 进入工作目录 cd /root/workspace # 查看app.py是否存在 ls -l app.py # 若不存在,可直接创建(内容见下文) vim app.py小贴士:
app.py是整个服务的核心脚本。它不是一次性工具,而是长期运行的Web服务入口。只要实例开机,它就会持续监听6006端口,随时响应语音上传请求。
2.2 核心代码解析:三步搞定语音识别
下面这段代码看似简单,实则完成了语音识别中最关键的三个环节:模型加载、音频推理、界面封装。我们逐行拆解,让你知其然更知其所以然:
import gradio as gr from funasr import AutoModel import os # 1. 加载模型(会自动去你下载好的缓存路径找) model_id = "iic/speech_paraformer-large-vad-punc_asr_nat-zh-cn-16k-common-vocab8404-pytorch" model = AutoModel( model=model_id, model_revision="v2.0.4", device="cuda:0" # 使用 4090D 识别,速度极快 ) def asr_process(audio_path): if audio_path is None: return "请先上传音频文件" # 2. 推理识别 res = model.generate( input=audio_path, batch_size_s=300, ) # 3. 提取文字结果 if len(res) > 0: return res[0]['text'] else: return "识别失败,请检查音频格式" # 4. 构建像 Ollama 一样漂亮的网页界面 with gr.Blocks(title="Paraformer 语音转文字控制台") as demo: gr.Markdown("# 🎤 Paraformer 离线语音识别转写") gr.Markdown("支持长音频上传,自动添加标点符号和端点检测。") with gr.Row(): with gr.Column(): audio_input = gr.Audio(type="filepath", label="上传音频或直接录音") submit_btn = gr.Button("开始转写", variant="primary") with gr.Column(): text_output = gr.Textbox(label="识别结果", lines=15) submit_btn.click(fn=asr_process, inputs=audio_input, outputs=text_output) # 5. 启动服务,端口设为 6006(AutoDL 的默认开放端口) demo.launch(server_name="0.0.0.0", server_port=6006)关键点说明(用人话说):
model_id指向的是阿里达摩院官方发布的工业级模型,自带VAD(语音活动检测)和Punc(标点预测),所以你传进去一段带停顿的讲话,它不仅能识别字,还能自动加逗号句号,分段也更合理。device="cuda:0"表示强制使用第一块GPU。如果你的机器没有GPU,可以改成"cpu",但识别速度会明显下降(长音频可能需数分钟)。batch_size_s=300不是“一次处理300条音频”,而是指“每批次最多处理300秒的音频片段”。Paraformer-large会自动把一小时的录音切成多个300秒的小段并行处理,再拼接结果——这就是它能高效处理长音频的秘密。- Gradio界面里
gr.Audio(type="filepath")支持两种输入:上传本地音频文件(mp3/wav等),或直接点击麦克风实时录音(浏览器权限允许时)。对用户来说,完全无感。
2.3 访问Web界面:三步走通本地映射
由于云平台通常不直接暴露Web端口,你需要在自己电脑上建立SSH隧道,把远程服务器的6006端口“搬”到本地:
# 在你的Mac或Windows(WSL)终端中执行 # 替换 [你的端口号] 和 [你的SSH地址] 为实际值(如 -p 2222 root@123.45.67.89) ssh -L 6006:127.0.0.1:6006 -p [你的端口号] root@[你的SSH地址]连接成功后,打开本地浏览器,访问:
http://127.0.0.1:6006
你会看到一个简洁的界面:左侧上传/录音,右侧实时显示识别结果。试试上传一段10秒的普通话录音,观察识别速度和准确率——正常情况下,2秒内出结果,中文识别准确率在95%以上(安静环境)。
常见问题直答
Q:上传MP3没反应?
A:确保音频采样率是16kHz(可用Audacity转换),或改用WAV格式。
Q:提示“CUDA out of memory”?
A:降低batch_size_s到150,或在AutoModel中添加quantize=True启用INT8量化。
Q:识别结果全是乱码?
A:检查音频是否为中文发音,Paraformer-large对中英文混合识别稍弱,建议纯中文输入。
3. 将语音识别接入LangChain:构建可理解、可行动的Agent
3.1 为什么不能只靠ASR?——识别≠理解
Paraformer-large输出的是高质量文本,比如:“今天下午三点在会议室A召开项目复盘会,请张经理和李工准时参加”。这句话本身没问题,但它对系统来说只是一串字符。真正的挑战在于:
- 如何识别出“三点”是时间,“会议室A”是地点,“张经理”“李工”是人名?
- 如何判断这是“会议安排”而非“闲聊”?
- 如何把这条指令同步到日历系统、自动发送提醒邮件、甚至生成会议议程?
这就需要LangChain来补全“理解”和“执行”这两块拼图。它不替代ASR,而是站在ASR肩膀上,做更高阶的事。
3.2 构建语音Agent的四层架构
我们不搞复杂设计,用最轻量的方式搭出可用原型。整个流程分为四层,每一层都对应一段可运行的代码:
| 层级 | 作用 | 关键组件 | 你负责什么 |
|---|---|---|---|
| 输入层 | 接收语音→转文字 | Paraformer-large + Gradio | 已完成,只需调用asr_process() |
| 理解层 | 解析文本→提取结构化信息 | LangChain的LLMChain + Prompt模板 | 写一段提示词,告诉大模型“你要做什么” |
| 决策层 | 判断意图→选择工具 | LangChain的AgentExecutor + 自定义Tool | 定义2-3个真实可用的工具函数 |
| 执行层 | 调用工具→返回结果 | Python原生函数(发邮件/写文件/查天气) | 写几行简单逻辑,无AI成分 |
这个架构的好处是:ASR和LLM完全解耦。你可以今天用Paraformer,明天换成Whisper,只要输出格式不变,上层逻辑完全不用改。
3.3 实战代码:三步集成LangChain(附完整可运行脚本)
我们以“语音记事本”为最小可行场景:你说一句话,Agent自动识别、提取关键信息、保存为带时间戳的文本文件。
第一步:安装LangChain依赖(在服务器终端执行)
# 激活环境 source /opt/miniconda3/bin/activate torch25 # 安装核心包(无需OpenAI密钥,用本地模型) pip install langchain-community langchain-core tiktoken第二步:编写agent.py(放在/root/workspace/下)
# agent.py import os import json from datetime import datetime from langchain_core.prompts import ChatPromptTemplate from langchain_core.output_parsers import StrOutputParser from langchain_community.llms import Ollama # 用本地Ollama的Qwen模型,免API密钥 from langchain.agents import AgentExecutor, create_tool_calling_agent from langchain.tools import tool # 1. 定义一个真实可用的工具:保存语音笔记到文件 @tool def save_voice_note(content: str) -> str: """将语音识别结果保存为带时间戳的文本文件""" timestamp = datetime.now().strftime("%Y%m%d_%H%M%S") filename = f"/root/workspace/notes/voice_note_{timestamp}.txt" # 确保目录存在 os.makedirs("/root/workspace/notes", exist_ok=True) with open(filename, "w", encoding="utf-8") as f: f.write(f"[{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}]\n{content}") return f" 笔记已保存:{filename}" # 2. 构建提示词模板(用中文,明确指令) prompt = ChatPromptTemplate.from_messages([ ("system", "你是一个语音助手,负责理解用户语音转写的文字,并执行具体操作。" "用户输入是ASR识别结果,可能包含口语化表达、错别字或不完整句子。" "请先提取核心意图和关键信息(时间、地点、人物、事件),再调用合适工具。" "不要编造信息,不确定就问用户。"), ("human", "{input}"), ]) # 3. 初始化本地大模型(需提前运行:ollama run qwen:7b) llm = Ollama(model="qwen:7b", temperature=0.3) # 4. 创建Agent(仅用save_voice_note一个工具,足够起步) tools = [save_voice_note] agent = create_tool_calling_agent(llm, tools, prompt) agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True) # 5. 封装成可调用函数(对接Paraformer) def voice_to_action(asr_text: str) -> str: if not asr_text.strip(): return "❌ 输入为空,请检查语音识别结果" try: result = agent_executor.invoke({"input": asr_text}) return result["output"] except Exception as e: return f"❌ 执行失败:{str(e)}"第三步:修改app.py,接入Agent(关键改动)
找到原app.py中的asr_process函数,替换为以下增强版:
# 替换原 asr_process 函数 def asr_process(audio_path): if audio_path is None: return "请先上传音频文件" # 1. ASR识别 res = model.generate( input=audio_path, batch_size_s=300, ) if len(res) == 0: return "识别失败,请检查音频格式" asr_text = res[0]['text'] # 2. 调用LangChain Agent处理 from agent import voice_to_action agent_result = voice_to_action(asr_text) # 3. 合并展示:原始识别 + Agent动作结果 return f"🗣 识别原文:{asr_text}\n\n Agent执行:{agent_result}"重启服务后,上传一段语音,比如:“记一下,明天上午十点和王总讨论新方案”,你会看到界面同时显示识别原文和“ 笔记已保存:/root/workspace/notes/voice_note_20250405_103022.txt”。
这就是语音Agent的雏形:它不再只是“转文字”,而是“听懂后做事”。整个过程完全离线,所有计算都在你的GPU上完成。
4. 进阶技巧与避坑指南
4.1 提升识别鲁棒性:三招应对真实场景
Paraformer-large虽强,但在真实环境中仍会遇到挑战。以下是经过验证的实用技巧:
降噪预处理(推荐):在调用
model.generate前,用noisereduce库对音频做轻量降噪import noisereduce as nr from scipy.io import wavfile rate, data = wavfile.read(audio_path) reduced_noise = nr.reduce_noise(y=data, sr=rate) # 保存降噪后音频再送入ASR方言适配(非必须):若主要识别粤语/四川话,可切换模型ID为
iic/speech_paraformer_asr_zh-cn-16k-common-vocab8404-pytorch(无VAD/Punc,但方言鲁棒性略好)长音频分段优化:对超长录音(>2小时),手动按自然停顿切分(如会议中的茶歇),再批量处理,比全自动切分错误率更低
4.2 LangChain Agent调优:让理解更准、动作更稳
初学者常犯的错误是“给大模型太多自由”。针对语音场景,我们坚持两个原则:
- Prompt必须带约束:在system prompt中明确写“只允许调用save_voice_note工具,禁止虚构、联网、调用其他API”
- 工具函数必须有防御:
save_voice_note中加入长度校验(如if len(content) < 5: return "内容过短,拒绝保存"),避免误触发
另外,如果你发现Agent总是“绕弯子”,大概率是LLM太“客气”。在初始化Ollama时加上参数:
llm = Ollama(model="qwen:7b", temperature=0.1, num_ctx=4096)temperature=0.1让输出更确定,num_ctx=4096确保能记住长上下文(对会议纪要很重要)。
4.3 可扩展方向:从记事本到生产力中枢
当前Demo是单工具Agent,但扩展极其简单。只需新增工具函数,再注册进tools = [...]列表即可:
- 发邮件工具:调用
smtplib发送识别结果到指定邮箱 - 日历同步工具:解析时间地点后,用
ics库生成.ics文件供Outlook导入 - 知识库检索工具:把识别文本作为Query,搜索本地Markdown文档库
所有工具都遵循同一模式:输入是字符串,输出是字符串,中间逻辑由你用Python写。LangChain只负责“调度”,不碰业务细节——这才是工程落地的关键。
5. 总结:你已经拥有了语音智能的起点
回顾整个过程,你完成了三件关键事:
- 跑通Paraformer-large离线识别:拥有一个不依赖网络、高精度、支持长音频的语音转文字能力
- 打通LangChain理解链路:让识别结果不再是孤零零的文字,而是可解析、可决策、可执行的指令
- 交付一个真实可用的Agent原型:语音输入 → 文字识别 → 意图理解 → 文件保存,全程自主可控
这不是一个“玩具Demo”,而是一个可立即投入试用的最小闭环。下一步,你可以根据自己的业务需求,替换或增加工具:销售团队接入CRM API自动录入客户线索,教育机构接入题库系统生成随堂测验,客服中心对接工单系统创建服务请求……
技术的价值不在于多炫酷,而在于多好用。Paraformer-large给你耳朵,LangChain给你大脑,剩下的,就是你想让它帮你做什么。
获取更多AI镜像
想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。