这是一个关于用 Go 和 Rust 实现对话机器人的项目记录。
- 起源:最初是在与朋友的群聊中关于足球经理的讨论中产生的想法,用 LLMs 克隆朋友声音让他们互相对话,当晚用 Go 实现了概念验证,之后决定用 Rust 做类似项目并让 Go 和 Rust 写的机器人讨论编程语言。
设计实现细节:
- 消息传输:最终选择消息总线(NATS JetStream),因其优点如无需处理消息路由细节、方便消息重播、有经过验证的通信协议和现成的客户端库等,放弃了 REST API 和 WebSockets 选项。
- LLM:选用 ollama 运行 llama2(当时 llama3 未发布,模型可配置),方便从机器人交互,避免在初始开发阶段使用付费 LLM 服务。
- TTS:音频合成选用 PlayHT,其定价适合业余爱好者,虽无 Go 和 Rust 客户端库,但自己开发了,在 Go 和 Rust 中分别有相应模块(go-playht 和 playht_rs),并提供了很多使用示例。
具体实现:
- gobot(Go 实现的机器人):管理一组工作协程,分别负责 LLM 提示、TTS 音频流、JetStream 任务处理等,使用 errgroup 管理协程取消和退出,通过标准输入提示开始对话,各协程通过通道通信,处理音频播放在 macOS 上曾遇到困难,llm 工人使用 github.com/tmc/langchaingo 模块,还实现了固定大小缓冲区处理 LLM 数据。
- rustbot(Rust 实现的机器人):设计与 gobot 类似,使用 tokio 任务,不同之处在于 Rust 没有双向通道,有专门的音频播放任务,通过克隆通知通道处理任务退出,使用 ollama-rs 与 ollama 通信,playht_rs 与 PlayHT API 通信,也有固定字节缓冲区实现。
- 结论:项目在过去几周的熬夜和早起中完成,在过程中体会到 Go 和 Rust 的不同,也学会了构建 TTS 客户端库,希望代码对他人有用,鼓励去修改和实践。
总的来说,这是一个有趣的尝试,展示了用不同语言实现类似功能的过程和挑战。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。