Pipecat es un framework Python de código abierto para agentes de voz en tiempo real. Cartesia incluye servicios de voz propios para él: Sonic para texto a voz en streaming e Ink para voz a texto. En esta guía ejecutarás en el navegador un agente de voz con ambos conectados y usarás las predicciones de fin de turno anticipado de Ink para recortar alrededor de medio segundo en cada respuesta.
El montaje completo requiere clonar el repositorio y configurar dos variables de entorno. El agente resultante escucha, decide cuándo has terminado de hablar, piensa y responde en voz alta.
Visión general
Un agente de Pipecat es un flujo de procesadores. El audio entra por un transporte, se transcribe, pasa por un LLM y sale como voz:
transport.input() → STT → LLM → TTS → transport.output()
Dos etapas deciden si la conversación parece humana o un intercambio por walkie-talkie: saber cuándo el usuario ha terminado realmente y pronunciar la respuesta pronto. Ahí intervienen los servicios de Cartesia. CartesiaTurnsSTTService ejecuta Ink 2, el modelo STT en streaming de Cartesia, y deja que el servidor determine cuándo termina el turno en lugar de estimarlo localmente. CartesiaTTSService transmite audio de Sonic mientras se genera, con marcas de tiempo por palabra si las necesitas.
La documentación de Pipecat sitúa el recorrido típico de ida y vuelta entre 500 y 800 milisegundos. Los pasos siguientes buscan dedicar ese tiempo al modelo en vez de a los silencios.
Requisitos previos
- Python 3.11 o posterior. El README del repositorio de Pipecat indica la versión mínima actual.
- Una clave API de Cartesia: créala en el panel.
- Una clave API del LLM que toma las decisiones. El ejemplo usa OpenAI (
OPENAI_API_KEY); Pipecat también incluye servicios para Anthropic, Gemini, Groq, Ollama y otros modelos.
Una limitación: Ink 2 solo admite inglés actualmente, así que este agente escucha en inglés. Sonic habla más de 40 idiomas; la respuesta hablada no es la restricción.
1. Instala los extras que importa el ejemplo
El repositorio de Pipecat incluye un agente Cartesia preparado en examples/voice/voice-cartesia-turns.py:
git clone https://github.com/pipecat-ai/pipecat.git
cd pipecat
uv sync --extra cartesia --extra daily --extra websocket --extra runner --extra webrtc
Un simple uv sync instala el framework, pero no los extras que importa este ejemplo. El archivo importa los transportes Daily y FastAPI WebSocket y el runner de Pipecat al principio, incluso si se ejecuta con -t webrtc. Esos extras deben estar instalados o la importación falla con No module named 'daily'. cartesia y webrtc son las partes que realmente utilizas.
Si estás creando tu propio proyecto en lugar de trabajar en el repositorio de Pipecat, instala el mismo conjunto:
pip install "pipecat-ai[cartesia,daily,websocket,runner,webrtc]"
Después copia examples/voice/voice-cartesia-turns.py del repositorio a tu proyecto. El ejemplo necesita CARTESIA_API_KEY y OPENAI_API_KEY; guarda ambas en un archivo .env junto al script:
CARTESIA_API_KEY=your-key-here
OPENAI_API_KEY=your-key-here
2. Ejecuta el agente
uv run examples/voice/voice-cartesia-turns.py -t webrtc
El runner inicia un servidor local y muestra una URL, http://localhost:7860 por defecto. Ábrela, permite el acceso al micrófono y habla. Esto es lo que sucede internamente:
- El navegador envía tu audio por WebRTC.
CartesiaTurnsSTTServicelo transcribe con Ink 2. El servidor detecta los límites de turno y emite eventosturn.start,turn.update,turn.eager_endyturn.end.- El LLM escribe una respuesta.
CartesiaTTSServicetransmite la respuesta con Sonic y el transporte la reproduce a medida que llega.
Lo interesante está en el paso 2. Las configuraciones antiguas añaden un detector de actividad de voz al audio y estiman cuándo ha terminado una frase. La detección de turnos de Ink 2 funciona en el servidor, lo que hace posible el siguiente paso.
3. Elige tu voz y tu LLM
El ejemplo incluye un ID de voz y un prompt de sistema sencillo. Puedes cambiar ambos:
tts = CartesiaTTSService(
api_key=os.environ["CARTESIA_API_KEY"],
settings=CartesiaTTSService.Settings(
voice="86e30c1d-714b-4074-a1f2-1cb6b552fb49",
),
)
Elige una voz en el Playground y pega aquí su ID, o genera una nueva a partir de una muestra corta con clonación de voz. Como el modelo pronuncia el texto, redacta el prompt para el habla: el ejemplo original indica al LLM que evite emojis, listas con viñetas y formatos que no se oyen.
Si prefieres un modelo Sonic concreto, pásalo en el mismo objeto de ajustes. El servicio usa actualmente sonic-3.6 por defecto.
4. Recorta medio segundo con finales de turno anticipados
Al terminar una frase, Ink predice que has acabado antes del final técnico y emite turn.eager_end. Pipecat lo expone como evento on_turn_eager_end(service, transcript), para que puedas empezar a generar la respuesta enseguida y reanudar la escucha si el usuario sigue hablando:
stt = CartesiaTurnsSTTService(
api_key=os.environ["CARTESIA_API_KEY"],
enable_eager_end_of_turn=True,
)
@stt.event_handler("on_turn_eager_end")
async def on_turn_eager_end(service, transcript):
# Ink predicted the user's turn is ending. Start the LLM now.
...
La opción enable_eager_end_of_turn=True importa: indica a Pipecat que actúe ante la predicción anticipada del servidor en lugar de esperar al final de turno confirmado. Pipecat publica un ejemplo de agregador especulativo de usuario que implementa el flujo completo: inicia el LLM al recibir la predicción y sigue escuchando por si continúas. La documentación de Cartesia estima un ahorro de alrededor de medio segundo, que marca la diferencia entre un agente que responde y uno que espera su turno.
Si el agente interviene mientras estás pensando, ajusta los umbrales en vez de desactivar los finales anticipados. Los cuatro ajustes, con los valores predeterminados de Cartesia, son turn_start_threshold (0.8), turn_eager_end_threshold (0.4), turn_end_threshold (0.2) y turn_end_timeout_ms (5600). Un agente paciente espera más antes de apostar por que has terminado: exige más evidencia antes de interrumpir. Baja el umbral de final anticipado hacia 0.3 y sube el tiempo de espera hacia 8000.
La lista de nombres que realmente dirán tus usuarios, como productos o jerga de la empresa, va en Settings(keyterm=["Pipecat", "Ink 2"]), para ayudar a la transcripción a reconocerlos.
Siguientes pasos
- Pon el agente en un número de teléfono: ejecuta el mismo ejemplo con
-t twilioy un proxy público. El flujo funciona por teléfono sin cambios. - Si prefieres no gestionar el flujo, crea el mismo agente en Managed Agents, que gestiona telefonía, herramientas y conocimiento.
- ¿Necesitas archivos de audio en lugar de una conversación en directo? La síntesis por lotes usa
CartesiaHttpTTSService, del mismo paquete.
Documentación relacionada
- Documentación de la integración de Cartesia con Pipecat
- Servicio STT de Cartesia en Pipecat y servicio TTS
- Ejemplo voice-cartesia-turns usado en esta guía
- Agregador especulativo de usuario, el patrón completo de final anticipado
- Qué hace que un agente de voz parezca funcionar en tiempo real, para entender el presupuesto de latencia de estas decisiones