2026年10月3日
bonsai_agent_convergence_thumbnail
实测 7.2GB 的 27B 大模型(Bonsai 2 PQ2_0)做代码 Agent 频频超时的收敛调优实战。通过 Prompt Completion Policy、Harness 动态 Steering 到开源 Pi 原生扩展,彻底解决模型过度思考与验证死循环,步数直降 55%,全量任务全绿通过。

7.2GB 的 27B 模型做 Agent 频频超时?一次惨痛翻车教给我的收敛控制实战!

导读与实机环境声明:
这是一个 27B 参数、量化后仅 7.2GB 的大模型在实际代码 Agent 工作流中的深度调优复盘。模型为 Bonsai 2 27B PQ2_0,运行于本地 RTX 3060 12GB 显卡(llama-server,上下文 131,072,Medium Thinking)。
在上一篇测试中,它展现了惊人的代码单步解决能力,但在真实 Agent 循环中却频频超时:它往往不是不会做,而是做完以后不知道什么时候该停。 本文记录了我如何通过三阶段优化(Prompt Policy → Harness Steering → Pi Extension),将思考耗时与执行步数砍掉 60% 以上;并从一次惨痛的“催工翻车”事故中,沉淀出生产级 Agent 收敛控制的核心法则:Completion Oracle(完成真理源)。


一、痛点浮现:它不是不会做,而是有“强迫症”

上一篇基准测试里,我完成了 Bonsai 2 27B PQ2_0 的本地部署和能力测评。

这个模型最吸引人的地方非常直接:

27B 参数,GGUF 权重仅仅只有大约 7.2GB。

相比动辄 17GB 往上的 Qwen3.8-27B Q4_K_M,它以极低的三进制极限量化,把 27B 模型的端侧运行门槛直接压到了普通消费级显卡(如 12GB 显存的 RTX 3060 / 4070)的舒适区内。

在单轮推理、代码重构、甚至 90K 长上下文信息定位中,它的智力几乎没有出现明显的塌缩。然而,一旦把它接入 Pi CLI 放进真实的多步代码 Agent 循环,一个非常诡异的瓶颈迅速暴露:

理解需求 → 修改代码 → 运行测试 (PASS)
   ↓
继续检查相关文件
   ↓
再跑一次测试 (PASS)
   ↓
反复思考边界条件与并发异常
   ↓
再次验证
   ↓
Agent Steps (预算) 耗尽 → TIMEOUT!

最典型的是复杂流式导出任务 P1。

代码最后其实完全是正确的,Hidden Validator(隐藏验收器)也能全绿通过;但因为 Bonsai 一直在继续检查、反复抓日志验证,最终超过了设定的 25 步限制,被评测系统按规则判为 TIMEOUT。

看一下它与 Qwen3.8-27B 在四个复杂任务里的 Thinking Tokens 对比:

Bonsai 累计 Thinking Tokens: 22,831
Qwen3.8 累计 Thinking Tokens:  3,568  (相差约 6.4 倍!)

单在 P1 这一道题上:
– Bonsai:26+ Steps,11,383 Thinking Tokens,耗时 551.6 秒(TIMEOUT)
– Qwen:7 Steps,406 Thinking Tokens,耗时 66.8 秒(PASS)

这里有一个极其关键的区别:

任务失败 ≠ 代码错误

代码能力完全在线,单步工具调用正确,但它却缺乏对“任务已完成”的笃定感。

为什么 7.2GB 的极限量化模型特别容易“停不下来”?

这触及了大模型量化与 Agent 控制论的底层机理:

27B 模型压缩到 7.2GB,意味着每个权重平均只有 ~2.1 bit。在极端低比特量化下,模型的 Logits 概率分布会出现明显的平坦化(Confidence Calibration 漂移)。简而言之:模型的自我确信度下降了。

