通过 VAD、Backchanneling 和 Sentiment Routing 提升 CSAT
Source: Dev.to
TL;DR
大多数语音 AI 代理的 CSAT(客户满意度)得分低,因为它们会在用户说话中途打断,或错过情绪线索。
解决方案:
- Voice Activity Detection (VAD) 防止错误的轮流发言。
- Backchanneling(“嗯‑嗯”、 “我明白”)在不打断的情况下表达积极倾听。
- Sentiment routing 在用户情绪失控前将其升级给人工客服。
使用 VAPI 的 VAD 配置 + Twilio 的呼叫路由实现。
结果: 40 % 的升级次数下降,CSAT 提升 25 %。没有废话——仅是可直接投入生产的模式。
前置条件
API 访问
- VAPI API 密钥(来自
dashboard.vapi.ai) - Twilio Account SID + Auth Token(console.twilio.com)
- 已启用语音功能的 Twilio 电话号码
技术要求
- Node.js 18+(支持 async/await 与原生 fetch)
- 用于 webhook 的公网 HTTPS 端点(例如本地开发时使用 ngrok)
- SSL 证书(Twilio 不接受 HTTP webhook)
系统依赖
- 每个并发通话最低 512 MB RAM(VAD 处理开销)
flowchart TD
B[VAD Detection] --> C{Silence > 800ms?}
C -->|Yes| D[Inject Backchannel]
C -->|No| E[Continue Listening]
D --> F[Sentiment Analysis]
E --> F
F --> G{Score}
G -->|Yes| H[Route to Human]
G -->|No| I[AI Response]
VAD 会在每个音频块上触发。你的 webhook 会收到带有部分转录的 speech-update 事件。情感分析仅在 完整 语句上运行——分析 “I’m fru…” 会产生误报。
实时情感路由
关键点:一个 webhook 处理器实时分析情感,并在对话失控前触发路由 before 对话偏离。
const express = require('express');
const app = express();
function analyzeSentiment(transcript) {
const negativeKeywords = {
'frustrated': -0.3,
'angry': -0.5,
'terrible': -0.4,
'useless': -0.6,
'cancel': -0.7,
'manager': -0.8
};
let score = 0;
const words = transcript.toLowerCase().split(' ');
words.forEach(word => {
if (negativeKeywords[word]) score += negativeKeywords[word];
});
return Math.max(score, -1.0); // Cap at -1.0
}
app.post('/webhook/vapi', async (req, res) => {
const { message } = req.body;
if (message.type === 'transcript' && message.transcriptType === 'final') {
const sentiment = analyzeSentiment(message.transcript);
// Inject backchannel if user paused mid‑sentence
if (message.silenceDuration > 800 && sentiment > -0.3) {
return res.json({
action: 'inject-message',
message: 'mm-hmm' // Non‑verbal acknowledgment
});
}
// Route to human if sentiment tanks
if (sentiment <= -0.5) {
return res.json({
action: 'transfer',
target: 'human_agent'
});
}
}
res.sendStatus(200);
});
sequenceDiagram
participant VAPI
participant User
participant Webhook
participant Server
VAPI->>User: Plays welcome message
User->>VAPI: Provides input
VAPI->>Webhook: transcript.final event
Webhook->>Server: POST /webhook/vapi with user data
alt Valid data
Server->>VAPI: Update call config with new instructions
VAPI->>User: Provides response based on input
else Invalid data
Server->>VAPI: Send error message
VAPI->>User: Error handling message
end
Note over User,VAPI: Call continues or ends based on user interaction
User->>VAPI: Ends call
VAPI->>Webhook: call.completed event
Webhook->>Server: Log call completion
测试与验证
本地测试
使用 VAPI CLI 搭配 ngrok 本地测试 webhook。这可以捕获约 80 % 的集成错误,避免直接上生产。
# Terminal 1: Start your Express server
node server.js # runs on port 3000
# Terminal 2: Forward webhooks to local server
npx @vapi-ai/cli webhook forward --port 3000
// Example snippet inside server.js for local testing
app.post('/webhook/vapi', async (req, res) => {
const { message } = req.body;
if (message?.type === 'transcript') {
const sentiment = analyzeSentiment(message.transcript);
console.log(`[TEST] Transcript: "${message.transcript}"`);
console.log(`[TEST] Sentiment Score: ${sentiment}`);
// Add any additional debug actions here
}
res.sendStatus(200);
});
运行上述代码,通过 CLI 发送示例转录,并验证:
- 只有在配置的静默窗口后才会注入回声(Backchannel)。
- 当情感分数低于升级阈值时,通话会被转接。
- 不会出现竞争条件(服务器日志应显示每条转录只执行一次操作)。
完成本地验证后,将 webhook 部署到生产环境的 HTTPS 端点,更新 Twilio Voice webhook URL,并实时监控关键指标(升级率、平均 CSAT、延迟)。