LiveKit Agents에서 ThunderPhone 사용
LiveKit 룸, SIP 및 전화 기능과 함께 LiveKit Agents 세션의 실시간(음성 간 음성) 모델로 ThunderPhone 음성 에이전트를 실행합니다.
LiveKit Agents는 LiveKit 룸을 기반으로 실시간 음성 에이전트를 구축하는 오픈 소스 프레임워크입니다. ThunderPhone은 실시간 모델로 연결됩니다. 프레임워크가 참여자의 오디오를 전송하면 ThunderPhone이 에이전트 음성, 트랜스크립트 및 함수 호출을 반환하고, LiveKit의 룸, SIP 트렁크 및 전화 기능이 오디오를 전달합니다. 음성 인식, 언어 모델, 음성, 턴 관리, 47개 언어 및 도구는 모두 ThunderPhone에서 실행됩니다.
이 방식으로 걸린 통화는 통화 기록에 표시되며, 다른 실시간 통화와 마찬가지로 제품의 분당 요금으로 청구됩니다. 구독이나 ThunderPhone 전화번호는 필요하지 않습니다.
설치
pip install livekit-plugins-thunderphone
export THUNDERPHONE_API_KEY=sk_live_... # a secret API keyThunderPhone의 Realtime WebSocket이 동일한 프로토콜을 사용하므로 이 플러그인은 LiveKit의 OpenAI Realtime 모델을 래핑합니다. livekit-agents 1.8 이상이 필요합니다.
저장된 에이전트 실행
에이전트가 수행하는 모든 작업(프롬프트, 음성, 엔진, 언어, 도구, 인사말, 무응답 확인)은 ThunderPhone에서 구성됩니다. 세션은 오디오만 전달합니다.
from livekit.agents import Agent, AgentSession, JobContext, WorkerOptions, cli
from livekit.plugins import thunderphone
async def entrypoint(ctx: JobContext):
session = AgentSession(llm=thunderphone.RealtimeModel(agent_id=12))
await session.start(agent=Agent(instructions=""), room=ctx.room)
if __name__ == "__main__":
cli.run_app(WorkerOptions(entrypoint_fnc=entrypoint))저장된 에이전트는 ThunderPhone에서 인사하고 자체 도구를 실행합니다. LiveKit Agent의 지침과 도구는 전송되지 않습니다. ThunderPhone 에이전트가 전화를 끊으면 통화가 종료되고 세션도 함께 닫힙니다.
세션을 인라인으로 구성
agent_id 없이 사용하면 OpenAI와 동일하게 지침과 도구가 LiveKit Agent에서 제공됩니다. product는 엔진을 선택하고 voice는 ThunderPhone 음성을 선택합니다.
from livekit.agents import Agent, AgentSession, RunContext, function_tool
from livekit.plugins import thunderphone
class Receptionist(Agent):
def __init__(self):
super().__init__(instructions="You are Acme Dental's receptionist. Be brief.")
@function_tool
async def check_availability(self, context: RunContext, date: str) -> dict:
"""Free appointment slots on a date."""
return {"slots": await calendar.free_slots(date)}
async def entrypoint(ctx: JobContext):
session = AgentSession(
llm=thunderphone.RealtimeModel(product="bolt", voice="olivia", language="es"),
)
await session.start(agent=Receptionist(), room=ctx.room)
await session.generate_reply() # the agent speaks firstThunderPhone은 통화가 시작될 때 지침과 도구를 고정하므로, 이를 변경하는 update_instructions, update_tools 및 에이전트 핸드오프는 통화 중에 지원되지 않습니다. 인라인 세션은 클라이언트가 제어합니다. generate_reply()를 호출하거나 참여자가 턴을 마치면 에이전트가 말합니다.
옵션
| 인수 | 의미 |
|---|---|
api_key | 비밀 키(sk_live_...)입니다. 기본값은 THUNDERPHONE_API_KEY입니다. |
agent_id | 저장된 에이전트를 실행합니다. product 및 voice와 함께 사용할 수 없습니다. |
product | 인라인 세션용 엔진입니다: spark, bolt 또는 storm. |
voice | 인라인 세션용 ThunderPhone 음성 이름입니다. |
language | 인라인 세션의 기본 언어 힌트입니다(예: es). |
from_number, to_number | 룸이 전화 회선을 연결할 때 통화에 기록할 번호입니다. |
live_transcripts | 발화 중간에 발신자 대화 기록 조각을 스트리밍합니다(추가 과금). |
base_url | 엔드포인트 재정의이며, 기본값은 wss://api.thunderphone.com/v1/realtime입니다. |
이벤트
ThunderPhone은 실시간 프로토콜에 플랫폼 이벤트를 추가합니다. 세션은 다음 이벤트를 발생시킵니다.
@session.llm.session.on("thunderphone_call_ended") # or on the RealtimeSession you hold
def on_call_ended(event):
print("call ended:", event["reason"])RealtimeSession은 세션이 활성화되면 call_id를 제공합니다. 통화 후
GET /v1/calls/{call_id}와 함께 사용하여 녹음,
대화 기록 및 평가를 가져옵니다. 그 외 모든 call.* 이벤트(통화 전환,
키패드, 음성 무시)는 thunderphone_call_event로 수신됩니다.
제한 사항
- 턴 감지는 서버 측에서 처리되며 항상 활성화됩니다. 프레임워크 측 턴 감지
(
AgentSession의turn_detection)는 무시됩니다. - 통화가 시작된 후에는 지시와 도구를 변경할 수 없습니다.
- 오디오는 양방향 모두 24kHz의 16비트 모노 PCM입니다.
- 동영상 프레임은 무시됩니다.