ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

级联式三明治架构:企业级 Voice Agent 从 STT 到 TTS 的完整落地实战

级联式三明治架构:企业级 Voice Agent 从 STT 到 TTS 的完整落地实战 先问大家一个问题你在公司里做语音助手类项目时是不是经常碰到下面这两种情况语音识别出来的文字乱七八糟带口音、带噪声、带专业名词直接把后面的大模型带偏。大模型回答得倒是挺好但语音合成出来像机器人念稿延迟还高整个对话体验非常“出戏”。说白了语音智能助手并不是“把 STT、LLM、TTS 三个模型拼在一起”就能跑通的。三个独立模型都很强但串联起来之后各种问题都来了上下文怎么传打断怎么办角色设定放哪里回答太长要不要截断TTS 遇到公式、英文、数字怎么读这篇文章我想结合今年实际落地企业级 Voice Agent 的经验梳理一套能直接拿去用的级联式三明治架构把STT → Agent/LLM → TTS三段链路拆开讲清楚并给出可运行的实战代码。内容会覆盖核心概念、环境准备、代码实现、性能瓶颈分析和常见排错思路。无论你是刚接触语音大模型应用还是已经有业务在跑这篇文章都值得收藏备用。1. 什么是 Voice Agent为什么需要“三明治架构”1.1 从 Chatbot 到 Voice Agent先做一个简单的名词区分。Chatbot只能处理文字输入输出用户打字它回复文字。Voice Agent能够直接接收语音、理解意图、生成回复并把回复合成为语音形成完整的“说话式对话闭环”。Voice Agent 的核心链路其实只有三条把语音转成文字STTSpeech-to-Text把文字交给大模型或 Agent 框架处理LLM / Agent把回复文字转成语音TTSText-to-Speech这条链路看起来简单但实际工程落地时远比单个模型评测要复杂得多。因为语音交互是实时、双向、有噪声、有打断的任何一环出问题整个体验都会崩。1.2 为什么叫“级联式三明治架构”所谓“级联”Cascade指的是数据流严格按照STT → LLM/Agent → TTS的顺序单向传递每一级的输出是下一级的输入。所谓“三明治”可以从两个层面理解物理分层STT 和 TTS 是两片“面包”负责语音与文本之间的转换LLM 是中间的“肉”负责语义理解和决策。逻辑分层外层是音频处理内层是文本处理LLM 不直接接触音频避免多模态模型带来的复杂部署和延迟问题。这种架构的优势在于每一层可以独立选型、独立优化、独立扩容。STT、LLM、TTS 可以来自不同厂商比如 STT 用本地 WhisperLLM 用云端大模型TTS 用另一家的合成服务。问题排查简单哪一环出问题就定位哪一环。1.3 这套架构解决了语音助手的哪“两大难题”结合标题和实际项目经验我认为级联式三明治架构重点解决了两大难题难题一语义理解与上下文管理难如果只是“语音转文字 大模型回复”没有会话管理和 Agent 设计大模型记不住前文回答会非常碎片化。级联式架构把 Agent 放在中间层让 LLM 不只是“聊天”而是具备工具调用、知识库检索、状态记忆的能力。难题二端到端语音系统的延迟与可控性难端到端语音大模型虽然听起来很美好但部署成本高、生成不可控、领域适配难。级联式架构通过把音频处理与文本处理解耦可以用成熟的 STT/TTS 引擎保障语音质量用 LLM 保障语义能力同时在每一层做缓存、打断、流式处理来降低延迟。2. 核心模块拆解STT、LLM/Agent、TTS 各自怎么选2.1 STT语音转文字STT 负责把麦克风采集到的音频转成文字。它是整个链路的第一环识别质量直接决定后面所有环节的效果。如果你的场景是中文普通话、带口音、有环境噪声建议优先考虑WhisperOpenAI 开源多语言支持好对噪声鲁棒但本地部署需要一定的 GPU 资源。如果是 CPU 环境建议用small或base模型。FunASR阿里开源中文效果很好支持流式识别适合实时对话场景。Paraformer阿里开源在中文识别和标点预测方面表现稳定工业界使用较多。云端 STT如果允许数据出域也可以接云厂商的语音识别服务延迟和并发都有保障但需要评估成本和数据合规风险。在级联架构中STT 有几个关键点需要注意返回结果需要带标点否则 LLM 很难断句。最好支持VAD 检测Voice Activity Detection也就是检测用户是否开始说话、是否停止说话。需要输出时间戳Timestamp方便后续做打断和日志分析。2.2 LLM / Agent中间决策层中间层是整个 Voice Agent 的大脑。它收到 STT 输出的文本后需要完成以下任务对话状态维护多轮记忆意图识别与槽位提取业务查询 / 工具调用Function Calling回复生成决定“说什么”回复文本后处理如增加标点、去掉 Markdown 符号、控制长度这里要特别强调给 TTS 的文本不能直接使用大模型的原始输出。因为大模型经常输出 Markdown、列表、加粗、代码块等格式TTS 遇到这些符号会读出“星号”“井号”或者直接读错。所以中间层必须包含一个“文本净化”模块。线上系统通常使用 Function Calling 或 Agent 框架如 LangChain、Dify、Coze、自研 Agent Runtime让 LLM 具备调用内部 API 的能力。比如用户说“帮我查一下明天的会议安排”LLM 并不需要凭空回答而是调用日历查询接口把结果组织成自然语言。2.3 TTS文字转语音TTS 是最后一片“面包”负责把 LLM 生成的内容朗读出来。它的核心评价指标是自然度听起来是否像真人。延迟首包延迟要低最好小于 300ms。稳定性长文本、特殊符号、数字、英文是否稳定发音。情感控制是否支持快乐、严肃、温柔等语气调节。现在可选的方案也很多Edge-TTS免费易用基于微软语音服务中英文效果都不错但依赖网络。ChatTTS开源对话场景 TTS支持一定的韵律和笑声适合闲聊类助手。CosyVoice阿里开源支持零样本声音克隆可以固定音色。火山引擎 / 阿里云 / 腾讯云 TTS商用级稳定延迟低支持 SSML 标记适合企业级项目。在企业级项目中我更推荐商用 TTS 服务因为超时、并发、热词定制都有保障。如果是本地离线优先场景可以用开源 TTS 做私有化部署但要提前做好音色合成质量和并发压力的测试。2.4 级联式三明治架构全景图使用 ASCII 简图表示整个链路用户说话音频 | v ---------- ASR 结果文本 ---------- 回复文本 ---------- | STT 模块 | ------------ | LLM/Agent | ------- | TTS 模块 | ---------- ---------- ---------- | | | 音频采集 会话记忆 音量/音色 噪声消除 工具调用 流式播放 端点检测 文本净化 打断处理可以看到STT 和 TTS 负责“语音到文本”和“文本到语音”的转换LLM 在中间负责纯粹的文本语义处理。这种分层设计让每一步的职责都清晰明确。3. 环境准备与项目结构规划3.1 环境与版本说明在开始写代码之前先说明一下本文示例的运行环境。不同的机器、不同版本的依赖库可能会带来差异所以下面的版本信息请当作“参考基准”而不是绝对固定值。操作系统Ubuntu 22.04 / macOS 14 / Windows 11WSL2 也可 Python3.10 语音识别openai-whisper 或 funasr 大模型OpenAI 兼容接口也可以换成任意本地 LLM 语音合成edge-tts 或 云厂商 TTS SDK如果你使用的是 CPU 环境可以把 Whisper 模型换成base或small版本如果你有 NVIDIA GPU显存 8GB 以上可以使用medium或large-v3版本。项目的重点在于架构思路和代码组织方式模型本身可以根据实际资源调整。安装依赖pip install openai-whisper edge-tts openai python-dotenv sounddevice numpy说明openai是调用兼容 OpenAI 格式的大模型接口。edge-tts是微软 Edge 浏览器同款语音合成接口的 Python 库免费且效果不错。sounddevice负责采集麦克风音频如果只是测试可以用本地音频文件替代。python-dotenv用来管理 API Key 等环境变量。3.2 项目结构下面是我比较推荐的最小项目结构后续扩展时也方便维护voice_agent_project/ ├── .env ├── requirements.txt ├── main.py ├── config.py ├── agent/ │ ├── __init__.py │ ├── stt.py │ ├── llm_agent.py │ ├── tts.py │ └── pipeline.py └── logs/ └── voice_agent.log每个文件职责如下main.py程序入口调度整个语音对话流程。config.py读取环境变量统一管理模型路径、API Key、音色配置。agent/stt.py语音识别模块封装 STT 逻辑。agent/llm_agent.pyLLM 对话模块负责多轮对话和文本后处理。agent/tts.py语音合成模块负责把文本变成音频并播放。agent/pipeline.py三明治架构的核心编排代码把 STT、LLM、TTS 串起来。logs/存放运行日志。3.3 环境变量配置在项目根目录创建.env文件OPENAI_API_KEYsk-xxx OPENAI_BASE_URLhttps://api.openai.com/v1 OPENAI_MODELgpt-4o-mini TTS_VOICEzh-CN-XiaoxiaoNeural STT_MODELsmall如果你的大模型是本地部署的比如 vLLM、Ollama则把OPENAI_BASE_URL改成对应的地址例如OPENAI_BASE_URLhttp://localhost:8000/v14. 实战基于级联式三明治架构实现 Voice Agent下面进入核心环节。我们用 Python 逐个模块实现然后把它们组合成一个完整的语音助手。4.1 配置模块 config.py配置文件在项目中起到“总闸”的作用所有可变的参数都从这里读取避免在业务代码里散落魔法值。# 文件路径voice_agent_project/config.py import os from dotenv import load_dotenv load_dotenv() class Config: # OpenAI / LLM 配置 OPENAI_API_KEY os.getenv(OPENAI_API_KEY, ) OPENAI_BASE_URL os.getenv(OPENAI_BASE_URL, https://api.openai.com/v1) OPENAI_MODEL os.getenv(OPENAI_MODEL, gpt-4o-mini) # STT 配置 STT_MODEL os.getenv(STT_MODEL, small) # TTS 配置 TTS_VOICE os.getenv(TTS_VOICE, zh-CN-XiaoxiaoNeural) # 系统提示词控制助手的角色定位 SYSTEM_PROMPT os.getenv( SYSTEM_PROMPT, 你是一个友好、专业的智能语音助手。请用简洁、口语化的方式回答问题 不要使用 Markdown 标记不要使用列表符号每次回复尽量控制在 80 字以内。, )这里特别说明一下系统提示词的作用。语音场景和文字聊天场景对回复格式的要求完全不同文字聊天可以输出 Markdown语音助手必须要求模型输出“适合朗读”的文本。如果你希望助手话少一点可以在提示词里直接约束“每次回复不超过 2 句话”。4.2 STT 模块 agent/stt.pySTT 模块接收一个音频文件或音频数据流返回识别出的文本。为了演示方便我这里使用本地音频文件作为输入最终你可以替换成麦克风采集或 WebRTC 音轨。# 文件路径voice_agent_project/agent/stt.py import whisper class STTEngine: def __init__(self, model_name: str small): # 加载语音识别模型 self.model whisper.load_model(model_name) def transcribe(self, audio_path: str) - str: 将语音文件转成文本。 :param audio_path: 音频文件路径支持 wav/mp3/m4a 等格式 :return: 识别出的文本 result self.model.transcribe(audio_path, languagezh, fp16False) return result[text].strip()如果你希望使用 FunASR 来获得更好的中文效果和流式识别能力可以把transcribe方法内部替换为 FunASR 的调用方式接口保持不变。这样做的好处是上层应用不需要关心底层用的是哪个 STT 引擎。4.3 LLM Agent 模块 agent/llm_agent.pyLLM Agent 是中间层这里我们实现两个核心能力维护多轮对话历史。对输出文本做净化处理保证 TTS 能顺利朗读。# 文件路径voice_agent_project/agent/llm_agent.py from openai import OpenAI from config import Config class LLMAgent: def __init__(self, system_prompt: str None): self.client OpenAI( api_keyConfig.OPENAI_API_KEY, base_urlConfig.OPENAI_BASE_URL, ) self.model Config.OPENAI_MODEL self.system_prompt system_prompt or Config.SYSTEM_PROMPT self.history [] def reset_history(self): 清空对话历史开始新一轮会话。 self.history [] def add_user_message(self, content: str): self.history.append({role: user, content: content}) def add_assistant_message(self, content: str): self.history.append({role: assistant, content: content}) def get_reply(self, user_text: str) - str: 调用大模型生成回复并净化文本。 :param user_text: 用户输入文本 :return: 适合 TTS 播放的回复文本 self.add_user_message(user_text) messages [{role: system, content: self.system_prompt}] messages.extend(self.history) response self.client.chat.completions.create( modelself.model, messagesmessages, temperature0.7, ) reply response.choices[0].message.content clean_reply self._clean_text(reply) self.add_assistant_message(reply) return clean_reply staticmethod def _clean_text(text: str) - str: 对模型输出做净化 1. 去掉 Markdown 标记 2. 去掉星号、井号、反引号 3. 压缩多余换行 4. 去掉列表序号 import re # 去掉 Markdown 图片和链接语法 text re.sub(r!\[.*?\]\(.*?\), , text) text re.sub(r\[(.*?)\]\(.*?\), r\1, text) # 去掉 Markdown 标题符号、加粗、斜体、代码块标记 text re.sub(r[#*_~], , text) # 去掉列表序号如 1. 2. - 等 text re.sub(r^\s*(\d[.、)]|\-)\s*, , text, flagsre.MULTILINE) # 压缩连续换行 text re.sub(r\n{2,}, \n, text).strip() return text这里有一个工程细节值得注意_clean_text不仅仅是为了显示美观更是为了避免 TTS 读出 Markdown 符号。如果你直接让 TTS 读 “你好” 这种文本可能会出现“加粗你好加粗”这种诡异发音。4.4 TTS 模块 agent/tts.pyTTS 模块把文本转成音频并播放。这里使用edge-tts作为示例它支持多种音色使用简单。# 文件路径voice_agent_project/agent/tts.py import asyncio import edge_tts from config import Config class TTSEngine: def __init__(self, voice: str None): self.voice voice or Config.TTS_VOICE async def synthesize_to_file(self, text: str, output_path: str): 将文本合成为音频文件。 :param text: 需要朗读的文本 :param output_path: 输出的音频文件路径 communicate edge_tts.Communicate(text, self.voice) await communicate.save(output_path) async def synthesize_and_play(self, text: str): 将文本合成并播放。 这里直接用 ffplay 播放也可以替换为 pygame / sounddevice。 output_path temp_reply.mp3 await self.synthesize_to_file(text, output_path) # 播放音频 process await asyncio.create_subprocess_exec( ffplay, -nodisp, -autoexit, output_path, stdoutasyncio.subprocess.DEVNULL, stderrasyncio.subprocess.DEVNULL, ) await process.wait() def tts_sync(text: str) - None: 同步包装方便在普通函数中调用。 engine TTSEngine() asyncio.run(engine.synthesize_and_play(text))需要说明的是edge-tts是一个在线服务使用前需要保持网络畅通。如果你的项目要求离线或内网部署可以替换成其他本地 TTS 引擎只要保持synthesize_and_play(text)这个接口不变即可。4.5 核心编排模块 agent/pipeline.py这是整个三明治架构的中枢它把 STT、LLM、TTS 串成一条完整的处理链。# 文件路径voice_agent_project/agent/pipeline.py from agent.llm_agent import LLMAgent from agent.stt import STTEngine from agent.tts import TTSEngine class VoiceAgentPipeline: def __init__(self): self.stt STTEngine() self.llm LLMAgent() self.tts TTSEngine() def handle_audio_file(self, audio_path: str): 完整处理一次语音输入 语音 - 文本 - 大模型回复 - 文本净化 - 语音输出 # Step 1: STT 识别 user_text self.stt.transcribe(audio_path) print(f[STT] 识别结果: {user_text}) # Step 2: LLM 推理 reply_text self.llm.get_reply(user_text) print(f[LLM] 回复文本: {reply_text}) # Step 3: TTS 合成 self.tts.synthesize_and_play(reply_text) return reply_text为了方便理解我在代码里加入了[STT]、[LLM]这样的日志前缀。在企业级项目中这些日志应该改为标准 logging 输出并把中间过程写入日志文件方便后续排查。4.6 程序入口 main.py现在编写主入口让整个流程可运行。# 文件路径voice_agent_project/main.py import sys from agent.pipeline import VoiceAgentPipeline def main(): if len(sys.argv) 2: print(用法: python main.py 音频文件路径) return audio_file sys.argv[1] pipeline VoiceAgentPipeline() pipeline.handle_audio_file(audio_file) if __name__ __main__: main()运行方式python main.py test_audio.wav预期输出类似[STT] 识别结果: 你好请帮我介绍一下你们公司的产品 [LLM] 回复文本: 好的我们公司主要提供智能语音解决方案包括语音识别、语音合成和对话式AI服务。请问您想了解哪方面然后设备会播放合成语音。4.7 加入多轮对话能力前面已经实现了基础的“一问一答”但这还不够。语音助手需要支持多轮对话比如用户说“再讲详细一点”系统要能理解“再”指的是上一轮的主题。下面升级VoiceAgentPipeline增加一个简单的多轮循环# 文件路径voice_agent_project/agent/pipeline.py from agent.llm_agent import LLMAgent from agent.stt import STTEngine from agent.tts import TTSEngine class VoiceAgentPipeline: def __init__(self): self.stt STTEngine() self.llm LLMAgent() self.tts TTSEngine() self.running True def handle_audio_file(self, audio_path: str) - str: user_text self.stt.transcribe(audio_path) print(f[STT] 识别结果: {user_text}) # 检测退出指令 if user_text in [退出, 再见, 结束, 拜拜]: self.running False reply_text 好的再见 else: reply_text self.llm.get_reply(user_text) print(f[LLM] 回复文本: {reply_text}) self.tts.synthesize_and_play(reply_text) return reply_text def start_conversation(self): 循环对话每次输入音频文件路径作为模拟语音输入。 print(开始语音对话输入音频文件路径继续输入 q 退出。) while self.running: audio_path input(请输入音频文件路径输入 q 退出: ).strip() if audio_path.lower() q: break self.handle_audio_file(audio_path) if __name__ __main__: pipeline VoiceAgentPipeline() pipeline.start_conversation()这样每轮对话都会携带之前的history大模型能够理解上下文。4.8 扩展Function Calling 让 Agent 具备工具能力真正的企业级 Voice Agent 不能只靠模型“脑补”答案还要能查数据库、调接口。下面给出一个用 Function Calling 查询天气的示例思路。# 文件路径voice_agent_project/agent/llm_agent.py扩展 def get_reply_with_tools(self, user_text: str) - str: self.add_user_message(user_text) messages [{role: system, content: self.system_prompt}] messages.extend(self.history) tools [ { type: function, function: { name: get_weather, description: 查询指定城市的当前天气, parameters: { type: object, properties: { city: {type: string, description: 城市名称} }, required: [city], }, }, } ] response self.client.chat.completions.create( modelself.model, messagesmessages, toolstools, tool_choiceauto, ) message response.choices[0].message if message.tool_calls: # 这里调用本地函数 tool_call message.tool_calls[0] if tool_call.function.name get_weather: import json args json.loads(tool_call.function.arguments) city args[city] weather_result f{city}今天晴转多云温度 18~26 摄氏度 self.add_assistant_message(str(message)) self.add_user_message(str({weather: weather_result})) # 二次请求让模型生成最终回复 final_response self.client.chat.completions.create( modelself.model, messages[{role: system, content: self.system_prompt}] self.history, ) return self._clean_text(final_response.choices[0].message.content) reply message.content clean_reply self._clean_text(reply) self.add_assistant_message(reply) return clean_reply这只是一个最简单的示意真实项目中需要把工具注册表、参数校验、超时重试、权限校验都完善起来。5. 如何解决语音助手的两大核心难题在前面我们已经从架构上理解了级联式三明治的基本形状。这里再深度展开一下这套架构到底怎么解决实际业务中的两大难题。5.1 难题一语义理解与业务落地的割裂纯大模型对话和真正的业务之间有一道很深的鸿沟。用户说“帮我查一下上个月的订单量”大模型如果不知道你的数据库结构根本无法回答。级联式三明治架构的解决方式是将中间层升级为Agent 层大模型负责理解用户意图并决定“要不要调用工具”。通过 Function Calling大模型可以查询订单系统、CRM、库存系统。Agent 框架维护任务状态把多次工具调用组合成一个完整答案。这种模式的业务价值在于语音助手不再是一个“聊天玩具”而是真正能完成任务的数字员工。用户对语音助手的信任度来自“能办成事”而不是“聊得开心”。5.2 难题二时延、并发与音频体验的矛盾语音交互对实时性要求极为严格。根据公开经验数据端到端延迟大于 2 秒时用户会明显感到卡顿大于 5 秒时用户大概率会打断或放弃。级联式三明治架构为时延优化提供了多个切入点STT 层流式识别不必等用户说完再识别可以边说话边出字节省等待时间。LLM 层流式输出大模型逐 token 生成TTS 可以增量合成实现“边说边生成”。TTS 层首包优先先合成第一句话并播放后续句子在后台继续合成。缓存机制高频问题如“你是谁”“你们公司地址在哪”可以直接命中缓存绕过大模型。下面是这些优化点在代码中的落点说明阶段优化方式代码落点STT开启流式识别 / VAD 端点检测transcribe改为流式接口LLM使用流式输出 增量提示词get_reply改为streamTrueTTS保存常用回复的合成音频synthesize_and_play加缓存判断管道并行化音频采集与 LLM 推理pipeline使用异步任务5.3 为什么不用端到端语音大模型现在市面也有一些“语音大模型”号称直接输入语音输出语音。这类模型确实体验很惊艳但在企业级场景中级联式三明治架构仍然更稳妥原因包括领域可控性端到端模型很难控制中间输出如果用户问“退款政策”你无法确定模型内部是否遵循了业务知识库。部署成本端到端模型参数量巨大私有化部署成本高。工具调用复杂级联架构中LLM 可以很方便地调用工具端到端模型要支持工具调用还需要额外工程开发。语音问题定位难端到端模型出问题时你不知道是听懂错了还是回答错了还是念错了。级联架构的日志链路清楚出问题可以直接定位到具体层。当然如果未来端到端语音大模型的成本和使用体验提升上来部分简单场景也可以尝试但短期内级联式三明治架构仍然是企业落地最稳妥的选择。6. 常见问题与排查思路6.1 STT 识别不准问题现象常见原因解决思路中文识别错别字多模型太小 / 领域词缺失换用更大的模型添加热词表噪声大导致识别乱码没有预处理音频加 VAD 和降噪模块专业名词识别错误未配置自定义词汇在 STT 中用热词列表强调英文和中文混读不准语言参数设置不当设置languagezh或multilingual建议在 STT 引擎初始化时传入自定义词汇列表例如公司产品名、行业术语。Whisper 可以通过“上下文提示”实现类似效果。6.2 LLM 回复不适合朗读问题现象常见原因解决思路TTS 读出 “星号”“井号”模型输出带 Markdown增加_clean_text净化模块回复太长语音播报超时未限制回复长度系统提示词明确约束字数模型输出英文缩写prompt 没有约束语言提示词中指定使用中文回复多轮回答跑题历史消息没有正确维护检查 history 拼接逻辑建议把“输出净化”作为一个独立模块来写并且要有单元测试覆盖。不要相信模型一定不会输出 Markdown一定要在代码层面兜底。6.3 TTS 播放卡顿或无声问题现象常见原因解决思路播放无声音系统没有音频输出设备检查声卡 / ffplay 是否安装首包延迟高TTS 合成慢换用流式 TTS 接口长文本合成失败文本长度超限将文本分段合成并发播放冲突多次调用播放器增加播放队列建议在代码中增加一个“播放锁”或“音频队列”避免多任务并发时互相抢占音频输出设备。6.4 完整排查 checklist如果你在运行中遇到问题可以按下面顺序排查单独测试 STT只运行transcribe确认识别文本是否正确。单独测试 LLM直接给get_reply传文本确认回复内容是否合理。单独测试 TTS只合成一句话确认能正常播放。最后再组合成完整链路观察哪一环的日志出现异常。这种“单独验证每一层”的思路是级联架构最大的工程红利。7. 最佳实践与工程化建议7.1 对话管理设计不要把所有对话状态都放在内存里。企业级系统需要考虑用 Redis 存储会话上下文设置过期时间如 30 分钟无操作自动清理。给每个会话分配session_id方便日志追踪和多轮对话恢复。对敏感对话进行脱敏处理避免用户隐私进入模型训练。7.2 提示词与文本后处理语音场景的提示词比文字聊天要更“啰嗦”一点一定要把格式约束写清楚。我这里提供一个相对成熟的模板你是一个语音助手正在和用户进行实时对话。 请遵循以下规则 1. 使用中文口语化回答。 2. 每句话尽量简短不要超过 30 个字。 3. 不要使用 Markdown、列表、加粗、斜体。 4. 如果不知道答案直接说“抱歉我暂时无法回答这个问题”。 5. 涉及数字金额时使用中文读法例如“一百二十八元”。7.3 安全边界即使是语音助手也必须考虑安全边界不要允许大模型直接执行高权限操作。比如“删除订单”“转账”这类操作必须二次确认。工具调用需要鉴权。每个 Function Call 要校验调用者身份和权限。音频数据要加密存储。用户语音属于敏感数据日志中不要明文记录完整音频内容。设置超时与重试。调用第三方模型服务时建议默认设置超时时间为 5~10 秒并做指数退避重试。7.4 日志与监控三明治架构的每一层都要输出结构化日志。STT 层记录音频时长、识别文本、识别置信度。LLM 层记录 prompt 长度、模型名称、首 token 延迟、总 token 数。TTS 层记录合成文本长度、首包延迟、播放时长。管道层记录总耗时和各阶段耗时占比。当用户反馈“助手变笨了”时第一件事就是看日志到底是 STT 没听清还是 LLM 答错还是 TTS 没播出来。这一步能节省大量排查时间。7.5 性能优化分级不同业务对延迟的要求不同优化优先级也不同。初级优化模型降级、文本净化、回复长度限制。中级优化流式 STT、流式 LLM、TTS 增量播报。高级优化端到端延迟预算系统、自动扩缩容、地域级边缘部署。建议先从初级优化开始因为它投入最小、收益最明显。不要一上来就追求高难度的流式改造。8. 总结与下一步学习方向这篇文章从企业级 Voice Agent 的落地视角把级联式三明治架构STT → LLM/Agent → TTS完整拆解了一遍。核心内容总结如下级联式三明治架构是当前企业落地语音助手最稳妥的方案分层清晰、可插拔、易排错。STT 负责“听清”LLM/Agent 负责“听懂”和“办成事”TTS 负责“说好”。文本净化是语音助手非常容易被忽略但又极其重要的一步。LLM 不只用来聊天更重要的是通过 Function Calling 完成真实业务任务。每一层都可以独立优化和替换这也是架构最大的价值。接下来你可以继续深入学习的方向包括流式 STT 与 VAD 端点检测让助手的响应更快。Function Calling 完整实战让语音助手接入真实业务系统。RAG 知识库增强让助手能回答私有领域问题。音色定制与情感合成提升产品体验。语音打断Barge-in实现“用户说话时助手立刻停止播放”。语音 Agent 并不是简单的模型拼接而是一部需要精心调校的“机器”。希望这篇文章能帮你把最难的两块骨头啃下来。如果你在实际运行中遇到问题欢迎在评论区留言交流觉得有用的话也可以收藏备用后续项目需要时再翻出来对照着配置。
返回列表