All recipes
GoIntermediate

OpenAI GPT Live with Go

Build a real-time GPT Live voice agent with Agora and Go.

Use with Agora CLI

Clone the recipe and configure it with an Agora project.

Agora CLI
agora init my-openai-gpt-live-go --recipe openai-gpt-live-go

Recipe prompt

Paste into Cursor, Claude Code, v0, or your coding agent
Use with your coding agent
You are implementing the "OpenAI GPT Live with Go" recipe in this project.

Read the recipe markdown first:
https://raw.githubusercontent.com/AgoraIO-Community/OpenAI-Agora-Voice-Agents-Go/main/docs/ai/RECIPE.md

Use the source repository for cross-reference:
https://github.com/AgoraIO-Community/OpenAI-Agora-Voice-Agents-Go

Build this recipe into the user's app using the markdown as the implementation guide. Inspect related source files through the repository links when the recipe points to them. Ask before installing new dependencies.

Recipe

Rendered from the configured recipe markdown.

Raw

Build an OpenAI GPT Live voice agent with Go

Use Agora's Go SDK to place an OpenAI GPT Live voice agent in an Agora channel. GPT Live handles speech input, reasoning, and speech output as one MLLM stage. The included browser client publishes microphone audio and displays transcripts, agent state, and latency metrics.

ItemValue
SDKgithub.com/AgoraIO/agora-agents-go/v2@v2.8.1
Provideropenai_gpt_live
Modelgpt-live-1
Voicecedar
BackendGo and Gin
Web clientNext.js

Prerequisites

  • Go 1.23 or newer
  • Node.js 22 or newer
  • pnpm
  • GNU Make
  • Agora CLI
  • An Agora project with an App ID and App Certificate
  • An OpenAI API key with GPT Live access

Run the recipe

Clone the repository and install its dependencies:

git clone git@github.com:AgoraIO-Community/OpenAI-Agora-Voice-Agents-Go.git
cd OpenAI-Agora-Voice-Agents-Go
make setup

Use the Agora CLI to select a project and write its credentials to server/.env:

agora login
agora project use <your-project-name-or-id>
agora project env write server/.env --template standard

Add your OpenAI key to server/.env:

OPENAI_API_KEY=your_openai_api_key

Start the Gin backend and Next.js client:

make dev

Open http://localhost:3000, allow microphone access, and select Start conversation.

Configure GPT Live

The following function is a complete SDK example. Pass the channel and UIDs used by the browser, retain the returned session, and stop it when the call ends.

package main

import (
	"context"
	"os"

	"github.com/AgoraIO/agora-agents-go/v2/agentkit"
	"github.com/AgoraIO/agora-agents-go/v2/agentkit/vendors"
	"github.com/AgoraIO/agora-agents-go/v2/option"
)

func startAgent(
	ctx context.Context,
	channel string,
	agentUID string,
	userUID string,
) (string, *agentkit.AgentSession, error) {
	client := agentkit.NewAgoraClient(agentkit.AgoraClientOptions{
		Area:           option.AreaUS,
		AppID:          os.Getenv("AGORA_APP_ID"),
		AppCertificate: os.Getenv("AGORA_APP_CERTIFICATE"),
	})

	enableRTM := true
	enableErrors := true
	enableMetrics := true
	enableTools := false
	dataChannel := agentkit.ParametersDataChannel("rtm")
	idleTimeout := 30
	expiresIn, err := agentkit.ExpiresInHours(1)
	if err != nil {
		return "", nil, err
	}

	agent := agentkit.NewAgent(
		client,
		agentkit.WithAdvancedFeatures(&agentkit.AdvancedFeatures{
			EnableRtm:   &enableRTM,
			EnableTools: &enableTools,
		}),
		agentkit.WithParameters(&agentkit.SessionParams{
			DataChannel:        &dataChannel,
			EnableErrorMessage: &enableErrors,
			EnableMetrics:      &enableMetrics,
		}),
		agentkit.WithAudioScenario(agentkit.ParametersAudioScenario("chorus")),
	).WithMllm(vendors.NewOpenAIGPTLive(vendors.OpenAIGPTLiveOptions{
		APIKey:          os.Getenv("OPENAI_API_KEY"),
		Model:           "gpt-live-1",
		Voice:           "cedar",
		Prompt:          "You are a concise and helpful voice assistant.",
		GreetingMessage: "Hello! How can I help?",
		Messages: []map[string]interface{}{
			{"role": "user", "content": "My name is Arlene."},
			{"role": "assistant", "content": "Nice to meet you, Arlene."},
		},
	}))

	session := agent.CreateSession(agentkit.CreateSessionOptions{
		Channel:     channel,
		AgentUID:    agentUID,
		RemoteUIDs:  []string{userUID},
		IdleTimeout: &idleTimeout,
		ExpiresIn:   expiresIn,
	})
	agentID, err := session.Start(ctx)
	if err != nil {
		return "", nil, err
	}
	return agentID, session, nil
}

The complete sample generates an RTC+RTM token before starting the agent. The browser and agent join the same channel with different UIDs, and RemoteUIDs identifies the browser user whose audio the agent should process.

Customize the conversation

Go optionRequest fieldPurpose
Promptmllm.params.promptPersistent system instructions
GreetingMessagemllm.greeting_messageRequested opening line
Messagesmllm.messagesPrior user and assistant turns
Voicemllm.params.voiceOutput voice

Use Prompt for system behavior and Messages to continue an earlier conversation. Keep credentials and conversation history on the server.

Stop the agent

Retain the session returned by startAgent and stop it when the call ends:

err := session.Stop(context.Background())

For a multi-instance deployment, store lifecycle ownership in shared state or route start and stop requests to the same instance.

Verify the project

make test
make verify-web

See the project README for architecture, deployment, configuration options, and troubleshooting.