项目背景与架构概述

本期视频由博主小木头带来,深入解析 Daniel 开发的 Ultimate——一个基于 Pi Durable 的本地 Coding Agent。该项目的核心愿景是突破传统 AI 辅助开发的局限,让 Agent 直接修改自身的软件界面与功能,实现“自我进化”。Ultimate 不仅是一个能读取文件、执行命令和修改项目的工具,更允许用户根据项目需求 定制专属的工具集与界面。其扩展、角色和配置均保存在 .ultimate/ 目录下,确保项目环境的可移植性。博主在本机使用 ChatGPT Plus 订阅成功运行了该项目,并演示了从增加清单面板到追加进度条的完整流程。

“能不能再往前走一步,用这个 Agent 发现它的界面或者功能缺失了一些什么,就直接让它修改自己的软件呢?”

Ultimate 的架构设计体现了清晰的职责分离:Pi Durable 负责底层的运行环境与状态持久化,而 Ultimate 则组织界面、扩展逻辑及协作流程。Daniel 为自己的博客项目定制了一个“博客视图”,将文章列表、配音、站点预览和写作 Agent 整合在一起。这种设计让开发者正在使用的工具本身也成为当前开发项目的一部分,使得“自我修改”这一概念具象化为可操作的技术流程。

环境搭建与初始配置

要复现这一过程,首先需要满足特定的运行环境。博主指出,项目需要 Node.js 26(注:原文如此),并在 macOS 系统下通过克隆仓库、安装依赖并启动 Ultimate。浏览器访问终端打印的地址即可进入界面,随后选择 OpenAI 的登录入口(如 ChatGPT Plus 或 Pro)完成授权。Ultimate 与 Pi Durable 共享本地的登录与模型配置,这意味着用户无需重复设置 API Key。

在角色分配上,项目中的协调者(Coordinator)角色、摘要功能等均可单独设置模型。博主在演示中启用了项目配置,加载了预设的角色和扩展。启动入口背后有一个名为 supervisor 的程序,负责管理核心进程。博主强调,在提出界面修改需求前,应先进行一次普通对话并让 Agent 读取项目文件。这一步骤至关重要,因为它能让 Agent 在本地项目中激活文件与命令工具,为后续的自主修改奠定基础。

“启动入口背后有一个 supervisor 也就是管理核心进程的程序,完成登录后先做一次普通对话再让它读取项目文件。”

实战演示一:动态面板与状态持久化

第一个需求是增加一个“演示进度面板”。Agent 在项目的扩展目录中生成了代码及说明文件,并在独立预览中打开。该面板包含三个条目:本地启动连接、订阅和自我修改。点击条目可切换完成状态,底部实时显示已完成数量。博主演示了逐项点击的过程,勾选状态从 0 变为 1、2、3。最关键的是,刷新页面后勾选状态依然保留。这证明了功能不仅被添加到了应用中,且具备持久化能力。

从技术实现来看,Agent 创建了协调会话和独立工作区。核心文件 web.tsx 包含了面板的注册逻辑与组件代码。测试流程包括:检查条目完整性、验证点击后数量变化、确认勾选/取消时数量对应关系,以及最后刷新页面后的状态保留。这一系列测试确保了新功能的健壮性。勾选状态使用的是 useExtensionUiState 接口,它将完成条目保存在当前实例的 UI 状态中,从而实现了跨刷新和对话切换的状态保持。

“勾选状态使用的是 useExtensionUiState 这个接口把完成条目保存在当前实例的 UI 状态中,所以刷新页面切换对话之后仍然可以继续使用。”

实战演示二:热更新与状态继承

在第一个需求的基础上,博主提出了第二个更复杂的需求:在完成数量下方增加一条细进度条,其长度随勾选数量动态变化。Agent 修改了同一个扩展文件,令人惊讶的是,无需刷新页面,新增的进度条直接出现在原页面上。由于博主在修改前保留了一项已完成的状态(1/3),新进度条准确对应了 1/3 的长度,且原有的勾选状态未被重置。

这一现象展示了前端更新的即时性。新代码进入页面后,已有状态继续参与新组件的计算。进度条功能直接复用了完成数量的数据源来计算宽度,使得旧的小组件能随新需求灵活变化。注册面板时,模型需填写扩展接口定义好的结构:标识、标题、图标和组件。其中,面板标题决定显示名称,组件决定内容。这种设计允许 Agent 生成符合规范的代码后,迅速将需求转化为应用内的实际功能。

