VoiceXML(Voice Extensible Markup Language)是一套由W3C制定的、基于XML的标记语言,专门用来描述语音对话系统与用户之间的交互流程。它把传统需要编写大量音频采集、识别、合成代码的复杂工作,抽象成一份结构化的XML文档。语音平台加载这份文档后,会按其中的节点顺序播报提示、识别用户语音或按键、填充变量并控制跳转,从而让开发者用声明式的方式开发电话银行、信息查询等语音应用。

VoiceXML的核心概念
在VoiceXML里,最外层的<vxml>标签代表一个完整的对话应用文档,其内部由若干个<form>组成。每个<form>可以理解为一个带有输入输出的交互页面,类似于Web开发里的表单。表单中通过<field>定义需要向用户收集的数据项,例如姓名、账号或选择项。
除了表单,VoiceXML还提供<menu>用于简单的语音菜单选择,以及<block>用于执行不需要用户输入的纯提示或逻辑。整个对话依靠平台内部的解释器驱动,开发者只需关心业务节点如何串联,不用处理音频流和识别引擎的底层接口。
用XML描述一次语音交互
下面是一段最小可用的VoiceXML示例,它向用户播报欢迎语,然后询问并识别其选择的业务类型,最后根据选择跳转到不同提示。注意其中所有XML特殊字符都按规范书写,标签均为VoiceXML标准元素。
<?xml version="1.0" encoding="UTF-8"?>
<vxml version="2.1" xmlns="http://www.w3.org/2001/vxml">
<form>
<block>
<prompt>欢迎致电语音服务,请说出您要办理的业务。</prompt>
</block>
<field name="service" type="grammar">
<grammar src="#services"/>
<prompt>您可以这样说:查余额,或办卡。</prompt>
<catch event="noinput">
<prompt>没有听到您的声音,请再说一次。</prompt>
<reprompt/>
</catch>
</field>
<block>
<if cond="service == 'balance'">
<prompt>正在为您查询余额。</prompt>
<elseif cond="service == 'card'"/>
<prompt>正在为您转接办卡专员。</prompt>
<else/>
<prompt>未能识别您的请求。</prompt>
</if>
</block>
</form>
<grammar id="services">
<item>查余额<tag>balance</tag></item>
<item>办卡<tag>card</tag></item>
</grammar>
</vxml>
上面的代码展示了VoiceXML如何使用XML节点表达交互:<prompt>负责语音合成播报,<field>结合<grammar>约束用户可说的词,<catch>捕获无输入事件并重试。逻辑判断使用<if>系列标签,完全声明在XML中。
这种写法的好处是业务人员也能通过阅读XML结构理解流程,开发与运维分离。当识别引擎升级时,只要平台兼容VoiceXML标准,文档无需重写。对比直接用Python调用语音SDK写状态机,VoiceXML显著降低了语音应用的迭代成本。
VoiceXML与底层语音引擎的协作
VoiceXML文档本身不包含声学模型或识别算法,它依赖支持VoiceXML的解释器(如开源的Vxi*或商业呼叫中心平台)。解释器一边解析XML,一边调用背后的语音识别(ASR)与语音合成(TTS)模块。比如当解释器遇到<prompt>,就把文本送给TTS生成音频;遇到<field>就开启麦克风并送入ASR,将识别结果填回变量。
这种分层让开发者用统一XML描述跨厂商设备。你在一个平台写的VoiceXML,理论上可迁移到另一个合规平台。实际中需注意不同平台对VoiceXML版本和扩展标签的支持差异,例如某些平台自定义了<record>的额外属性,移植时要做兼容处理。
开发语音应用的一般步骤
使用VoiceXML开发,通常先梳理对话流程,画出状态节点;再用XML写出对应<form>与<field>,为每个收集项定义语法或内置类型;随后在本地用模拟器调试提示与识别;最后部署到语音网关。下面给出一个带外部语法的字段示例,展示如何引用独立SRGS语法文件。
<?xml version="1.0" encoding="UTF-8"?>
<vxml version="2.1" xmlns="http://www.w3.org/2001/vxml">
<form>
<field name="city">
<prompt>请说出您所在的城市。</prompt>
<grammar mode="voice" type="application/srgs+xml" src="city.grxml"/>
<filled>
<prompt>您选择的城市是 <value expr="city"/>。</prompt>
</filled>
</field>
</form>
</vxml>
在上面的片段中,<grammar>的src指向独立的SRGS语法文档,使识别词表可动态维护。当用户输入被成功识别,<filled>区块会被触发,用<value>读出变量内容。这样的结构让语音交互像拼装XML积木一样清晰。
总体来看,VoiceXML以XML为骨架,把语音应用的界面、逻辑与数据收集声明化。它不适合需要自由闲聊的场景,但在确定性高的自助服务里,是用XML高效开发语音交互的成熟方案。