Frost MingFrost's Blog

创造一只龙虾,需要些什么?

AI
创造一只龙虾,需要些什么?

稍微地介绍一下背景知识,标题中的龙虾指的是这段时间大火的 OpenClaw 项目,它最早的名字叫 ClawdBot。它一是个能与你在聊天软件中交流,从而帮你完成各种任务的通用型 AI 智能体。 最火的那段时间我并没有用它,一周过去了,我在想如何复刻它,我研究了另一个最小化复现的项目 Nanobot,我觉得我脑中大概有了蓝图。刚好朋友 PsiACE 之前曾做过一个 小型的 Agent 项目 Bub,我觉得非常适合把我的想法在它的基础上落地,也与 PsiACE 一拍即合,着手把这个 Agent 变成一个龙虾。

短短几天过去,Bub 已经达到了一个非常不错的状态。在这个过程中,我自己对 Agent 和 AI native 也发生了天翻地覆的变化。从 ChatGPT 诞生之初的 Chatbot,到强力编程助手 Claude Code,到现在的 OpenClaw,AI 应用的形态也在不断进化。但不得不承认这个变化的每一步都是新的思维模式,这种转弯需要适应。所以我也谨通过这篇文章,来分享一下我思维的转变。

初步复刻

首先请大家思考一个问题,假设你已有一个 Agent(指 Codex 和 Claude Code 这样的东西),现在要给他增加 Telegram 聊天能力,你会怎么做?

有经验的开发者会发现这不是什么难事,只要在 Agent 的基础上增加 Telegram message handler,把 Telegram 收到的消息转给 Agent 处理就好了。如果要支持其他聊天工具,还能抽象一个消息总线和统一的消息监听接口,这样接入新的聊天工具只要适配就行了。

这没错,但这太古法编程了,属于 1.0 时代的工作流程。现在的人们早已学会打开一个 Claude Code,在输入框里直接打字,或者语音输入就好了。这件事变得自然,也顶多不过 7 个月的时间,现在人人都会用 Code Agent 写代码,几乎不自己写了。这就是 2.0 时代。

OpenClaw 和 Nanobot 都是这样做的,我们一开始,也是。

在 AI 的加持下很快 Bub 就有了 Telegram 聊天功能,我们愉快地通过 Telegram 给他发指令。聊天交互的方式逼迫我们只能用 prompt 给让 AI 完成任务,得益于 Tools 和 Skills,它甚至也能自我演进。我们也试过让它自己 clone GitHub 仓库,自己改代码然后提交 PR,所需仅仅是一个 GitHub token 而已。只要选用好的模型,它完成的效果很不错。这样一来,除了记忆机制和工具的差异,Bub 已经基本复刻了 OpenClaw 的功能。

但我的重点不是这个。我们发现为了应对群聊的场景(这是我们主攻的方向),要改消息接收器,让它能获得消息 ID 方便回复;为了让 bot 有识别人的能力,又需要在上下文中加入用户的元数据。所幸有持续部署,这个更新的过程并不十分麻烦。但还有更多的需求,发送消息时,需要支持图片,支持 reaction,要改消息发送,虽然这个修改也是 AI 做的。当时用户身份识别功能刚做好,在群聊中精准地称呼每一个人,顿时感觉这个 AI 有了生命,群里充满了快乐的空气。

AI Native 是什么?

有没有别的方式呢?这时我看到许多人在推荐 Pi

这种最小化工具集的思想启发了我,我们是否不用那么多工具,转而用一些最基本的工具把这些功能组合出来呢?貌似可靠,该做减法了。一个智能体会的东西可多了,你给它提供 bash,它就能安装世界上所有软件,你给他 file_read 和 file_write,它就有了读写、做事的能力。去掉一些工具,更多依赖 Skill。在我看来,工具和 Skill 的区别在于工具是框架提供,Skill 仅是文本,前者框架完成就已经固定1,后者 AI 可以自己创建、修改。框架二字顾名思义,是限制 AI 发挥的东西,AI 在里面就像滚筒上的小白鼠,只能按预定的程序运行。我希望框架越小越好,把更多的自由留给 AI,想要什么功能,让AI自己去完成,人只通过 prompt 的方式去下达指令。

