감정을 담은 음성 합성은 상황에 따라 기쁘게, 걱정스럽게, 미안하게, 혹은 짜증스럽게 들리는 합성 음성입니다. 모든 것을 똑같이 공손하고 단조로운 톤으로 읽는 것과는 다릅니다. 요즘 모델은 이 중 많은 부분을 스스로 합니다. 문장을 읽고 어떻게 들려야 할지 판단합니다. 그 위에 더하는 제어는 다듬기 위한 것이지, 감정 없이 쓴 문장을 살려내기 위한 것이 아닙니다.
이 순서가 이 가이드의 핵심입니다. 음성 에이전트나 앱을 만든다면, 들리는 감정의 질은 대부분 시스템이 쓰는 문장과 고른 목소리에서 나옵니다. 태그와 파라미터는 나머지를 조정합니다. 아래에서 각 방식의 원리, 주요 API가 이를 다루는 방법, Cartesia Sonic용으로 작동하는 코드, 그리고 결과가 좋은지 판단하는 방법을 설명합니다.
TTS의 감정은 어디서 오는가
한 문장에 정답인 읽기가 하나만 있는 것은 아닙니다. “I can’t believe it”은 기쁨일 수도, 분노일 수도, 슬픔이나 비꼼일 수도 있습니다. Cartesia 연구팀은 음성 합성을 일대다 문제라고 부릅니다. 모델은 어디서 쉴지, 어떤 단어를 강조할지, 얼마나 빨리 말할지, 어떤 감정을 실을지를, 대개 그런 내용을 적어 두지 않은 텍스트에서 골라야 합니다.
모델이 이 선택을 하는 방법은 네 가지입니다.
- 텍스트에서 추론한다. 주변 단어와 문장 부호를 읽고 읽는 방식을 고릅니다. 현재 모든 모델의 기본 동작이며, 가장 중요한 방법입니다.
- 이름으로 지정한다. 파라미터나 태그로
angry나calm을 지정합니다. 모델은 무리가 없는 범위에서 그쪽으로 기웁니다. - 스타일을 고른다. 일부 목소리에는 고객 상담이나 뉴스 같은 이름 붙은 말하기 스타일이 있고, 각각 별도의 연기로 녹음되거나 학습되어 있습니다.
- 말로 설명한다. “친구를 안심시키듯 따뜻하게 말해 줘” 같은 자연어 프롬프트를 쓰면 모델이 그 설명을 해석합니다.
모든 API가 이 방법들을 섞어 씁니다. 다른 점은 무엇을 주된 제어로 삼느냐입니다.
주요 API는 감정 지시를 어떻게 받는가
2026년 10월 12일 기준 각 제공업체 문서를 바탕으로 정리했습니다.
| API | 감정을 지시하는 방법 | 알아 둘 점 |
|---|---|---|
| Cartesia Sonic 3.6 | 기본적으로 텍스트에서 추론. 요청별 generation_config.emotion 또는 인라인 <emotion value="..."/> 태그. 웃음은 [laughter]. | 값 58개, 그중 주요 값 6개. 태그는 베타이며 영어 전용이고, 모든 언어에서 Sonic은 여전히 텍스트에서 감정을 읽습니다. 태그가 문장과 맞을 때 효과가 있습니다. 스트리밍 도중 감정을 바꿀 수 있습니다. |
| ElevenLabs v4·v3 | 텍스트 안의 대괄호 오디오 태그. 예: [sarcastic], [whispers], [laughs]. | 태그는 고정 목록이 아닌 자유로운 지시문입니다. v4와 v3는 SSML break 태그를 지원하지 않습니다. |
| Azure Speech | SSML <mstts:express-as style="...">와 0.01~2 범위의 styledegree. HD 음성은 [whispering] 같은 스타일 마커도 받습니다. | 뉴럴 음성 스타일은 일부 목소리에만 있습니다. 스타일을 전제로 설계하기 전에 목소리를 확인하세요. |
| Gemini TTS | 텍스트 옆에 쓰는 자연어 prompt 필드와 [laughs], [sigh] 같은 인라인 태그. | 2.5와 3.1 프리뷰 TTS 모델은 빠르면 2026년 11월 17일에 Gemini API에서 빠집니다. |
| OpenAI gpt-4o-mini-tts | instructions 문자열. 예: “Speak in a cheerful and positive tone.” | 지원 중단 예정. OpenAI는 2027년 1월 6일에 음성 엔드포인트의 모든 모델을 제거합니다. |
| Amazon Polly | 감정 태그 없음. 일부 뉴럴 음성에 뉴스 앵커 스타일이 있습니다. | 읽는 방식은 주로 목소리와 텍스트로 결정됩니다. |
자연어 연기 지시를 받던 Hume의 Octave도 얼마 전까지 이 표에 있었습니다. Hume은 2026년 11월 13일에 TTS와 EVI API를 종료합니다. 옮기는 중이라면 Hume 대안 가이드에서 먼저 저장해야 할 것을 확인하세요.
프로덕션에서 중요한 점이 하나 있습니다. 프롬프트형 제어(Gemini, 그리고 종료 예정인 OpenAI 모델)는 자유 텍스트라서 테스트할 고정 어휘가 없습니다. 같은 읽기를 재현하려면 지시문의 문구를 그대로 보관하고, 바뀔 때마다 다시 테스트해야 합니다. 이름 붙은 값(Sonic의 감정 목록, Azure의 스타일)은 버전 관리, 테스트, 롤백이 가능한 설정입니다. 하루 10,000건의 통화가 같은 에이전트를 거친다면 필요한 것은 이쪽입니다.
먼저 문장에 감정을 쓰세요
많은 팀이 건너뛰는 단계이고, 가장 효과가 큰 단계입니다.
Sonic 3.6은 태그 없이도 텍스트의 감정적 맥락에 맞춰 속도와 억양을 바꿉니다. 미국 영어 1대1 블라인드 테스트에서 청취자들은 Eleven v3보다 Sonic 3.6을 92%의 비율로 선호했고, 그 이유로 더 나은 억양과 맥락에 맞는 감정을 들었습니다. 즉 모델은 이미 여러분의 문장을 듣고 있습니다. 들을 가치가 있는 문장을 주세요.
음성 에이전트라면 감정은 LLM 프롬프트 안에 있다는 뜻입니다. 공감하는 톤을 원한다면 LLM이 공감하는 문장을 써야 합니다. 주문이 늦어진 고객에게 보내는 두 답변을 비교해 보세요.
- “주문이 지연되었습니다. 새 배송일은 목요일입니다.”
- “정말 죄송해요. 기다리고 계셨을 텐데요. 목요일에 도착할 예정입니다.”
어떤 태그를 붙여도 첫 번째는 미안하게 들리지 않습니다. 두 번째는 태그 없이도 미안하게 들립니다. 음성 AI 모델 선택 가이드도 반대편에서 같은 이야기를 합니다. Sonic은 텍스트에 맞춰 감정을 표현하고, 텍스트와 어긋나는 설정은 무시합니다.
어떤 모델에도 도움이 되는 글쓰기 습관 몇 가지입니다.
- 문장 부호를 평소처럼 남기세요. 물음표, “하지만” 앞의 쉼표, 느낌표에는 읽는 방식에 관한 정보가 담겨 있습니다. LLM 출력을 “정리”한다고 문장 부호를 지우면 목소리가 밋밋해집니다.
- 사람이 머뭇거릴 곳에서 에이전트도 머뭇거리게 하세요. Sonic은 텍스트 속 “음”, “흠” 같은 말을 자연스럽게 생각하는 속도로 읽습니다. 조회한 숫자 앞이나 어려운 질문 뒤처럼 아껴 쓰고, 모든 문장에 넣지는 마세요.
- 감정을 서술하지 마세요. “그녀가 화를 내며 말했다”는 그대로 소리 내어 읽힙니다. 화는 그녀가 하는 말 속에 담으세요.
성향이 맞는 목소리를 고르세요
목소리에는 기본 분위기가 있습니다. 밝게 뭐든 해결해 주는 사람으로 만든 목소리는 어떤 태그를 붙여도 믿음직한 상담자처럼 들리지 않습니다. 먼저 일에 맞는 목소리를 고르고, 그다음에 다듬으세요.
Cartesia 보이스 라이브러리는 표현력이 큰 목소리에 Emotive 태그를 붙이고, 감정 제어는 이런 목소리에서 가장 잘 반응합니다. 문서는 감정 폭이 가장 넓은 목소리로 Leo, Jace, Kyle, Gavin, Maya, Tessa, Dana, Marian을 꼽습니다. 목소리를 클론하면 클론은 원본 녹음의 말투를 이어받으므로, 에이전트에 주고 싶은 분위기로 샘플을 녹음하세요.
Sonic으로 감정 제어하기
문장과 목소리가 준비되면, 다음 방법으로 연기를 더 밀어붙일 수 있습니다. 아래 예제는 Cartesia Python SDK 4.2.0 버전과 sonic-3.6을 사용합니다. 먼저 환경 변수 CARTESIA_API_KEY를 설정하고, 스트리밍 예제를 위해 cartesia[websockets]를 설치하세요. 설정 방법은 Python 음성 합성 튜토리얼에 있습니다.
요청 전체에 감정 하나 지정하기
import os
from cartesia import Cartesia
with Cartesia(api_key=os.environ["CARTESIA_API_KEY"]) as client:
response = client.tts.generate(
model_id="sonic-3.6",
transcript="I'm sorry, I know you were counting on this. It's now arriving Thursday.",
voice="6ccbfb76-1fc6-48f7-b71d-91ac6298247b", # Tessa, an Emotive voice
language="en",
output_format={"container": "wav", "encoding": "pcm_s16le", "sample_rate": 44100},
generation_config={"emotion": "sympathetic", "speed": 0.95},
)
response.write_to_file("apology.wav")
generation_config는 해당 요청에만 적용되며, 계정 전체 설정은 없습니다. speed는 0.61.5, 2.0이고, Sonic은 셋 모두를 엄격한 배율이 아니라 가이드로 다뤄 말투가 자연스럽게 유지되도록 합니다. 확실히 들리는 변화를 원하면 0.9 대신 0.7처럼 크게 조정하세요.volume은 0.5
텍스트 안에서 감정 바꾸기
transcript = (
'<emotion value="calm"/> I can help with that. '
'<emotion value="excited"/> Good news, your refund went through this morning!'
)
인라인 태그는 분명한 전환이 있는 대본 대사에 편리합니다. 텍스트 중간의 전환은 이 기능에서 가장 실험적인 부분이므로, 변화가 중요할 때는 각 부분을 별도의 생성 컨텍스트로 보내세요.
스트리밍 중에 감정 바꾸기
WebSocket API에서는 보내는 텍스트 조각마다 설정을 따로 줄 수 있습니다. LLM 토큰이 도착하는 대로 음성으로 바꾸는 에이전트라면 다음과 같은 형태입니다.
with client.tts.websocket_connect() as ws:
ctx = ws.context(
model_id="sonic-3.6",
voice="6ccbfb76-1fc6-48f7-b71d-91ac6298247b",
output_format={"container": "raw", "encoding": "pcm_s16le", "sample_rate": 44100},
language="en",
)
ctx.push("Well, maybe if you just ")
ctx.push("loosen up a little!", generation_config={"emotion": "angry"})
ctx.no_more_inputs()
for response in ctx.receive():
if response.type == "chunk" and response.audio:
... # play or buffer the audio
이 예제는 문서의 WebSocket 감정 제어 예제에서 가져왔습니다. 웃음이 필요하면 텍스트에 [laughter]를 넣으세요. 정확한 쉼이 필요하면 <break time="1s"/>를 쓰되, 대개는 쉼표나 마침표가 더 자연스러운 쉼을 만듭니다.
어떤 값을 고를까
먼저 주요 감정 6개, 즉 neutral, calm, angry, content, sad, scared부터 시작하세요. 학습 데이터가 가장 많은 값들입니다. 나머지 52개(sympathetic, apologetic, curious, skeptical, determined, sarcastic 등)는 전체 목록에 있으며, 주요 값이 비슷하지만 딱 맞지 않을 때 시험해 볼 만합니다. 많은 상담 에이전트는 세 가지로 충분합니다. 기본은 calm, 나쁜 소식에는 sympathetic, 문제가 해결되면 content입니다.
감정이 맞는지 확인하는 방법
감정은 TTS 품질 중 어떤 지표로도 잡히지 않는 부분입니다. 단어 오류율 같은 전사 기반 검사는 “기다려 주셔서 감사합니다”를 격분한 톤으로 읽어도 만점을 줍니다. 직접 들어야 하고, 상황을 염두에 두고 들어야 합니다.
- 듣는 사람에게 상황을 알려 주세요. “상담원이 고객에게 항공편 결항을 알리는 상황”이라고 하면 쓸모 있는 판단이 나옵니다. “이 클립을 평가해 주세요”라고 하면 목소리 자체에 대한 판단이 나옵니다.
- 문장 하나가 아니라 대화 전체로 테스트하세요. 한 턴에 맞는 감정이 세 턴 뒤에는 어색하게 들릴 수 있고, 통화 도중 목소리 분위기가 흘러가는 것은 맥락 속에서만 들리는 문제입니다.
- 청취자 의견이 갈린다고 예상하세요. 표현이 풍부한 에이전트를 좋아하는 사람도 있고, 같은 연기를 과장되고 피곤하다고 느끼는 사람도 있습니다. 평균으로 덮지 말고 갈린 결과를 그대로 보고하세요. MOS(평균 의견 점수) 가이드에서 숫자 하나가 이를 가리는 이유를 설명합니다.
- 실제 스트리밍 경로로 들으세요. 첫 오디오 청크에서 잘못된 감정을 고른 모델은 회복하지 못할 때가 있습니다. 오프라인 렌더링에서는 들리지 않습니다.
Cartesia가 맞는 곳
Sonic은 실시간 음성을 위해 만들어졌습니다. 음성 에이전트, 전화 통화, 말로 답하는 앱입니다. 기본적으로 감정은 텍스트에서 나오고, 제어는 스트리밍 중에도 작동하며, 감정 설정은 에이전트의 다른 부분처럼 테스트하고 버전 관리할 수 있는 이름 붙은 값입니다. 전화 에이전트를 만들면서 음성 인식, LLM, TTS를 직접 연결하고 싶지 않다면 Managed Agents가 Sonic을 목소리로 삼아 전체 루프를 실행합니다.
오디오북이나 영상 내레이션을 제작하면서 타임라인에서 한 줄씩 연기를 편집하고 싶다면, API보다 스튜디오형 편집기가 더 맞습니다. ElevenLabs 대안 가이드에서 몇 가지를 소개합니다.
차이를 직접 들어 보려면 플레이그라운드를 열고 Emotive 목소리를 고른 뒤, 같은 문장을 calm과 sympathetic으로 읽혀 보세요. 그다음 태그 없이도 미안하게 들리도록 문장을 고쳐 써 보세요. 대개 두 번째 실험에서 배우는 것이 더 많습니다.