原文首发自 BMPI: https://www.bmpi.dev/dev/free4chat/
GitHub: https://github.com/i365dev/free4chat (1.1k⭐,三个分支:golang / elixir / cloudflare)
一句话总结
这不是一个"技术升级"的故事,而是一个 "运维成本归零"与"控制权出让"之间的反复校准。作者用三次重写回答了同一个问题:个人项目的边界在哪里? —— 不是性能极限,而是你愿意为多少控制权付出多少运维时间。
三个版本的核心决策逻辑
| 维度 | Go + Pion(第一版) | Elixir + Membrane(第二版) | Cloudflare + RTK(第三版) |
|---|---|---|---|
| 核心动机 | 学习 WebRTC 底层 | 集群扩容 + 分布式状态 | 运维归零 |
| SFU 控制权 | 完全自建 | 完全自建 | 托管,无底层控制 |
| 集群扩容 | 手工实现,复杂 | OTP 原生,极简 | 托管,无需关心 |
| 运维成本 | 中(\(5-10/月 + coturn) | 中高(\)10-20/月,双节点) | 极低($0-5/月,按量付费) | |
| 开发效率 | 中 | 高 | 极高(vibe coding 一个周末) |
| AI 语音注入 | ✅ 可实现 | ✅ 可实现 | ❌ 不可实现(RTK 不暴露 WHIP) |
| 调试体验 | 一般 | 优(LiveDashboard + remote REPL) | 一般(Worker 日志) |
| 适合场景 | 学习 WebRTC 底层、需要定制 SFU | 生产集群、高并发、需要 AI 语音 | 个人项目、零运维、快速上线 |
关键洞察:没有"最好的技术栈",只有"边界最匹配的技术栈"。三个版本的产品目标从未改变——改变的只是运维负担。
第一版:Go + Pion,1核1G 扛住千人并发
核心事实:一台 AWS 1核1G 实例,近千人访问,上千个房间,服务器负载几乎没有变化。
这证明了 SFU 架构的本质:媒体转发是 I/O 密集型,不是 CPU 密集型。SFU 不解码、不混流,只转发 RTP 包,所以 CPU 消耗极低。
技术债务:
- kraken 的内存泄漏(issue #32):断开连接标记删除但资源未释放
- 单点故障:所有用户接入同一台服务器
- 只有语音,无文字聊天
第二版:Elixir + Membrane,Erlang/OTP 的集群魔法
这版最有价值的地方不是功能,而是展示了Erlang/OTP 为什么是电信级实时通信的原生答案。
在大多数语言中,集群 = Kubernetes + Redis Pub/Sub + 消息队列。在 Erlang/OTP 中:
- 节点通过 epmd 自动发现
- Erlang Distribution Protocol 互联
- 进程跨节点发消息,代码层面完全看不出节点边界
- Supervisor 树自动重启崩溃的媒体管道
结果:两个节点的集群,用户随机接入,同一房间的用户可以跨节点存在。在 Go 版里需要 Redis/etcd 协调,在 Elixir 里是开箱即用的。
新增:一周时间加了 Phoenix Channels 文字聊天。
但依然是自建 SFU 的代价:coturn 维护、EC2 安全补丁、UDP 端口范围手工配置。
第三版:Cloudflare 全栈,运维归零
技术栈拆解
| Cloudflare 服务 | free4chat 用途 |
|---|---|
| Cloudflare RealtimeKit (RTK) | 托管 SFU,WebRTC 媒体路由、STUN/TURN |
| Cloudflare Turnstile | 防机器人人机验证 |
| Workers KV | IP 维度访问限流(60秒20次token) |
| Durable Objects (DO) | 每个房间独立的 AI 会话(BotSession),持久化对话历史 |
| Cloudflare AI Gateway | AI 请求代理层,日志/缓存/限速/模型回退 |
| Workers AI | @cf/zai-org/glm-4.7-flash 模型推理 |
关键背景:Cloudflare 收购了 Dyte
2025-04,Cloudflare 收购 Dyte(印度 WebRTC SDK 公司),将其包装为 RealtimeKit。2026-04-20 的 RTK Web Core 1.4.0 发布说明明确提到:SDK 内部从 dyte.io 迁移到 *.realtime.cloudflare.com。Android Core 2.0.0 更直接:dyte.io base domain 现在会立即报错 MeetingError.InvalidBaseUrl。
所以文章中写的 "Dyte(Realtime Kit,以下简称RTK)" 实际上是 Cloudflare RealtimeKit,基于 Dyte 技术栈。
Durable Objects:每个房间一个 AI 会话
普通 Cloudflare Worker 是无状态的——每次请求可能路由到不同边缘节点,无法在请求之间保持内存状态。
DO 解决了这个问题:
- 同一房间的所有请求路由到同一个 DO 实例
- 实例有自己的内存 + 持久化存储
- 安全维护对话历史(最近20条)+ 每小时调用计数
- 房间之间完全隔离,无竞态条件
这是 "无服务器 + 有状态" 的优雅解法——不是数据库,也不是纯内存,而是两者结合的中间态。
AI 语音 Bot 的卡点:DTLS 握手与服务端音频注入
这是文章中最有价值的技术洞察之一。
WebRTC 的所有媒体流必须加密(DTLS + SRTP)。服务端如果想处理媒体流(录制、混流、AI分析),必须参与 DTLS 握手,成为连接的一端——不能只是透明转发。
这意味着:AI 语音 Bot 的核心链路(STT → LLM → TTS → 注入房间)的最后一步——音频注入——需要服务端作为一个 WebRTC peer 完成完整的 ICE + DTLS + SRTP 流程,然后向 SFU 推送 AI 合成的音频。
第三版的硬边界
RTK 是托管 SFU,不暴露底层的 SFU App ID 或 WHIP 接口。这是托管方案的代价:便利性和控制权之间的取舍。
在 Go/Pion 或 Elixir/Membrane 版本中,由于 SFU 是自建的,服务端进程可以直接作为一个 peer 加入房间——这个能力完全可以实现。
2026 年的解决方案:WHIP + Cloudflare Realtime Agents
文章写于 2026-05,提到"Cloudflare 的 Calls API 和 Agents SDK 中已出现相关能力雏形,但未全面开放"。但实际上:
Cloudflare 已于 2025-08-29 发布 Realtime Agents,支持完整的语音 AI pipeline:
- WebRTC 音频直接接入 Worker(PCM 格式)
- STT(Deepgram)→ LLM(Workers AI / OpenAI / Anthropic)→ TTS(ElevenLabs)
- 支持打断检测和轮替管理
- 与 Cloudflare Agents SDK 集成
- 使用
RealtimeKitTransport加入 RTK 会议
// Cloudflare Realtime Agent 示例
const transport = new RealtimeKitTransport(meetingId, authToken, [
{ media_kind: 'audio', stream_kind: 'microphone' },
]);
await this.initPipeline(
[transport, new DeepgramSTT(key), textHandler, new ElevenLabsTTS(key), transport],
agentId, workerUrl, accountId, apiToken,
);
await meeting.rtkMeeting.join();
这意味着:服务端音频注入在 Cloudflare 生态中已经可行,只是需要通过 Realtime Agents 的特定 API,而非直接暴露 WHIP 端点给普通开发者。
WHIP 协议:2026 年 AI 语音注入的生产模式
WHIP(WebRTC-HTTP Ingestion Protocol, RFC 9725, 2025-03 发布) 把整个 WebRTC 注入信令压缩为一个 HTTP POST:
- Client POST SDP offer (
Content-Type: application/sdp) - Server 返回 SDP answer +
Location:header - Client DELETE location 拆除
到 2026 年,所有主流 SFU(LiveKit、mediasoup、Janus、Cloudflare Realtime)都已支持 WHIP。
但 RTK 作为高层 SDK,选择不暴露底层 WHIP——这是产品设计决策,不是技术限制。
Vibe Coding:第三版一个周末完成
文章提到一个值得记录的事实:
- 第一版、第二版:人工一行行写
- 第三版:OpenCode + Claude Sonnet 4.6,vibe coding 一个周末完成
同样的功能量,开发速度差距是数量级的。Cloudflare 的产品体系(边缘函数、托管服务)+ AI 辅助开发加在一起,让"一个人在业余时间维护一个有实际功能的产品"变得真正可持续。
AI 与实时通信的未来方向
文章对 AI + WebRTC 的发展做了三层预判:
当前可做(文字层):AI 助手参与文字聊天,上下文感知,总结会议。free4chat 的 Luna 就是这个阶段。
近期可期(语音层):STT → LLM → TTS → 注入 SFU。Cloudflare Workers AI 已有 Whisper(STT)和 TTS 模型,前三步可在 Worker 内完成。卡住的是最后一步——媒体注入。
但 Cloudflare Realtime Agents 的发布意味着:这个卡点已经被解决,只是通过更高层的抽象(SDK)而非底层协议(WHIP)暴露。
更远期(多模态层):
- AI 带着组织知识库实时接入会议,在讨论卡壳时主动补充上下文
- 一对一语音陪伴:心理咨询、情感支持、职业辅导(延迟需控制在 800ms 以内)
- 真正难的是"主动介入"——AI 判断什么时机该说话、说什么、说多少
核心结论
-
技术选型没有绝对优劣,只有边界匹配。Go 给了学习路径,Elixir 给了分布式理解,Cloudflare 给了零运维未来。
-
托管 SFU 的控制权损失是真实的代价。如果项目未来需要 AI 语音 Bot,自建 SFU(Go/Elixir)是唯一路径;如果只是文字 AI 助手,Cloudflare 全栈是最优解。
-
Cloudflare Realtime Agents 已解决服务端音频注入,但走的是 SDK 抽象层路线,而非暴露 WHIP 协议。这是托管服务的典型权衡。
-
Vibe coding + 边缘托管 = 个人项目的可持续模式。开发速度和运维成本的双重下降,让"业余项目"可以长期存活。
参考资源
- free4chat 在线体验:https://free4.chat
- GitHub 仓库(三分支):https://github.com/i365dev/free4chat
- 原文博客:https://www.bmpi.dev/dev/free4chat/
- WebRTC 协议栈开源书:https://webrtcforthecurious.com/
- Pion WebRTC Examples:https://github.com/pion/webrtc/tree/master/examples
- Cloudflare Realtime Agents 发布说明:https://blog.cloudflare.com/cloudflare-realtime-voice-ai/ (2025-08-29)
- Cloudflare RealtimeKit 发布说明:https://developers.cloudflare.com/realtime/realtimekit/release-notes/
- WHIP 生产模式指南:https://callsphere.ai/blog/vw3e-webrtc-whip-ai-ingress-2026
- Cloudflare 收购 Dyte 分析:https://bloggeek.me/future-video-api-ai/ (2025-04-28)
#WebRTC #实时通信 #AI语音 #Cloudflare #Elixir #Go #Pion #Membrane #VibeCoding #技术选型
讨论回复
0 条回复还没有人回复,快来发表你的看法吧!
推荐
智谱 GLM-5 已上线
我正在智谱大模型开放平台 BigModel.cn 上打造 AI 应用,智谱新一代旗舰模型 GLM-5 已上线,在推理、代码、智能体综合能力达到开源模型 SOTA 水平。