以下详细记录一次利用vibe coding将Nest Camera接入Clawdbot的项目。
项目背景:一台Nest Camera(Google Home的battery版本),一直用于监控住宅正门区域,在Google Home中设置了热点区域,预警人类进出热点区域。用户通过Google Home可以翻看历史预警记录,调看预警视频片段。一直使用免费版本,没有订阅Nest Pro付费方案。免费版本存在一些产品缺失,首先是历史影像只能保存7天,其次是不提供自定义熟人,所以经常存在熟人进出预警。最后是不提供AI解析影片的功能,只预警,必须人工翻看历史视频自行做判断。
本次项目希望达到的目的:首先是能够将预警的相关视频下载并永久保存在本地服务器,以便永久存档并随时翻查。其次是希望实现熟人不预警功能。还希望通过大模型对视频做文字解析,在预警时提供文字描述,方便使用者快速过滤不需要关注的预警。最后是希望通过接入Clawdbot,可以把预警转移到telegram上,这样可以在预警信息上实现更灵活配置。
项目结构是编写一个基于python的常驻内存服务,连接到Camera的服务器端,监听Camera上触发的人物预警事件,如果发生事件,则下载服务器端的预警记录,保存到本地,基于本地预定义的熟人做预判,如果是熟人则不需要通知Clawdbot。如果是非熟人,则把预警信息和视频发送给Clawdbot,让Clawdbot将视频转换为文字,再通过Telegram提醒用户。Python服务和Clawdbot之间通过webhook方式通讯:python服务发送通知到Clawdbot的webhook。
第一步是设置Google Cloud Platform项目,开通Pub/Sub服务,创建Topic,获取授权文件,并和Nest Project联通。这一步的目的是打通Camera到Nest服务器再到Google Cloud Application,让Google Cloud Application可以获取人物事件。这一步的难点是各种繁琐的配置,各种ID和token满天飞,起码要经过10步配置,中间各种操作对新手极不友好。我这一步是根据ChatGPT的提示一步一步操作的。ChatGPT对于这类操作的信息还算是比较清晰,其中我也穿插使用过Gemini和Claude,但相比起来,还是ChatGPT提供的配置步骤最容易follow。这一步整体难度不高,就是过程繁琐,需要慢慢熟悉。一旦跑通这个配置,以后应对Google Cloud其他项目都会更容易些。
第二步是编写基本的python脚本实现上述一系列操作。本来以为配置跑通这一步会相对比较容易,毕竟vibe coding还是很成熟的。结果这一步反而耗费了大量时间。其中有一个大坑。首先用python获取Google Cloud传来的事件还是比较容易的,ChatGPT Codex直接手搓脚本,测试通过基本没有难度。下面我以为可以容易地拉取对应的视频,毕竟做Google Home上是可以翻看历史视频的,所以视频数据肯定在服务器上,说明里也说可以通过url获取。但后来发现,要拉取视频是不可能的,因为Nest Camera统一是没有ClipReview这个trait的,所以所有Nest的Camera都不支持视频拉取功能。只有门铃才具备这个trait。好吧,不拉视频拉snapshot快照可以吗?检查设备trait发现是有ImageGeneration这个trait的,但是拉取快照时提示没有RSTP协议访问权限。这里ChatGPT是很快判断这条路走不通的,并给出了通过WebRTC的提议。我同时问了Gemini和Claude,这里两个模型都给出了误导提示,它们认为ChatGPT搞错了,拉取图片根本不会涉及RSTP流协议,所以根本不会触发RSTP协议访问权限。乍一看也对,毕竟只是拿快照,不是拿流视频。而且Gemini很笃定地说这是开发者一个常见误区,以为拉图片会触发RSTP,其实是混淆了拉取流视频截屏和拉取快照图片的概念,还给我代码让我测试。结果代码测试也是RSTP无权限。在我反复逼问下Gemini才说是Nest Camera一个设计死循环:调用ImageGeneration时底层实现还是会去调用RSTP服务获取流视频,所以绕不开这个问题。后来我反应过来,其实因为这个历史数据是Nest用来作为Pro订阅的产品特性,所以Nest和Google Cloud直接禁止用户调取服务器存储的这个历史数据,否则你自己调用了存到自己服务器岂不是轻易绕开这个收费的feature了吗?其实这个数据属于用户隐私,应该是归用户自己所有,但现在Google实际把这个数据据为己有了,这个数据本身已经不属于用户自己的了。最后没有办法,还是回到ChatGPT给出的WebRTC方案。其实这个方案就是先获得事件,然后通过WebRTC动态建立一个链接,去拉取Camera实时的snapshot。WebRTC只能获取当前实时数据。ChatGPT通过简单几轮编码也毫无压力做好了WebRTC。实际测试发现WebRTC建立链接到获取截屏,中间握手导致的延迟就有5-10秒,等到链接建立获得snapshot已经是事件发生好几秒钟之后的事了,结果就是根本捕捉不到事件发生时的画面。这里ChatGPT给出了一个比较惊艳的解决方案:持续保持一个WebRTC链接,每隔一秒钟(最初建议是连续不断,但太过频繁导致资源占用太多,因此我建议一秒一次)获得一个snapshot并存到本地硬盘,一旦事件发生,根据事件直接从本地硬盘拉取相关事件范围内的snapshots。这个方案很好地避免了事件发生时临时创建WebRTC带来的延迟效应。而且为了避免硬盘上积累太多buffer snapshots,ChatGPT也建议滚动保存60帧snapshot,覆盖一分钟范围,这样确保buffer文件不超过60个。我认为这个方案不错。实现起来也是没有任何难度。后来我把这个方案的编码又扔给Claude评估,Claude也表示很认同,只有一点可以优化,那就是与其反复读写硬盘,不如直接把60帧buffers放到内存,这样可以延长硬盘寿命,还可以加速读取snapshot的速度。有意思的是,ChatGPT不认可这个方案,认为每秒读写对现代SSD硬盘的寿命影响微乎其微,如果不保存到硬盘,反而会造成服务重启时丢失历史snapshots。我评估后觉得还是采纳Claude的方案。其实我拍板前它们两个都各执己见,互不让步。当然,从硬盘到内存的修改也是毫无压力,Claude直接完成。这里忘了说,在反复纠结WebRTC和RSTP方案到底咋回事的节点,我已经把主力程序员从ChatGPT换到Claude了。最后和Clawdbot打通这一步比较简单,没遇到什么麻烦。至此python服务编写完毕,可以顺利执行。
这个过程中我也比较了ChatGPT、Gemini和Claude。整体感觉是Gemini是三者里最弱的,逻辑比较乱,经常自己整迷糊,我基本没用它编写代码,还是不太信任。ChatGPT整体不错,它最明确RSTP方案不行不是因为编码问题而是硬件和Google的限制,因此它是最早建议放弃尝试走WebRTC路线的。Claude和Gemini都曾经坚持认为是开发者搞混了概念,通过修改调用命令可以解决。实际这个问题是无法解决的。这也是Nest Camera对开发者极不友好的体现。反正以后我采购硬件,肯定不会优先考虑Google或Nest的产品,因为后续自行开发成本估计比较高,限制也估计比较多。话题拉回来,Claude应该是三者中编程能力最强的,但token真的限制太死,动不动就限流,所以只能用于难点攻坚,不适合从头开始建项目。ChatGPT就宽容很多,完全没有遇到任何限流问题。以后开发我还会主力用ChatGPT,直到有些复杂问题感觉它搞不掂才用Claude试试。我还发现一个有趣的地方,都是默认模式,ChatGPT每一步都询问你,很多时候需要你手动确认才能执行,所以人基本要保持和ChatGPT的互动。Claude就自信很多,基本不过多询问你的意见,吭哧吭哧就自己修改代码了。有的时候我以为Claude会和我确认,结果发现人家已经动手写完代码了。所以和Claude打交道git还是比较重要,万一改错了还可以回滚。
最后Clawdbot处理webhook信息依然还算比较通畅。这里有个点反正我深有体会,那就是如果你想让Clawdbot严格执行你教的流程,那写成skill是最稳妥的,其他什么memory都不太靠谱。这个项目里,我就规定了Clawdbot拿到snapshots后先翻译成文字,再判断危险程度,只有危险程度超过5才详细预警,否则提一声就行。我口头交代它后,虽然它说了会记住,但下次依然不按照这个流程执行。一定要写到skill里后它才老实按流程走。所以我现在很多东西都直接写skill,懒得口头交代它,反正它也不太上心。好在Clawdbot可以自己写skill,所以让它自己写一个也不麻烦。另外这个项目我应该也可以让Clawdbot参与编程和开发,但总觉得它又要调用Claude比较费token,就没让它参与。我估计Clawdbot是思考比较多的类型,一些东西其他模型可能三句话说完,Clawdbot一定会给你整七八句,各种你想到想不到的它都考虑周全。用Clawdbot开发可能和它沟通费劲些。下次可以试试。