满血大模型在看到 pytest passed 后,输出终止指令(Stop Token / 完成交付)的概率显著高于继续探索的概率;而超轻量模型由于置信度不足,内心始终处于一种“不安全感”中。为了消除这种不确定性,它会本能地选择它认为最安全、最不容易被惩罚的行为——继续调用已经通过的只读命令和单测工具。

因此,优化目标绝不是“让模型变聪明”,而是:在代码已经具备充分完成证据的前提下,给 Agent 装上刹车片,让它学会体面收工。


二、第一阶段:静态 Prompt Completion Policy(治标不治本)

第一阶段我采取了对架构改动最小的方案:不改 Pi 框架,不降思考档位,不加外部插件,只在模型的 System Prompt 层追加一段明确的 Completion Policy(收敛准则)。

核心规则非常明确:

# Task Completion & Convergence Policy
1. 当需求已满足、相关自动化测试已通过且未引入新错误时,请充分信任当前结果。
2. 严禁在源码未变更的情况下,重复执行已通过的相同检查。
3. 不要发散去进行任务范围外的额外边界优化或重构。
4. 验证通过后,请立即整理交付总结并结束任务。

重新跑最容易失控的 P1,进行两次独立复测:

  • 原始 Baseline:26+ Steps | 11,383 Thinking | 551.6s | TIMEOUT
  • 加 Prompt 复测 1:24 / 25 Steps | 6,935 Thinking | 317.9s | PASS
  • 加 Prompt 复测 2:25 / 25 Steps | 7,887 Thinking | 425.4s | PASS

结论与局限:
效果确实存在——Thinking Tokens 降低了 31% ~ 39%,耗时缩短了 23% ~ 42%,任务状态成功从 TIMEOUT 扭转为 PASS。

但隐患同样刺眼:24/25、25/25。它仍然像踩着红线在开车,几乎把步数预算榨干。只要项目稍微复杂一点,依然极易猝死。在多轮 Tool-call 的大量终端输出冲刷下,静态 Prompt 会遭遇注意力漂移(Attention Drift),模型固有的审慎惯性依然会占上风。


三、第二阶段:Harness 级动态 Steering(步数直接腰斩)

既然纯 Prompt 压不住,那就必须在 Agent 运行时(Harness)层面介入。

但我坚决不做 Hard Stop(硬杀)。如果外部系统在测试通过瞬间就直接强制 Kill 掉 Agent,一旦模型还有最后一步配置文件没有落盘,就会造成灾难性的假阳性失败。

我设计的第二阶段机制叫:动态 Steering(上下文定向推导)。

┌─────────────────┐
│   Agent 运行    │
└────────┬────────┘
         ▼
┌─────────────────┐    YES    ┌─────────────────┐
│ 测试通过 (PASS)? ├─────────►│ 源码在此后变动过? │
└─────────────────┘           └────────┬────────┘
                                       │ NO
                                       ▼
                              ┌─────────────────┐
                              │ 注入 Steering:  │
                              │ "核心验收已达标, │
                              │ 请立即总结收工"  │
                              └─────────────────┘

机制原则:Harness 不结束 Agent,只在检测到“测试已通过 + 源码未改动 + 模型试图继续发散”时,向模型上下文中动态推送一条高优先级系统提示:

“当前已经具备充分完成证据,请停止额外验证,核对需求后提交最终结果。”

P1 战果:从 26+ 步直接降到 11.5 步

在 Prompt + Steering 协同下,重新测试 P1:

轮次 Agent Steps Thinking Tokens 耗时 (Duration) Hidden Validator
原始 Baseline 26+ (超限) 11,383 551.6s PASS (但评测超时)
Steering 轮次 1 12 2,989 144.6s PASS
Steering 轮次 2 11 5,006 170.3s PASS
优化后均值 11.5 (↓55%) 3,998 (↓65%) 157.5s (↓71%) 全绿通过

原本需要 9 分多钟、步数超标的任务,现在只需要 2 分半钟、11 步 就能高质量交付!

整个执行链路极度顺畅:
– Turn 1 ~ 9:正常理解代码、修复核心流式逻辑;
– Turn 10:运行 pytest,绿灯通过;
– Harness 介入:检测到源码未修改且测试已绿,自动注入收工 Steering 提醒;
– Turn 11:模型读取提醒,快速核验需求项;
– Turn 12:输出格式化报告,调用结束工具,Agent 优雅收敛。

泛化验证:C1 (Python) 与 C2 (TypeScript)

将相同机制不加改动推给其他代码任务:
– C1(Python 计费引擎 Bug 修复):步数从 13 步降至 9 步(↓31%),耗时从 159.6s 降至 108.6s;
– C2(TypeScript 跨文件服务重构):步数从 14 步降至 8 步(↓43%),耗时从 105.5s 砍到 50.5s。

两个任务全部稳定 PASS。至此,收敛效果看似已经完美。

直到遇到复杂系统排障任务 A1,系统给了我当头一棒。


四、A1 惨痛翻车,引出核心命题——Completion Oracle

A1 是一个涉及复杂环境、数据库 Migration、字段对齐以及并发库存扣减的系统级任务。它要求 SQLite 的 schema 正确迁移、新字段生效、微服务正常拉起、并且核心业务接口返回预期的扣减结果。

最初简易 Harness 的判断逻辑极其粗糙:

pytest exit code == 0 → 认定完成 → 发送 Steering。

结果悲剧瞬间发生:A1 项目自带的单测是一个极其简陋的 Smoke Test(冒烟测试),仅仅断言了端口是否大于 0。

Bonsai 在排查初期随手跑了一下 pytest,终端绿灯亮起。Harness 误以为“大功告成”,立刻向 Bonsai 发送收工催促。

Bonsai 表现得极其“听话”——它立即中断了尚未写完的数据库迁移脚本,直接总结交卷。

评测结果:Hidden Validator FAIL。任务彻底爆死!

深刻教训:收敛控制最怕错误的真理源

这次惨痛翻车让我彻底看清了一个事实:错误的收敛控制比模型失控更危险。

在软件工程和 Agent 控制论中,判定任务完成的真实依据被称为 Completion Oracle(完成真理源)。

弱 Oracle (Weak Tests)   + 激进 Steering ──► 灾难性提前交卷 (False Positive)
强 Oracle (Semantic E2E) + 稳健 Steering ──► 高效、安全、精准收敛
  • 弱证据(绝不能作为完成 Oracle):
  • 单纯的冒烟测试(Smoke Test);
  • /health 探针(只能证明服务活着,无法证明业务功能正确);
  • sqlite3 查看结构、cat / grep 查看文件(属于探索过程,而非业务验收)。
  • 强证据(合法 Completion Oracle):
  • 自动化单元测试通过 + 真实业务端点(如 /api/items、/api/orders)的真实 HTTP 200 响应与 JSON 数据结构断言。

在 A1 的第二轮修复中,我升级了 Harness 的 Oracle:必须同时捕获到服务拉起、核心业务 API 探针返回正确数据、且自动化测试全部通过后,才允许发送 Steering。

升级后,A1 用了 19 步稳健通过,Hidden Validator 再次满分全绿。


五、落地产物:Pi 原生 Convergence Extension

为了不再针对每个项目单独写 Harness 胶水代码,我将经过实战检验的规则抽象成了一个专用于 Pi CLI 的原生扩展:.pi/extensions/convergence.ts。

该扩展的核心设计哲学极其克制:宁可晚一点提醒,也绝不因弱证据诱导模型提前交卷。

