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

# Build a Prism agent with the SDK

> Build the backend of a Prism voice agent with the Rime SDK in Python or Node.js, and talk to it with your own instructions. The quickstart also explains the code and how to connect real callers.

In this quickstart, you'll run a Prism voice agent on your computer, give it your own instructions, and talk to it through your microphone and speakers.

You'll set up two parts. The server is your agent, built with our SDK. A page in your browser acts as the caller's phone. It captures your voice, plays the replies, and cancels the echo of Prism's voice, so laptop speakers work and you can interrupt Prism at any time.

## What you'll need

* A Rime API key. If you don't have one yet, [create one](https://docs.rime.ai/docs/api-authentication.md).
* [uv](https://docs.astral.sh/uv/getting-started/installation/) for Python, or Node.js 22 or later.
* A browser and a microphone.

## Set up with your coding agent

To build this agent backend and test page in your project, paste this prompt into Claude Code, Codex, or Cursor:

```text Prompt for your coding agent wrap theme={null}
Build the backend of a voice agent on Rime Prism, a speech-to-speech
voice-agent API, and a test page that lets me talk to the agent in my
browser, through my microphone.

Read these pages first, and follow them over anything you remember:
- https://docs.rime.ai/docs/prism/quickstart.md
- https://docs.rime.ai/docs/prism/live-conversations.md
- https://docs.rime.ai/api-reference/sdk/prism.md

Requirements:
- A server in Python (the latest rimelabs-sdk) or Node.js (the latest
  @rimelabs/sdk) reads RIME_API_KEY from the environment. The key never
  reaches the browser.
- The server uses the SDK's conversation runner: run_conversation in
  Python, or runConversation in Node.js. The browser connection is its
  source and playback adapter.
- The server connects to wss://prism.api.rime.ai/v1/realtime with my
  instructions and the voice aurora.
- The browser captures the microphone with echo cancellation on, and sends
  it to the server the whole time, also while Prism speaks.
- The browser plays Prism's 24 kHz mono PCM16 replies in order.
- When Prism reports that the caller started speaking, stop playback at
  once, drop the queued audio, and report how much of the reply played.
- The page shows the caller's transcript and Prism's reply text.

When it runs, tell me the command that starts it and the address to open.
```

When it's done, your coding agent tells you the command to run and the address to open.

## Set up by hand

To run our starter instead, follow these steps.

**1. Get the starter**

Clone the starter from the [rime-sdk repository](https://github.com/rimelabs/rime-sdk), at a tag that holds both the Python and Node.js servers:

```bash theme={null}
git clone --depth 1 --branch python-v0.1.0-alpha.20 https://github.com/rimelabs/rime-sdk.git
cd rime-sdk/examples/prism-web
```

Inside, you'll find one page and a server for each language:

| File | What it does |
| - | - |
| `public/` | The test page: your instructions, the voice, the microphone, playback, and the transcript |
| `server.py` | Your agent in Python, with `rimelabs-sdk` |
| `server.mjs` | Your agent in Node.js, with `@rimelabs/sdk` |
| `check.py`, `check.mjs` | A test without a microphone, for servers and CI |
| `question.wav` | The recorded question that the check sends |

For Go or Rust, see the [Prism SDK reference](https://docs.rime.ai/api-reference/sdk/prism.md).

**2. Set your API key**

Set your key in the terminal where you'll start the server:

**macOS and Linux**

```bash theme={null}
export RIME_API_KEY="YOUR_API_KEY"
```

**Windows PowerShell**

```powershell theme={null}
$env:RIME_API_KEY = "YOUR_API_KEY"
```

**3. Start the server**

**Python**

Start the server with uv. The first run installs the SDK.

```bash theme={null}
uv run server.py
```

**Node.js**

Install the packages, and then start the server:

```bash theme={null}
npm install
node server.mjs
```

The server prints the page's address:

```text theme={null}
Open http://localhost:3000 and press Start.
```

**4. Talk to your agent**

Open [http://localhost:3000](http://localhost:3000) in your browser. The instructions box starts with a made-up cafe, so you can start talking right away:

1. Keep the instructions, or paste your own system prompt.
2. Choose a voice. Prism has four: `aurora`, `wawona`, `brando`, and `astra`.
3. Press **Start**, and allow the microphone when the browser asks.
4. Ask "What's on the menu?" in English.
5. While Prism lists the menu, ask "What time do you close?" Prism stops and answers the new question.

You should hear each answer, and the page shows a transcript like this one:

```text theme={null}
Connecting to Prism...
Ready. Start talking.
You: Hi there, what's on the menu?
Prism: We have a latte for $5, a cold brew for $4, and a blueberry muffin for $3.
You: Sorry, what time do you close?
Prism: We close at 4 p.m. every day.
```

The wording changes from run to run, but the prices and closing time come from your instructions, so they'll stay the same. While you try it:

* **To change the voice or instructions:** press **Stop**, make the change, and press **Start**. Each start is a new conversation.
* **If the page shows an error:** look up its code in [Errors and limits](https://docs.rime.ai/docs/prism/errors.md). If the server stops right away and asks for `RIME_API_KEY`, set it in the terminal that runs the server.
* **If port 3000 is in use:** start the server with `PORT=3001`, and open [http://localhost:3001](http://localhost:3001).

## How the starter works

The server is the part you keep and build on:

```mermaid theme={null}
%%{init: {"sequence": {"mirrorActors": false}}}%%
sequenceDiagram
    participant Page as Caller (the page in your browser)
    participant Server as Your server
    participant Prism
    Server->>Prism: Connect with your API key, voice, and instructions
    Page->>Server: Microphone audio, the whole time
    Server->>Prism: The same audio, also while Prism speaks
    Prism->>Server: Reply text and audio
    Server->>Page: Reply audio to play
    Page->>Server: How much of the reply played
    Server->>Prism: Playback report
```

Your whole agent is three parts: one connect call, the SDK's conversation runner, and two audio adapters. Here are the first two, simplified from the `talk` function in [`server.py`](https://github.com/rimelabs/rime-sdk/blob/python-v0.1.0-alpha.20/examples/prism-web/server.py#L167) and [`server.mjs`](https://github.com/rimelabs/rime-sdk/blob/python-v0.1.0-alpha.20/examples/prism-web/server.mjs#L164):

**Python**

```python theme={null}
async with client.realtime.connect(voice=voice, instructions=instructions) as session:
    await run_conversation(session, source=browser, playback=browser, on_event=show)
```

**Node.js**

```javascript theme={null}
const session = await client.realtime.connect({ voice, instructions });
await runConversation(session, { source: browser, playback: browser, onEvent });
```

The SDK connects to `wss://prism.api.rime.ai/v1/realtime`. Then the runner handles the work that every Prism conversation needs:

* It sends the microphone audio the whole time, even while Prism speaks, so Prism can hear an interruption.
* It plays each reply in order.
* It stops playback at once when the caller talks over a reply.
* It reports how much of each reply the caller heard, because Prism keeps only that part.

The two adapters are yours: `source` brings in the caller's audio, and `playback` plays each reply and measures how much the caller heard. In the starter, one `Browser` object is both adapters, passing audio to and from the page, and the event callback shows the transcript. Swap the adapters, and the same agent can answer phone calls or run inside your own app.

## Connect real callers

When you're ready, real callers can reach your agent in one of three ways:

* **Your own application:** write a `source` and a `playback` adapter for its audio, and keep the rest of the server. [Live conversations](https://docs.rime.ai/docs/prism/live-conversations.md) explains each step.
* **A LiveKit room:** the [LiveKit quickstart](https://docs.rime.ai/docs/prism/livekit.md) builds the agent with LiveKit Agents, and the Rime plugin connects to Prism for you.
* **A phone line:** the phone audio goes through your server, and only the adapters change. They convert the audio for Prism and play the replies back, as [Phone audio](https://docs.rime.ai/docs/prism/live-conversations.md#phone-audio) in Live conversations explains.

## Test without a microphone

A server, a CI job, or a coding agent's sandbox has no microphone, so the starter's check sends a recorded question instead:

**Python**

```bash theme={null}
uv run check.py
```

**Node.js**

```bash theme={null}
node check.mjs
```

Here's the output from one run:

```text theme={null}
Caller started speaking
Caller stopped speaking
Prism: We close at 4 p.m.
Saved 1.6 seconds of audio to reply.wav
```

The recording, `question.wav`, is a caller asking when the cafe closes today. The check sends it at a microphone's pace, followed by silence, so Prism can find the end of the turn. If Prism says 4 p.m., the connection, turn detection, and instructions all worked, and you can hear the answer in `reply.wav`.

### Use your own recording

The check reads a 16 kHz mono WAV file. To ask your own question:

1. Record your question in English.
2. Convert the recording with [FFmpeg](https://ffmpeg.org/download.html). This command reads `recording.mp3` and writes `recording.wav`:

   ```bash theme={null}
   ffmpeg -i recording.mp3 -ac 1 -ar 16000 -c:a pcm_s16le recording.wav
   ```
3. Run the check with your file: `uv run check.py recording.wav` or `node check.mjs recording.wav`. The check's instructions cover only the cafe's hours, so change them for other questions.

> [!TIP]
>
> **Record the question without long pauses:** Prism finds the end of the turn by itself, so a long pause can end the turn early. The check then stops after the first part, or fails with `Reply cancelled: turn_detected`.

## Use the API without the SDK

To use a plain WebSocket client instead, for a backend in any language, follow the [WebSocket quickstart](https://docs.rime.ai/docs/prism/websocket-quickstart.md).

## Next steps

Now that your agent answers, you can:

* [Write your own system prompt](https://docs.rime.ai/docs/prism/sessions.md#write-instructions-for-a-phone-call), starting with rules for speech.
* [Give Prism tools](https://docs.rime.ai/docs/prism/tools.md), so it can ask your backend for data it doesn't have, such as Saturday's opening hours.
* [Choose the voice that suits your callers](https://docs.rime.ai/docs/prism/sessions.md#choose-a-voice) from the four that Prism offers.
* [Make Prism speak first](https://docs.rime.ai/docs/prism/typed-turns.md) with a nudge, or send it typed text.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.