“林羽凡笔记”中的语音Agent开发完成了,还有一些细节需要处理,这部分和ai说不清楚了,得手动处理了。


演示视频: https://www.bilibili.com/video/BV1CgjE6KEDA/ ?
一、方案及效果
我看了下其他人的类似的功能,都是在本地录音,再将录好的音频发送给语音识别接口(大模型或专门的语音转文本的接口),然后接口将转好的文本发送给前端,基本流程应该使用http完成的。
我的想法是,既然弄了就弄得体验好一些,而且我开发的系统中已经有websocket了,就直接上websocket好了。
想法是好的,但执行起来比较麻烦,虽然有ai帮助,但整体架构还得我提前搭好。
因为这样的逻辑比单一的一个websocket通信麻烦得多得多。
1、语音识别(ASR)
我目前使用的是阿里云的语音识别ASR功能,一来便宜,二来我的系统中已经有之前配置过的“千问”的相关功能了,方便接入。
我目前开发的思路是,本地(浏览器)采集pcm格式的数据片段,将这些数据实时传送给服务端。

服务端解析这些数据,再以“客户端”的身份开启一个websocket连接阿里云的接口:$websocket_url = 'wss://dashscope.aliyuncs.com/api-ws/v1/inference/';
也就是说服务端现在变成“客户端”了,这样阿里云识别的文字就能实时发送给服务端,服务端再通过websocket把识别后的文本发送给前端,由前端显示在界面上。

这样的效果就是,我可以一边说话,一边看到我说话的结果,理论上只要我的服务端没问题,阿里云的服务端没有问题,数据传输非常快,基本上吐完几个字,立马就显示在界面上了。
比那种把一整个音频发送给识别接口的体验要好一些,而且也不用考虑存储音频数据的问题(连临时的都不需要,有了数据就直接转发)。

页面还有一个标签,我也没找到,ai也没找到,不清楚是怎么渲染出来的。
2、语音合成(TTS)
这个用的也是阿里云的,原因同上。
我在前端增加了不同的音色:

我比较喜欢的是陕西话和四川话的,非常nice,而且还可以自定义语音的情感,说话的声调也不一样。
后续有空我分享一个视频,这种感觉比纯文字对话的好太多了。
纯文字对话的功能我留下了,方便一些不适合说话的场合使用。
语音合成使用的也是websocket方式传送消息。
LLM在生成回复消息后,因为LLM我要求返回的是流式数据,所以这个流式数据可以直接转发给阿里云的TTS接口。
因为这个转发是通过websocket实时发送的,所以阿里云的TTS返回的语音数据也是实时的,我再通过服务端的websocket把合成的语音消息发给前端。

所以能看到一个现象是,在看到LLM返回的文本消息后,马上就能听到语音声音。
这里有一个比较大的坑,搞了很久才搞定,就是音频采样,这个我也不是很懂。
反正就是刚开始的时候阿里云返回的合成语音的消息,在前端播放的时候有很多杂音噪声,就像收音机在信号不好的时候的声音一样,能听到说话的声音,但有的字听不清楚。
后面打了很多日志,让ai根据日志调试。
现在的效果非常Nice,完全能听清楚不同音色的声音。
二、Token消耗
我之前开发对Token的消耗是没清晰的概念的,因为在不同工具间切换,也没有特别注意这个,甚至有时直接用的Trae和Qoder的免费Token。
这几天用了Zcode,没抢到 coding plan 的套餐,就一直用的赠送的Token,每天有500百万。

但我发现了一个很郁闷的问题,这500万的Token在Zcode里消耗特别快。
对我这个项目,我提问一轮就消耗结束了,我搞不明白是怎么个情况。
我昨天的时候以为是Zcode这个工具本身消耗Token快,今天的时候甚至想用codex完成剩下的功能。
想了想再加个deepseek的接口吧,不然我还得重新在codex里描述任务和文件。
结果在用了一天后,总的上下文窗口中的token才50万,我在同一个对话里写了一天的功能,有几十轮对话了,看下图的滚动条的大小:

我的项目还算是比较消耗Token的,在Zcode里我把前后端都放一起了。
缓存命中非常高,不清楚Zcode的计算准不准,6.20的deepseek的token的具体消耗还没出来,明天了补充数据。
补充图片

三、 关于“林羽凡笔记”未来的计划
我不打算在Agent这块开发更多功能了,今天看到一个视频,觉得分析得很有道理。
大概的意思是,现在开发的这些Agent,看起来功能很多,很实用,但未来一但LLM更新,以前吭哧吭哧开发的这些功能就失去意义了。
仔细想想这个角度还是有点道理,就拿我开发的发票识别、语音识别、语音合成来说,也许在不远的未来,LLM就直接内置这些基础功能了。
不需要再费劲开发,直接一个LLM接口请求,就能得到想要的数据。
在不远的将来,多模态或世界模型中,输入语音,指定输出语音,应该也很快了。
在这种情况下,再费劲接这些语音接口,完全就没有意义了。
我唯一能做的,或者可做的,就是这个系统中产生的内容是我的,和外部接口解耦。
四、扎心的真相
我之前开发程序,都是分模块把功能描述清楚给ai,甚至有一些接口我写好函数名,或者参数及类型,再让ai写具体功能,而且每次完成功能,我都要把代码调试一遍,有些写法不符合我的风格的,我再改改。
所以今天之前的所有的,有ai参与我开发的程序,我都做到了心里有数,而且维护啥的我都清楚。
但是,今天完全不一样的,我今天把这个双层websocket的功能交给了ai,函数我没动,接口我也没动,只是配合修改了几个表字段和类型定义。
其他的完全由ai开发,虽然有很多问题,也沟通了很多回,但我一眼都没看过代码,这让我有点慌。
我以有的观点是,哪怕把所有功能交给ai开发,至少要懂一些程序,给ai描述问题时,表达上专业一些。
但现在我感觉大部分情况不需要,直接大白话说就行,只要能说明白,ai基本全能搞定。
以前我让ai写代码,我还控制着ai,一点点来,每修改一个文件,我还手动确认下。
今天完全把文件的操作权限给ai了,但是每一轮有大的文件改动,我会手动备份一份在本地,没提交git,总感觉从git上恢复过来本地的文件就不干净了。
我现在的观点是,只要你没想法,不管写代码也好,还是创作其他的东西,只要具体想法,ai产出的东西就可以,一旦你有想法,你就会觉得ai问题很多。
五、简单总结
Deepseek的上下文管理真的牛,我配置了200万,但官方是100万,我今天接近50万了,基本感觉不到幻觉问题。
之前在Trae上用deepseek比较多(写代码),产出结果问题非常多,一直怀疑是模型的问题,今天看来,工具的问题占很大一部分原因。
评论 (2)
畅快淋漓的享受着 AI 输出,已完全无视 token 的增长了。我最近也消耗了不少 deepseek 的 token,高深的使用还是不会。
:lyf-点赞: