語音代理正在改變客戶支援、旅遊、金融和零售產業——提供免持、對話式的體驗,感覺就像真人互動。但要發揮用處,語音代理需要即時且相關的網路資料(例如航班狀態、股票價格、產品庫存),才能避免給予過時或籠統的回應。LiveKit 為低延遲語音通訊提供基礎架構,而 IPFLY 的優質代理解決方案(遍佈 190 多個國家的 9000 多萬個全球 IP、靜態/動態住宅代理及資料中心代理)則解決了關鍵瓶頸:不受限制地存取即時網路資料。
本指南將逐步帶您使用 LiveKit(用於語音串流)、OpenAI Whisper(用於語音轉文字)、TTS(用於文字轉語音)和 IPFLY(用於網路資料擷取)來建構即時語音代理。您將學習如何整合 IPFLY 來爬取即時資料、繞過地理限制,並確保您的語音代理提供準確且富含情境的回應——無論使用者詢問的是本地天氣、全球股市趨勢或產品庫存。

語音代理、LiveKit 與 IPFLY 角色簡介
什麼是語音代理?
語音代理(或語音機器人)使用自然語言處理(NLP)和語音識別技術,透過語音與使用者互動。與聊天機器人不同,它們以即時方式運作——需要即時存取即時資料來回答問題,例如:
- 「比特幣目前的價格是多少?」
- 「我飛往巴黎的航班延誤了嗎?」
- 「你們有新款無線耳機的庫存嗎?」
為何選擇 LiveKit?
LiveKit 是即時語音代理的骨幹:它提供可擴展、低延遲的 WebRTC 語音串流、房間管理和音訊處理功能——對於流暢、無延遲的對話至關重要。
- 低延遲:確保語音串流以毫秒級處理——對於自然對話至關重要。
- 可擴展性:支援數千個併發語音工作階段(非常適合企業部署)。
- 靈活性:可與 NLP 工具(Whisper、ChatGPT)、TTS 引擎和自訂資料來源整合。
- 可靠性:為生產環境而建,內建容錯機制和全球邊緣節點。
為何選擇 IPFLY?
LiveKit 能實現語音串流,但語音代理需要即時網路資料才能運作。IPFLY 解決了最大的資料存取挑戰:
- 地理限制:使用 IPFLY 遍佈 190 多個國家的 IP 池存取特定地區的資料(例如英國火車時刻表、日本零售價格)。
- 反爬蟲封鎖:動態住宅代理模仿真實使用者,避免在航空、電商或加密貨幣網站(如 Amazon、Delta、CoinGecko)上被封鎖。
- 速度:資料中心代理為時間敏感的查詢(例如股票價格、體育比分)提供低延遲資料擷取。
- 一致性:99.9% 的正常運作時間和多層 IP 過濾確保您的代理在關鍵對話中絕不會在擷取資料時失敗。
LiveKit 與 IPFLY 共同打造強大的技術堆疊:LiveKit 處理語音互動,而 IPFLY 則以即時網路資料為其提供動力,使回應更具實用性。
先決條件
在建構語音代理之前,請確保您已備妥:
- Python 3.10+(用於後端邏輯)
- LiveKit 帳戶(有免費方案;請在此註冊)
- LiveKit Server SDK(用於房間管理)和 Client SDK(用於語音串流)
- OpenAI API 金鑰(用於 Whisper API 和 TTS;請在此取得)
- IPFLY 帳戶(含 API 金鑰、代理端點,以及動態住宅代理的存取權限)
- 對 WebRTC、Python 和 REST API 的基本熟悉度
安裝必要的相依套件:
pip install livekit-server-sdk livekit-client openai requests python-dotenv
逐步指南:使用 LiveKit 與 IPFLY 建構即時語音代理
我們將建構一個以旅遊為主的語音代理,它能夠:
- 透過 LiveKit 串流語音(使用者提出如「Delta 航班 DL123 是否延誤?」的查詢)
- 使用 OpenAI Whisper 將語音轉換為文字
- 使用 IPFLY 代理從 Delta 網站爬取即時航班資料
- 使用 OpenAI TTS 生成自然回應
- 透過 LiveKit 將回應串流回傳給使用者
步驟 1:設定 LiveKit 專案
- 登入您的 LiveKit 帳戶並建立新專案(例如「TravelVoiceAgent」)
- 前往「專案設定」→「API 金鑰」,產生 Server API Key 和 Secret(安全地儲存這些資訊——它們將用於驗證您的後端與 LiveKit)
- 記下您的 LiveKit 伺服器 URL(例如
wss://project-xyz.livekit.cloud)
步驟 2:設定 IPFLY 代理以進行即時資料擷取
IPFLY 將為代理的航班資料爬取提供動力。設定方式如下:
- 登入您的 IPFLY 帳戶並取得:
- 代理端點(例如
http://[USERNAME]:[PASSWORD]@proxy.ipfly.com:8080) - API 金鑰(用於代理管理)
- 代理端點(例如
- 對於旅遊資料(例如 Delta 航班狀態),使用動態住宅代理——它們模仿真實使用者,避免在航空公司網站上被封鎖
建立 .env 檔案以安全地儲存憑證:
env
LIVEKIT_API_KEY="<YOUR_LIVEKIT_API_KEY>"
LIVEKIT_API_SECRET="<YOUR_LIVEKIT_API_SECRET>"
LIVEKIT_SERVER_URL="wss://<YOUR_LIVEKIT_PROJECT>.livekit.cloud"
OPENAI_API_KEY="<YOUR_OPENAI_API_KEY>"
IPFLY_PROXY_ENDPOINT="http://[USERNAME]:[PASSWORD]@proxy.ipfly.com:8080"
IPFLY_API_KEY="<YOUR_IPFLY_API_KEY>"
步驟 3:建構後端(LiveKit + Whisper + IPFLY)
建立 voice_agent_backend.py 檔案來處理語音串流、語音轉文字、資料擷取和文字轉語音。
步驟 3.1:初始化相依套件並載入環境變數
Python
import os
import json
import requests
from dotenv import load_dotenv
from bs4 import BeautifulSoup
from livekit import RoomServiceClient, AccessToken
from livekit.rtc import RoomEvent, ParticipantEvent
from openai import OpenAI
# Load environment variables
load_dotenv()
# Initialize clients
livekit_client = RoomServiceClient(
url=os.getenv("LIVEKIT_SERVER_URL"),
api_key=os.getenv("LIVEKIT_API_KEY"),
api_secret=os.getenv("LIVEKIT_API_SECRET")
)
openai_client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
IPFLY_PROXY = {"http": os.getenv("IPFLY_PROXY_ENDPOINT"), "https": os.getenv("IPFLY_PROXY_ENDPOINT")}
步驟 3.2:建立 IPFLY 資料擷取工具(航班狀態爬蟲)
新增使用 IPFLY 代理爬取即時航班狀態的函式:
Python
def get_flight_status(airline: str, flight_number: str) -> str:
"""Scrape live flight status using IPFLY proxies (Delta example)."""
# Delta flight status URL (customize for other airlines)
url = f"https://www.delta.com/en-us/flights/status?flightNumber={flight_number}&date=today"
headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"}
try:
# Send request with IPFLY proxy to avoid blocks
response = requests.get(
url,
proxies=IPFLY_PROXY,
headers=headers,
timeout=15 # Low timeout for real-time voice agent
)
response.raise_for_status()
# Parse flight status (customize selector for target airline)
soup = BeautifulSoup(response.text, "html.parser")
status_element = soup.find("div", class_="flight-status-value")
departure_time = soup.find("div", class_="departure-time").get_text(strip=True) if soup.find("div", class_="departure-time") else "N/A"
arrival_time = soup.find("div", class_="arrival-time").get_text(strip=True) if soup.find("div", class_="arrival-time") else "N/A"
if status_element:
status = status_element.get_text(strip=True)
return f"Flight {airline} {flight_number} status: {status}. Departure: {departure_time}. Arrival: {arrival_time}."
else:
return f"Could not retrieve status for flight {airline} {flight_number}."
except Exception as e:
return f"Error fetching flight status: {str(e)}"
步驟 3.3:新增語音轉文字(Whisper)與文字轉語音(TTS)功能
新增將使用者語音轉換為文字以及將代理回應轉換為語音的函式:
Python
def voice_to_text(audio_data: bytes) -> str:
"""Convert audio from LiveKit to text using OpenAI Whisper."""
with open("temp_audio.wav", "wb") as f:
f.write(audio_data)
response = openai_client.audio.transcriptions.create(
model="whisper-1",
file=open("temp_audio.wav", "rb"),
language="en"
)
os.remove("temp_audio.wav")
return response.text
def text_to_speech(text: str) -> bytes:
"""Convert agent response text to speech using OpenAI TTS."""
response = openai_client.audio.speech.create(
model="tts-1",
voice="alloy",
input=text
)
return response.content
步驟 3.4:定義 LiveKit 房間邏輯
新增處理 LiveKit 房間、音訊串流和代理回應的邏輯:
Python
async def handle_room(room):
"""Handle LiveKit room events (user join, audio stream, etc.)."""
print(f"Room {room.name} created. Waiting for users...")
@room.on(ParticipantEvent.TRACK_PUBLISHED)
async def on_track_published(participant, track):
"""Process audio track from user."""
print(f"User {participant.identity} published audio track.")
# Subscribe to the audio track
await track.subscribe()
# Collect audio data (stream in chunks for real-time processing)
audio_chunks = []
@track.on("data")
def on_audio_data(data):
audio_chunks.append(data)
# Process after ~3 seconds of audio (adjust for longer/shorter queries)
if len(audio_chunks) > 30: # ~3s of 100ms chunks
process_audio(participant, b"".join(audio_chunks))
audio_chunks.clear()
async def process_audio(participant, audio_data):
"""Convert audio to text, retrieve data, generate response."""
try:
# Step 1: Voice to text
user_query = voice_to_text(audio_data)
print(f"User query: {user_query}")
# Step 2: Extract intent (simplified NLP for travel agent)
if "flight" in user_query.lower() and ("status" in user_query.lower() or "delayed" in user_query.lower()):
# Extract flight details (simplified—use NLP library for production)
airline = "Delta" # Customize with NLP extraction (e.g., "United flight 456" → airline=United)
flight_number = user_query.split()[-1] # Assume last word is flight number
# Step 3: Retrieve live flight status with IPFLY
agent_response = get_flight_status(airline, flight_number)
else:
agent_response = "I can help with flight status queries. Please ask: 'What's the status of Delta flight 123?'"
# Step 4: Text to speech
audio_response = text_to_speech(agent_response)
# Step 5: Stream response back to user via LiveKit
await publish_audio(room, participant, audio_response)
except Exception as e:
error_response = "Sorry, I couldn't process your request. Please try again."
audio_error = text_to_speech(error_response)
await publish_audio(room, participant, audio_error)
print(f"Error processing audio: {str(e)}")
async def publish_audio(room, participant, audio_data):
"""Publish agent's audio response to the user."""
# Create audio track (LiveKit expects PCM 16kHz, 16-bit, mono)
audio_track = await room.create_local_audio_track(
name="agent-response",
source=audio_data
)
await room.local_participant.publish_track(audio_track)
# Send track to specific user (or broadcast to all)
await room.local_participant.send_data(
data=audio_data,
destination_identities=[participant.identity]
)
# Create a LiveKit room and start handling events
async def start_voice_agent():
room = await livekit_client.create_room(name="travel-voice-agent-room")
await handle_room(room)
# Keep room alive (run in production with a server like Uvicorn)
while True:
await asyncio.sleep(1)
if __name__ == "__main__":
import asyncio
asyncio.run(start_voice_agent())
步驟 4:建構前端(LiveKit 客戶端)
建立一個簡單的 HTML/JavaScript 前端(index.html),讓使用者可以加入語音房間並與代理對話:
HTML
<!DOCTYPE html>
<html>
<head>
<title>Travel Voice Agent</title>
<script src="https://cdn.jsdelivr.net/npm/livekit-client@2.0.0/dist/livekit-client.umd.min.js"></script>
<style>
body { font-family: Arial; max-width: 800px; margin: 2rem auto; padding: 0 1rem; }
button { padding: 1rem 2rem; font-size: 1.1rem; cursor: pointer; background: #007bff; color: white; border: none; border-radius: 8px; }
button:disabled { background: #6c757d; cursor: not-allowed; }
#status { margin: 1rem 0; padding: 1rem; border-radius: 8px; background: #f8f9fa; }
</style>
</head>
<body>
<h1>Travel Voice Agent</h1>
<p>Ask about flight status (e.g., "What's the status of Delta flight 123?")</p>
<button id="joinBtn">Join Voice Room</button>
<button id="leaveBtn" disabled>Leave Room</button>
<div id="status">Status: Disconnected</div>
<script>
const LIVEKIT_SERVER_URL = "wss://<YOUR_LIVEKIT_PROJECT>.livekit.cloud";
const ROOM_NAME = "travel-voice-agent-room";
const USER_IDENTITY = `user-${Math.random().toString(36).substr(2, 9)}`;
let room;
// Generate LiveKit token
async function getToken() {
// In production, generate token on backend (never expose API secret client-side)
const response = await fetch("/generate-token", { method: "POST" });
return response.text();
}
// Join room
document.getElementById("joinBtn").addEventListener("click", async () => {
const token = await getToken();
room = new LiveKit.Room({ audioCaptureDefaults: { echoCancellation: true } });
// Update status
document.getElementById("status").textContent = "Joining room...";
document.getElementById("joinBtn").disabled = true;
// Join room
await room.connect(LIVEKIT_SERVER_URL, token);
document.getElementById("status").textContent = "Connected! Speak to the agent.";
document.getElementById("leaveBtn").disabled = false;
// Publish microphone audio
const audioTrack = await LiveKit.createLocalAudioTrack();
await room.localParticipant.publishTrack(audioTrack);
// Listen for agent's audio response
room.on(LiveKit.RoomEvent.TRACK_SUBSCRIBED, (track) => {
if (track.kind === "audio") {
const audioElement = document.createElement("audio");
audioElement.autoplay = true;
audioElement.srcObject = track.attach();
document.body.appendChild(audioElement);
}
});
});
// Leave room
document.getElementById("leaveBtn").addEventListener("click", async () => {
await room.disconnect();
document.getElementById("status").textContent = "Disconnected";
document.getElementById("joinBtn").disabled = false;
document.getElementById("leaveBtn").disabled = true;
});
</script>
</body>
</html>
步驟 5:新增權杖生成(後端)
為了確保 LiveKit 房間的安全性,請新增權杖生成功能端點(生產環境請使用 FastAPI 或 Flask)。以下是簡單的 FastAPI 範例(token_server.py):
Python
from fastapi import FastAPI
from livekit import AccessToken
import os
from dotenv import load_dotenv
load_dotenv()
app = FastAPI()
@app.post("/generate-token")
def generate_token():
token = AccessToken(
api_key=os.getenv("LIVEKIT_API_KEY"),
api_secret=os.getenv("LIVEKIT_API_SECRET"),
identity="user-123", # Replace with dynamic user identity
room_name="travel-voice-agent-room"
)
token.add_grant("join", room="travel-voice-agent-room")
return token.to_jwt()
# Run with: uvicorn token_server:app --reload
步驟 6:測試語音代理
- 啟動權杖伺服器:
uvicorn token_server:app --reload
- 啟動語音代理後端:
python voice_agent_backend.py
- 在瀏覽器中開啟
index.html,點擊「Join Voice Room」,然後詢問:「What’s the status of Delta flight 123?」
代理將會:
- 使用 Whisper 將您的語音轉換為文字
- 使用 IPFLY 代理從 Delta 網站爬取即時航班狀態
- 使用 TTS 生成自然的音訊回應
- 透過 LiveKit 將回應串流回傳給您
IPFLY 對語音代理的關鍵優勢
IPFLY 的代理對於語音代理的成功至關重要——以下說明它們如何提升效能:
- 即時資料擷取:資料中心代理提供低延遲回應(對語音對話至關重要,延遲超過 1 秒就會感覺不自然)。
- 繞過反封鎖機制:動態住宅代理模仿真實使用者,避免在航空公司、電商或金融網站上被封鎖。
- 全球覆蓋:使用 IPFLY 遍佈 190 多個國家的 IP 池存取特定地區的資料(例如歐洲航班狀態、亞洲股票價格)。
- 一致性:99.9% 的正常運作時間確保您的代理在對話中絕不會在擷取資料時失敗。
- 協定支援:支援 HTTP/HTTPS/SOCKS5——與 LiveKit 和爬蟲工具無縫整合。
LiveKit + IPFLY 語音代理的使用案例
1. 旅遊語音助理
- 爬取即時航班狀態、飯店空房率和本地景點營業時間
- 使用 IPFLY 的區域 IP 存取特定國家的旅遊資料(例如德國火車時刻表、日本新幹線資訊)
2. 金融語音機器人
- 擷取即時股票價格、加密貨幣價值和市場趨勢
- 使用靜態住宅代理持續存取 Bloomberg 或 Yahoo Finance 等金融網站
3. 零售語音代理
- 檢查產品庫存、價格和商店營業時間
- 爬取競爭對手定價以提供價格匹配(IPFLY 的動態代理可避免在零售網站被封鎖)
4. 客戶支援語音機器人
- 從電商平台提取即時訂單追蹤資料
- 使用 IPFLY 的全球 IP 存取區域支援政策(例如加拿大 vs 英國的退款規定)
生產環境最佳化技巧
1. 選擇正確的 IPFLY 代理類型
- 時間敏感的查詢(加密貨幣價格、航班狀態):使用資料中心代理以獲得速度
- 嚴格網站(航空公司、銀行):使用動態住宅代理以獲得匿名性
- 重複查詢(商店營業時間):使用靜態住宅代理以獲得一致性
2. 新增 NLP 進行意圖識別
使用 spaCy 或 OpenAI GPT 等工具取代簡化的意圖提取,以處理複雜查詢(例如「Is my 3 PM United flight to Chicago delayed?」)
3. 快取頻繁查詢
快取頻繁請求的資料(例如熱門航班路線)5–10 分鐘,以減少代理使用量和延遲
4. 使用 LiveKit Cloud 進行擴展
對於企業部署,使用 LiveKit Cloud 處理數千個併發語音工作階段——IPFLY 的無限併發能力可與您同步擴展
5. 監控代理效能
使用 IPFLY 的儀表板追蹤成功率、延遲和 IP 使用量——根據效能資料最佳化代理類型
總結
建構能提供價值的即時語音代理需要兩個關鍵元件:低延遲語音串流(LiveKit)和不受限制地存取即時網路資料(IPFLY)。有了 LiveKit 處理語音基礎架構,加上 IPFLY 解決資料存取挑戰,您可以創造出感覺自然、實用且可靠的語音代理。
IPFLY 的 9000 多萬個全球 IP、反封鎖技術和 99.9% 的正常運作時間,確保您的語音代理隨時擁有所需的資料——無論使用者詢問航班狀態、股票價格或產品庫存。將此與 LiveKit 的可擴展性和 Whisper 精準的語音轉文字功能結合,您就擁有了能從眾多靜態語音機器人中脫穎而出的企業級語音 AI 解決方案。
準備好建構自己的語音代理了嗎?從 IPFLY 的免費試用、LiveKit 的免費方案以及本指南的程式碼開始——為語音 AI 解鎖即時網路資料的力量。