“不用刷新页面新增的进度条就出现了,之前勾选状态依然保留着。”

核心进程重启与会话连续性

前端更新仅发生在浏览器层,而 Pi Durable 负责会话、工具调用和存储。为了演示更深层次的“自我进化”,博主让 Agent 重启核心进程。Agent 调用重启工具后,继续回答之前未说完的内容。结果显示:会话编号仍为 45(表明上下文连贯),但界面的 generation 从 1 变为 2,证明核心进程已更换。重启后,Agent 不仅说出了之前给它的文字,面板也保留了 1/3 的完成状态。

这一过程涉及复杂的协调:Agent 调用重启工具 -> supervisor 切换核心进程 -> 新进程接管并继续处理原请求。这种热加载效果让 Agent 看起来像是在自我进化。关键在于,核心进程的替换并非简单的断开重连,而是涉及正在执行的工作的无缝衔接。supervisor 确保在旧进程释放控制权前,新进程已准备好接手。

“结果是会话编号仍然是 45,界面的 generation 从 1 变成 2,说明核心进程已经更换过了。”

Git Worktree 与隔离开发机制

Ultimate 如何实现安全的自我修改?关键在于 Git worktree 的使用。协调者角色默认利用 Git worktree,将开发中的版本与正在使用的版本分开。Agent 在独立的工作目录中修改文件、运行检查并启动预览,而用户继续使用稳定版本。只有当功能经过验证后,才通过代码管线进行常规合并与配置检查。

这种分工清晰:worktree 可理解为同一 Git 项目的另一份工作目录,拥有独立的开发分支。Agent 在其中实现新功能、执行诊断(由 Lander 角色参与),而当前使用的版本继续运行。预览机制提供了“先试用后集成”的安全网,避免了直接修改生产环境代码的风险。功能实现与版本集成有了清晰的界限,非常适合持续定制应用。

“Ultimate 它的 coordinator,也就是协调者角色默认使用了 Git worktree把开发中的版本与正在使用的版本分开。”

多层级代码加载策略

Ultimate 针对不同层的修改采用了不同的生效机制: 1. 前端组件与扩展界面:通过 Vite 实现热更新,即时生效。 2. 服务端扩展(工具/后端逻辑):保存后重新安装。正在执行的工具调用用旧代码完成,后续新调用使用新代码。 3. 核心进程:通过 supervisor 切换。旧进程运行,新进程准备就绪后接替。

对于核心进程的替换,supervisor 自身也可被修改(需手动重启)。在切换前,Ultimate 会对代码进行类型检查。若检查失败或新进程未准备好,则继续使用旧进程。交接时,旧进程先将重启工具的调用结果写入数据库,再释放控制权。新进程通过 Pi Durable 的 Harness 打开 SQLite 数据库,读取会话内容、执行进度及工具调用结果。新进程据此知道接下来该做什么,从而继续处理原请求。

“旧进程会先把重启工具的调用结果写入数据库再释放数据库的控制权,随后呢新进程接管数据库继续处理原来的请求。”

状态保存与避免重复操作

整个自我进化过程依赖于精准的状态管理。Pi Durable 将执行状态保存在 SQLite 数据库中,确保核心进程更换后工作不中断。而面板的勾选状态则由 Ultimate 的 UI 接口单独保存。每一轮修改的代码可通过 Git 查看,请求进度有对应记录。

对于操作外部系统的工具(如发送邮件、调用 API),系统还需考虑恢复执行时如何避免重复操作。博主总结道:用户提出需求 -> Agent 在独立工作区利用 Git worktree 修改代码、运行检查并预览 -> 通过热更新或核心重启使改动生效 -> Pi Durable 保存状态以支持进程切换后的连续性。这种机制让“自我修改”从概念变为可落地的工程实践。

“对于会操作外部系统的工具还要考虑恢复执行时怎样避免重复操作。”

结论

Ultimate 项目通过整合 Pi Durable 的持久化能力与 Git worktree 的隔离开发机制,成功实现了 Agent 对自身软件界面和核心进程的自我修改与热更新。演示证明,Agent 不仅能动态添加前端组件并保留状态,还能在重启核心进程后无缝继续之前的任务。这种架构将开发、测试与运行环境分离,通过 supervisor 管理进程切换和数据库交接,确保了“自我进化”过程的安全性与连续性。它展示了 AI Agent 从被动辅助转向主动构建和迭代自身工具的潜力,为未来定制化、自进化的 AI 应用提供了可行的技术路径。