资讯动态

PI框架实操:Plan-Implement双循环打造靠谱AI编程代理

发布时间:2026/10/20 18:58:12 来源:尧图企业网站定制
1. PI 框架到底是什么为什么我盯上它我平时对又冒出来一个 Agent 框架这种事相当警惕市面上换皮的多、真能省事的少。但 PI 框架是我在做一个跨平台系统 Demo 时真正用顺手的调度框架它解决的从来不是能不能调大模型而是怎么让大模型安安分分地帮你把代码改对。一句话概括PI 框架是面向编程场景的 Agent 编排框架核心是 Plan-Implement 双循环先让模型产出可执行计划再由执行器落地执行结果回流修正计划如此反复直到任务收敛。这套循环天然复刻了写代码→跑测试→看报错→改代码的真实工作方式。如果你正打算给内部项目做一个自动修 bug 的小助手、想把重复的脚手架工作交给 AI或者单纯想研究 AI 编程代理的内部机制这篇文章值得你看完。我一开始也怀疑多套一层循环不是更慢吗实际用下来发现恰恰是这层循环让结果从像那么回事变成真的能用。下面我会从设计思路讲起再给出一份可以直接抄的搭建过程最后把我踩过的坑全部摊开。1.1 编程代理最常见的三个翻车现场先说痛点。我在早期尝试直接拿大模型裸接业务时遇到过三个特别典型的翻车点。第一个是答非所改。你让它改某个模块的接口它洋洋洒洒生成了一大段新代码结果你仔细一看改的根本不是你要的那个文件甚至把不相关的依赖也动了一遍。原因很简单大模型对项目结构的感知来自你塞给它的上下文而上下文一旦没讲清楚文件边界它就会自由发挥自由发挥的结果就是灾难。第二个是循环空转。模型输出一段代码你拿去执行报错了你把报错丢回去它改了一版还是错再丢回去它可能在同样的问题上反复打转三四轮。这背后是反馈信号太弱——你只是把错误文本原样塞回没有给它当前执行环境到底处于什么状态的结构化信息。第三个是上下文失控。对话轮次一多整个历史全部堆积在上下文窗口里后面几轮模型开始忘记早期约束生成的代码风格漂移、接口张冠李戴更别提 token 成本蹭蹭往上跑。这些问题的根源不是模型能力不够而是没人帮它把任务拆成计划和执行两条线。PI 框架做的就是把这套分工制度化。1.2 PI 框架的核心定位Plan 与 Implement 分离PI 这个名字本身就很直白——Plan 和 Implement。它把整个 Agent 的工作切成两个角色规划器只负责思考不碰具体文件执行器只负责落地不负责决策。规划器拿到任务后先产出结构化计划每个计划步骤包含目标文件、改动类型、预期结果三个字段执行器拿到计划步骤后调用对应工具去真实地读写文件、运行命令然后把结果打包成反馈回传。这个分离带来一个直接好处你终于可以单独控制思考的质量和执行的纪律。想提升思考质量就调规划器的模型参数想管住执行不乱来就收紧工具权限。两者互不污染排查问题的时候也特别清晰——计划错了找规划器执行错了找工具链不会出现一团乱麻。我在项目里把这一层理解为拆手和脑。手归手脑归脑中间用一份带格式的工单交接。事实证明这是让 AI 编程代理从玩具走向工具的关键一步。1.3 它和其它 Agent 框架的本质区别市面上的 Agent 框架大多走通用对话 工具调用路线相当于给大模型装了一堆插件它想怎么用就怎么用。PI 框架不一样它默认你在处理的是一个有明确目标的工程任务所以它强制走先计划、后执行、再反馈的流程不允许模型跳过计划直接动手。这听起来像限制实际是保护。通用框架适合闲聊、问答、信息搜集但编程任务的成败完全取决于有没有按约束改对地方没有流程约束模型自由度越高破坏力越大。在我做过的模拟项目 X 里PI 框架的流程强制力帮我挡掉了至少三四次模型差点把配置文件改崩的意外。后面实操部分你会看到这种流程约束是通过工具之间不共享自由上下文来实现的而不是靠提示词里写一句请你小心。2. 设计思路拆解PI 凭什么敢叫利器这一节我会把 PI 框架的几个关键设计点逐个拆开讲重点讲为什么这么设计因为理解了这些你遇到问题才知道往哪个方向排查。2.1 双循环的关键不是分段而是反馈闭环很多人第一次看到 Plan-Implement 双循环会觉得这不就是先列计划再干活吗多此一举。但真正关键的不是分了两步而是执行结果一定要回流到计划层形成一个闭环。我实际跑过的流程是这样规划器先产出一个计划比如第一步读取某个模块的配置第二步修改日志级别第三步运行测试验证。执行器执行第一步后拿到真实的文件内容这时它不会直接开始改而是把内容作为观察结果回传给规划器。规划器根据观察结果修正后续步骤比如发现配置项名字和计划里写的不一样它立刻调整第二步的改动方案。这个闭环解决了我开头说的答非所改问题。因为每一步动手之前模型都基于最新的真实状态做决策而不是基于一开始那点可怜的项目摘要硬猜。打个比方这就像一个人进厨房做菜不是拿着菜谱闷头做完再发现盐放错了而是每炒一步就尝一口随时调整。闭环带来的第二个好处是可审计。每一轮计划、每一次执行结果都有记录任务失败的时候你能清楚看到是哪一步的计划假设错了还是哪一步的执行动作出了问题。这一点在工程协作里价值极大你总不能跟团队说AI 抽风了就完事。2.2 工具注册机制把大模型的手交给业务PI 框架里模型不能随便调用任何函数所有能力必须通过工具注册显式暴露。你注册什么它才能用什么没注册的想破脑袋也调不到。这个设计看起来是限制实则是安全边界的基础。我在模拟项目 X 里注册的工具非常克制核心就三个一个命令行执行器、一个文件读写器、一个静态检查器。命令行执行器被限制在项目目录内禁止访问项目目录之外的文件系统文件读写器只允许操作白名单后缀的文件静态检查器只能做语法和风格检查不执行任何副作用操作。这套机制的价值在于你可以放心地让模型随便折腾因为它的活动范围被你用工具边界圈死了。我见过很多人不敢让 AI 代理真正动手就是怕它乱来而 PI 框架的答案不是靠模型自律而是靠工具权限硬约束。记住一句话永远不要指望提示词约束行为要靠在架构上让它做不到。2.3 上下文预算管理写代码场景下的 token 焦虑写代码和聊天最大的区别在于代码文件可能很长项目结构可能很复杂而模型的上下文窗口永远是有限的。PI 框架对这个问题没有选择简单粗暴的全部塞进去而是实现了上下文预算管理。具体做法是规划器默认只接收任务描述 项目结构树 与当前步骤相关的文件摘要不加载完整文件执行器在真正操作某个文件时才把该文件内容加载进上下文。这样一来单个节点的上下文消耗被控制在一个文件加若干元信息级别而不是整个项目的级别。我在实操中把单步上下文上限设定在 3 万 token 左右超过就会被强制要求精简计划拆得更细。实测下来一个中等规模项目几十个文件跑完整轮任务累计消耗比那种全量上下文一把梭的做法省了一半还多。而且更重要的是模型在每一步看到的都是当前需要的精准信息注意力更集中生成质量明显提升。2.4 沙箱执行先让它随便折腾编程代理最让人心跳加速的时刻是它执行命令的那一下。万一它跑了删除操作怎么办万一它改了不该改的配置文件怎么办PI 框架的思路是默认让执行器跑在沙箱环境里所有对文件系统的修改先落在临时工作副本上确认无误后再合并回真实项目。这个确认后合并的机制极大地降低了试错成本。模型可以在沙箱里反复跑测试、装依赖、删了重建你完全不心疼。等一轮任务结束时你把沙箱里的 diff 拿出来人工过一眼或者跑一遍项目自带的测试套件通过后再真正落地。这一步相当于给 AI 的鲁莽上了一道保险。我在实际项目中遇到过模型在沙箱里把依赖版本改乱的场景如果是直接在真实环境跑项目当场就废了但因为沙箱隔离我只花了一分钟就回滚重来。沙箱不是 PI 框架的发明但它把沙箱集成成了循环的标准环节这才是它省心的地方。3. 实操5 步搭一个能改代码的编程代理理论讲完了下面进入实操。我以模拟项目 X 为例演示怎么用 PI 框架搭一个最小可用的编程代理目标任务是给项目里所有日志调用增加调用位置信息。整个流程五个步骤每一步我都会给出可复现的配置。3.1 环境准备与最小依赖先准备好环境。我这边用的是带 Python 运行时的 Linux 环境项目本体是一个标准的 Python 工程。PI 框架本身是个轻量库只依赖一个核心运行时和大模型服务的标准 API 客户端没有乱七八糟的传递依赖。安装完成之后记得先建一个独立的工作目录把项目完整复制一份进去作为沙箱副本后面所有 AI 的动作都发生在这个副本里。我当时用的命令大致是这样mkdir -p ~/agent-sandbox/sample-x cp -r ~/projects/sample-x/* ~/agent-sandbox/sample-x/ cd ~/agent-sandbox/sample-x # 初始化虚拟环境避免污染系统环境 python -m venv .venv source .venv/bin/activate这一步看起来不起眼但请务必做。我见过有人跳过沙箱直接让 AI 代理动真实项目结果一行正则写错整个目录被替换哭都来不及。沙箱副本是底线不是可选项。3.2 定义任务对象与目标描述PI 框架里一切从一个任务对象开始。任务对象需要包含三个部分目标描述、约束条件、验收标准。我当时写的任务对象大致长这样from pi import Task task Task( goal给项目里所有日志调用增加调用位置信息格式为文件名:行号 - 日志内容, constraints[ 只允许改动 src 目录下的 .py 文件, 禁止改动测试目录和配置文件, 日志格式调整不得影响现有功能 ], acceptance[ 所有日志输出都包含文件名:行号前缀, 项目测试套件全部通过 ] )注意约束条件要尽量写具体别写小心一点这种没法验证的话。PI 框架的规划器会把这些约束逐条解析进计划并在每一步执行前重新校验所以约束越明确后期越不容易跑偏。3.3 注册第一个工具命令行执行器工具注册是 PI 框架的核心操作。我按最小可用原则先注册两个工具一个跑命令一个读文件。from pi import Tool execute_tool Tool( namerun_command, desc在项目沙箱目录内执行命令行指令返回标准输出与退出码, schema{ command: string, 要执行的命令, timeout: integer, 超时秒数, 默认 30 }, handlerrun_in_sandbox ) read_tool Tool( nameread_file, desc读取指定文件的完整内容, schema{ path: string, 相对沙箱根目录的文件路径 }, handlerread_sandbox_file )这里有两个细节值得说。第一desc 别偷懒要写清楚工具的边界和副作用这直接影响模型对工具的调用判断。第二handler 里一定要绑定到沙箱路径不要让模型有办法拼接出沙箱之外的路径我是在 handler 内部做了严格的前缀校验路径一旦越界直接返回错误。3.4 配置规划器与执行器接下来把两个角色串起来。规划器负责拆分任务执行器负责调用工具落地from pi import Agent agent Agent( planner{ model: general-llm, temperature: 0.2, max_tokens: 2000 }, implementor{ model: general-llm, temperature: 0.0, tools: [execute_tool, read_tool] }, steps_limit6, sandbox_path~/agent-sandbox/sample-x )温度设置是我反复试出来的规划器可以稍微有点创造性但执行器一定要稳所以执行器温度设为 0。steps_limit 设为 6是防止模型进入死循环无限空转一旦超过步数上限Agent 会强制终止并把已完成的改动汇总报告。3.5 跑通第一个真实任务给项目加日志位置配置完成直接运行任务。PI 框架会先打印规划器产出的计划每个步骤都有编号和目标说明。我当时看到的计划是这样遍历 src 目录下所有 .py 文件筛选包含调用日志语句的文件清单。逐个读取目标文件定位所有日志调用语句。在每处日志调用前插入定位信息修改对应调用参数。运行测试套件验证改动后项目行为正常。执行过程中模型每一步都会调用工具框架会把工具返回结果回传给规划器。第一个生成版本里模型把所有日志调用改成了统一的装饰器实现虽然语法没错但和项目里已有的自定义日志封装冲突了。规划器收到执行反馈后立刻发现了重复包装问题自动回退了刚才的改动改成直接在调用点插入定位字符串。这一步如果放在没有闭环的设计里基本就废了。最终跑了二十多分钟产出 17 个文件的改动测试套件全绿。我仔细检查了 diff确实只动了日志相关行零副作用。这就是可放心的编程代理落地后的样子。4. 核心环节的细节与参数经验跑通一遍只是开始真正让人头大的是参数调优和边界控制。这一节我把几个关键环节的经验整理出来全部来自真实踩坑。4.1 规划阶段的温度与最大 token 怎么给有一个普遍误区是温度越低越可靠。放在普通问答里没错但放在规划器上我试过温度压到 0结果计划死板遇到稍微绕一点的场景就只会走直线不知道怎么变通。后来我把规划器温度调到 0.2执行器保持 0效果最好——规划需要一点发散执行必须绝对稳定。max_tokens 的设定更讲究。给太少规划器会为了省 token 把关键字段截断比如遗漏约束条件给太多它会啰嗦地输出大段解释浪费上下文。我的经验是单步骤规划 800 到 2000 token 比较合适整个任务的全局计划不要试图一次输出完而是按步骤持续更新。PI 框架支持计划增量更新每执行完一步规划器只输出下一步调整不必重新生成全文这招能省大量 token。4.2 代码生成后的校验策略不能盲信输出模型生成的代码看起来再对也必须走一道程序化校验这是我从一次事故里总结出来的。那次模型生成了一段看起来完美的正则替换逻辑结果一跑直接抛异常原因是一个字符类边界写错了。如果当时我把生成即信任直接合并回项目线上问题就藏下了。我的校验链路是三层第一层静态检查跑一遍语法解析和风格检查工具第二层测试套件只跑与改动模块相关的用例保证反馈速度快第三层 diff 审阅我用脚本自动列出所有改动文件和行数人眼抽查关键改动点。前两层是机器把关第三层是最后的人肉闸门。三层都过了才允许沙箱合并。注意这里合并我设置成手动触发而不是全自动因为工程场景里有些 trade-off 需要人判断。4.3 多轮反馈中的上下文裁剪方案Agent 跑任务动辄几十轮如果每轮反馈都累积到上下文里很快窗口就会爆掉。PI 框架的默认策略是只保留最近三轮的完整反馈更早的历史压缩成一条摘要记录放到规划器的系统提示里。我一开始偷懒没改这个配置让所有历史都保留结果任务跑到第 40 轮时代理开始不断重复验证同一个文件明显是上下文里原始约束被大量工具输出淹没。后来我手动做了裁剪效果立竿见影。简单原则是工具原始输出不应累积只保留结论保留的结论里优先保留失败信息因为成功信息能通过测试结果重建。5. 常见问题与排查技巧实录这一部分直接给工作多年的同事风格的经验全是遇到过的真实问题按高频程度排序。5.1 高频问题速查表现象直接原因排查与解决规划器反复生成相似计划不进下一步反馈信息里没有包含上一步已经做了什么检查工具返回结果是否带状态标记确保执行器把已完成/失败原因明确回传执行器调用工具时路径拼接越界工具 schema 对路径参数描述不够严格在 handler 内部做绝对路径前缀校验越界直接抛错并销毁调用上下文模型频繁修改无关文件约束条件写得太模糊把约束拆成可验证规则比如只允许改动 src 目录必须落到工具白名单上下文增长过快后半程效果下降工具输出全部保留在历史里开启上下文裁剪只保留最近三轮完整反馈加早期摘要沙箱内测试通过合并后报错沙箱环境与真实环境有细微差异系好环境一致性合并前对比依赖锁定文件和环境变量差异任务步骤到达上限仍没收敛单一任务粒度太大拆分子任务宁可多跑几轮代理也不要让一个任务吞下太多目标5.2 一次失败案例的完整复盘那次任务的目标是重构一个模块的错误处理逻辑。规划器第一步就产生了误判把修改错误处理函数理解成了替换整个模块的异常基类执行器按计划改了文件然后测试大量报错。按理说反馈回来了模型应该意识到问题但它连着重试三次每次都是换一个文件重新做类似的大改。我查了运行日志发现问题不在模型能力而在工具返回结构。执行器的返回只有命令退出码 1 报错文本没有告诉规划器你改错了哪个层的定义。规划器收到的反馈太粗根本定位不了因果链。解决方案是把执行器反馈从二维输出 退出码扩展成四维输出、退出码、受影响文件列表、文件差异摘要。加了后面两个字段之后规划器瞬间就能看到是我动了基类定义导致依赖它的三个模块全部崩了下一轮计划直接改成了精准回滚加小的修正。这次复盘让我彻底明白反馈的结构化程度直接决定代理智商。5.3 几条压箱底的避坑心得第一一切权限收敛在工具层不要寄希望于提示词。提示词写得再狠模型一绕就绕过去了工具白名单是物理层面的约束这才是真安全。第二沙箱副本一定要和真实项目保持基础一致。我吃过一次亏沙箱里的依赖版本比真实环境旧模型在沙箱里怎么测都通过合并回来全是问题。从此以后每次开任务前加一步同步依赖锁定文件。第三不要追求全自动。我见过有人把合并也做成自动结果模型改了一批风格不统一的代码项目可维护性大幅下降。我现在的做法是自动改、自动测、人工合并。人工合并这一步不是不信任 AI而是保留工程兜底代价很小收益很大。第四步数上限别给太宽。给它 20 步自由度它真的会走上 20 步弯路给 6 步它反而会逼自己在计划阶段想得更周全。我现在的习惯是从小步数开始跑不通再加而不是一开始就给大空间。最后分享一个我个人的使用习惯每次跑完一个任务我会把规划器产出的完整计划存下来作为下一次类似任务的参考样例。PI 框架支持导入历史计划作为 few-shot 示例这招用下来同类任务的首次计划准确率提升非常明显。编程代理这东西喂给它多少工程纪律它就回报多少可靠性PI 框架只是把纪律变成了一段可以执行的代码而已。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