微信小程序集成实战调用SenseVoice-Small实现语音搜索功能不知道你有没有过这样的体验在手机上购物或者找资料想搜个东西但打字特别麻烦尤其是商品名字很长或者描述很复杂的时候。要是能直接说出来让手机自己听懂去搜那该多方便。现在这个想法在微信小程序里就能轻松实现。今天我就来分享一个实战项目如何在一个电商类小程序里集成一个“动动嘴”就能搜商品的语音搜索功能。整个过程不复杂核心就是用户在小程序里说话我们把语音传给一个非常厉害的语音识别模型——SenseVoice-Small它把语音转成文字我们再拿着这个文字去搜索商品最后把结果展示给用户。听起来是不是挺酷的下面我就带你一步步把它做出来。1. 为什么选择语音搜索先聊聊场景和价值在开始敲代码之前我们得先想清楚为什么要做这个功能。对于一个小程序特别是电商、内容资讯或者工具类的小程序语音搜索能带来几个实实在在的好处。首先是提升用户体验。想象一下用户想买“那个带硅胶保护套的黑色无线充电器”用键盘输入这十几个字不仅慢还可能输错。而对着手机说一句话一秒搞定。这种便捷性尤其在用户双手不方便比如在做家务、通勤时体验提升是巨大的。其次能提高搜索的准确性和丰富性。用户的口语化描述往往比关键词更具体、包含更多信息。比如用户说“我想找昨天在抖音上看到的那款露营灯”这句话里包含了时间、来源平台、产品类型等多个维度虽然目前的搜索系统可能还无法完全解析这么复杂的语义但至少“露营灯”这个核心词能被准确抓取比用户自己只输入“灯”要精准得多。最后这也是一个技术亮点和差异化竞争点。当大多数小程序还停留在传统的输入框搜索时你的小程序提供了更自然、更智能的交互方式无疑能吸引更多用户尝试和留存。所以我们这次的目标很明确在小程序前端实现语音录制和播放通过我们自己的服务器做中转和调度调用云端强大的SenseVoice-Small模型完成语音转文字最后将识别结果无缝对接回小程序的搜索逻辑。整个流程对用户来说就是“按住说话 - 松开看到搜索结果”简单又神奇。2. 技术方案设计与核心组件要把这个想法落地我们需要一个清晰的技术架构。整个流程可以分成三个部分小程序前端、自有业务服务器、以及星图GPU平台上的SenseVoice-Small服务。用户说话 ↓ [微信小程序前端] ├── 录音模块 (wx.getRecorderManager) ├── 播放模块 (wx.createInnerAudioContext) └── 界面交互 (按钮、动画、提示) ↓ (上传语音文件) [自有业务服务器] ├── 接收小程序上传的语音文件 ├── 调用星图平台API (请求SenseVoice-Small) ├── 处理识别结果 (文本后处理) └── 执行商品搜索 (调用内部搜索接口) ↓ (返回搜索结果) [微信小程序前端] └── 展示搜索结果列表核心组件介绍小程序前端这是用户直接交互的界面。我们需要用到微信小程序提供的RecorderManager来管理录音包括开始、停止、监听录音过程。录音完成后我们会得到一个临时音频文件路径需要将它上传到我们的服务器。自有业务服务器这是我们的“中枢大脑”。它负责几个关键任务安全地接收小程序上传的文件以正确的格式和参数去调用星图平台的SenseVoice-Small语音识别服务拿到识别文本后可能还需要做一些简单的清洗比如去掉语气词、纠正明显的同音错字最后调用我们已有的商品搜索接口获取结果再打包返回给小程序。SenseVoice-Small服务这是技术的核心。我们选择它是因为它在中文语音识别上表现非常出色准确率高对嘈杂环境也有一定的抗干扰能力并且通过星图GPU平台可以方便地以API形式调用省去了我们自己部署和维护模型的巨大成本。这个方案的优势在于我们将复杂的AI模型能力封装在后端小程序前端保持轻量只负责交互和展示。同时所有业务逻辑和安全性校验都在我们自己的服务器上完成可控性更强。3. 前端实战小程序录音与交互实现前端是小程序的门面我们的目标是做出一个流畅、反馈及时的录音交互。这里会用到微信小程序的基础API。首先我们需要在页面的wxml中布局。通常我们会设计一个显眼的、按压式的录音按钮。!-- pages/search/search.wxml -- view classcontainer !-- 搜索框区域 (可选保留传统搜索) -- !-- input typetext placeholder输入商品名称... / -- !-- 语音搜索区域 -- view classvoice-search text试试语音搜索/text view classrecord-btn {{isRecording ? recording : }} bindtouchstartonRecordStart bindtouchendonRecordEnd bindtouchcancelonRecordCancel text{{isRecording ? 松开结束 : 按住说话}}/text /view text classtip长按按钮说话松开立即搜索/text !-- 识别结果和状态提示 -- view classresult-box wx:if{{recognitionText}} text识别结果/text text classresult-text{{recognitionText}}/text /view text classstatus-tip{{statusText}}/text /view !-- 搜索结果列表 -- view classresult-list wx:if{{searchResults.length 0}} block wx:for{{searchResults}} wx:keyindex view classresult-item !-- 商品图片、名称、价格等 -- image src{{item.image}} modeaspectFill/image text{{item.name}}/text text classprice¥{{item.price}}/text /view /block /view /view接下来在js文件中我们要实现录音的核心逻辑。微信小程序的wx.getRecorderManager()是一个全局的录音管理器我们需要在页面加载时创建它的实例并监听相关事件。// pages/search/search.js Page({ data: { isRecording: false, recognitionText: , statusText: 等待开始..., searchResults: [], recorderManager: null }, onLoad: function() { // 初始化录音管理器 const recorderManager wx.getRecorderManager(); this.setData({ recorderManager }); // 监听录音开始事件 recorderManager.onStart(() { console.log(录音开始); this.setData({ statusText: 正在聆听... }); }); // 监听录音结束事件这里会拿到临时文件路径 recorderManager.onStop((res) { console.log(录音结束, res); const { tempFilePath, duration } res; this.setData({ statusText: 录音结束时长${Math.floor(duration/1000)}秒正在识别... }); // 录音结束后立即调用上传函数 this.uploadVoiceFile(tempFilePath); }); // 监听录音错误事件 recorderManager.onError((err) { console.error(录音失败:, err); this.setData({ statusText: 录音失败请重试 }); wx.showToast({ title: 录音失败, icon: none }); }); }, // 手指按下按钮开始录音 onRecordStart: function() { this.setData({ isRecording: true, recognitionText: , statusText: 正在聆听... }); const { recorderManager } this.data; const options { duration: 10000, // 最长录音10秒可根据需要调整 sampleRate: 16000, // 采样率建议16000与模型匹配 numberOfChannels: 1, // 单声道 encodeBitRate: 48000, // 编码码率 format: mp3, // 输出格式mp3兼容性好 }; recorderManager.start(options); }, // 手指松开按钮结束录音 onRecordEnd: function() { this.setData({ isRecording: false }); this.data.recorderManager.stop(); }, // 处理录音意外取消如来电打断 onRecordCancel: function() { this.setData({ isRecording: false, statusText: 录音已取消 }); this.data.recorderManager.stop(); }, // 上传语音文件到我们的服务器 uploadVoiceFile: function(tempFilePath) { const that this; wx.uploadFile({ url: https://your-backend-domain.com/api/voice-recognize, // 你的服务器API地址 filePath: tempFilePath, name: voice_file, formData: { user_id: optional_user_id // 可传递用户标识 }, success(res) { // 服务器返回的数据是字符串需要解析 const data JSON.parse(res.data); if (data.code 0) { const text data.result.text; const results data.result.searchResults || []; that.setData({ recognitionText: text, searchResults: results, statusText: 识别成功 }); wx.showToast({ title: 搜索完成, icon: success }); } else { wx.showToast({ title: 识别失败: ${data.msg}, icon: none }); that.setData({ statusText: 识别失败 }); } }, fail(err) { console.error(上传失败:, err); wx.showToast({ title: 网络错误请重试, icon: none }); that.setData({ statusText: 上传失败 }); } }); } })这样一个基础但完整的语音搜索前端交互就完成了。用户长按按钮说话松开后音频上传并等待结果显示。4. 后端桥梁服务器中转与模型调用前端把语音文件传过来了现在轮到我们的服务器大显身手。服务器的核心任务有两个调用SenseVoice-Small做识别以及执行搜索。这里以Python的Flask框架为例展示后端的关键代码。你需要先在星图GPU平台上获取SenseVoice-Small服务的API调用凭证如API Key。# app.py (Flask后端示例) import os from flask import Flask, request, jsonify import requests from werkzeug.utils import secure_filename import json app Flask(__name__) app.config[UPLOAD_FOLDER] ./uploads app.config[MAX_CONTENT_LENGTH] 10 * 1024 * 1024 # 限制10MB # 星图平台SenseVoice-Small的API配置 SENSEVOICE_API_URL https://api.xingtu.cn/v1/audio/transcriptions # 示例URL请替换为实际地址 SENSEVOICE_API_KEY your_sensevoice_api_key_here # 你的API Key # 你的内部商品搜索服务地址 INTERNAL_SEARCH_API https://your-internal-service.com/api/search app.route(/api/voice-recognize, methods[POST]) def voice_recognize(): 处理小程序上传的语音文件调用语音识别并执行搜索。 if voice_file not in request.files: return jsonify({code: 1, msg: 未找到语音文件}) voice_file request.files[voice_file] if voice_file.filename : return jsonify({code: 1, msg: 文件名为空}) # 1. 保存上传的临时文件 filename secure_filename(voice_file.filename) filepath os.path.join(app.config[UPLOAD_FOLDER], filename) voice_file.save(filepath) try: # 2. 调用SenseVoice-Small API进行语音识别 with open(filepath, rb) as f: files {file: (filename, f, audio/mpeg)} # 根据实际格式调整 headers { Authorization: fBearer {SENSEVOICE_API_KEY}, } # 可以传递一些参数例如指定模型或语言 data { model: sensevoice-small, # 指定模型 language: zh, # 指定中文 response_format: json } response requests.post(SENSEVOICE_API_URL, headersheaders, filesfiles, datadata) if response.status_code ! 200: return jsonify({code: 2, msg: f语音识别服务错误: {response.text}}) recognition_result response.json() # 假设返回格式为 {text: 识别出的文字} recognized_text recognition_result.get(text, ).strip() if not recognized_text: return jsonify({code: 3, msg: 语音识别结果为空}) # 3. (可选) 对识别文本进行简单后处理 processed_text post_process_text(recognized_text) # 4. 调用内部搜索接口 search_payload {query: processed_text, page: 1, size: 20} search_headers {Content-Type: application/json} # 这里假设内部搜索接口需要认证请根据实际情况调整 # internal_auth request.headers.get(Authorization) # if internal_auth: # search_headers[Authorization] internal_auth search_response requests.post(INTERNAL_SEARCH_API, jsonsearch_payload, headerssearch_headers) if search_response.status_code 200: search_data search_response.json() search_results search_data.get(data, []) else: search_results [] # 5. 返回结果给小程序 return jsonify({ code: 0, msg: success, result: { text: processed_text, searchResults: search_results } }) except Exception as e: app.logger.error(f处理语音请求时出错: {e}) return jsonify({code: 99, msg: 服务器内部错误}) finally: # 清理临时文件 if os.path.exists(filepath): os.remove(filepath) def post_process_text(text): 简单的文本后处理例如去除首尾空白、常见语气词等。 可以根据业务需求增强如纠错、关键词提取。 # 去除常见的口语化前缀/后缀 remove_words [嗯, 啊, 那个, 这个, 我想找一下, 帮我搜一下] for word in remove_words: if text.startswith(word): text text[len(word):].lstrip() if text.endswith(word): text text[:-len(word)].rstrip() return text if __name__ __main__: if not os.path.exists(app.config[UPLOAD_FOLDER]): os.makedirs(app.config[UPLOAD_FOLDER]) app.run(host0.0.0.0, port5000, debugFalse)这段代码构建了一个简单的后端服务。它接收小程序上传的MP3文件然后将其转发给星图平台的SenseVoice-Small服务。拿到识别文本后进行简单的清洗再调用已有的商品搜索接口最后将识别文本和搜索结果一并返回给小程序。这样就完成了从“声音”到“搜索结果”的完整闭环。5. 效果展示与优化思考当我们把前后端都部署好之后整个功能就跑起来了。用户在小程序里按住按钮说“白色连衣裙”松开手后大概一两秒的时间屏幕上就会显示出“白色连衣裙”的识别结果并同时列出相关的商品列表。整个过程非常流畅识别准确率也相当高对于常见的商品词汇和口语化表达SenseVoice-Small都能很好地处理。当然在实际应用中我们还可以做很多优化来让体验更好视觉反馈在录音时可以增加一个动态的声波动画让用户直观地感受到“正在录音”。识别过程中可以显示一个加载动画。错误处理网络超时、识别失败、搜索无结果等情况都需要有友好的提示引导用户重试或改用文字搜索。性能优化语音文件在上传前可以考虑在客户端进行压缩微信小程序RecorderManager的encodeBitRate参数可以控制以减少流量消耗和上传时间。语义增强后端的post_process_text函数可以做得更智能。比如识别出“苹果”时可以根据用户历史行为或当前上下文判断是指水果还是手机品牌从而向搜索接口传递更精确的查询词。多场景适配除了电商搜索这个架构完全可以复用到内容搜索、智能客服语音输入、语音便签等场景只需要替换最后一步的“搜索”动作为其他业务逻辑即可。6. 总结走完这一趟实战你会发现在微信小程序里集成一个像样的语音搜索功能并没有想象中那么遥不可及。关键是把链条拆解清楚前端负责交互和录音后端负责调度和集成AI能力而SenseVoice-Small这样的云端模型服务则提供了强大且稳定的核心识别能力。这种模式的好处是我们不需要深入研究语音识别的算法细节也不用操心模型的训练和运维只需要通过API调用就能获得行业领先的技术能力从而快速为自己的产品添加智能特性。这其实就是当前AI应用开发的一个典型范式聚焦业务逻辑善用云服务。如果你正在开发一个小程序并且正在寻找提升用户搜索体验的方法那么语音搜索绝对是一个值得投入的方向。从这个小功能开始或许就能打开一扇通往更自然、更智能人机交互的大门。获取更多AI镜像想探索更多AI镜像和应用场景访问 CSDN星图镜像广场提供丰富的预置镜像覆盖大模型推理、图像生成、视频生成、模型微调等多个领域支持一键部署。