ThunderPhone 2.0을 출시했습니다.별도 문의 없이 분당 2¢부터.출시 소식 보기

Connect tools & data

Pipecat에서 ThunderPhone 사용

자체 전송 및 전화 시스템을 사용하여 Pipecat 파이프라인 내에서 ThunderPhone 음성 에이전트를 음성 간 서비스로 실행합니다.

Pipecat은 조합 가능한 서비스로 음성 에이전트를 구축하기 위한 오픈 소스 프레임워크입니다. ThunderPhone은 음성-음성 LLM 서비스로 연결됩니다. Pipecat이 발신자 오디오를 전송하면 ThunderPhone은 에이전트의 음성, 대화 기록 및 함수 호출을 반환하고, Pipecat의 전송 계층(Daily, LiveKit, Twilio, WebRTC, 로컬 마이크)이 오디오를 전달합니다. 음성 인식, 언어 모델, 음성, 턴 처리, 47개 언어 및 도구는 모두 ThunderPhone에서 실행됩니다.

이 방식으로 이루어진 통화는 다른 모든 실시간 통화와 마찬가지로 통화 기록에 표시되며 제품의 분당 요금으로 청구됩니다. 구독이나 ThunderPhone 전화번호는 필요하지 않습니다.

설치

pip install pipecat-thunderphone
export THUNDERPHONE_API_KEY=sk_live_...   # a secret API key

ThunderPhone의 Realtime WebSocket이 동일한 프로토콜을 사용하므로, 이 패키지는 Pipecat의 OpenAI Realtime 서비스를 래핑합니다. pipecat-ai 1.8 이상이 필요합니다.

저장된 에이전트 실행

에이전트가 수행하는 모든 작업(프롬프트, 음성, 엔진, 언어, 도구, 인사말, 무응답 확인)은 ThunderPhone에서 구성합니다. 파이프라인은 오디오만 전달합니다.

from pipecat.pipeline.pipeline import Pipeline
from pipecat.pipeline.worker import PipelineParams, PipelineWorker
from pipecat.processors.aggregators.llm_context import LLMContext
from pipecat.processors.aggregators.llm_response_universal import LLMContextAggregatorPair
from pipecat_thunderphone import ThunderPhoneRealtimeLLMService
 
llm = ThunderPhoneRealtimeLLMService(agent_id=12)
 
context = LLMContext()
aggregators = LLMContextAggregatorPair(context)
pipeline = Pipeline([
    transport.input(),
    aggregators.user(),
    llm,
    aggregators.assistant(),
    transport.output(),
])
worker = PipelineWorker(pipeline, params=PipelineParams(allow_interruptions=True))

저장된 에이전트는 자체 일정에 따라 통화를 시작하므로 서비스는 Pipecat에 첫 응답을 요청하지 않습니다. 그래도 요청하려면 greet_on_connect=True를 전달합니다.

세션을 인라인으로 구성

agent_id가 없으면 OpenAI와 동일하게 지시 사항과 도구가 Pipecat 컨텍스트에서 제공됩니다. product는 엔진을 선택하고 voice는 ThunderPhone 음성을 선택합니다.

from pipecat.adapters.schemas.function_schema import FunctionSchema
from pipecat.adapters.schemas.tools_schema import ToolsSchema
from pipecat.services.llm_service import FunctionCallParams
 
llm = ThunderPhoneRealtimeLLMService(product="bolt", voice="olivia", language="es")
 
async def check_availability(params: FunctionCallParams):
    slots = await calendar.free_slots(params.arguments["date"])
    await params.result_callback({"slots": slots})
 
llm.register_function("check_availability", check_availability)
 
context = LLMContext(
    messages=[{"role": "system", "content": "You are Acme Dental's receptionist."}],
    tools=ToolsSchema(standard_tools=[
        FunctionSchema(
            name="check_availability",
            description="Free appointment slots on a date",
            properties={"date": {"type": "string"}},
            required=["date"],
        )
    ]),
)

인라인 세션은 클라이언트가 제어합니다. Pipecat이 컨텍스트가 도착할 때 응답을 요청하므로 에이전트가 먼저 말하며, 메시지를 추가하거나 다른 응답을 요청하지 않는 한 무응답 상태에서는 조용히 유지됩니다.

옵션

인수의미
api_key비밀 키(sk_live_...)입니다. 기본값은 THUNDERPHONE_API_KEY입니다.
agent_id저장된 에이전트를 실행합니다. productvoice와 함께 사용할 수 없습니다.
product인라인 세션용 엔진입니다. spark, bolt 또는 storm입니다.
voice인라인 세션용 ThunderPhone 음성 이름입니다.
language인라인 세션의 기본 언어 힌트입니다. 예: es
from_number, to_number파이프라인이 전화 회선의 앞단에 있을 때 통화에 기록할 번호입니다.
live_transcripts발화 중간에 발신자 트랜스크립트 조각을 스트리밍합니다(추가 과금).
greet_on_connect세션이 준비되는 즉시 첫 응답을 요청합니다.
end_task_on_call_endedThunderPhone이 통화를 종료할 때 EndWorkerFrame을 푸시합니다(기본적으로 활성화됨).

이벤트

ThunderPhone은 실시간 프로토콜에 플랫폼 이벤트를 추가합니다. 서비스는 이를 핸들러에 전달합니다.

@llm.event_handler("on_call_ended")
async def on_call_ended(service, event):
    print("call ended:", event["reason"], "call id:", service.call_id)

service.call_id는 세션이 활성화되면 설정됩니다. 통화 후 GET /v1/calls/{call_id}를 사용하여 녹음, 트랜스크립트 및 평가를 가져옵니다.

제한 사항

  • 턴 감지는 서버 측에서 수행되며 항상 활성화됩니다. Pipecat 기반 턴 (turn_detection=False)은 지원되지 않습니다.
  • 서비스에 등록된 함수는 인라인 세션에서만 실행됩니다. 저장된 에이전트는 ThunderPhone에서 자체 도구를 실행합니다.
  • 오디오는 양방향 모두 24kHz, 16비트 모노 PCM입니다.
  • 비디오 프레임은 무시됩니다.