资讯详情

AI自动接电话实战:从SIP网关到ASR+LLM+TTS的完整工程实现

📅 2026/10/20 7:34:48 | 华诺云谱 👁 阅读
AI自动接电话实战:从SIP网关到ASR+LLM+TTS的完整工程实现
这次我们来看一个很直接的自建项目AI 自动接电话。项目名字相当口语就叫“快点接电话啦”。它要做的事情可以用一句话概括电话响铃时系统自动接起来先识别对方在说什么再由大模型生成回复最后用语音合成把回复播出去整个环节不需要人动手操作。这类项目最有价值的地方不在某个“新模型”而在“工程拼装”把 SIP 语音网关、语音识别 ASR、大模型 LLM、语音合成 TTS 四个相对成熟的环节串成一条可用的通话链路。只要链路能跑通后续加多路并发、加通话日志、加转人工都很方便。难点往往是“电话没声音”“转写一直空”“回复太慢”这类细节而不是任务本身有多神秘。本文会先从整体规格和适用场景讲清楚再按环境准备、部署启动、功能测试、接口与批量任务、资源占用、问题排查、最佳实践的顺序展开。文章偏工程实践不会把某个模型的原理从头推一遍你需要能跑 Python、熟悉 Linux 基本命令并且最好准备一台可以 24 小时运行的主机。电话线路方面强烈建议先拿内部分机或测试线路验证不要一开始就直接暴露到真实号码上。如果你正在给自己的工作环境做一个“漏接电话秘书”或者准备做企业前台语音机器人这篇可以直接收藏备用。1. 核心能力速览能力项说明项目类型自建 AI 自动接听电话项目本质是 SIP 网关与多个 AI 模型的组合方案解决什么问题来电自动接起、实时听懂对方、自动生成回复、语音播报回复核心链路SIP 语音网关 → 语音识别 ASR → 大模型 LLM → 语音合成 TTS主要功能自动应答、实时转写、语义回复、TTS 播报、通话日志与录音留存启动方式命令行启动可注册为 systemd 服务实现开机自启接口能力可提供 HTTP 或 WebSocket 回调方便对接已有业务系统批量任务支持来电排队和多路并发超过并发上限时排队或转语音信箱推荐硬件普通 x86 主机即可起步低并发可在 CPU 上运行有 NVIDIA GPU 可明显降低 ASR 和 TTS 延迟显存占用没有固定值取决于 ASR、TTS、LLM 三个模型的选择实际需要按本机测试适合读者Python 开发者、语音机器人入门者、想做个人或企业 AI 电话助理的团队这里的“项目”不是单一仓库而是一套可以用多种开源组件拼出来的架构。如果你手头已经有某个具体的开源仓库那就以那份仓库的文档为准本文讲的是通用的实现思路和验证方法。下面的所有命令、路径和配置文件都属于示例结构实际使用时需要替换为你自己的组件和路径。2. 适用场景与使用边界这类“AI 接电话”方案最适合下面几个场景个人漏接电话场景你在开会或不方便接电话时AI 先接起说“您好我现在不方便接听请留下您的需求”然后由 ASR 转写内容再用 LLM 整理成文字发到你的聊天工具里。企业前台座席忙线场景所有线路都占线时AI 作为应急应答兜底记录来电意图再把记录转给人工回访。语音机器人开发学习场景用来学习 SIP 协议、实时音频处理、ASR、LLM、TTS 完整链路是非常好的综合项目。但使用边界必须划清楚第一不要做未经同意的外呼营销。自动外呼骚扰电话在很多地区都是明确的违规行为。即使是在测试阶段外呼号码也必须是你自己拥有或有明确授权的号码且被叫方知情同意。第二不要伪造来电显示不要伪装成公共服务号码。这类行为涉嫌欺诈没有任何技术合理性可以洗白。第三涉及声音克隆时必须获得被克隆人的明确授权。TTS 部分如果使用真人音色克隆使用范围只限于授权场景不能拿去生成冒用他人身份的内容。第四通话录音要慎重。如果系统需要录音保存应当在通话开始前通过语音提示告知对方通话可能被录音如果所在地区对录音有严格合规要求宁可先不做录音只保存转写文本。第五不要在未完成充分测试时把真实号码接入。先用软电话、内部分机、测试线路验证稳定性再决定是否开放真实线路。3. 环境准备与前置条件下面给出一套通用的前置检查清单不绑定具体发行版项目建议要求操作系统LinuxDebian/Ubuntu 系最方便Windows 也可以做部分功能验证主机配置普通 x86 主机内存建议不低于 4GB若本地跑大模型建议 16GB 以上GPU可选不是必须CPU 可以跑通完整链路只是延迟更高Python3.10 或更高版本通话通道支持 SIP 的软电话、话机或一个可以注册到本地语音网关的通道音频设备如果只是测试 SIP 网关主机可以不插声卡设备由软电话提供端口要求SIP 默认使用 5060/5061RTP 使用 10000 到 20000 之间的 UDP 端口云服务器需要放行对应 UDP 端口磁盘空间至少预留 10GB用于存放模型文件、日志和录音在开始安装前先把软电话选好。Windows 上可以准备 MicroSIP 之类的 SIP 软电话Linux 上可以选用 Linphone 或通过 WebRTC 方式接入。测试目标很简单先用软电话注册到本地 SIP 网关拨打一个内部测试分机确认能正常响铃再往里面加 AI 逻辑。网络环境也要注意。如果主机在 NAT 后面SIP 网关的防火墙和 NAT 穿透规则要提前处理。否则会出现“软电话显示已注册但一打电话就断线”或者“接听之后双方都听不到声音”的情况。先用纯内网 IP 测试避免一开始就和公网 NAT 纠缠。模型选型方面给出一个参考组合ASR中文场景优先考虑 FunASR 或者 Whisper 系列。CPU 上可用 Whisper 的 tiny/base 模型先跑通链路再根据效果换大模型。LLM可以用本地的 Ollama、vLLM也可以使用 OpenAI 兼容接口。电话回复场景要求低延迟建议把系统提示词写成“简洁、口语化、一次只回答一个问题”。TTS可以用 edge-tts 快速验证它使用起来简单如果要求离线则用 CosyVoice 或 GPT-SoVITS 这类模型但需要更多资源和授权准备。4. 安装部署与启动方式整套方案建议拆成两个层次来做第一层先解决“电话能自动接起来”。 第二层再解决“接起来之后AI 能听懂、能回答、能播报”。先做第一层。以常见的 SIP 网关为例安装命令大概是这样的sudo apt-get update sudo apt-get install -y asterisk sudo systemctl enable --now asterisk然后配置一个测试分机。下面是一份示意配置只用于理解流程不保证在不同版本环境下可以直接运行[transport-udp] typetransport protocoludp bind0.0.0.0:5060 [1000] typeendpoint contextfrom-internal disallowall allowulaw allowalaw direct_mediano authauth1000 aors1000 [auth1000] typeauth auth_typeuserpass passwordtest1234 username1000 [1000] typeaor max_contacts1这段配置的意思是网关监听 UDP 5060 端口提供一个内部测试分机 1000密码是 test1234。软电话注册到这台机器后就能作为内部线路互相拨打测试。特别注意direct_mediano它强制媒体流经过服务器方便后续做 ASR 和录音如果开启直连媒体AI 可能拿不到通话音频。紧接着配置拨号方案让分机一拨通某个号码就进入自动应答流程[from-internal] exten 888,1,Answer() same n,Wait(1) same n,Playback(hello) same n,Hangup()这个配置让用户拨打 888 时网关自动接听播放一段hello提示音然后挂断。只要能跑通这一步说明“自动接电话”的物理链路已经打通。接下来做第二层把 ASR、LLM、TTS 接入通话链路。通常的做法是写一个常驻 Python 进程通过通话网关的事件接口接收通话事件然后在通话接通后开始处理音频流。核心逻辑的伪代码大致如下audio await read_audio_until_silence(timeout2.0) text asr_client.transcribe(audio) if not text.strip(): reply 抱歉我刚才没有听清可以再说一遍吗 else: reply llm_client.chat( system_prompt你是电话助理回复要简短自然控制在50字以内。, user_texttext, ) tts_audio tts_client.synthesize(reply) await play_audio(tts_audio)流程看起来不复杂但真实项目里有几个关键点通话音频通常是 8k 采样率而很多现成 ASR 模型更适合 16k 音频。需要先确认所选 ASR 对 8k 音频的支持情况必要时做重采样。read_audio_until_silence 要考虑回音问题。如果开着扬声器AI 自己播报的声音可能又被 ASR 识别进去形成回声。测试时最好用耳机或者启用回声消除模块。LLM 回复要控制长度。电话场景不是写文章回复越长TTS 播报时间越长进入等待对方说话的静音期就越久。系统提示词里直接限制在 30 到 60 字是更合理的做法。启动整个服务时可以先用前台命令观察日志python voice_bot.py --config config.yaml确认没有报错后再注册成 systemd 服务[Unit] DescriptionAI Phone Bot Afternetwork.target [Service] Userphonebot WorkingDirectory/opt/phonebot ExecStart/opt/phonebot/venv/bin/python voice_bot.py --config config.yaml Restartalways RestartSec3 [Install] WantedBymulti-user.target使用 systemd 的好处是崩溃后会自动重启开机也能自动拉起适合长时间运行的电话服务。5. 功能测试与效果验证部署完成后按下面的顺序做功能测试。每次只加一个变量不要一次测太多功能否则出问题后很难定位。5.1 基础接通测试测试目的确认电话能被自动接起。操作步骤用软电话拨打测试号码 888。预期结果电话被自动接起能听到 hello 提示音几秒后挂断。判断标准如果软电话显示通话建立但听不到声音说明媒体流没有到服务器先查 RTP 端口和 direct_media 配置。失败排查如果一直没有应答查网关日志确认拨号方案里的 extensions 是否匹配。5.2 ASR 转写测试测试目的确认对方说的话能变成文本。操作步骤给机器人通话说一句“你好我想咨询一下产品价格”。预期结果日志里能输出对应的转写文本。判断标准转写内容基本一致没有大面积错字。失败排查转写为空时先把通话录音保存成 wav 文件离线用 ASR 模型测试同一个文件。如果离线能识别说明链接到实时音频流时格式不对如果离线也识别不了说明模型效果不匹配需要换模型或提升采样率。5.3 LLM 回复测试测试目的确认回复质量是否适合电话场景。操作步骤先在纯文本环境测试 LLM输入“我想咨询产品价格”看回复是否简洁自然。预期结果回复在 50 字以内没有长篇大论。判断标准表达口语化没有“作为一个人工智能”这类不适合电话朗读的冗长表达。失败排查如果回复过长调整系统提示词如果回复不稳定降低 temperature 到 0.6 左右。5.4 TTS 播报测试测试目的确认文字能转成声音并播报给对方。操作步骤手动触发一次 TTS 合成例如edge-tts --voice zh-CN-XiaoxiaoNeural --text 您好请问有什么可以帮您 --write-media out.mp3预期结果生成一个可播放的音频文件。判断标准播放时没有明显爆音和断句错误。失败排查如果播放到通话里出现“只能听到前半句”说明音频格式和网关节点的语音编码不一致需要转成带特定采样率或压缩格式的音频。5.5 完整端到端测试把 5.1 到 5.4 连起来拨打一次测试电话并说一句完整的话。关键要看三个数字从说完话到 AI 开始回复的时间也就是响应延迟。AI 播报是否会被 ASR 再次识别形成回声循环。通话结束后的日志和录音是否完整存储。端到端测试建议至少连续拨 20 次覆盖不同语速、不同音量和不同表达习惯的测试者才能基本排除随机偶发问题。6. 接口 API 与批量任务完整链路跑通后下一步就是把能力接口化方便接到自己的业务系统里。内部接口可以设计成下面这种结构但要注意这只是一个示例实际端点路径要根据项目实现调整不能照搬。{ endpoints: { answer: POST /api/call/answer, generate_reply: POST /api/llm/generate, call_log: POST /api/call/log } }推荐把 LLM 回复封装成一个独立的同步接口。这样业务系统可以在不触发电话外呼的情况下先对同一段用户文本做回复测试再决定是否接入真实通话。Python 调用模板如下import requests url http://127.0.0.1:8000/api/llm/generate payload { user_text: 你好我想咨询一下产品价格, system_prompt: 你是电话助理回复要简短自然控制在50字以内。, temperature: 0.6 } response requests.post(url, jsonpayload, timeout30) print(response.json())超时时间建议设置得短一些。电话场景里对方不会有耐心等一个超过 5 秒的回复如果 LLM 超时接口应该返回一个兜底文案例如“抱歉我正在处理请稍后再试”。这个兜底文案在正式使用中非常重要它避免了通话中的尴尬静音。批量任务的处理方式和一般图像生成或文档处理的批量任务不太一样。这里的“批量”更像是“批量接听排队来电”。单路测试通过后再开启多路并发。并发上限由网关授权、ASR 线程数、LLM 请求并发数共同决定。超出上限的来电不应该排队等待而应该直接转给语音信箱或提示稍后再试因为人工等待成本太高。如果要做自动外呼每一次外呼都必须有明确授权和合规依据。除非是内部测试分机之间的自动拨打否则不建议自动外呼。任务队列建议使用 Redis 或数据库表来记录每条通话的状态包含字段通话 ID、主叫号码、被叫号码、开始时间、结束时间、转写文本、LLM 回复、录音文件路径、处理状态。这样即使进程崩溃也能根据数据库记录重放或补偿。7. 资源占用与性能观察电话机器人是实时系统性能观察不能只看“能跑”还要看“延迟能不能被接受”。先看 CPU 和内存。启动后可以用以下命令持续观察top -p $(pgrep -f voice_bot.py) free -h如果有 GPU则用watch -n 1 nvidia-smi关键性能指标有三个第一ASR 识别延迟。通常从按下通话音频开始到输出文本延迟越低越好。如果发现延迟过高可以试试更小的模型或者开启流式识别。第二LLM 首 token 延迟。电话场景对首 token 延迟很敏感模型再聪明如果 3 秒才输出第一句话体验也会很差。建议使用支持流式输出的 OpenAI 兼容服务并设置较低的 max_tokens。第三TTS 合成延迟。一次性合成长文本会很慢更合理的做法是把 LLM 回复按句子拆分先合成第一句并播放后面的句子再并行合成从而实现“边说边合成”。通话音频的采样率也需要关注。SIP 网关的默认语音编码通常只提供 8k 采样率而商用语音合成和识别在 16k 或更高采样率下效果更好。如果测试发现中文识别错误率明显偏高先检查是不是采样率失配再考虑换模型。延迟优化还可以从业务流程入手在对方说话停顿的间隙就提前让 ASR 做部分识别LLM 回复生成后立刻开始 TTS 播放不要等到整句话生成完毕。8. 常见问题与排查方法问题现象可能原因排查方式解决方案软电话能注册但一打电话就挂断拨号方案未匹配或鉴权信息不对查看网关实时日志核对 extensions 和 context 配置电话接通了但听不到声音RTP 端口被防火墙拦截或 NAT 配置错误抓包查看 RTP 流是否到达服务器放行 UDP 10000-20000 端口关闭 direct_media接起后只有嘟嘟声没有语音语音编码不一致查看协商编码在网关配置中固定使用 ulaw 或 alawASR 转写始终为空音频采样率不对或回声干扰先保存录音离线测试重采样到 ASR 支持的采样率开启回声消除LLM 接口返回超时模型服务排队或网络到模型服务不稳定直接 curl 测试模型接口增加超时兜底减少并发请求TTS 播报只播一半音频格式与网关不匹配查看网关音频日志将音频转成网关支持的 wav 或 ulaw 格式多路并发时开始卡顿ASR 或 LLM 请求没有做并发控制观察 CPU 和模型服务并发数量使用请求队列限制最大并发系统重启后机器人不工作服务未设开机自启查看 systemd 状态启用 voice_bot.service通话日志丢失数据库写入失败或路径无权限查看日志文件目录权限指定持久化存储目录并设置权限部署后一直回显自己的声音未做回声消除或外放音量过大测试时用耳机开启 AEC降低扬声器音量9. 最佳实践与使用建议给准备长期运行这个项目的读者几条建议。第一做一套最小可运行配置。不要把 ASR、LLM、TTS 的所有参数混在一个文件里。把配置拆成config.yaml里面明确区分网关地址、模型路径、端口、提示词模板、日志目录、录音目录。这样换环境部署时只改配置不动代码。第二先跑通“单路通话”再考虑并发。真实项目里最多的问题都出现在并发上ASR 线程阻塞、LLM 请求超时、TTS 音频播放资源冲突。单路稳定运行一周后再逐步开放第二路、第三路。第三录音文件要定期归档。每通电话的录音和转写文本应该用同一通话 ID 关联。日志保留时间建议至少 30 天但也要考虑隐私合规要求不需要长期保留的录音要定期删除。第四LLM 提示词要针对电话场景单独调优。可以准备多套提示词模板比如开场白模板告知对方这里是语音助手正在记录来电内容。未听清模板礼貌请求对方重复。转人工模板检测到对方需要人工服务时记录信息并承诺稍后回电。结束语模板确认没有其他需求后自然结束通话。第五部署时段要分阶段。先用内部分机测试再开放给少数测试号码最后才考虑真实场景。真实场景开放前至少完成 100 通以上的测试电话并统计成功率、平均延迟、错误率三个指标。第六注意模型和依赖的版本更新。ASR、TTS、LLM 服务经常更新更新前先备份旧版本配置和模型文件。不要在生产环境下直接升级核心依赖。10. 总结与下一步“快点接电话啦”这个项目最值得尝试的地方不是某一个 AI 模型有多强而是把电话通信和多个 AI 能力完整串起来的工程经验。你真正学会的是SIP 网关怎么配置、实时音频怎么处理、ASR 怎么接入链路、LLM 怎么写出适合朗读的回复、TTS 怎么在低延迟下播报以及整套服务的日志、并发、异常处理怎么做。最先要验证的功能一定是“电话能不能被自动接起并播放一段语音”。这一步是最基础的物理链路这里如果有问题后面所有 AI 能力都无从谈起。最容易踩的坑是 RTP 音频不通表现为双方建立了通话但没有声音排查优先级最高。后续扩展方向可以考虑把转写文本和回复内容自动发送到钉钉、飞书或企业微信群机器人。在 LLM 回复中识别“转人工”“投诉”“回电”等意图触发不同的后续流程。加入姓名和手机号的实体识别把对方留下的联系方式自动提取到通话记录里。将多路来电接入任务队列结合业务系统实现工单自动创建。先把单路链路跑稳再逐步扩展。电话机器人是一个“看起来简单实际上很考工程细节”的项目值得认真调试几轮。
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