학습 자료

Pipecat과 Cartesia로 음성 에이전트 만들기

Rene 
Pipecat과 Cartesia로 음성 에이전트 만들기

Pipecat은 실시간 음성 에이전트를 위한 오픈 소스 Python 프레임워크입니다. Cartesia는 스트리밍 텍스트 음성 변환용 Sonic과 음성 인식용 Ink를 자사 서비스로 제공합니다. 이 가이드에서는 두 서비스를 연결하여 브라우저에서 음성 에이전트를 실행한 뒤, Ink의 조기 턴 종료 예측으로 매 응답 시간을 약 0.5초 줄입니다.

전체 구축에는 저장소 복제와 환경 변수 두 개가 필요합니다. 완성된 음성 에이전트는 듣고, 말이 끝났는지 판단하고, 생각한 다음 소리로 답합니다.

개요

Pipecat 음성 에이전트는 처리기들의 파이프라인입니다. 오디오가 전송 계층으로 들어와 전사되고 LLM을 거친 다음 음성으로 나갑니다.

transport.input() → STT → LLM → TTS → transport.output()

대화가 사람과 대화하는 느낌인지 무전기 같은 느낌인지는 두 구간에 달려 있습니다. 사용자가 실제로 말을 멈춘 시점을 아는 것과 답변을 빨리 말하는 것입니다. Cartesia 서비스는 이 부분을 담당합니다. CartesiaTurnsSTTService는 Cartesia의 스트리밍 STT 모델 Ink 2를 실행하고 로컬에서 추측하는 대신 서버가 턴 종료를 판단하게 합니다. CartesiaTTSService는 Sonic 오디오를 생성하면서 스트리밍하며, 필요하면 단어 타임스탬프도 제공합니다.

Pipecat 문서는 일반적인 파이프라인 왕복 시간을 500~800밀리초로 설명합니다. 아래 단계는 그 시간을 침묵 대신 모델 처리에 쓰도록 돕습니다.

준비 사항

  1. Python 3.11 이상. 현재 최소 버전은 Pipecat 저장소 README에 나와 있습니다.
  2. Cartesia API 키. 대시보드에서 생성하세요.
  3. 추론에 사용할 LLM API 키. 예제는 OpenAI의 OPENAI_API_KEY를 사용하지만, 다른 모델을 원하면 Pipecat의 Anthropic, Gemini, Groq, Ollama 등 서비스를 쓸 수 있습니다.

범위를 명확히 하겠습니다. Ink 2는 현재 영어만 지원하므로 이 에이전트는 영어로 듣습니다. Sonic은 40개 이상의 언어를 말할 수 있으므로 응답 언어가 제약은 아닙니다.

1. 예제가 가져오는 extras 설치

Pipecat 저장소에는 examples/voice/voice-cartesia-turns.py에 바로 실행할 수 있는 Cartesia 에이전트가 있습니다.

git clone https://github.com/pipecat-ai/pipecat.git
cd pipecat
uv sync --extra cartesia --extra daily --extra websocket --extra runner --extra webrtc

uv sync만 실행하면 프레임워크는 설치되지만 예제가 가져오는 extras는 설치되지 않습니다. 파일 위쪽에서 Daily와 FastAPI WebSocket 전송, Pipecat runner를 가져오며, -t webrtc로 실행해도 마찬가지입니다. 따라서 해당 extras가 없으면 No module named 'daily' 오류가 납니다. 실제로 사용하는 부분은 cartesia와 webrtc입니다.

Pipecat 저장소 밖에서 자체 프로젝트를 만든다면 같은 구성을 설치하세요.

pip install "pipecat-ai[cartesia,daily,websocket,runner,webrtc]"

저장소의 examples/voice/voice-cartesia-turns.py를 프로젝트에 복사하세요. 예제에는 CARTESIA_API_KEY와 OPENAI_API_KEY가 필요합니다. 스크립트 옆의 .env 파일에 둘 다 넣으세요.

CARTESIA_API_KEY=your-key-here
OPENAI_API_KEY=your-key-here

2. 에이전트 실행

uv run examples/voice/voice-cartesia-turns.py -t webrtc

runner는 로컬 서버를 시작하고 URL을 출력합니다. 기본값은 http://localhost:7860입니다. 페이지를 열고 마이크 사용을 허용한 뒤 말해 보세요. 내부에서는 다음 일이 일어납니다.

  1. 브라우저가 WebRTC로 오디오를 보냅니다.
  2. CartesiaTurnsSTTService가 Ink 2로 전사합니다. 서버는 턴 경계를 관찰하며 turn.start, turn.update, turn.eager_end, turn.end 이벤트를 보냅니다.
  3. LLM이 답변을 작성합니다.
  4. CartesiaTTSService가 Sonic으로 답변을 스트리밍하고 전송 계층이 도착하는 대로 재생합니다.

주목할 부분은 2단계입니다. 이전 구성은 오디오에 음성 활동 감지기를 붙여 문장이 끝났는지 추측했습니다. Ink 2의 턴 감지는 서버에서 실행되며, 덕분에 다음 단계가 가능합니다.

3. 음성과 LLM 선택

예제에는 음성 ID와 간단한 시스템 프롬프트가 있습니다. 둘 다 바꿀 수 있습니다.

tts = CartesiaTTSService(
    api_key=os.environ["CARTESIA_API_KEY"],
    settings=CartesiaTTSService.Settings(
        voice="86e30c1d-714b-4074-a1f2-1cb6b552fb49",
    ),
)

