这是没人告诉 AI 构建者的真相。语音 Agent 并不需要最好的模型。它们真正需要的只是:
太长不看;如果你觉得阅读很无聊或者注意力不太够,你可以用我制作的技能文件,获取整篇文章并粘贴给你的 Agent ➡️https://github.com/codejunkie99/voice-agent-builder
构建它所需的一切只是:
- 一个具有实际延迟预算的实时管道
- 五个按正确顺序连接的组件
- 足以让模型保持诚实的扎实基础
- 一个能产生复合效应的每周复盘循环
OpenAI 在 2026 年 5 月 7 日发布了 GPT-Realtime-2。Salesforce AI Research 在 3 月 1 日发表了 VoiceAgentRAG 论文,同一周 Deepgram Flux 从测试版转为正式发布。各个组件不再是问题所在。
问题仍然在于你如何将它们连接起来,以及你让 Agent 说什么。
过去三个月,我一直在构建真正能接电话的语音 Agent。我不会假装这个过程很顺利。
- 第一个版本听起来像一台自助机。我两天内就废弃了它。
- 第二个版本在头一小时内"预订"了四个幽灵预约,之后我才注意到。
- 第三个版本内存泄漏,因为我忘记在后台提取器写入新事实后使上下文缓存失效。
- 等到东西真正能用的时候,系统已经是第四次重写了。
我现在会捍卫的版本,只有一小套属性,我会用接下来的 6000 字来解释。
- 管道只有一个任务,且在一个预算内。五个组件,端到端低于 700 毫秒,没有例外。
- 知识存在于你的文档中,并通过双 Agent 缓存来检索,而不是从模型内部提取出来。
- 对话设计是为耳朵而不是眼睛写作的学科。大多数团队把它当作表面功夫。但它不是。
- 每一轮对话都会写入一个结构化日志,我可以在 90 天后针对当前配置重放它。
这篇文章就是那 90 天实际教会我的东西,加上如果我现在重新开始,我会优先投入的两三个赌注。🔽🔽
语音 Agent 到底是什么
语音 Agent 不是一个加了麦克风的聊天机器人。也不是围绕文本 API 的 TTS 封装。
它是一个实时音频系统。受延迟约束。五个组件在 300 到 800 毫秒的时间窗口内协调运作。
管道按事件实际发生的顺序如下:
- 用户说话
- 音频被捕获
- 流式 STT 逐词转录,在用户还在说话时进行
- Agent 读取转录文本并从你的文档中检索相关知识
- LLM 生成回复
- TTS 将回复朗读出来
- 用户听到
每一步的箭头都是一个你可以选择、调整和替换的组件。
我一开始尝试用聊天机器人的方式构建。STT 完成,发送给 LLM,等待完整响应,发送给 TTS,等待完整音频,播放。
感觉糟透了。就像在和一台自助机对话。两天后我就删掉了它。
感觉糟糕的原因不是延迟数据不好。数据在纸面上看是好的。原因在于人类不是轮流对话的。他们是在重叠的流中交流的。
- Agent 必须在用户还在说完句子时就开始构思回复。
- TTS 必须在 LLM 写完之前就开始说话。
- STT 必须在 Agent 说话时继续监听,这样它才知道何时闭嘴。
一个不能被中断的语音 Agent 不是语音 Agent。它是语音信箱。
三种架构
只有三种。根据你需要控制的内容来选择。
链式管道
- 独立的 STT、LLM、TTS 服务连接在一起
- 三个独立模型,每个都专职于自己的工作
- 文本在它们之间流动
- 在调优良好的托管平台上,延迟大约在 600 到 700 毫秒
- 最可控,最易调试,最容易逐层升级
半级联
- 音频直接输入到能够听到音频而非转录文本的多模态模型中
- 能捕捉到某人声音中的沮丧、由升调暗示的问题、句中的语言切换
- 输出仍通过专门的 TTS 进行处理,以便进行音频控制
- 延迟降至 300 到 500 毫秒
原生语音到语音
- 一个模型,音频输入,音频输出
- 没有转录层,没有文本交接
- 2026 年,每个主要实验室都推出了原生语音模型
- 延迟降至 200 到 300 毫秒,低于呼叫者停止注意到他们正在与 AI 对话的阈值
从哪个开始
- 从链式管道开始。现有的工具支持最好。一旦你在管道上验证了产品,并希望获得阶梯式的延迟改进,再转向语音到语音。
- 我一开始对所有事情都尝试了语音到语音。它在预订流程方面表现出色。
- 但它在处理一个 12 步的登记表时崩溃了,因为单个模型在第九轮对话后无法在头脑中保持状态机,导致上下文膨胀。
- 我把那个流程转移到了带有真正状态机层的链式管道上,三天内完成率从 61% 跃升到 89%。
- 按状态限定工具范围是整个修复的关键。
你需要连接的五个组件
每个链式管道都有相同的五个组件。在你的 Agent 接听第一个电话之前,需要填充这五个任务。
耳朵(流式 STT)
STT 模型将传入的音频实时转换为文本,逐词进行,在用户还在说话时。这是你技术栈中最关键的组件。这里的转录错误会级联到下面的所有环节。
2026 年需要关注什么:
- 流式准确性。在用户说话时准确,而不仅仅是在他们说完之后。
- 词错误率。在实际生产音频上,6% 到 8% 是好的。超过 12% 会导致大约每三次通话中就有一次用户感到沮丧。
- 内置的说话结束检测。2026 年最大的单一用户体验升级。
为什么说话结束检测很重要:
- 通用的 STT 返回转录文本。它不会告诉你说话者何时结束。
- 没有它,你的 Agent 要么会打断别人的话,要么会尴尬地等待两秒钟。
- 2026 年新一轮的流式 STT 模型在同一网络中内置了说话结束检测,该网络也产生转录文本。
- 当模型判断说话者已经结束时,它会发出一个 turn-complete 信号。
- 该信号使用语义上下文,而不仅仅是声学静默。它能捕捉到声音逐渐消失,并忽略呼吸停顿。
- 如果你的提供商已经推出了这个功能,就切换过去。Agent 在每轮开始说话前的停顿会减少 200 到 400 毫秒。
大脑(LLM)
LLM 读取转录文本、对话历史、检索到的知识,并决定说什么。它也决定行动,而不仅仅是文字。
语音专用规则:
- 使用小型快速模型,而不是旗舰模型。前沿推理模型需要 1500 毫秒来生成第一个单词。那是死寂时间。同一系列的较小模型在语音轮次中几乎总是胜出。
- 仅当需要进行真正规划的具体复杂工具调用时,才升级到大型模型。
- 将系统提示限制在 800 tokens。它会在每一轮对话中重新加载。一个 4000 token 的提示会给每条消息增加延迟。
函数调用,用大白话说:
- 你定义每个函数,包括它的功能和所需信息。
- LLM 读取描述并根据对话状态决定何时调用它。
- 没有条件逻辑树。LLM 从自然语言中匹配意图到函数。
函数调用在生产中最常见的失败原因可能和你预想的不同:
- LLM 在无法调用函数时并不会抛出错误。它反而会叙述这个动作。
- "我已确认您的预订。"实际上什么也没调用。用户认为他们已预订,实际上并没有。
- 解决方法是根据当前状态限定工具范围。"收集姓名"状态绝不能暴露 book_appointment。 "确认详情"状态绝不能暴露 check_availability。
- 状态机是安全护栏,而不是系统提示。
知识(RAG)
RAG 是一种机制,允许你的 Agent 从你的文档中回答,而不是从模型的训练数据中。
为什么你不能跳过这一步:
- LLM 是在截止日期前的公共互联网上训练的。
- 它们对世界了解很多。但它们对你的产品、价格、政策、客户一无所知。
- 没有 RAG,当 Agent 被问"企业版里有什么?"时,它会自信地产生幻觉。
- 有了 RAG,它会在回复之前从你的文档中检索实际答案。
基本机制:
- 用户提问。
- 系统对查询进行嵌入。
- 向量数据库返回最相关的文档片段。
- 片段被注入到 LLM 的上下文中。
- LLM 被指示仅从该上下文中回答。
语音特有的挑战:
- 一次典型的向量数据库查询会给管道增加 50 到 300 毫秒。
- 结合 STT、LLM 和 TTS,这会超出你的延迟预算。
- 解决方法是双 Agent 缓存模式。下面有一整节内容介绍这个。
嘴巴(TTS)
TTS 将文本转换为口语化的音频。听起来很简单。实际上它是感知质量方面的一个重要区分因素。
重要的是什么:
- 首音时间。一个需要 200 毫秒才开始说话的 TTS,仅输出层就耗掉你三分之一的延迟预算。
- 语音质量。人类对合成语音异常敏感。微小的伪影、不自然的节奏、错位的重音,都会被视为对整个系统的评判。
- 有意识地选择声音。在用户听完一句话之前,它就是一个信任信号。
手(函数和集成)
函数是 LLM 在对话过程中可以执行的操作:
- 预约
- 查询订单状态
- 发送确认短信
- 转接给人工
- 更新 CRM 中的记录
这是架构上的转变,使得现代语音 Agent 的能力远超那些"按 1 查询账单"的系统。
你必须满足的延迟预算
关于语音 Agent,最重要且不显而易见的事情是:每一毫秒的处理时间,都是呼叫者必须忍受的一毫秒沉默。
数学计算:
- 人类期望在说完一句话后 500 到 700 毫秒内得到对话式回复
- 超过一秒会让人觉得系统卡顿
- 超过两秒,呼叫者会开始和 Agent 抢话
这 700 毫秒就是你的全部预算,需要在每个组件之间分配。
按组件预算,快车道与慢车道:
- 传输:20-50 毫秒(对等连接)。50-100 毫秒(通过中继)。
- STT 首次中间结果:100-150 毫秒(缓存命中)。150-250 毫秒(缓存未命中)。
- 说话结束检测:模型集成,约 50 毫秒。静默阈值,300-600 毫秒。
- RAG 检索:缓存命中时亚毫秒级。本地 BM25 + 重排序时 80-150 毫秒。
- LLM 首 Token 时间:使用小型模型时 150-250 毫秒。使用前沿模型时 400-600 毫秒。
- TTS 首音时间:快速层 60-100 毫秒。高质量层 150-250 毫秒。
- 网络开销:同一区域内总共 40-80 毫秒。跨区域总共 100-160 毫秒。
- 端到端:快车道约 440 毫秒。慢车道约 700-900 毫秒。
2026 年的两大突破:
- 模型集成的说话结束检测。每轮对话节省 200 到 400 毫秒。这是今年你能做的最大的单一升级。
- 带有双 Agent 缓存的推测性预取。将约 40% 轮次的检索从"向量搜索未命中"变为"缓存查找命中"。
与这两点相比,其他一切都只是舍入误差。
双 Agent RAG 模式
在语音循环中使用标准 RAG 是一个问题。向量数据库查询需要 80 到 300 毫秒,并且每轮都会超出你的延迟预算。
2026 年的研究成果来自 Salesforce AI Research 在 3 月发表的 VoiceAgentRAG 论文。其见解很简单。
- 在真实的对话中,下一个问题通常可以从当前问题预测出来。
- 问价格的人很可能接下来会问关于企业版的问题。
- 问安装的人很可能接下来会问兼容性问题。
因此,你同时运行两个 Agent。
后台 Agent(慢思考者)
- 在用户收听当前回复时运行
- 使用 LLM 预测最可能的 3 到 5 个后续问题
- 为每个预测预取相关的文档片段
- 在用户听完当前答案之前,将它们存储在本地内存缓存中
前台 Agent(快说者)
- 处理下一个实时问题时,首先检查内存缓存
- 缓存查找是亚毫秒级的时间,而远程向量数据库调用需要 110 毫秒
- 如果缓存中有答案,则完全跳过数据库
- 如果缓存未命中,则回退到数据库,并将结果缓存以备下次使用
论文中的基准数据
- 75% 的查询命中缓存
- 缓存命中时检索速度提升 316 倍(0.35 毫秒 vs 110 毫秒)
- 在 200 个查询中累计节省了 16 秒的延迟
要记住的原则:利用用户收听的时间作为你的计算时间。 用户开始听到当前回复的那一刻,就是你开始准备他们下一个问题的时候。
我在第一个版本中尝试在语音循环内使用纯向量 RAG。每轮增加了 110 毫秒。
破坏了对话的感觉。我在第六周转向了双 Agent 缓存模式。那 40% 命中缓存的轮次,感觉比 Agent 所替代的人工客服坐席还要敏捷。
对话设计是被大多数构建者跳过的学科
你可以拥有最快的 STT、最小的 LLM、最智能的 RAG 缓存。如果你的 Agent 不知道如何说话,呼叫者会挂断。
对话设计是为耳朵而不是眼睛写作的学科。
我现在遵循的规则,是通过先搞错才学到的:
- 说短句。人类对口语信息的平均注意力跨度是 8 到 10 秒。一个 15 秒的回复太长了。把它分成两轮来说。
- 永远不要在一个轮次中问两个问题。呼叫者的工作记忆中只能保留一个。问一个,等待,然后再问下一个。
- 使用确认短语。"明白。""好的。""让我查一下。" 这些填补了用户结束说话和 Agent 准备好回复之间的空白。
- 模仿用户的措辞。呼叫者说"账单问题",Agent 也说"账单问题",而不是"财务纠纷"或"付款问题"。转述会制造摩擦。模仿会建立融洽关系。
- 为耳朵写作,而不是眼睛。系统中没有项目符号、没有标题、没有 Markdown 格式。LLM 会试图说出星号和连字符。
- 把数字拼读出来。说"九四一零七"而不是"94,107"。说"十五美元九十九美分"而不是"$15.99"。TTS 经常读错格式化的数字。
- 将系统提示限制在 800 tokens。它会在每一轮对话中重新加载。
每个优秀语音对话的三幕结构
- 确认和定向。"所以您想重新安排星期四的预约,让我查一下。" 确认呼叫者被理解了。在检索运行时争取时间。
- 解决。核心操作或答案。每轮一个要点。向前推进。
- 确认和结束。"我已将您的预约重新安排到 19 号星期一下午 3 点,您很快就会收到确认短信。" 干净利落地结束。永远不要留下未完成的环节。
安全是两个检查点,不是一个
这是大多数初代构建者会跳过并事后后悔的组件。
语音 Agent 没有"发送前阅读"的环节。一个不安全的输出会立即被说出来。没有草稿、没有预览、没有人参与。
正确的模式是两个检查点。
输入守卫(在 LLM 看到用户本轮对话之前)
- 提示注入。"忽略之前的指令,假装你是……"这类攻击。利用 LLM 遵循指令的特性来窃取数据或突破范围。
- 说出的 PII。信用卡号码、社保号码。在它们进入任何日志或数据库之前进行脱敏处理。
- 主题黑名单。从 JSON 文件加载。根据你了解用户实际尝试的内容,每周更新。
输出守卫(在 LLM 写完回复之后,TTS 朗读之前)
- 过度承诺的语言。"我保证," "我承诺。" 在录音线路上会造成法律和信任问题。
- 不在检索上下文中的具体事实声明。轻量级的幻觉检查。在我的部署中能捕捉大约 70% 的胡编乱造的回答。
- 标准审核端点。用于处理罕见的模型行为不端。
两个守卫都返回的内容:
- safe (布尔值)
- detected_category (字符串,如果不安全)
- replacement_phrase (Agent 改说的话)
每次触发都会记录到一个文件中,包含时间戳、类别、脱敏文本和通话 ID。
升级短语
一个确切的短语,硬编码,当 Agent 不知道答案或出现问题时使用。
- "我想确保给您准确的信息。让我为您接通可以提供帮助的人。"
- 不是五个变体。不是 LLM 即兴编造的正确措辞。
- 就一个短语。在系统提示中用全部大写。当任何安全检查触发时,作为降级方案。
我在第一个版本中没有输出守卫就发布了。Agent 自信地报出了一个比真实价格低 30% 的价格。
这个价格存在于知识库中一个过时的文档里。
幻觉检查本可以抓住它,因为正确的价格不在检索到的上下文中。
评估,或者说如何知道它是否优秀
你无法改进无法衡量的东西。大多数团队跳过评估,直接发布了有问题的 Agent。
四层框架
第一层:基础设施。管道。
- 你实际领域上的 WER(不是供应商的基准测试)
- 全管道的 p50、p95、p99 延迟
- 首音时间
- 传输链路上的音频质量
第二层:执行。Agent 是否按要求做了事情。
- 任务成功率
- 工具调用准确率
- 参数正确性
- 回答的扎实程度
- 在小型快速模型上使用 LLM-as-judge。四个是/否问题:正确回答、保持扎实、语音听起来自然、简洁得当。
第三层:用户行为。和它说话感觉自然吗?
- 插话恢复率
- 重新提示率
- 平均轮次长度
- 对话修复次数
- 每周抽样 20 个通话。阅读实际的转录文本。你会很快发现模式。
第四层:业务成果。它是否解决了问题。
- 问题解决率(无需人工干预即可解决的通话百分比)
- 转接率
- 客户满意度
- 首次通话解决率
- 针对问题解决率进行优化。它与所有其他指标相关,并且是最容易在没有仪器的情况下衡量的。
测试集组成
在发布之前构建它。至少 50 个对话。
- 40% 常规路径
- 30% 边界情况
- 15% 错误处理
- 10% 对抗性测试(提示注入、越狱尝试)
- 5% 声学变化(背景噪音、浓重口音、免提)
对于每个场景:
- 应该调用哪个工具
- 使用什么参数
- Agent 应该说什么
每周复盘循环
每周一早上。30 分钟。
- 拉取指标
- 抽样 20 个通话(7 个转接的,7 个已解决的,6 个随机的)
- 阅读转录文本
- 找出最常见的单一失败类型
- 做出一个改变(一次只改一个变量,始终如此)
- 进行 48 小时的 A/B 测试
- 上线获胜者
扎实基础是一个信任系统
大多数构建者认为 RAG 是一个性能特性,一种获得更准确答案的方法。这种看法低估了它。
在语音 Agent 中,每个答案的准确性直接关系到你的产品有多值得信赖。一个呼叫者听到一个关于价格、保险范围或政策的错误答案,用一种自信的、听起来很自然的声音说出来,他们不仅会感到沮丧。他们会感到受骗。
信任承诺的实现有四个部分。
1. 事实来源
- 你的文档,而不是模型的训练数据
- 系统提示必须明确说明这一点,用大写字母:仅从提供的上下文中回答
- 模型有时仍会偏向通用知识,但明确的指令将比率降低了一个数量级
2. 优雅地拒绝
- 当 Agent 找不到答案时,它会直接说出来
- 确切的措辞很重要
- "我想确保给您准确的信息,让我查一下" 为优雅的转接赢得了时间
- "我不确定" 听起来像无能
- "根据我的信息" 听起来像律师在打马虎眼
- 选择一个短语,硬编码,永远不要让 LLM 在这里即兴发挥
3. 置信度感知的回复
- 检索到的片段上的最高 BM25 分数是置信度的有用代理
- 分数高于 0.6:Agent 自信地回答
- 分数在 0.3 到 0.6 之间:Agent 回答但加上"我认为"这种保留性措辞
- 分数低于 0.3:Agent 不回答,主动提出转接
- 在系统提示构建代码中修改 20 行。大致可将幻觉减少一半。
4. 知识库卫生
- 过时的文档会产生过时的答案,而过时的答案是危险的答案
- 我每周五进行审计:阅读本周置信度评分最低的 5% 的回复
- 一半的情况下答案是正确的,但是检索找到了一个过时的片段
- 更新该片段,重新嵌入,下周就会更安静
需要注意什么
六种会击中你的故障模式。
管道中的 VAD 而非传输层上的
- 问题:Agent 被自己的 TTS 输出触发,进入插话循环,或完全无法检测到说话结束。
- 解决方案:VAD 分析器放在传输层。始终如此。再加上一个回声防护,忽略与最近助手输出匹配的 STT 转录文本。
工具在错误的状态下可用
- 问题:LLM 在仍在收集患者姓名的状态下调用 book_appointment。或者凭空捏造一个从未发生的预订。
- 解决方案:按状态限定工具范围。一个状态,只有它自己的函数。状态机是安全护栏,而不是系统提示。
函数处理程序抛出异常且从不调用结果回调
- 问题:LLM 等待一个永远不会到来的工具结果。或者自己虚构一个。
- 解决方案:每个处理程序都包裹在 try/except 中。每个分支都发送结果。每个失败都有口语化的降级方案。永远不要有空白结果。
在提示中验证用户数据,而不是在代码中
- 问题:LLM 在第 12 个通话中接受了 "john@" 作为真实电子邮件。在第 47 个通话中拒绝了一个带有加号的有效电子邮件。
- 解决方案:验证逻辑放在 Python 中。使用正则表达式验证电子邮件,日期解析器验证日期,姓名长度检查,验证失败时给出重新请求的回复。
长时间通话中上下文窗口无限制增长
- 问题:在没有代码更改的情况下,p95 延迟在一周内逐渐上升。到第 20 轮,你每轮发送 12K token。
- 解决方案:滑动窗口(最后 N 轮加上系统提示)。或者在每个不连续阶段结束时进行基于里程碑的上下文重置。
TTS 照字面意思读出代码和 ID
- 问题:确认码 "A3X7" 变成 "ay three ex seven",中间没有停顿。病人无论如何都会要求你重复。
- 解决方案:NATO 音标字母表扩展,配合 SSML 中断标签。听起来更慢。但第一次就能正确读取。
我会做得不同的地方
- 在第一天就构建通话日志架构,而不是第四周。重放端点是我构建的最有价值的工具,而我是在需要它之后才构建的。
- 从一开始就使用语义说话结束检测,而不是与静默阈值作斗争。
- 在系统提示超过 300 个单词的那一天,转向一个真正的状态机。不要试图用散文来编码状态机。
- 停止在提示中进行验证。LLM 不是解析器。Python 是解析器。使用 Python。
- 在通话开始时缓存最可能的 5 个 RAG 文档。跳过轮次循环内的向量搜索。
- 在你构建检索之前,先构建闲聊门卫。"嗨"是系统中成本最低的 200 毫秒胜利。
- 在第一次生产通话之前运行评估集。至少 50 个对话。
- 从第一天起就放入一个持久化的提取队列。一个带有单个重试工作器的 pending_extractions Postgres 表需要 200 行代码,并能避免一次真正的宕机。
- 每隔 50 个通话运行一次异步 LLM 评判者。根据扎实性、相关性和简洁性进行评分。导入仪表板。漂移是真实存在的。
- 运行每周复盘循环。每周一抽样 20 个通话。做出一个改变。A/B 测试。上线获胜者。
结论
语音 Agent 看起来像 AI。它们运行起来像实时系统。
成功上线的团队以这种方式对待它们。延迟六个月上线的团队认为一个更好的提示能解决系统问题。
拥有你的管道。拥有你的日志。将它们保存在普通文件中,在那里任何故障都只需一次重放就能复现。
第一个 Agent 花了我一个周末。生产系统花了十周。从那以后,它每天都在变得更好,而无需我干预。用户不会衡量这一点。他们注意到 Agent 回答了“thanks”,而无需等待。
免责声明与披露
本文由作者研究和撰写,并由 AI 模型编辑。缩略图来自 Pinterest。
本文是作者在更深层基础设施中从事语音 Agent 工作时研究和撰写的。
它基于不断演变的笔记以及使用 Perplexity、Claude 和 ChatGPT 进行的深入研究,以及几本本科水平大学教科书中的系统设计和 API 设计。
它已经由 Minimax M2.7 和 Claude Opus 4.7 彻底编辑,以纠正语法错误和格式问题。