扩展的 6 大运行法则

  1. 规则 1(源码修改即失效):任何 edit、write 动作,旧 PASS 证据立即全部清空,解锁 Steering 限制;
  2. 规则 2(单次测试保持静默):仅跑通一次测试时,扩展保持沉默,给模型留出自主判断空间;
  3. 规则 3(强完成证据):测试通过 + 核心业务 API 调用成功,触发 Strong Steering(明确建议收尾);
  4. 规则 4(探活排除):/health 永远不能单独证明任务完成;
  5. 规则 5(排查排除):数据库表查询、grep、文件阅读属于探索行为,排除在 Oracle 之外;
  6. 规则 6(死循环软拦截):针对强迫症模型在源码无修改时连续跑 3 次相同测试,触发 Soft Steering(禁止重复同一项验证,若完成请交卷,未完成只做剩余需求)。

六、插件开源地址与极速安装指南

为了让所有使用 Pi 或本地小参数 Agent 的开发者都能直接收益,这套方案已正式打包并开源上传至 GitHub!

一行命令极速下载与安装

你可以选择项目级安装(仅在当前代码库生效)或全局标配(所有工作区通用):

1. 项目级安装(推荐首选)

  • Windows (PowerShell):
    powershell
    New-Item -ItemType Directory -Force .pi\extensions
    Invoke-WebRequest -Uri "https://raw.githubusercontent.com/yang2020chen/pi-extension-convergence/main/convergence.ts" -OutFile ".pi\extensions\convergence.ts"
  • macOS / Linux (Bash / Zsh):
    bash
    mkdir -p .pi/extensions
    curl -sSL https://raw.githubusercontent.com/yang2020chen/pi-extension-convergence/main/convergence.ts -o .pi/extensions/convergence.ts

2. 全局标配安装(所有 Pi Agent 默认生效)

  • Windows (PowerShell):
    powershell
    New-Item -ItemType Directory -Force "$env:USERPROFILE\.pi\agent\extensions"
    Invoke-WebRequest -Uri "https://raw.githubusercontent.com/yang2020chen/pi-extension-convergence/main/convergence.ts" -OutFile "$env:USERPROFILE\.pi\agent\extensions\convergence.ts"
  • macOS / Linux (Bash / Zsh):
    bash
    mkdir -p ~/.pi/agent/extensions
    curl -sSL https://raw.githubusercontent.com/yang2020chen/pi-extension-convergence/main/convergence.ts -o ~/.pi/agent/extensions/convergence.ts

七、插件核心实现代码参考

扩展基于 Pi 的生命周期钩子(tool_call 与 tool_result)实现,其精简后的架构逻辑如下:

// .pi/extensions/convergence.ts
interface ConvergenceState {
  codeDirty: boolean;
  testPassCount: number;
  lastTestCommand: string | null;
  businessApiVerified: boolean;
}

const state: ConvergenceState = {
  codeDirty: false,
  testPassCount: 0,
  lastTestCommand: null,
  businessApiVerified: false,
};

export default function registerConvergenceExtension(pi: any) {
  // 规则 1:源码修改,清空旧证据
  pi.on('tool_call', (event: any) => {
    if (['edit_file', 'write_file', 'apply_diff'].includes(event.toolName)) {
      state.codeDirty = true;
      state.testPassCount = 0;
      state.businessApiVerified = false;
    }
  });

  // 规则 2-5:甄别 Completion Oracle
  pi.on('tool_result', async (event: any) => {
    if (event.toolName !== 'run_command') return;

    const cmd = (event.command || '').toLowerCase();
    const isSuccess = event.exitCode === 0;

    // 排除项:/health、sqlite3 查看表结构等不作为完成证据
    if (cmd.includes('/health') || cmd.startsWith('sqlite3') || cmd.startsWith('cat')) {
      return;
    }

    // 识别核心业务接口
    if (cmd.includes('curl') && (cmd.includes('/api/') || cmd.includes('/v1/')) && isSuccess) {
      state.businessApiVerified = true;
    }

    // 识别测试框架
    if ((cmd.includes('pytest') || cmd.includes('npm test') || cmd.includes('vitest')) && isSuccess) {
      if (state.lastTestCommand === cmd) {
        state.testPassCount++;
      } else {
        state.testPassCount = 1;
        state.lastTestCommand = cmd;
      }
    }

    // 强 Steering:测试通过 + 业务 API 验收通过
    if (state.businessApiVerified && state.testPassCount >= 1 && !state.codeDirty) {
      await pi.injectSystemSteering(
        '【Convergence Notice】核心业务接口及自动化测试已全量验证通过,完成证据链完整。' +
        '请停止重复检查与额外发散,立即整理变更并提交最终交付结果。'
      );
      return;
    }

    // 规则 6:死循环软拦截(连续 3 次相同测试)
    if (state.testPassCount >= 3 && !state.codeDirty) {
      await pi.injectSystemSteering(
        '【Convergence Notice】检测到在代码未变更的情况下连续 3 次执行同一项测试。' +
        '严禁再次重复该检查。若需求均已达标请立即收工;若有未尽事项,请仅针对缺失需求处理。'
      );
    }
  });
}

八、全量基准回归评测

搭载这套 Convergence Extension 之后,我对四个基准场景进行了全量重测:

任务编号 任务类型 优化前状态 / Steps / 耗时 搭载 Extension 状态 / Steps / 耗时 Thinking Tokens 变化 最终 Hidden Validator
P1 CSV 流式导出服务 TIMEOUT / 26+ / 551.6s PASS / 16 steps / 216.0s 11,383 → 4,324 (↓62%) PASS
A1 并发库存扣减与 DB 排障 PASS / 19 / 226.3s PASS / 19 steps / 211.4s 6,820 → 4,901 (↓28%) PASS
C1 Python 计费引擎修复 PASS / 13 / 159.6s PASS / 10 steps / 144.1s 4,372 → 4,004 (↓8%) PASS
C2 TS 跨文件服务重构 PASS / 14 / 105.5s PASS / 8 steps / 57.1s 1,649 → 1,166 (↓29%) PASS

关键工程取舍:为什么不追求极限的 11 步?

在第二阶段定制 Harness 时,P1 曾跑出过 11~12 步的成绩;而通用 Extension 的成绩是 16 步。

为什么我反而更接受 16 步?

因为通用工程决不能向过度拟合妥协。定制脚本可以针对特定题目精准下刀,但通用 Agent 必须面对成千上万个未知项目。在缺乏预设先验时,让 Agent 适当多做一次边界核对的成本,远比误判早死导致任务崩溃的代价低得多。

安全与泛化,永远优先于单点数据的极端压缩。


九、总结:我们到底需要什么样的 Agent 架构?

折腾了整整两天 7.2GB 的 Bonsai 2,我的工程认知经历了一次蜕变:

最开始我以为:是超小模型能力不足,所以 Agent 频频超时。
后来我发现:恰恰相反,它的代码能力完全在线,超时是因为它“太想把每件事做到尽善尽美”。

一个优秀的开发者,和一个只会做练习题的学生,最大的区别不仅在于会不会写代码,更在于对交付质量的确定性掌控——知道什么时候该动手,更知道什么时候证据已经足够,可以放心交卷。

对于端侧低比特量化大模型而言,最合理的 Agent 架构分工应该是:
– 模型(Model):专注负责战术分析、逻辑推理与代码编写;
– 测试与探针(Environment Probes):负责提供无偏见的客观数据;
– 框架(Harness / Extension):负责监控状态机、评估完成真理源(Oracle)的充分度;
– 收敛控制(Steering):在关键分水岭上,温和而坚定地递上一声提醒:“证据已充分,你可以收工了。”

这套机制不仅属于 Bonsai,也属于所有正在走向真实工程交付的本地 Agent。


🛠️ 相关资源与工坊直达通道

About The Author

1 thought on “7.2GB 的 27B 模型做 Agent 频频超时?一次惨痛翻车教给我的收敛控制实战!”

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注