Skip to content

第二十章 任务内进化:搜索、反思与验证—修复 ​

证据地位:本章综合公开研究与作者工程推导;近期演化研究以预印本为主,结论不等同于长期生产复现。控制流和费用表是教学示例。

任务内进化是在一次任务中根据新观察调整计划、候选和资源,通常不改变长期发布版本。只要候选能隔离、反馈足够快,它就适合做有界试验;但真实副作用未必容易回滚,不能仅因属于 L1 就认定风险较低。当前任务结束后,若没有另行验证并发布经验,下一次独立任务不会自动继承本次改进。

1. 本层的证据模板实例 ​

字段任务内实例
可变对象当前计划、候选分支、临时反思、检索范围、分配预算
观测信号工具错误、测试差异、环境状态、复核诊断、成本增量
归因方法错误分类、假设—动作—结果链、固定环境下的候选比较
候选生成best-of-N、树搜索、独立工作单元、最小修复
评价隔离方式开发诊断可回传;封存终测不进入修复上下文
门禁判据必需检查通过、预算和副作用上限;失败集合只作诊断
发布方式选定当前任务产物,不改全局配置
回滚粒度分支、工作树和可恢复检查点
失败模式无限重试、自我确认、错误反思、重复副作用、测试泄漏

2. 反思要绑定观察,采样也可以构成搜索 ​

Reflexion 将环境反馈写成语言反思,在后续尝试中复用而不更新模型权重。它展示了文本反馈改变后续策略的路线,但反思是否正确仍依赖外部反馈。Reflexion 同一模型可能把权限拒绝解释为命令写法错误,然后反复换命令。有效的反思应绑定动作编号、错误类别、产物和仍未排除的解释,写成“观察—贡献假设—下一试验”。

best-of-N 可以从相同提示随机采样,再由外部选择器筛选;显式写出不同假设不是搜索成立的必要条件。不过,候选高度相关或选择器不可靠时,增加 N 未必值得。仓库修复可以比较“恢复 API”“补兼容层”“改调用方”,并记录每条路线的适用证据,使有限预算覆盖不同解释。

有三类选择器可串联使用:编译、测试和约束校验先筛明确错误;评分准则下的复核者判断难以形式化的质量;责任人处理业务取舍。模型复核应盲化候选顺序并保留分歧,其总分不能覆盖硬检查失败。通过硬门后再比较成本、改动范围和风险,选择规则应在看到候选前确定。

3. 一个会推进、会扣费、会停止的搜索 ​

下面是控制流示意,宿主负责预算、隔离和事件记录,候选不能修改这些对象。paid 包装每一个生成、执行和验证动作:调用前预留该动作的费用、时间及调用数上限,宿主在上限处停止,调用结束后结算实耗;异常也结算,拿不到可靠计量时保守扣留预留额并登记待对账。未获得预算就不能启动动作。

代码里的propose、run_in_fresh_branch和development_checks只构造延迟执行的Operation描述,不调用模型或工具。获得ticket后,host.run_with_limits才执行该描述。若实现使用普通立即执行的函数,应把闭包交给paid,例如paid("execute", lambda: run_branch(c)),不能在求值参数时就先花费预算。本书运行测试采用前一种显式描述对象的约定。

text
paid(kind, operation):
    ticket = budget.reserve_upper_bound(kind)   # 不足则抛 BudgetExhausted
    try:
        return host.run_with_limits(operation, ticket)
    finally:
        budget.settle(ticket, measured_usage_or_reserved_upper_bound)

frontier = queue([(baseline_state, depth=0)])
visited = set()
verified = []
expansions = 0
stalled = 0
reason = "frontier_empty"