Playground에서 음성을 골라 ID를 여기에 붙여 넣거나, 음성 복제로 짧은 샘플에서 새 음성을 만드세요. 모델이 텍스트를 소리 내어 읽으므로 시스템 프롬프트도 말하기에 맞아야 합니다. 원본 예제는 LLM에 이모지, 글머리 기호, 소리로 들을 수 없는 다른 서식을 피하라고 지시합니다.

특정 Sonic 모델을 쓰고 싶다면 같은 settings 객체에 전달하세요. 현재 서비스 기본값은 sonic-3.6입니다.

4. 조기 턴 종료로 0.5초 줄이기

문장을 마칠 때 Ink는 실제 종료가 확정되기 전에 말이 끝날 것을 예측해 turn.eager_end를 보냅니다. Pipecat은 이를 on_turn_eager_end(service, transcript) 이벤트로 제공하므로 즉시 답변 생성을 시작하고, 사용자가 계속 말하면 다시 듣도록 할 수 있습니다.

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.
    ...

enable_eager_end_of_turn=True가 중요합니다. 턴 종료 확정을 기다리는 대신 서버의 조기 예측에 반응하도록 Pipecat에 지시합니다. Pipecat의 추측형 사용자 집계기 예제는 전체 흐름을 처리합니다. 조기 예측 때 LLM을 시작하면서 사용자가 계속 말할 경우에 대비해 듣기를 유지합니다. Cartesia 문서는 약 0.5초를 절약한다고 설명합니다. 바로 답하는 에이전트와 잠시 기다리는 에이전트의 차이입니다.

생각하는 중에 에이전트가 계속 끼어든다면 조기 종료를 끄기보다 임계값을 조정하세요. 네 설정과 Cartesia 기본값은 turn_start_threshold 0.8, turn_eager_end_threshold 0.4, turn_end_threshold 0.2, turn_end_timeout_ms 5600입니다. 참을성 있는 에이전트는 말이 끝났다고 판단하기까지 더 기다립니다. 끼어들기 전 판단 기준을 높이려면 조기 종료 임계값을 0.3 쪽으로 낮추고 시간 제한을 8000 쪽으로 높이세요.

사용자가 실제로 말할 제품명이나 사내 용어는 Settings(keyterm=["Pipecat", "Ink 2"])에 넣으면 전사 정확도를 높이는 데 도움이 됩니다.

다음 단계

  1. 전화번호에 연결하세요. 같은 예제를 -t twilio와 공개 프록시로 다시 실행하면 파이프라인을 바꾸지 않고 통화에 사용할 수 있습니다.
  2. 파이프라인을 전혀 운영하고 싶지 않다면 전화, 도구, 지식을 처리하는 Managed Agents에서 같은 에이전트를 만드세요.
  3. 실시간 대화 대신 오디오 파일이 필요하다면 같은 패키지의 CartesiaHttpTTSService로 일괄 합성하세요.

관련 문서

자주 묻는 질문

Pipecat은 Cartesia를 지원하나요?

네. Cartesia는 Pipecat 저장소의 자사 통합 서비스입니다. 스트리밍 TTS 서비스 CartesiaTTSService와 STT 서비스 두 개가 있으며, 그중 CartesiaTurnsSTTService는 Ink 2를 실행하고 Cartesia 서버가 턴 경계를 결정하게 합니다. pipecat-ai를 cartesia extra 및 진입점이 가져오는 전송과 runner extras와 함께 설치하고 CARTESIA_API_KEY를 설정하세요.

Cartesia 통합은 어떤 모델을 사용하나요?

TTS 서비스는 Cartesia의 실시간 음성 모델 Sonic을 스트리밍하며 현재 Pipecat 버전의 기본값은 sonic-3.6입니다. 턴 STT 서비스는 Ink 2인 ink-2를 실행하여 서버에서 턴 감지를 처리하고 turn.eager_end 예측을 보냅니다. 다른 Sonic 버전을 선택하려면 Settings에 model=을 전달하세요.

Pipecat 음성 에이전트는 얼마나 빠른가요?

Pipecat 문서는 일반적인 파이프라인 왕복 시간을 500~800밀리초로 설명합니다. 줄일 수 있는 두 구간은 턴 감지와 음성 합성입니다. Ink의 조기 종료 예측은 사용자 턴이 공식적으로 끝나기 전에 답변 생성을 시작해 응답 시간을 약 0.5초 줄일 수 있습니다.

에이전트가 전화를 받을 수 있나요?

네. Pipecat은 Twilio, Exotel, Plivo 전화 전송을 제공합니다. -t twilio와 공개 프록시를 사용하면 같은 파이프라인을 전화 통화에서 실행할 수 있습니다. 직접 운영하고 싶지 않다면 Cartesia Managed Agents로 코드 없이 인바운드와 아웃바운드 음성 에이전트를 만들 수 있습니다.

LLM은 반드시 OpenAI를 사용해야 하나요?

아닙니다. 예제는 코드가 짧아서 OpenAILLMService를 사용하지만 Pipecat은 Anthropic, Gemini, Groq, 로컬 Ollama 등 여러 LLM 서비스 구현을 제공합니다. 파이프라인의 해당 서비스만 바꾸고 Cartesia STT 및 TTS 서비스는 그대로 두세요.