跳到主要内容基于 Azure 和 OpenAI 构建智能语音客服系统 | 极客日志PythonSaaSAI
基于 Azure 和 OpenAI 构建智能语音客服系统
一个基于 Azure 和 OpenAI 的智能呼叫中心解决方案。它支持通过 API 发起 AI 代理电话或接听来电,适用于保险、IT 支持等场景。核心功能包括自然语言对话、通话生命周期管理、实时低延迟响应、动态工单收集及多渠道支持。文章提供了系统要求、安装步骤(Python 环境、Azure 配置)、API 使用说明及核心代码片段解析,帮助开发者快速部署智能语音助手。
不知所云1 浏览 基于 Azure 和 OpenAI 构建智能语音客服系统
Call Center AI 是一个基于 Azure 和 OpenAI 的智能呼叫中心解决方案。它允许你通过 API 发起由 AI 代理拨打的电话,或直接接听来自配置号码的来电。该项目旨在帮助开发者在几小时内(而非几周)为保险、IT 支持、客户服务等场景定制和部署智能语音助手。
示例:让 AI 机器人拨打电话
curl --header 'Content-Type: application/json' \
--request POST \
--url https://your-instance/call \
--data
'{"bot_company": "Contoso", "bot_name": "Amélie", "phone_number": "+11234567890", "task": "帮助客户解决数字化工作场所问题。助手为 IT 支持部门工作,目标是帮助客户解决问题并收集工单信息。", "agent_phone_number": "+33612345678", "claim": [{"name": "硬件信息", "type": "text"}, {"name": "首次发现时间", "type": "datetime"}, {"name": "建筑位置", "type": "text"}]}'
功能特性
- 🤖 AI 驱动的语音交互:集成了 Azure OpenAI 服务,实现与客户的自然语言对话,自动处理复杂的对话流程和任务。
- 📞 完整的通话生命周期管理:支持呼入和呼出电话,具备实时音频流、断线重连、通话录音和事件回调,确保通话的稳定性和连续性。
- ⚡️ 实时响应与低延迟:通过 WebSocket 实现音频流的实时双向传输,结合智能语音活动检测(VAD)和文本转语音(TTS)流式处理,提供流畅的对话体验。
- 📋 动态工单收集:可在通话开始前动态定义需要收集的信息(如文本、日期时间等),AI 助手会在对话中自然地引导客户提供,并结构化输出。
- 🔧 高度可扩展的工具调用:内置插件系统,允许 AI 助手在对话中执行特定操作,如结束通话、创建新工单、转接人工坐席等,并可轻松扩展自定义工具。
- 📱 多渠道支持:除了语音通话,还集成了 SMS 功能,可以在通话前后通过短信与客户互动,例如发送通话摘要或询问额外信息。
安装指南
系统要求
- Python 3.10+
- 一个 Azure 订阅(需开通 Communication Services、OpenAI、Speech Services 等服务)
- (可选)一个 Twilio 账户(如果使用 Twilio 作为 SMS 提供商)
分步安装
uvicorn app.main:app --host 0.0.0.0 --port 8000 --reload
配置环境变量或配置文件
项目支持从环境变量或 YAML 文件加载配置。复制示例配置文件并根据你的 Azure 资源进行修改。
cp config.example.yaml config.yaml
或者,你也可以将所有配置放入名为 CONFIG_JSON 的环境变量中(JSON 格式)。
pip install -r requirements.txt
git clone https://github.com/your-repo/call-center-ai.git
cd call-center-ai
使用说明
发起一个由 AI 代理拨打的电话
通过 API 端点 /call 发起一个 POST 请求,即可让 AI 机器人主动呼叫指定的电话号码。
import requests
import json
url = "https://your-instance/call"
payload = {
"bot_company": "Contoso",
"bot_name": "Amélie",
"phone_number": "+11234567890",
"task": "帮助客户解决网络连接问题。",
"agent_phone_number": "+33612345678",
"claim": [
{"name": "用户 ID", "type": "text"},
{"name": "问题描述", "type": "text"}
]
}
headers = {'Content-Type': 'application/json'}
response = requests.post(url, headers=headers, data=json.dumps(payload))
print(response.json())
接收来电
将你在 Azure Communication Services 或 Twilio 中配置的电话号码指向你的服务端点。当有来电时,服务会自动应答,并启动 AI 助手与客户对话。
核心 API 概览
POST /call: 发起一个新的由 AI 代理拨打的电话。
POST /events: 用于接收来自 Azure Communication Services 的通话事件回调(如通话已连接、已断开、DTMF 识别结果等)。
- WebSocket
/ws: 用于与实时音频流进行双向通信,实现低延迟的语音交互。
POST /sms: 用于接收 SMS 消息的回调端点。
核心代码
1. 呼叫入口与事件处理 (app/main.py - 片段)
这是 FastAPI 应用的入口,定义了接收来电和事件回调的核心端点。
from fastapi import FastAPI, Request
app = FastAPI()
@app.post("/events")
async def events(request: Request) -> JSONResponse:
"""处理来自 Azure Communication Services 的回调事件。
包括新呼入、通话已连接、已断开、DTMF 识别等。
"""
cloud_events = await request.json()
for cloud_event in cloud_events:
event = CloudEvent.from_dict(cloud_event)
logger.info("收到事件:%s", event.type)
if event.type == "Microsoft.Communication.CallLegStateChanged":
if event.data["state"] == "Connected":
await on_call_connected(...)
elif event.type == "Microsoft.Communication.PlayCompleted":
await on_automation_play_completed(...)
return JSONResponse(status_code=HTTPStatus.OK, content={})
@app.post("/call")
async def outbound_call(
request: OutboundCallRequest,
background_tasks: BackgroundTasks,
) -> JSONResponse:
"""发起一个由 AI 代理拨打的呼出电话。
"""
call_state = CallStateModel(
await _db.call_create(call_state)
background_tasks.add_task(
start_outbound_call,
callback_url=str(request.url_for("events")),
call=call_state
)
return JSONResponse(status_code=HTTPStatus.ACCEPTED, content={"call_id": str(call_state.call_id)})
2. AI 对话核心逻辑 (app/helpers/call_llm.py - 片段)
这是 AI 对话管理的核心,负责接收用户语音识别结果,调用 LLM,并将 LLM 的响应转换为语音。
@start_as_current_span("call_load_llm_chat")
async def load_llm_chat(
audio_in: asyncio.Queue[bytes],
audio_out: asyncio.Queue[bytes | bool],
audio_sample_rate: int,
automation_client: CallAutomationClient,
call: CallStateModel,
post_callback: Callable[[CallStateModel], Awaitable[None]],
scheduler: Scheduler,
training_callback: Callable[[CallStateModel], Awaitable[None]],
) -> None:
"""加载并运行 LLM 聊天循环。从 audio_in 队列获取用户的语音输入,
将其转换为文本,发送给 LLM,然后将 LLM 的文本响应转换为语音放入 audio_out 队列。
"""
async with SttClient(call=call, sample_rate=audio_sample_rate) as stt_client, \
use_tts_client(call.locale) as tts_synthesizer:
def tts_callback(text: str):
asyncio.create_task(handle_realtime_tts(text, tts_synthesizer, audio_out))
tools_plugin = DefaultPlugin(
call=call,
client=automation_client,
post_callback=post_callback,
scheduler=scheduler,
tts_callback=tts_callback,
tts_client=tts_synthesizer,
)
messages = await _init_messages(call)
messages.append(MessageModel(persona=PersonaEnum.ASSISTANT, text=call.greeting))
while True:
transcript = await stt_client.wait_for_transcript()
if transcript:
messages.append(MessageModel(persona=PersonaEnum.USER, text=transcript))
async for delta in completion_stream(
max_tokens=call.max_tokens,
messages=messages,
system=call.prompts,
tools=tools_plugin.tools_definitions,
):
if delta.content:
await tts_callback(delta.content)
if delta.tool_calls:
await tools_plugin.execute_tool_call(delta.tool_calls[0])
3. 缓存装饰器 (app/helpers/cache.py)
项目使用自定义的 LRU 缓存装饰器来优化异步和同步函数的性能,减少重复计算和外部服务调用。
from collections import OrderedDict
from functools import wraps
import asyncio
from collections.abc import Awaitable
def lru_acache(maxsize: int = 128):
"""异步函数的 LRU 缓存装饰器。
缓存函数的返回值。当达到最大大小时,最久未使用的缓存项会被移除。
"""
def decorator(func):
cache: OrderedDict[tuple, Awaitable] = OrderedDict()
@wraps(func)
async def wrapper(*args, **kwargs):
key = (id(asyncio.get_event_loop()), args, frozenset(kwargs.items()),)
if key in cache:
cache.move_to_end(key)
return cache[key]
value = await func(*args, **kwargs)
cache[key] = value
cache.move_to_end(key)
if len(cache) > maxsize:
cache.popitem(last=False)
return value
return wrapper
return decorator
def lru_cache(maxsize: int = 128):
"""同步函数的 LRU 缓存装饰器,原理同上。
# ... 实现
微信扫一扫,关注极客日志
微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
相关免费在线工具
- RSA密钥对生成器
生成新的随机RSA私钥和公钥pem证书。 在线工具,RSA密钥对生成器在线工具,online
- Mermaid 预览与可视化编辑
基于 Mermaid.js 实时预览流程图、时序图等图表,支持源码编辑与即时渲染。 在线工具,Mermaid 预览与可视化编辑在线工具,online
- curl 转代码
解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online
- Base64 字符串编码/解码
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
- Base64 文件转换器
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online
- Markdown 转 HTML
将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML 转 Markdown 互为补充。 在线工具,Markdown 转 HTML在线工具,online