try:
    while frontier and expansions < max_expansions and stalled < max_stalled:
        state, depth = frontier.pop()           # 取出并移除
        key = hash(state.artifact, state.environment, state.hypothesis)
        if key in visited or depth >= max_depth:
            continue
        visited.add(key)
        expansions += 1
        progressed = false
        candidates = paid("generate", propose(state, max_children))
        for c in candidates:                    # 结果数由宿主截在 max_children
            result = paid("execute", run_in_fresh_branch(c))
            verdict = paid("verify", development_checks(result))
            record(c, result, verdict)
            if verdict.integrity_alarm:
                raise IntegrityAlarm
            if verdict.all_required_pass:
                verified.append(seal(c, verdict))
            if verdict.comparable_progress and c.state_key not in visited:
                frontier.push((c.state, depth + 1))
                progressed = true
        stalled = 0 if progressed else stalled + 1
    reason = stop_reason(frontier, expansions, stalled)
except BudgetExhausted:
    reason = "budget_exhausted"
except (IntegrityAlarm, UnknownEffect):
    quarantine_and_reconcile()
    return incomplete("integrity_or_effect_unresolved")
except HostActionError as error:
    reason = record_error_and_stop(error)

if verified:
    return best_by_preregistered_rule(verified), reason
return incomplete(reason)                    # 空候选、全失败均不可宣称成功

验证不通过但有可比较进展的分支可以继续搜索;验证通过的产物要封存,后续改动不能继承旧结论。达到深度、展开数、无进展或总预算上限,就返回已有合格候选或明确未完成。生成器返回空集合也会消耗一次展开机会和实际费用,不能无成本无限重试。用于防止重复展开的状态键应包含环境与假设,不能只用聊天摘要。

开发检查通过只产生待确认产物。合同要求封存终测或外部提交时,控制器还须完成对应门禁,才可宣称业务完成。终测费用应预先保留,不得把预算全部花在搜索后再临时省略验收。

以下虚构轨迹用“费用单位”说明账目,不代表任何 API 价格。总预算 15,预留最终确认 2,开发搜索可用 13;共同生成三条路线花费 3,每条执行与开发验证分别为 2 和 1:

路线隔离执行开发验证本路线实耗阶段结果
A:恢复旧 API执行完成兼容检查失败3不入已验证集合
B:增加兼容层执行完成新增高严重度失败3拒绝继续扩展
C:修正调用方执行完成必需检查全部通过3封存待确认

共同生成 3 加三条路线 9,开发实耗为 12;最终确认再花 2,总计 14,剩余 1。三条候选都应进搜索记录,但这是一个任务的三条分支,不是三个独立实验单位。如果最后 2 单位未获预留或确认失败,任务仍未完成。

4. 验证反馈与环境重试 ​

固定版本和输入下稳定复现的失败,可称为确定性失败;根因仍可能未知。结果忽好忽坏是稳定性问题,也不自动等于外部环境故障。开发检查可以返回定位诊断,封存终测则只按第二十四章的协议回传结果。不能把终测失败全文交给代理修复,再称重测仍是独立确认。

text
候选 → 干净环境中的检查
  ├─ 必需检查通过 → 封存待确认
  ├─ 开发诊断失败 → 有界修复
  ├─ 不稳定或疑似环境失败 → 独立归类、按统一限额重试并保留账目
  ├─ 完整性告警 → 隔离并停止
  └─ 无进展或预算耗尽 → 未完成、合法升级或人工接管

实验主分析按事先分配的全部合格任务或运行计分。标记为 invalid_environment 的运行、未激活机制和没有成功返回的运行,都不能事后从这个分母筛掉。独立控制面确认的外部故障可以按两组相同的限额重试,保留原失败、关联尝试、最终结果和全部费用;重试没有增加一个新的实验单位。候选自己造成的内存耗尽、超时或进程破坏也不能由候选改标为外部故障。

全局环境事故可以按预注册规则暂停整批并作废结论,另建新批次;原批次的暴露和费用仍需报告。机制分析可以另看激活或环境有效的子集,但它回答的是条件性问题,不能替代部署策略的端到端效果。