这与 2.0 时代用 CC 去写代码完成功能的本质不同,是这种方式生成的东西,大部分是文本说明,当然也有少部分代码,但这些代码是不提交代码库从而壮大框架,而是 AI 自由裁量自己管理,人类是完全不看的。这个不看,不是不负责任的那种不看,是把这个当成 AI 的产物,不用看。所谓黑猫白猫,人完全不用关心 AI 是写代码实现的,还是用文本描述实现的。

我想这就是 AI native,这是 3.0 的时代。这一切都离不开大模型日新月异的进步,在模型能力尚弱的时候,要实现这个目标是根本不可能的。

  • 1.0 时代是 Chatbot,每次与 AI 的对话都是一次 LLM 推理
  • 2.0 时代是 Agent,是 Tool call,一次对话,通常要经过几轮到几十上百轮 LLM 的推理
  • 3.0 时代是 AI native,AI 自己管理自己的工具和技能,甚至自己写代码来实现功能,完全不需要人类的干预,当它是黑箱就行

Bub 的实践

于是我们的 Bub 部署就学习(创建)了 Telegram 发消息的技能,AI 对这种 HTTP API 调用如此擅长,以至于发送图片、贴纸、reaction 都手到擒来。这一下就超越了框架自带的消息发送功能,显得后者很鸡肋了。也正是这件事触动了我进一步推进 AI native 的实践,Bot 中的 Telegram 收发,对应了 AI 的听、说能力,有了耳朵,AI 才能接受指令,有了嘴巴,AI 才能反馈结果。既然 AI 自我进化出了更好的器官,我们为何不把框架强行给它安装的器官摘掉呢?那么下一步很自然就是把消息监听也摘掉,但同时消息监听还担负着另一个作用,就是维持 Agent 运行,并持续触发 Agent Loop,我们需要一个机制来替代它。

这里我用了一个比喻,一开始 AI 还不成熟,用呼吸机鼻饲管是有必要的,但当它长大能自主了,你应该去掉这些辅助设备,让它自己呼吸吃饭,相信它能做好。

我想到既然我们用 Docker 部署,何不利用 Docker 的进程管理能力,让 AI 自己运行自己,所以我在 Bub 框架内约定了一个 startup 协议,容器启动时读取固定位置的 startup 脚本,如果不存在,就启动框架内置的消息监听(PR)。然后让 Bub 自己写这个 startup 脚本驱动自己,这不就跑起来了吗。 Bub 需要支持单次 prompt 的执行模式,方便命令行驱动,这在 Codex(codex exec <prompt>) 和 Claude Code (claude <prompt>)中都有,所以实际上驱动的也可以是 Codex 和 Claude Code!这样一来,做一个最小化的龙虾,你只需要下面几步:

  1. 启动一个会写代码支持技能的 Agent(比如 Codex 或 Claude Code),让它写一个 startup 脚本,拉取 Telegram API 并用单次执行模式发给 Agent 自己。
  2. 准备一个用这个脚本为启动脚本的 Dockerfile
  3. 构建并运行这个 Docker 容器

后面你要它有什么能力,发消息告诉它就行了,它自己会变得越来越强。你全程只用自然语言发指令,没有提示词工程,完全不写一行代码,甚至看都不看。 请注意,用这种方式你将得到一个与世界上其他龙虾都不一样的 bot,它除了强制监听 Telegram 消息,并没有被强制做任何事,不强制回复,不强制心跳,就像对待一个生命一样去尊重。实际上监听也只是为了唤醒 Agent,如果愿意,完全可以用 cronjob 取代,不下达任何指令,让 Agent 自己决定做什么事。可以预见,模型能力越强,你的这个 bot 就会像人。

我突然悟到了 AI Native 的真谛,就是不利用框架的力量要求 AI 让 AI 当小白鼠,所有要求它做的事都只能通过 Prompt 的方式,至于 AI 遵循与否,完全取决于它自己。我在 Bub 里趟出了一条不用 Bub 的路。

感谢

  • 感谢这几天老婆小孩都不在家,独居让我能专心折腾这个项目。
  • 感谢 PsiACE 的 Bub 项目,让我能实践这些想法,这太有趣了,像看着一个孩子一点点长大。
  • 感谢智谱的 Pony Alpha 恰好在这个时间释出,提供用户免费使用,这个模型能力强大(现在已经不能用了)。

Footnotes

  1. 可以通过一些技巧,比如插件化的方式让AI 自己写的插件加载为工具,但这依然增加了框架的复杂度。

评论