跳到主要内容

babyagi — 本课题摘录

读了哪几篇: 02-execution-engine(一次执行的生命周期)、03-self-building(自建 agent)。 其余两篇(三件套与函数存储、巧妙之处与边界)本轮没读。

这一家在本课题里只回答一个问题,但答得最极端:工具从哪来?——答案是"不够就自己写一个"。

它对本课题回答了什么

决定二/一:工具不是给定的,是会自己变多的

核心直觉不是"每次都让模型写代码",而是:先翻库里有没有现成的,没有才生成——而且生成时鼓励拆成小而可复用的函数。

一句话需求


查库里有现成的吗? ── 有 ──► 直接用
│ 没有

让模型把任务拆成若干小函数(名 / 描述 / 参数 / 依赖)


逐个函数:先向量查重 → 确实没有才让模型写代码 → 存回库


让模型从原始需求里抽出调用参数 → 执行

(依据:Agent 库 · BabyAGI (functionz) · 自建 agent(LLM 写函数存回库) —— 自建的中心思想是「先查库里有没有现成的,没有才生成」,生成时鼓励拆成小而可复用的函数,逐个函数还会先做向量查重,于是库会越用越肥、复用率越来越高)

它给的理由:这样库会越用越"肥",复用率越来越高。

这条对本课题的意义:我们一直默认"工具清单是给定的",讨论的是"怎么给模型看""太多怎么裁"。 它提出的是第三种可能:工具清单会自己长。 前面 deepagents 是"按能力增删"、langchain4j 是"只增不减"、cherry-studio 是"折叠成元工具"—— 这一家是"不够就造一个",而且造出来的会留下。

注意它有一道"先查重再造"的闸门。 没有这道闸门,库会被同义函数塞满。

决定三:执行一个"函数即数据"的工具,难点在环境装配

它把真正的难点点破了:

库里躺着的是一段代码字符串。直接执行会报错——因为它依赖的其它函数没定义。 所以引擎得在执行之前,先把这个函数的所有依赖(其它函数、第三方库)备进同一个作用域。

(依据:Agent 库 · BabyAGI (functionz) · 执行引擎(exec 生命周期) —— 执行引擎的核心难题是环境装配——库里是代码字符串,直接 exec 会因依赖未定义而报错,必须先递归把依赖函数与第三方库装进同一个作用域)

一次执行的七步:

① 取出活跃版本(含代码字符串)
② 先写一条「开始」日志,拿到日志 id
③ 建一个共享命名空间
④ 递归解析依赖:装第三方库 + 把每个依赖函数装进作用域 ← 最关键
⑤ 把密钥注入作用域
⑥ 执行本函数;绑参、校验、调用 → 输出
⑦ 写成功日志 + 耗时
└─ 跑触发器(带防递归)

"先写开始日志再执行"这一步值得抄: 崩了也知道它开始过。跟 codex/mini-swe-agent 的"每步都落盘"是同一个思路。

一个很激进的细节:缺的第三方库当场自动安装再导入。

这在实验项目里是便利,在我们的原型里应该明确禁止——运行期装包是很难排查的不确定性来源。

决定四相关:触发器要防递归

跑完之后会跑"触发器"(某个函数完成后自动触发另一些函数),而且带防递归保护

这条提醒了一件事:"工具执行完可以触发别的东西"这个设计一旦引入,就必须防环。 我们的循环里如果加"某个工具执行后自动追加一条消息"这类钩子,同样要防。

它没回答什么

  • 循环本身怎么写——这两篇讲的是函数存储与执行,不是 agent 循环。
  • 停止条件——不在这两篇。
  • 历史怎么管——不在这两篇。

坑与代价

  • 作者自己标注这是实验性草稿,生成的代码"最小可用、可能需要改进"。 (依据:Agent 库 · BabyAGI (functionz) · 自建 agent(LLM 写函数存回库) —— 自建 agent 相关代码在 drafts 目录,作者明确标注是实验性 draft,生成的代码 minimal and may need improvement)

    引用它的结论时要带上这个前提:这是一个方向的演示,不是生产实践。

  • "让模型写代码存回库"把安全问题整个提前了。 执行的是模型现写的代码,而且会自动装包——攻击面比"调固定工具"大一个量级。
  • 它假设主函数是拆出来的第一个。 这种"约定优于判断"的做法在拆分结果不符合预期时会静默出错。

    判断(无锚): 我们的最小原型不走这条路。工具应该是我们写死的、我们审过的。 如果错,会错在: 如果任务的形态是"每次都不一样的小脚本"(数据清洗、临时统计),那固定工具集会很快不够用,"让模型写代码"反而是更省事的路——那时该走的是 smolagents 的"代码即动作",而不是 babyagi 的"生成并存库"。