Build a Voice Agent with C
This tutorial walks you through building a basic voice agent using C# and the Deepgram .NET SDK. You will learn how to connect to the Agent API, configure its behavior, and stream audio for processing.
Prerequisites
Section titled “Prerequisites”Before you begin, ensure you have the following:
- A Deepgram API key. You can get one in the Deepgram Console.
- The .NET SDK installed on your machine.
1. Set up your environment
Section titled “1. Set up your environment”Create a new console project and navigate into it.
mkdir deepgram-agent-demo
cd deepgram-agent-demo
dotnet new consoleExport your Deepgram API key as an environment variable.
# macOS/Linux
export DEEPGRAM_API_KEY="your_api_key"
# Windows PowerShell
$env:DEEPGRAM_API_KEY = "your_api_key"2. Install the Deepgram SDK
Section titled “2. Install the Deepgram SDK”Add the Deepgram .NET SDK to your project.
dotnet add package Deepgram3. Create the Voice Agent
Section titled “3. Create the Voice Agent”Open Program.cs and replace its content with the following code. This script connects to Deepgram, configures the agent, and streams a sample audio file.
using Deepgram;
using Deepgram.Logger;
using Deepgram.Models.Authenticate.v1;
using Deepgram.Models.Agent.v2.WebSocket;
using System.Collections.Generic;
using System.Net.Http;
namespace SampleApp
{
class Program
{
static async Task Main(string[] args)
{
try
{
Deepgram.Library.Initialize(LogLevel.Debug);
var apiKey = Environment.GetEnvironmentVariable("DEEPGRAM_API_KEY");
DeepgramWsClientOptions options = new DeepgramWsClientOptions(null, null, true);
var agentClient = ClientFactory.CreateAgentWebSocketClient(apiKey, options);
var lastAudioTime = DateTime.Now;
var audioFileCount = 0;
var settingsConfiguration = new SettingsSchema();
settingsConfiguration.Agent.Think.Provider.Type = "open_ai";
settingsConfiguration.Agent.Think.Provider.Model = "gpt-4o-mini";
settingsConfiguration.Audio.Output.SampleRate = 24000;
settingsConfiguration.Audio.Output.Container = "wav";
settingsConfiguration.Audio.Input.SampleRate = 24000;
settingsConfiguration.Agent.Greeting = "Hello, how can I help you today?";
settingsConfiguration.Agent.Listen.Provider.Type = "deepgram";
settingsConfiguration.Agent.Listen.Provider.Model = "nova-3";
settingsConfiguration.Agent.Speak.Provider.Type = "deepgram";
settingsConfiguration.Agent.Speak.Provider.Model = "aura-2-thalia-en";
bool connected = await agentClient.Connect(settingsConfiguration);
if (!connected)
{
Console.WriteLine("Failed to connect to Deepgram WebSocket server.");
return;
}
await agentClient.Subscribe(new EventHandler<AudioResponse>((sender, e) =>
{
if (DateTime.Now.Subtract(lastAudioTime).TotalSeconds > 7)
{
audioFileCount++;
using (BinaryWriter writer = new BinaryWriter(File.Open($"output_{audioFileCount}.wav", FileMode.Create)))
{
writer.Write(CreateWavHeader(24000, 16, 1));
}
}
if (e.Stream != null)
{
using (BinaryWriter writer = new BinaryWriter(File.Open($"output_{audioFileCount}.wav", FileMode.Append)))
{
writer.Write(e.Stream.ToArray());
}
}
lastAudioTime = DateTime.Now;
}));
string url = "https://dpgr.am/spacewalk.wav";
using (var httpClient = new HttpClient())
{
var response = await httpClient.GetAsync(url);
var stream = await response.Content.ReadAsStreamAsync();
var buffer = new byte[8192];
int bytesRead;
while ((bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length)) > 0)
{
var chunk = new byte[bytesRead];
Array.Copy(buffer, chunk, bytesRead);
await agentClient.SendBinaryImmediately(chunk);
}
}
Console.WriteLine("Press any key to exit...");
Console.ReadKey();
await agentClient.Stop();
Deepgram.Library.Terminate();
}
catch (Exception ex)
{
Console.WriteLine($"Exception: {ex.Message}");
}
}
static byte[] CreateWavHeader(int sampleRate, short bitsPerSample, short channels)
{
int byteRate = sampleRate * channels * (bitsPerSample / 8);
short blockAlign = (short)(channels * (bitsPerSample / 8));
byte[] header = new byte[44];
header[0] = 0x52; // R
header[1] = 0x49; // I
header[2] = 0x46; // F
header[3] = 0x46; // F
header[8] = 0x57; // W
header[9] = 0x41; // A
header[10] = 0x56; // V
header[11] = 0x45; // E
header[12] = 0x66; // f
header[13] = 0x6D; // m
header[14] = 0x74; // t
header[15] = 0x20; // Space
header[16] = 0x10; // Subchunk1Size
header[20] = 0x01; // AudioFormat
header[22] = (byte)channels;
header[24] = (byte)(sampleRate & 0xFF);
header[25] = (byte)((sampleRate >> 8) & 0xFF);
header[26] = (byte)((sampleRate >> 16) & 0xFF);
header[27] = (byte)((sampleRate >> 24) & 0xFF);
header[28] = (byte)(byteRate & 0xFF);
header[29] = (byte)((byteRate >> 8) & 0xFF);
header[30] = (byte)((byteRate >> 16) & 0xFF);
header[31] = (byte)((byteRate >> 24) & 0xFF);
header[32] = (byte)blockAlign;
header[34] = (byte)bitsPerSample;
header[36] = 0x64; // d
header[37] = 0x61; // t
header[38] = 0x74; // t
header[39] = 0x61; // a
return header;
}
}
}4. Run the Voice Agent
Section titled “4. Run the Voice Agent”Run your project using the .NET CLI.
dotnet runThe agent will process the audio and generate responses. You can find the agent's audio responses in output_*.wav files in your project directory.
Next steps
Section titled “Next steps”Now that you have built a basic agent, you can customize its behavior:
- Configure the Voice Agent: Explore all available settings for models and voices.
- Build a Voice Agent: Return to the overview to see other language options.