Utiliser ThunderPhone depuis Pipecat
Exécutez un agent vocal ThunderPhone comme service de synthèse vocale de bout en bout dans un pipeline Pipecat, avec votre propre transport et téléphonie.
Pipecat est un framework open source permettant de créer des agents vocaux à partir de services composables. ThunderPhone s'intègre en tant que service LLM de parole à parole : Pipecat envoie l'audio de l'appelant, ThunderPhone renvoie la voix de l'agent, les transcriptions et les appels de fonction, et le transport de Pipecat (Daily, LiveKit, Twilio, WebRTC, un microphone local) transmet l'audio. La reconnaissance vocale, le modèle de langage, la voix, la gestion des tours de parole, 47 langues et les outils s'exécutent tous sur ThunderPhone.
Les appels effectués de cette manière apparaissent dans l'historique des appels et sont facturés au tarif à la minute de votre produit, comme tout autre appel en temps réel. Aucun abonnement ni numéro de téléphone ThunderPhone n'est nécessaire.
Installer
pip install pipecat-thunderphone
export THUNDERPHONE_API_KEY=sk_live_... # a secret API keyLe package encapsule le service OpenAI Realtime de Pipecat, car le
WebSocket Realtime de ThunderPhone utilise le même protocole. Il
nécessite pipecat-ai 1.8 ou une version ultérieure.
Exécuter un agent enregistré
Tout ce que fait l'agent (prompt, voix, moteur, langues, outils, message d'accueil, relances en cas de silence) est configuré dans ThunderPhone. Le pipeline ne fait que transmettre l'audio.
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))Un agent enregistré ouvre l'appel selon sa propre planification ; le service ne
demande donc pas de réponse d'ouverture à Pipecat. Transmettez greet_on_connect=True si vous
en voulez tout de même une.
Configurer la session directement
Sans agent_id, les instructions et les outils proviennent du contexte Pipecat, de
la même manière que pour OpenAI. product sélectionne le moteur et voice sélectionne la
voix 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"],
)
]),
)Les sessions configurées directement sont pilotées par le client : l'agent parle en premier car Pipecat demande une réponse lorsque le contexte arrive, et reste silencieux en cas de silence, sauf si vous ajoutez un message ou demandez une autre réponse.
Options
| Argument | Signification |
|---|---|
api_key | Clé secrète (sk_live_...). Utilise THUNDERPHONE_API_KEY par défaut. |
agent_id | Exécute un agent enregistré. Mutuellement exclusif avec product et voice. |
product | Moteur pour les sessions en ligne : spark, bolt ou storm. |
voice | Nom de voix ThunderPhone pour les sessions en ligne. |
language | Indication de langue principale pour les sessions en ligne, par exemple es. |
from_number, to_number | Numéros à enregistrer dans l'appel lorsque le pipeline est connecté à une ligne téléphonique. |
live_transcripts | Diffuse des fragments de transcription de l'appelant en cours d'énoncé (facturé en supplément). |
greet_on_connect | Demande une première réponse dès que la session est prête. |
end_task_on_call_ended | Envoie EndWorkerFrame lorsque ThunderPhone met fin à l'appel (activé par défaut). |
Événements
ThunderPhone ajoute des événements de plateforme au protocole temps réel. Le service les transmet aux gestionnaires :
@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 est défini une fois la session active. Utilisez-le avec
GET /v1/calls/{call_id} pour récupérer l'enregistrement,
la transcription et l'évaluation après l'appel.
Limites
- La détection des tours est côté serveur et toujours activée ; les tours pilotés par Pipecat
(
turn_detection=False) ne sont pas pris en charge. - Les fonctions enregistrées sur le service s'exécutent uniquement pour les sessions en ligne. Un agent enregistré exécute ses propres outils sur ThunderPhone.
- L'audio est en PCM mono 16 bits à 24 kHz dans les deux sens.
- Les images vidéo sont ignorées.