进展也不能只数失败减少了多少。ΔF = |失败_before| − |失败_after| 仅适用于同一套检查。应一起列出已解决、新增、未运行的检查及严重度;跳过测试、改测试版本或用许多轻微修复掩盖一项严重失败,都不构成晋级。连续无进展时换假设或停止,阈值按任务成本预设。

5. 修计划、修状态与真实副作用 ​

计划错误可从同一检查点换路线;状态已经被破坏则要恢复环境或新建分支。例如先升级依赖再修代码,回退时必须一起处理锁文件、缓存和后台进程,否则下一候选仍运行在混合状态。检查点应记录代码版本、依赖镜像、环境引用、待确认外部动作和事件位置。

工作树可以分支,邮件、工单、部署和数据写入却不能随候选任意复制。搜索阶段使用模拟、只读或受控预演;真实提交由选定候选在最新授权和幂等控制下执行。结果未知的调用先对账,不能借“再试一个分支”重复提交。回滚环境也不能把已经消耗的费用退回搜索预算。

不同错误需不同权限。INVALID_ARGUMENT 可在限额内修参数;TEST_FAILURE 需要新证据或假设;POLICY_DENIED 只能合法变更授权或停止;INFRASTRUCTURE 由控制面按统一规则重试并计费;UNKNOWN_EFFECT 暂停可能重复的动作直到对账完成。重试次数是配置,不是所有任务通用的常数。

6. 长项目靠产物和证据延续 ​

Harness-of-Harness 在固定模型、基础 Harness、角色和运行策略下,组织规划、开发与 QA 循环。开发者修改产物,QA 检查冻结候选,后续规划使用项目产物和执行证据;隐藏基准评价不回传开发循环。这是同一项目的有界迭代,不是固定基础 Harness 在运行中改写自己,项目内状态也不自动成为跨独立任务的学习。Harness-of-Harness v1

这项工作提供了匹配开发轮数的对照,但轮数相同不代表模型调用、token 或总费用相同。其长期案例仍有未解决和重新打开的问题,因此进度要同时报告新增、关闭、重开和未决项。多个角色调用同一模型,可以分开权限,却不会自动消除相关判断错误。

Stellar Colosseum 把长证明组织为相互依赖的子问题,先探索路线,再以针对性反证和验证发现驱动局部修复,聚合时保留批评。它提醒我们:并行生成的段落不能仅凭各自看似合理就直接合并;改掉一个前提,还要重查依赖它的结论。这是作者报告的研究机制,本书没有独立复现其数学成果。Stellar Colosseum v2

7. 将预算用在可区分的解释上 ​

平均分配 token 可能把资源耗在已被否定的路线。若测试失败可能来自代码、测试数据或环境,先复现最小失败并校验镜像与数据摘要,往往比直接生成三个补丁更有信息。记录预测与实际观察能提高诊断质量;随机采样仍是合法搜索方式,只需按候选相关性和选择收益证明它值得付费。

停止行为本身也应测量。组件实证研究中的计划机制在部分模型上帮助完成任务,在另一些设置中主要减少重复验证;计划与动作接口的比较仅发生在指定上下文配置,不能泛化为“多计划必然更好”。Harness 组件实证研究 v1

本层指标包括可信完成率、每任务候选数、全费用下的单位可信完成成本、重复副作用、无进展停止和人工接管。可确定执行的流程、弱验证器下的高损失任务,不一定适合开放搜索。更多思考轮数不是独立目标。

8. 如何结束当前任务 ​

任务结束时可以提出经验候选,附原任务、证据、适用条件、反例、暴露标签与归因不确定性,再进入第二十一章的写入门。来自封存测试的诊断不能直接变成技能或训练样本;若经授权转作开发材料,派生产物也继承暴露标签,并更换后续终测数据。

失败也可产出有价值的发现,例如工具错误不可诊断、合同缺字段或检查不稳定,不必强行写成“以后都应该怎样做”。本层交付是产物、检查记录、完整费用和停止原因;跨任务复用需要另一次验证与发布决定。

公开阅读版本