与OpenAI GPT实时聊天
使用OpenAI实时API进行双向音频对话的实时语音聊天应用程序。
🎯 功能
- 🎤 实时音频捕获 从麦克风
- 🤖 OpenAI实时API集成 与模型
gpt-realtime-mini-2025-10-06 - 💬 自动转录 对话(用户和IA)
- 🔊 音频响应 直接在浏览器中播放
- 🎨 界面现代且响应迅速 带动画
- ⚡ 通信WebSocket 双向(客户端↔ C服务器↔ OpenAI)
🏗️ 建筑
Client Web (Browser)
↓ WebSocket
Serveur ASP.NET Core 9.0
↓ WebSocket
OpenAI Realtime API数据流
- 用户音频 麦克风→客户端→WebSocket→C服务器→OpenAI
- 答复IA OpenAI→C服务器→WebSocket→客户端→扬声器
📋 先决条件
- .NET 9.0 SDK 或更高
- CléAPI开放人工智能 访问实时API
- 现代浏览器 支持WebSocket和Web音频API(建议使用Chrome、Edge)
- 麦克风 功能性
🚀 安装
1.克隆或下载项目
cd /chemin/vers/chatrealtime2.配置OpenAI API密钥
打开文件 appsettings.json 并替换 YOUR_OPENAI_API_KEY_HERE 通过您的API密钥:
{
"OpenAI": {
"ApiKey": "sk-proj-xxxxxxxxxxxxxxxxxxxxx",
"Model": "gpt-realtime-mini-2025-10-06",
...
}
}3.恢复依赖关系
dotnet restore4.Lancer l'application
dotnet run该应用程序将在以下网站提供:
- 超文本传输协议 : http://localhost:5000
- 超文本传输安全协议 : https://localhost:5001
⚙️ 配置
所有配置都在 appsettings.json :
| 参数 | 描述 | 默认值 |
|---|---|---|
ApiKey | 要配置的OpenAI API密钥 | |
Model | 要使用的OpenAI模型 | gpt-realtime-mini-2025-10-06 |
Voice | 人工智能之声(合金、回声、寓言、玛瑙、新星、闪光) | echo |
TranscriptionModel | 转录模型 | gpt-4o-transcribe |
SystemPromptFile | 包含系统提示的文件 | Prompts/Marvin.md |
Temperature 答案的创造性(0.0-2.0) | 0.8 | |
MaxResponseOutputTokens | 最大输出令牌数 | 4096 |
Instructions | 内联系统说明(如果没有文件) | 可自定义文本 |
TurnDetection.Type | 语音转动检测类型 | server_vad |
TurnDetection.Threshold | 语音检测阈值(0.0-1.0) | 0.5 |
TurnDetection.SilenceDurationMs | 句子结尾的沉默时间 | 500 ms |
Tools | MCP工具列表(见下文) | [] |
🎭 自定义快速系统
该应用程序支持 来自Markdown文件的提示系统 :
{
"OpenAI": {
"SystemPromptFile": "Prompts/Marvin.md"
}
}提供的示例 : Prompts/Marvin.md -H2G2抑郁机器人马文的个性
要创建自己的个性:
- 创建文件
.md在文件中Prompts/ - 描述个性、风格和说明
- 更新
SystemPromptFile在appsettings.json
🛠️ 配置MCP(模型上下文协议)
您可以配置 外部工具 AI可以在对话期间调用:
{
"OpenAI": {
"Tools": [
{
"Name": "get_weather",
"Description": "Obtenir la météo actuelle pour une ville donnée",
"Parameters": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "Le nom de la ville (ex: Paris, Londres)"
},
"unit": {
"type": "string",
"enum": ["celsius", "fahrenheit"],
"description": "L'unité de température"
}
},
"required": ["location"]
}
}
]
}
}MCP工具的结构
| 冠军 | 类型 | 描述 |
|---|---|---|
Name | 字符串 | 工具的唯一名称(snake-case) |
Description | 字符串 | 描述工具的功能 |
Parameters | 对象 | 参数JSON模式(OpenAPI格式) |
MCP工具示例
1.天气
{
"Name": "get_weather",
"Description": "Obtenir la météo actuelle",
"Parameters": {
"type": "object",
"properties": {
"location": { "type": "string", "description": "Ville" }
},
"required": ["location"]
}
}2.当前时间
{
"Name": "get_time",
"Description": "Obtenir l'heure actuelle dans un fuseau horaire",
"Parameters": {
"type": "object",
"properties": {
"timezone": { "type": "string", "description": "Fuseau horaire (ex: Europe/Paris)" }
},
"required": ["timezone"]
}
}3.计算器
{
"Name": "calculate",
"Description": "Effectuer un calcul mathématique",
"Parameters": {
"type": "object",
"properties": {
"expression": { "type": "string", "description": "Expression mathématique" }
},
"required": ["expression"]
}
}⚠️ 关于MCP的重要注意事项
配置的工具包括: 宣布 OpenAI API,但您必须 实现执行逻辑 在您的代码中。
API将向您发送事件 function_call 您需要拦截和处理 OpenAIRealtimeService.cs.
🎵 音频配置
L应用程序利用率 soundtouch js 倾倒修改器la vitesse音频 不改变声音的音高 :
- 界面中的滑块 0.5x 至 2.0x
- 启动缓冲区 :8个块(可配置的数据块)
app.js第29行)
要调整缓冲区(如果有中断):
// Dans wwwroot/app.js
this.minBufferChunks = 10; // Augmenter pour plus de stabilité个性化示例
倒水器la voix:
"Voice": "nova"可用语音: alloy, echo, fable, onyx, nova, shimmer
🌐 MCP工具的REST API
除了语音接口,所有MCP工具都是 可通过HTTP REST访问 !
可用端点
1.工具清单
GET /api/tools答复 :
{
"count": 2,
"tools": [
{
"name": "get_weather",
"description": "Obtenir la météo actuelle pour une ville donnée",
"parameters": { ... }
},
{
"name": "get_time",
"description": "Obtenir l'heure actuelle dans un fuseau horaire donné",
"parameters": { ... }
}
]
}2.运行(通用)工具
POST /api/tools/{toolName}
Content-Type: application/json
{
"location": "Paris",
"unit": "celsius"
}答复 :
{
"tool": "get_weather",
"success": true,
"result": {
"location": "Paris",
"temperature": 22,
"unit": "°C",
"condition": "Ensoleillé",
"description": "Il fait actuellement 22°C à Paris avec un temps ensoleillé."
},
"executedAt": "2025-10-08T14:30:00Z"
}3.实用捷径
天气 :
GET /api/tools/weather/Paris?unit=celsius小时 :
GET /api/tools/time/Europe_Pariscurl示例
# Liste des outils
curl http://localhost:5166/api/tools
# Météo à Paris
curl http://localhost:5166/api/tools/weather/Paris
# Météo en Fahrenheit
curl http://localhost:5166/api/tools/weather/London?unit=fahrenheit
# Heure à New York
curl http://localhost:5166/api/tools/time/America_New_York
# Exécution générique
curl -X POST http://localhost:5166/api/tools/get_weather \
-H "Content-Type: application/json" \
-d '{"location": "Tokyo", "unit": "celsius"}'实施的工具
🌤️ get_weather
获取城市天气(模拟数据)
设置 :
location(字符串,必填):城市名称unit(字符串,可选):celsius或fahrenheit
示例 :
curl http://localhost:5166/api/tools/weather/Paris🕐 get_time
获取时区中的当前时间
设置 :
timezone(字符串,必需):时区(例如:Europe/Paris,America/New_York)
示例 :
curl http://localhost:5166/api/tools/time/Europe_Paris🧮 calculate
执行简单的数学计算
设置 :
expression(字符串,必需):数学表达式(例如:2 + 2,10 * 5)
示例 :
curl -X POST http://localhost:5166/api/tools/calculate \
-H "Content-Type: application/json" \
-d '{"expression": "2 + 2"}'添加您自己的工具
选项1:HTTP工具(调用本地或外部URL)
帕菲倒 调用您自己的API 不带修饰符的C#代码!
{
"Tools": [
{
"Name": "mon_outil_local",
"Description": "Appelle mon API locale",
"Type": "http",
"Parameters": {
"type": "object",
"properties": {
"param1": { "type": "string", "description": "Premier paramètre" }
},
"required": ["param1"]
},
"Http": {
"Url": "http://localhost:3000/api/mon-endpoint",
"Method": "POST",
"Headers": {
"Authorization": "Bearer mon-token",
"X-Custom-Header": "valeur"
}
}
}
]
}HTTP工具示例 :
1.使用URL中的参数进行GET调用 :
{
"Name": "get_user",
"Type": "http",
"Parameters": { ... },
"Http": {
"Url": "http://localhost:3000/users/{user_id}",
"Method": "GET"
}
}2.使用body json进行POST调用 :
{
"Name": "create_task",
"Type": "http",
"Parameters": { ... },
"Http": {
"Url": "http://localhost:5000/tasks",
"Method": "POST",
"Headers": {
"Content-Type": "application/json"
}
}
}3.调用外部API :
{
"Name": "check_stock",
"Type": "http",
"Parameters": { ... },
"Http": {
"Url": "https://api.example.com/stock/{symbol}",
"Method": "GET",
"Headers": {
"X-API-Key": "votre-clé-api"
}
}
}选项2:内置工具
对于在C#中具有自定义逻辑的工具:
- 声明工具 在
appsettings.json与"Type": "builtin" - 实现逻辑 在
Services/Tools/ToolExecutorService.cs - 工具将是 自动可用 :
- 通过API REST(POST /api/tools/{nom}) - 通过语音人工智能(马文可以打电话给他)
马文现在可以调用您的工具了!🤖
当你和马文谈话时,他可以 自动 :
- 调用本地API(本地主机)
- 使用内置工具(天气、时间、计算)
- 通过语音向您传达结果
对话示例 :
- 您 “马文,巴黎现在几点?”
- 马文 : *自动呼叫
get_time与timezone: "Europe/Paris"* - 马文 “现在是巴黎下午2点30分……对我巨大的大脑来说,这是另一个徒劳的问题……”
🛡️ HTTP调用弹性(Polly)
L应用程序利用率 波莉,弹性图书馆。NET引用,用于管理工具的HTTP调用 重试政策 和 断路器.
默认配置
{
"OpenAI": {
"Resilience": {
"Retry": {
"Enabled": true,
"MaxRetryAttempts": 3,
"InitialDelayMs": 100,
"MaxDelayMs": 5000
},
"CircuitBreaker": {
"Enabled": true,
"FailureThreshold": 5,
"BreakDurationSeconds": 30,
"SamplingDurationSeconds": 60
},
"Timeout": {
"Enabled": true,
"TimeoutSeconds": 30
}
}
}
}📋 复原力政策
1.重试(重试策略) 🔄
- 指数退避 :初始延迟100ms,每次尝试加倍,最多5秒
- 3个尝试 默认情况下
- 自动触发:
- 瞬态HTTP错误(500、502、503、504、408) - 超时 - 网络错误
2.断路器(断路器) ⚡
- 保护您的API 防止过载
- 之后打开 5échecs 在一个窗口 60秒
- 保持开放 30秒 (不打电话)
- 切换到“半打开”模式以测试API是否返回
- 国家 :
- 🟢 关闭(Closed) :正常操作 - 🔴 Open(开放) :所有请求立即失败 - 🟡 半开放式(半开放式) :测试服务是否返回
3.超时(超时) ⏱️
- 30秒 默认为HTTP请求
- 避免无限期阻塞的呼叫
策略架构(执行顺序)
Circuit Breaker (outermost)
↓
Retry Policy (middle)
↓
Timeout Policy (innermost)
↓
HTTP Request- 乐 断路器 检查他是否应该让请求通过
- 啦 重试策略 处理失败,必要时重试
- 乐 超时 限制每次尝试的持续时间
- HTTP请求最终被执行
Logs de Polly
策略生成详细日志:
[Polly Retry] Retry 1/3 after 100ms. Reason: 503 Service Unavailable
[Polly Retry] Retry 2/3 after 200ms. Reason: Timeout
[Polly Circuit Breaker] Circuit opened for 30s. Reason: 500 Internal Server Error
[Polly Circuit Breaker] Circuit half-open (testing)
[Polly Circuit Breaker] Circuit reset (closed)
[Polly Timeout] Request timed out after 30s个性化
你可以 停用 或 调整 每个政策单独:
禁用重试 :
{
"Resilience": {
"Retry": {
"Enabled": false
}
}
}增加尝试次数 :
{
"Resilience": {
"Retry": {
"Enabled": true,
"MaxRetryAttempts": 5,
"InitialDelayMs": 200,
"MaxDelayMs": 10000
}
}
}断路器+接触器 :
{
"Resilience": {
"CircuitBreaker": {
"Enabled": true,
"FailureThreshold": 3,
"BreakDurationSeconds": 60,
"SamplingDurationSeconds": 30
}
}
}Cas d'usage
不稳定的外部API :
{
"Retry": { "MaxRetryAttempts": 5 },
"CircuitBreaker": { "FailureThreshold": 10 }
}快速本地电话 :
{
"Retry": { "MaxRetryAttempts": 2, "MaxDelayMs": 1000 },
"Timeout": { "TimeoutSeconds": 5 }
}重试次数(测试唯一性) :
{
"Retry": { "Enabled": false },
"CircuitBreaker": { "Enabled": false }
}优势
- ✅ 提高可靠性 :自动处理瞬态错误
- ✅ 过载保护 :电路断路器保护您的API
- ✅ 详细日志 :故障和重试的完全可见性
- ✅ 无代码配置 :我们来配置一下
appsettings.json - ✅ 标准。网 :Polly是参考弹性库
📋 即用配置示例
该项目包括几个不同用例的示例文件:
1.不稳定的外部API (appsettings.example-external-unstable.json)
{
"Resilience": {
"Retry": { "MaxRetryAttempts": 5, "InitialDelayMs": 500, "MaxDelayMs": 15000 },
"CircuitBreaker": { "FailureThreshold": 10, "BreakDurationSeconds": 60 },
"Timeout": { "TimeoutSeconds": 60 }
}
}2.快速本地呼叫 (appsettings.example-local-fast.json)
{
"Resilience": {
"Retry": { "MaxRetryAttempts": 2, "InitialDelayMs": 50, "MaxDelayMs": 500 },
"CircuitBreaker": { "FailureThreshold": 3, "BreakDurationSeconds": 10 },
"Timeout": { "TimeoutSeconds": 5 }
}
}3.无弹性测试 (appsettings.example-no-resilience.json)
{
"Resilience": {
"Retry": { "Enabled": false },
"CircuitBreaker": { "Enabled": false },
"Timeout": { "Enabled": false }
}
}4.平衡生产 (appsettings.example-production.json)
{
"Resilience": {
"Retry": { "MaxRetryAttempts": 4, "InitialDelayMs": 200, "MaxDelayMs": 10000 },
"CircuitBreaker": { "FailureThreshold": 7, "BreakDurationSeconds": 45 },
"Timeout": { "TimeoutSeconds": 30 }
}
}使用 :
# Copier un exemple
cp appsettings.example-production.json appsettings.json
# Ou fusionner la section "Resilience" dans votre config existante📖 完整指南 :咨询 Prompts/ResilienceGuide.md 倾倒:
- 了解每个参数
- 选择正确的配置
- 避免常见陷阱
- 快速决策表
🎮 使用
模式人声
- 打开应用程序 在您的浏览器中
- 选择麦克风 在下拉列表中
- 点击“开始收听” (按钮变红)
- 自然说话 -人工智能将自动响应您
- 莱斯转录 实时显示在聊天中
- 点击“停止收听” 倾析仪
视觉指示器
- 🟢 垂直 :准备倾听
- 🔴 胭脂 :积极倾听
- 💬 祝福我们 :你的话
- 💬 消息gris :来自IA的答案
📁 项目结构
chatrealtime/
├── Configuration/
│ └── OpenAISettings.cs # Configuration OpenAI
├── Models/
│ ├── RealtimeEvents.cs # Événements API Realtime
│ └── ClientMessage.cs # Messages WebSocket
├── Services/
│ ├── OpenAIRealtimeService.cs # Service connexion OpenAI
│ └── RealtimeWebSocketHandler.cs # Gestion WebSocket client
├── wwwroot/
│ ├── index.html # Interface utilisateur
│ ├── styles.css # Styles CSS
│ └── app.js # Logique JavaScript
├── Program.cs # Point d'entrée
├── appsettings.json # Configuration
└── chatrealtime.csproj # Fichier projet🔧 技术规格
音频
- 格式 :PCM16(16位线性PCM)
- 采样率 :24 000赫兹
- 频道 :单声道(1个声道)
- 缓冲区大小 :4096个样本
WebSocket
- 端点客户端 :
ws(s)://host/ws/realtime - 持久连接 :120秒
- 设置邮件格式 :JSON
消息WebSocket
客户端→服务器
{
"type": "audio",
"audio": "base64_encoded_pcm16_data"
}服务器→客户端
{
"type": "audio|transcript|status|error",
"audio": "base64_audio",
"transcript": "texte transcrit",
"role": "user|assistant",
"status": "message de statut"
}🐛 解决问题
“未配置OpenAI API密钥”
➡️ 确保已在中配置API密钥 appsettings.json
“无法访问麦克风”
➡️ 在浏览器设置中允许麦克风访问
“无法连接到OpenAI”
➡️ 检查:
- 您的API密钥有效
- 您可以访问实时API
- 您的internet连接正在工作
答案中没有声音
➡️ 检查:
- 浏览器的音量
- 导航员的权限
- 无论您使用的是Chrome还是Edge
📝 重要事项
- 成本 :OpenAI实时API按使用付费。监控你的消费。
- 浏览器 :建议使用Chrome和Edge以获得更好的兼容性
- 安全 :切勿将API密钥提交到公共存储库
- 生产 :对于生产,使用环境变量存储API密钥
🔒 安全
对于生产,使用环境变量:
export OpenAI__ApiKey="sk-proj-xxxxx"
dotnet run或配置 appsettings.Development.json (未版本化):
{
"OpenAI": {
"ApiKey": "votre-clé-ici"
}
}📚 资源
📄 许可证
本项目用于教育和示范目的。
