学习频道 · 长文研读

返回学习频道

学习频道 · PHOENIX HARNESS

Phoenix Agent Harness 演进实践

Phoenix 是我自己用 Go 写的 Agent 运行时(Harness)——包住大模型、负责「能跑、可控、可运维」的那层系统。这篇不按模块罗列,而是按它长大的顺序复盘:每一章讲一个实际运行中撞上的问题、我加的模块、以及加完之后架构变成了什么样。

导览:从「一个循环 + 模型 + 几个工具」的最小可用版起步,被实际使用中的问题推着,逐步长出事件日志、审批与沙箱、上下文管理、记忆系统、插件化内核,最后学会「派活」——把探索分包给子代理、只收结论。章节按「问题驱动」的复盘顺序组织,不是严格的提交顺序;每章的「实现展开」块留给想深挖的读者,跳过不影响主线。

一、Agent MVP 的诞生

我想要的很简单:一个能自己干活的 Agent——我说一件事,它自己查、自己改、自己验证。最小实现其实不复杂:一个循环,反复做三件事——把对话发给模型、模型说要调什么工具就去调、把结果拼回对话里再问。这就是第一个版本的全部:一个循环、一个模型、一批工具。Agent 的本质就是这么一个「决策—行动—看结果」的循环,剩下的一切都是工程。它能跑,能读代码、改文件、跑命令。

实现展开 · MVP 的工具集设计(pkg/tools/builtins)

  • 分类原则不是按数据结构凑类别,而是每个工具都在补模型的一块能力短板
  • 「看」:read_file / list / grep / glob / now。now 值得单说一句——模型没有「现在几点」的概念,训练数据有时间截止,排障和做计划都需要真实时间。(read_file 另有一个别名 read,只为对齐业界习惯。)
  • 「改」:write_file / edit / apply_patch / mkdir / rm。改文件给了三种粒度(整体重写 / 局部编辑 / 补丁),因为不同改动规模的成本和风险不同。
  • 「跑」:shell。构建、测试、git 这些必须起真实进程的事。
  • 「算」:calculator。模型做算术天然不可靠,精确计算交给确定性工具——模型不擅长的事不硬撑。
  • 「自我管理」:todo_write。长任务拆成步骤记在便签里,防止做到一半丢步骤。
  • 「链路自检」:echo。安全探针,排障时先区分是模型的问题还是工具链路本身的问题。
  • 每个工具的定义都分两部分。给模型看的:名字、一段说明(description,模型靠它判断什么时候该用这个工具)、输入参数的约束(parameters)。给系统看的:风险等级(Risk)、能否与其它工具并发(IsConcurrencySafe)、超时上限(Timeout)。另外还有一条全局约定:所有工具的输出都有截断上限,单次输出不许失控。

然后我真拿它干活,再和头部 Agent 产品摆在一起对比,差距立刻就出来了——没存下来、说不清、没人拦、装不下、插不上手,五条,逐条对照如下:

FIG.01//实跑对比头部 Agent 产品:五条看得见的差距看懂:差距不在「能不能跑」,在「敢不敢交给它真干活」
没存下来
MVP:进程一重启,之前的对话全没了
头部:会话能恢复、过程能回放
说不清
MVP:它做过什么、为什么这么做,事后查不到
头部:每一步决策都有据可查
没人拦
MVP:有风险的命令问都不问就跑了
头部:危险动作先问人
装不下
MVP:任务一长,前面的内容就被挤出上下文
头部:长任务有上下文管理
插不上手
MVP:想中途纠正,只能杀掉重来
头部:随时能接管、能纠正
FIG.02//架构快照:本章长出了什么看懂:高亮的是本章新增,灰色的是前几章已就位
最小内核循环 + 模型 + 工具

起点最小内核

还没解决 → 下一章

这五条有个共同的根子:没有一份可靠的记录——追责、回放、中途接管,全都建立在「有一份记录」之上。所以我第一件事不是加功能,而是先让它记住。