Voice agent cho tổng đài: chia ngân sách 500ms, xử lý ngắt lời và chuyển máy cho người
Pipeline STT→LLM→TTS mẫu của Twilio mất khoảng 1,1 giây, hơn gấp đôi mục tiêu 500ms. Kể cả khi agent trả lời đúng, khách vẫn bực nếu nó tranh lời hoặc chuyển máy vụng về.
Tóm tắt nhanh
- Pipeline cascaded mẫu của Twilio mất khoảng 1,1 giây mouth-to-ear. Future AGI đặt mục tiêu cho agent bán hàng và hỗ trợ là trung bình dưới 350ms, P95 ở mức 500ms.
- Với barge-in, ngắt nhầm còn tệ hơn ngắt chậm một chút. Hãy chọn chế độ turn detection trước khi chỉnh bất kỳ tham số nào khác.
- Cold transfer đóng phiên của người gọi. Warm transfer cho agent tóm tắt ngữ cảnh cho người quản lý trước khi nối máy.
Không phải chặng nào cũng phải thu hẹp: TTS 100ms của Twilio đã nằm trong ngân sách, phần dư nằm ở LLM, STT và đường ống quanh model.
Đồ hoạ: FDE Times
Hãy hình dung buổi demo diễn ra trong phòng họp yên tĩnh và mọi thứ đều ổn. Một tuần sau, agent lên tổng đài thật. Người gọi nói xong thì gặp một khoảng lặng dài, phải hỏi lại “alo, có ai không?”.
Họ vừa ho một tiếng thì agent im bặt. Họ xin gặp nhân viên thì cuộc gọi bị chuyển đi và họ phải kể lại mọi chuyện từ đầu.
Không lỗi nào trong số đó nằm ở chất lượng câu trả lời. Chúng là lỗi về thời gian và về cách nhường lời, đúng phần việc mà FDE phải làm tại chỗ khách hàng.
Twilio nói thẳng rằng độ trễ là ràng buộc định hình cả thiết kế voice agent. Ba lỗi ở trên tương ứng với ba kỹ năng cần luyện: chia ngân sách độ trễ, xử lý ngắt lời và chuyển máy cho người.
Nửa giây là con số phải chia cho từng chặng
Con số cần nhớ là mouth-to-ear, tức thời gian từ lúc người gọi ngừng nói đến lúc họ nghe được âm thanh đầu tiên của agent. Một hướng dẫn của Future AGI đặt mục tiêu làm việc cho agent bán hàng và hỗ trợ là trung bình dưới 350ms, P95 ở mức 500ms.
Chữ P95 quan trọng hơn chữ trung bình. Trung bình 300ms nghe rất ổn, nhưng nếu cứ 20 lượt có một lượt mất 1,2 giây thì khách vẫn nhớ đúng lượt đó. Vì thế ngay từ ngày đầu, báo cáo gửi khách nên có cả trung bình lẫn percentile.
Cộng thử một lượt: 1,1 giây đến từ đâu?
Twilio dựng một pipeline cascaded mẫu gồm STT, LLM và TTS, ra tổng khoảng 1,1 giây (1.115ms) mouth-to-ear. Họ chia ngân sách thành STT 350ms, LLM 375ms (tính đến token đầu tiên, TTFT) và TTS 100ms (tính đến byte đầu tiên, TTFB), đồng thời nói rõ đây chỉ là mốc xuất phát.
Cộng ba chặng lại được 825ms. Khoảng 290ms còn lại rơi vào những chỗ ít ai để ý: mạng, mã hóa lại audio, buffer. Bài học thứ nhất là đừng chỉ đo model. Một phần tư độ trễ có thể nằm ở đường ống bao quanh nó.
Giờ đặt cạnh bảng ngân sách 500ms ở P95 mà Future AGI đề xuất. Đây là bài của một vendor, nên chỉ nên coi các con số là mốc tham khảo:
| Chặng | Ngân sách 500ms (P95) | Ghi chú |
|---|---|---|
| Mạng | 30–50ms | Đặt server gần người gọi |
| STT, partial đầu tiên | 100–150ms | Lấy kết quả tạm, không chờ câu hoàn chỉnh |
| LLM TTFT | 200–300ms | Dùng prefix caching |
| TTS, audio đầu tiên | 80–150ms | Dùng provider có streaming |
| Orchestration và guardrail | 50–100ms | Gồm kiểm tra inline |
Hãy làm phép cộng. Lấy cận dưới mọi chặng được 460ms, vừa lọt dưới 500ms. Lấy cận trên mọi chặng được 750ms, vượt xa mục tiêu.
Nghĩa là bạn không thể để mọi chặng cùng chạm cận trên. Bốn chặng ngoài LLM, ở cận dưới, đã tốn 260ms, nên LLM chỉ còn tối đa 240ms. Nếu LLM của khách bắt buộc chạy 300ms vì lý do bảo mật, tổng đã là 560ms dù mọi chặng khác đạt mức tốt nhất trong bảng.
Khi đó phải đẩy một chặng xuống dưới mức trong bảng, chẳng hạn chuyển guardrail inline sang chạy song song, hoặc thương lượng lại mục tiêu với khách. Ngân sách là một bài toán đánh đổi, không phải danh sách để tick. Cũng lưu ý rằng cộng P95 của từng chặng chỉ cho một ước lượng thận trọng, vì các lượt chậm hiếm khi rơi cùng lúc vào mọi chặng.
Việc đầu tiên tại khách hàng vì thế rất đơn giản: ghi timestamp ở mọi ranh giới chặng. Nên ghi riêng cả mốc partial đầu tiên lẫn mốc transcript cuối, vì hai mốc này đo hai thứ khác nhau, và bạn cần biết pipeline của khách đưa mốc nào cho LLM. Đoạn mã giả dưới đây đủ để bắt đầu:
# mỗi lượt hội thoại ghi lại các mốc thời gian (ms)
turn = {
"user_end": t0, # VAD báo người gọi ngừng nói
"stt_first_partial": t1,
"stt_final": t2, # transcript cuối
"llm_first_token": t3,
"tts_first_byte": t4,
"audio_played": t5, # đo phía người gọi nếu được
}
stages = {
"stt_partial": t1 - t0,
"stt_final": t2 - t0,
"llm_ttft": t3 - t2, # đổi mốc gốc thành t1 nếu pipeline gửi partial cho LLM
"tts": t4 - t3,
"mang_va_buffer": t5 - t4,
"tong": t5 - t0,
}
# gom 50-100 lượt, tính mean và p95 cho từng chặng
Ngắt lời: chọn cách nhận lượt trước, chỉnh độ nhạy sau
LiveKit định nghĩa xử lý ngắt lời là quyết định agent sẽ làm gì khi người dùng bắt đầu nói đè lên nó. Trước đó còn một quyết định lớn hơn: chế độ turn detection, tức cách hệ thống biết người gọi đã nói xong. Tài liệu của LiveKit khuyên chốt chế độ này trước tiên, vì nó quyết định các tham số khác có còn áp dụng hay không.
Nếu làm ngược lại, bạn có thể ngồi chỉnh ngưỡng VAD hàng giờ, rồi đổi chế độ turn detection và phát hiện một phần các tham số vừa chỉnh không còn tác dụng.
Với barge-in, một bài hướng dẫn khác của Future AGI đặt ngân sách: TTS phải dừng trong vòng 60ms, và tổng thời gian đến lúc bộ đệm TTS được xóa sạch phải dưới 150ms. Bài không dẫn benchmark độc lập nào, nên đây cũng chỉ là mốc tham khảo.
Cùng tác giả đó nhấn mạnh rằng ngắt nhầm còn tệ hơn ngắt chậm một chút, và đặt mục tiêu tỷ lệ false barge-in dưới 2%.
LiveKit gọi trường hợp này là false interruption: VAD nghe thấy tiếng, làm agent dừng lại, nhưng không có transcript nào xuất hiện. Thủ phạm thường là tiếng ho hoặc tiếng ồn nền. Mặc định, agent sẽ chờ một chút rồi nói tiếp.
Với tổng đài, đây là chỗ cần thử ngoài hiện trường. Người gọi đứng ngoài đường, gọi từ chợ, trong xe máy, hay chen “dạ”, “vâng” khi agent đang đọc số hợp đồng. Hãy thu vài chục cuộc gọi trong điều kiện ồn thật rồi đếm số lần dừng nhầm, đừng chỉnh độ nhạy dựa trên cảm giác trong phòng họp.
Chuyển cho người: nguội hay ấm?
Sẽ luôn có cuộc gọi agent không nên tự xử lý. Câu hỏi là chuyển máy theo cách nào.
Cold transfer
- Dùng SIP REFER để chuyển cuộc gọi đi
- Phiên LiveKit của người gọi bị đóng lại
- Trunk của nhà mạng phải được cấu hình cho phép chuyển cuộc gọi
Warm transfer có agent hỗ trợ
- Người gọi được đặt ở chế độ chờ
- Người quản lý được gọi vào phòng tham vấn riêng
- Agent tóm tắt ngữ cảnh rồi mới nối máy
Cold transfer phù hợp khi chỉ cần đưa cuộc gọi đến đúng phòng ban, chẳng hạn bộ phận kế toán. Khi khách đang bực hoặc vấn đề phức tạp, warm transfer gần như luôn đáng thêm vài giây chờ. LiveKit khuyến nghị dùng task warm transfer dựng sẵn cho hầu hết trường hợp thay vì tự viết.
Phần FDE thực sự phải thiết kế là nội dung tóm tắt. Thử hình dung agent nói với nhân viên trong phòng tham vấn:
“Khách là chị Lan, gọi lần thứ hai về đơn hàng giao trễ. Chị đã xác minh số điện thoại và muốn hủy đơn để được hoàn tiền. Chị đang khá bực vì lần trước phải chờ lâu.”
Ba câu này trả lời ba câu hỏi: ai đang gọi, đã làm được gì, cần gì tiếp theo.
Các bước khi bắt tay vào làm
Hãy đo trước khi tối ưu: đặt timestamp ở mọi chặng, gom ít nhất vài chục lượt, rồi báo cáo cả trung bình lẫn P95. Sau đó đối chiếu với bảng ngân sách và tìm chặng đang vượt nhiều nhất. Đó thường là chỗ đáng sửa đầu tiên.
Tiếp theo, chốt chế độ turn detection cùng đội của khách, rồi mới chỉnh barge-in bằng audio thật từ tổng đài. Cuối cùng, ngồi với trưởng nhóm tổng đài để vẽ ra những tình huống phải chuyển cho người, quyết định tình huống nào dùng cold transfer, tình huống nào dùng warm transfer, và viết mẫu tóm tắt cùng họ.
Những lỗi hay gặp
Lỗi đầu tiên là chỉ báo cáo độ trễ trung bình và chỉ đo phần model, bỏ quên mạng và buffer. Lỗi thứ hai là chỉnh barge-in quá nhạy để agent “dừng thật nhanh”, rồi agent dừng mỗi khi có xe máy chạy qua.
Lỗi thứ ba là dùng cold transfer cho mọi trường hợp, buộc khách phải kể lại từ đầu, hoặc tự viết luồng warm transfer khi đã có sẵn task dựng sẵn.
Nếu bạn đang chuẩn bị ứng tuyển vị trí FDE, ba kỹ năng trong bài này kể được bằng số. Trên CV, viết cụ thể kiểu “giảm P95 mouth-to-ear từ X xuống Y bằng streaming TTS và prefix caching” sẽ thuyết phục hơn nhiều so với “xây dựng voice agent”.
Bài tập: cộng ngân sách cho một khách cụ thể
Giả sử khách cho biết LLM của họ có TTFT ở P95 là 220ms. Lấy 500ms trừ 220ms, còn 280ms cho mạng, STT, TTS và orchestration. Cận dưới của bốn chặng này trong bảng là 30, 100, 80 và 50ms, cộng lại 260ms.
Vậy bạn chỉ còn 20ms dư cho cả bốn chặng. Câu hỏi để mang đến buổi họp đầu tiên: chặng nào trong pipeline hiện tại của khách đang vượt cận dưới nhiều nhất, và có thể thay provider hay đổi vị trí server để lấy lại phần đó không? Làm lại phép tính với con số thật của khách trước khi hứa bất kỳ mục tiêu độ trễ nào.
Người gọi tổng đài không chấm điểm độ thông minh của model. Họ chỉ nhớ agent có để họ chờ không, có tranh lời không, và khi cần thì có chuyển họ cho người đã nắm sẵn câu chuyện không.
Bài này có hữu ích không?
Cảm ơn bạn đã góp ý!
6 nguồn
- A Guide to Core Latency in AI Voice Agents (Cascaded Edition) · 2025-11-17
- Sub-500ms Voice AI: The Complete Latency Budget Guide for 2026 · 2026-03-12
- Configuring turn detection and interruptions in LiveKit Agents · 2026-06-30
- Voice AI Barge-In and Turn-Taking: A 2026 Implementation Guide · 2026-02-19
- LiveKit docs: Telephony › Transfers › Call forwarding
- LiveKit docs: Telephony › Transfers › Agent-assisted warm transfer