> ## Documentation Index
> Fetch the complete documentation index at: https://docs.sambanova.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Cartesia

[Cartesia](https://cartesia.ai) は低レイテンシの音声合成 (text-to-speech) プラットフォームです。websocket API がテキストを少しずつ受け取り、受け取った端から音声をストリーミングで返すため、テキスト全体が揃う前に発話を始められます。

これは SambaCloud と相性のよい仕組みです。SambaNova はモデルの回答をトークン単位でストリーミングするため、届いた断片をそのまま Cartesia に渡せます。モデルが回答の続きを書いている間に、冒頭から聞き始められます。

本ガイドでは、両者をつなぐ仕組みを説明し、最小構成のスクリプトを順に見た上で、[SambaNova integrations リポジトリ](https://github.com/sambanova/integrations/tree/main/cartesia_integration) の完全なターミナル音声チャットを実行します。

> [!NOTE]
>
> この例では、音声フレームワークを使わず、SambaNova と Cartesia の SDK を直接使用します。音声認識 (speech-to-text)・ターンテイキング (turn-taking)・電話連携 (telephony) まで備えた音声エージェントを構築する場合は、どちらも Cartesia に対応している [Pipecat](https://docs.sambanova.ai/docs/ja/integrations/pipecat.md) と [LiveKit](https://docs.sambanova.ai/docs/ja/integrations/livekit.md) をご参照ください。

## 前提条件

* [SambaCloud](https://cloud.sambanova.ai/?utm_source=cartesia\&utm_medium=external\&utm_campaign=cloud_signup) アカウントと [API キー](https://cloud.sambanova.ai/apis?utm_source=cartesia\&utm_medium=external\&utm_campaign=cloud_signup)
* [Cartesia](https://play.cartesia.ai/keys) アカウントと API キー
* Python 3.11 以上
* スピーカーまたはヘッドホン
* Debian または Ubuntu の場合は PortAudio ライブラリ (`sudo apt install libportaudio2`)。macOS と Windows では追加の準備は不要です

## 仕組み

2 つのストリームが同時に動きます。

1. **SambaNova から Cartesia へ**。チャット補完を `stream=True` でリクエストし、テキストのデルタ (delta) が届くたびに Cartesia の websocket の「コンテキスト」に送り込みます。
2. **Cartesia からスピーカーへ**。同じコンテキストからは、発話に十分なテキストが溜まり次第、生の音声チャンクが返されます。各チャンクは届いた端から再生されます。

Cartesia のコンテキストは、1 回の発話 (utterance) に対応します。そこに送り込んだテキストはすべてひと続きの音声として読み上げられるため、テキストが断片で届いても声は自然なままです。モデルの生成が終わったら、`no_more_inputs()` で発話の完了を Cartesia に伝えます。

```text theme={}
question ─► SambaCloud (stream=True) ── text deltas ──► Cartesia context ── audio chunks ──► speakers
```

> [!NOTE]
>
> この例では、すぐに回答を返し始める `Meta-Llama-3.3-70B-Instruct` を使用しています。`gpt-oss-120b` のような Reasoning モデルを使う場合、モデルの reasoning はストリームの別フィールドで届きます。Cartesia に送られるのは `delta.content` だけなので reasoning が読み上げられることはありませんが、最初の言葉までの無音にはなります。`chat.completions.create` に `reasoning_effort="low"` を渡すと、この無音を短く抑えられます。完全な例では、`gpt-oss` 系のモデルに対してこの指定を自動で行います。

## 最小構成の例

以下のスクリプトは、1 つの質問を送り、ストリーミングで届く回答をそのまま読み上げます。

**1. パッケージのインストール**

```bash theme={}
pip install sambanova==1.13.0 "cartesia[websockets]==4.2.0" sounddevice==0.5.6 python-dotenv==1.1.0
```

> [!NOTE]
>
> `[websockets]` の指定は必須です。これがないと、websocket 接続を開くときに Cartesia SDK がエラーを送出します。

**2. API キーの設定**

スクリプトと同じディレクトリに `.env` ファイルを作成します。

```bash .env theme={}
SAMBANOVA_API_KEY="your-sambanova-api-key"
CARTESIA_API_KEY="your-cartesia-api-key"
```

**3. スクリプトの作成**

以下を `speak.py` として保存します。

```python speak.py theme={}
import asyncio
import os

import sounddevice as sd
from cartesia import AsyncCartesia
from dotenv import load_dotenv
from sambanova import AsyncSambaNova

load_dotenv()

QUESTION = 'In two sentences, why is the sky blue?'
SAMPLE_RATE = 44100


async def main() -> None:
    llm = AsyncSambaNova(api_key=os.environ['SAMBANOVA_API_KEY'])
    tts = AsyncCartesia(api_key=os.environ['CARTESIA_API_KEY'])
    speaker = sd.RawOutputStream(samplerate=SAMPLE_RATE, channels=1, dtype='int16')
    speaker.start()

    async with tts.tts.websocket_connect() as conn:
        # One context = one utterance. Text pushed into it is spoken as it arrives.
        ctx = conn.context(
            model_id='sonic-3.6',
            voice={'mode': 'id', 'id': '6ccbfb76-1fc6-48f7-b71d-91ac6298247b'},
            output_format={'container': 'raw', 'encoding': 'pcm_s16le', 'sample_rate': SAMPLE_RATE},
            language='en',
        )

        async def write() -> None:
            stream = await llm.chat.completions.create(
                model='Meta-Llama-3.3-70B-Instruct',
                messages=[{'role': 'user', 'content': QUESTION}],
                stream=True,
            )
            async for chunk in stream:
                text = chunk.choices[0].delta.content if chunk.choices else None
                if text:  # only the answer is spoken, never the model's reasoning
                    print(text, end='', flush=True)
                    await ctx.push(text)
            await ctx.no_more_inputs()

        async def speak() -> None:
            async for event in ctx.receive():
                if event.type == 'chunk' and event.audio:
                    await asyncio.to_thread(speaker.write, event.audio)
                elif event.type == 'error':
                    raise RuntimeError(event.message or event.title or 'unknown error')

        await asyncio.gather(write(), speak())

    speaker.stop()  # waits for the last audio to finish playing
    speaker.close()
    await tts.close()
    print()


asyncio.run(main())
```

**4. 実行**

```bash theme={}
python speak.py
```

回答がターミナルに表示され、表示が終わらないうちに読み上げが始まります。

`write()` と `speak()` は `asyncio.gather` によって並行に実行されます。モデルの生成が終わる前に音声の再生を始められるのは、この並行実行のおかげです。`speaker.write` はサウンドカードのバッファが空くまでブロックするため、スレッドで実行し、SambaNova のストリームを処理するイベントループを塞がないようにしています。

> [!NOTE]
>
> どちらの例も、`language='en'` で英語の発話を指定しています。英語以外の回答もそのまま読み上げられますが、英語のアクセントになります。別の言語で話させるには、`language` を変更し、[Cartesia のボイスライブラリ](https://play.cartesia.ai/voices) からその言語のボイスを選択してください。

## 完全な例: ターミナル音声チャット

[Cartesia 連携のサンプル](https://github.com/sambanova/integrations/tree/main/cartesia_integration) は、最小構成のスクリプトを発展させたもので、複数ターンの会話、回答ごとのレイテンシ計測、Ctrl-C による回答の途中停止、Cartesia のソケット切断時の再接続を備えています。

**1. リポジトリのクローン**

```bash theme={}
git clone https://github.com/sambanova/integrations.git
cd integrations/cartesia_integration
```

**2. 仮想環境の作成と依存パッケージのインストール**

```bash theme={}
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
```

**3. API キーの設定**

```bash theme={}
cp .env.example .env
```

`.env` を開き、`SAMBANOVA_API_KEY` と `CARTESIA_API_KEY` を設定します。その他の設定は任意です。

| 変数 | デフォルト値 | 説明 |
| :- | :- | :- |
| `SAMBANOVA_MODEL` | `Meta-Llama-3.3-70B-Instruct` | 任意の [SambaCloud モデル](https://docs.sambanova.ai/docs/ja/models/sambacloud-models.md) |
| `CARTESIA_MODEL` | `sonic-3.6` | Cartesia の音声合成モデル |
| `CARTESIA_VOICE_ID` | `6ccbfb76-1fc6-48f7-b71d-91ac6298247b` | [Cartesia のボイスライブラリ](https://play.cartesia.ai/voices) の任意のボイス |

**4. 会話の開始**

```bash theme={}
python main.py
```

質問を入力して Enter キーを押します。Ctrl-C で回答を途中で停止でき、`exit` と入力すると終了します。

```text theme={}
Connected to Cartesia in 1005 ms. Model: Meta-Llama-3.3-70B-Instruct.
Type a question and press Enter. Ctrl-C stops an answer, "exit" quits.

you > why is the sky blue?

  The sky is blue because of the way light behaves when it enters our atmosphere. When sunlight comes in, it's made up of all different colors, but our atmosphere scatters the shorter, blue wavelengths more than the others. This scattering effect is what gives the sky its blue color, and it's why it usually looks blue on a sunny day. It's pretty cool how it all works together like that.

  first token    846 ms   (SambaNova inference: 150 ms)
  first sound   1169 ms   (Cartesia)
  audio 22.6 s generated in 4.0 s  (5.6x realtime)
```

### 計測値の読み方

回答が終わるたびに、サンプルは 3 つの計測値を表示します。いずれも、質問を送信した瞬間からの計測です。

* **First token**: 回答の最初の語が手元のマシンに届くまでの時間。括弧内の値は SambaNova 自身の推論時間で、ネットワークを含みません。両者の差がネットワークの往復分で、お使いの回線に依存します。
* **First sound**: Cartesia から最初の音声が届くまでの時間。音が聞こえ始めるまでの待ち時間です。
* **Realtime**: 待ち時間 1 秒あたりに生成された音声の秒数。1x を超えていれば、音声は再生よりも速く届くため、再生が途切れることはありません。

Cartesia への接続は起動時に 1 度だけ開かれ、すべての回答で再利用されます。そのため、接続時のハンドシェイクはこれらの数値に含まれません。

## トラブルシューティング

> [accordion] You need to install cartesia\[websockets]
>
> websocket クライアントは、Cartesia SDK のオプションの追加依存 (extra) です。`pip install "cartesia[websockets]==4.2.0"` でインストールするか、これを含むサンプルの `requirements.txt` からインストールしてください。

> [accordion] PortAudio is not installed, or OSError: PortAudio library not found
>
> `sounddevice` には PortAudio ライブラリが必要です。Debian または Ubuntu では `sudo apt install libportaudio2` を実行してください。macOS と Windows ではパッケージに同梱されています。

> [accordion] 音声出力デバイスを開けない
>
> スピーカーまたはヘッドホンが接続され、デフォルトの出力デバイスとして選択されているか確認してください。SSH やコンテナなどのリモートセッションには、通常は音声デバイスがありません。

> [accordion] 認証エラーまたは HTTP 401
>
> `.env` ファイルの `SAMBANOVA_API_KEY` と `CARTESIA_API_KEY` を確認してください。完全な例では、Cartesia の API キーが拒否されると `Could not connect to Cartesia: … HTTP 401` と表示されます。

> [accordion] Cartesia からのエラーメッセージ
>
> 不明なボイス ID や、契約プランでは利用できないモデルなど、Cartesia 側で発生したエラーは、Cartesia 自身のメッセージとともに表示されます。`CARTESIA_VOICE_ID` と `CARTESIA_MODEL` を確認してください。

> [accordion] 最初の言葉までの無音が長い
>
> Reasoning モデルは、回答を始める前に考える時間を取ります。`SAMBANOVA_MODEL` を `gpt-oss-120b` のような Reasoning モデルに設定している場合は、デフォルトの `Meta-Llama-3.3-70B-Instruct` に戻してください。また、SambaNova が報告する最初のトークンまでの時間は負荷によっても変動するため、1 回だけ遅い回答があっても異常ではありません。

## 参考情報

ボイス、モデル、websocket API の詳細については、[Cartesia の公式ドキュメント](https://docs.cartesia.ai) をご参照ください。
