跳转到正文
OrbZ指南语音助手

语音与对话运行时

连接时 Orbz 保持静音。在 @neongate-ai/orbz@1.0.3 中,包不提供问候语、角色或对话:talk 是冻结的空对象,DEFAULT_TALK_FLOW 是冻结的空数组。宿主通过 speech 提供单句或通过有类型的 talkFlow 提供对话,配置语音引擎,并且仅在用户明确操作后启动。

speech 优先于 talkFlow。两者都未提供时,startTalking() 不执行操作。启动非空对话流程会重置运行时上下文;宿主调用 receive() 时,ask 步骤将输入保存到其 capture 键,后续步骤可插值使用。此上下文不会持久保存到 cookie、本地存储、IndexedDB 或后端。

内置对话数据

import { DEFAULT_TALK_FLOW, talk } from "@neongate-ai/orbz"; console.log(talk); // {} console.log(DEFAULT_TALK_FLOW); // []

继续流程

下方自定义流程启动并到达 ask 步骤后,将用户提交的输入传给 receive()。fullName 键来自示例声明的 capture: "fullName",并非内置对话数据。

import "@neongate-ai/orbz/browser"; import type { OrbzElement } from "@neongate-ai/orbz"; const orb = document.querySelector<OrbzElement>("orb-z"); await orb?.receive("Jonatas"); console.log(orb?.talkContext.fullName);

浏览器英语语音

已安装包中的 WebSpeechAdapter 默认使用 pt-BR。示例句子是英语,因此显式选择 en-US。其他语言应同时设置宿主提供的文本与适配器语言。适配器等待异步语音列表,并对符合请求语言的声音排序;可用声音仍取决于访客环境。

import '@neongate-ai/orbz/browser' import { WebSpeechAdapter, type OrbzElement } from "@neongate-ai/orbz"; const orb = document.createElement("orb-z") as OrbzElement; orb.speech = "Hello. This is an explicit speech example."; orb.voiceEngine = new WebSpeechAdapter({ language: "en-US", preferredVoices: ["Google US English", "Microsoft Aria Online"] }); document.body.append(orb); const startVoiceButton = document.querySelector<HTMLButtonElement>("[data-start-voice]"); startVoiceButton?.addEventListener("click", async () => { await orb.startTalking(); });

实际安装的语音仍取决于访客的浏览器和操作系统。WebSpeechAdapter 能改善选择过程,但无法将系统语音变为 OpenAI 语音。

OpenAI 品质的语音

在 1.0.3 中,OpenAISpeechAdapter 默认使用 gpt-4o-mini-tts、marin、MP3 和巴西葡萄牙语朗读指令。本英语示例覆盖 instructions,使其与宿主文本一致。应用必须实现并保护示例端点。

import '@neongate-ai/orbz/browser' import { OpenAISpeechAdapter, type OrbzElement } from "@neongate-ai/orbz"; const orb = document.createElement("orb-z") as OrbzElement; orb.speech = "Hello. This is an explicit speech example."; orb.voiceEngine = new OpenAISpeechAdapter({ endpoint: "/api/orbz/speech", instructions: "Speak in natural American English. Do not change the supplied text." }); document.body.append(orb); const startVoiceButton = document.querySelector<HTMLButtonElement>("[data-start-voice]"); startVoiceButton?.addEventListener("click", async () => { await orb.startTalking(); });

端点由实现集成的应用负责。它接收兼容 OpenAI 的 JSON 请求体,其中包含 input、instructions、model、response_format 和 voice,并返回生成的音频响应。将 OpenAI API 密钥保留在该服务端端点中;切勿将其放入浏览器代码或 npm 软件包。

使用生成语音的应用应明确告知用户,该语音由 AI 生成。

显式激活与浏览器策略

渲染一个具有明确标签(例如启动语音)的原生 <button>,然后在其点击处理函数中调用 startTalking()。连接球体、设置语音引擎或进入页面都不会开始播放音频。

如果浏览器仍以 NotAllowedError 拒绝所请求的音频,Orbz 会携带原始错误分发 orbz-talk-error,并在下一次指针、键盘或触摸交互后重试请求的流程。重置控件不应仅为了允许语音播放而重新挂载元素。

提供自定义流程

import "@neongate-ai/orbz/browser"; import { WebSpeechAdapter, type OrbzElement, type OrbzTalkStep } from "@neongate-ai/orbz"; const flow = [ { id: "welcome", kind: "say", needsAuth: false, text: "Hello." }, { id: "name", kind: "ask", needsAuth: false, text: "What is your name?", capture: "fullName" }, { id: "help", kind: "say", needsAuth: false, text: "How can I help, {{fullName}}?" }, { id: "answer", kind: "respond", needsAuth: false, strategy: "openai", fallback: "I cannot answer that right now." } ] as const satisfies readonly OrbzTalkStep[]; const orb = document.createElement("orb-z") as OrbzElement; orb.talkFlow = flow; orb.voiceEngine = new WebSpeechAdapter({ language: "en-US" }); document.body.append(orb); const startVoiceButton = document.querySelector<HTMLButtonElement>("[data-start-voice]"); startVoiceButton?.addEventListener("click", async () => { await orb.startTalking(); });

在调用 startTalking() 之前设置 voiceEngine、talkFlow 和 intelligence,以便显式启动的这次运行使用它们。

可选的智能能力

import type { OrbzElement, OrbzIntelligencePort } from "@neongate-ai/orbz"; const intelligence: OrbzIntelligencePort = { async respond(input, context) { return productAgent.respond({ context, input }); } }; orb.intelligence = intelligence;

事件与视觉状态

播放音频期间,Orbz 临时使用 speaking 视觉状态,随后恢复此前的状态。

事件详情
orbz-speaking-change{ speaking: boolean }
orbz-talk-error{ error: unknown }

以上文本转语音流程不采集麦克风。宿主负责输入控件、权限、转录、产品逻辑和 receive() 调用。Orbz 另有独立的 Realtime 对话 API,这些 startTalking() 示例不会启动它。

最近更新于