编程 Agent 跑 6 小时不可怕,可怕的是你没有这三道保险

把一个重构任务交给编程 Agent,设置好目标,然后让它在后台持续运行。

6 小时后,你最先看的大概率不是“完成了多少”,而是三样东西:调用账单、测试结果,以及 Git diff 到底膨胀成了什么样。

真正让人不安的,也不是 Agent 写不出代码,而是它可能在同一个错误上反复尝试:测试失败了,继续改;新改动引发更多错误,再继续补;原本只要求重构一个模块,最后却顺手升级了依赖、调整了配置,还碰了几个不在任务范围内的目录。

这时最难回答的问题是:

它是在接近成功,还是已经进入了一个昂贵的低效循环?

因此,判断编程 Agent 能不能承担长任务,关键从来不是“它能连续运行多久”,而是任务能否做到四件事:可观测、可中断、可恢复、可验收。

而要实现这四点,至少需要三道保险:检查点、预算熔断、自动回滚。

说明:本文没有拿到一份可公开验证的完整 6 小时运行日志,因此不会虚构调用次数、Token、费用和成功率。文中的时间节点与数值配置用于展示实验方法,正式使用时必须由真实日志填充。

“后台跑 6 小时”,为什么很容易变成失控实验

一个看起来很适合交给 Agent 的任务,通常是这样的:

  • 重构某个核心模块;
  • 为缺失逻辑补充单元测试;
  • 修复 TypeScript 类型错误;
  • 更新接口文档;
  • 最后运行完整测试并提交代码。

如果让人类开发者处理,他会自然地停下来检查:改完一部分先跑测试,发现方向不对就撤回,涉及依赖升级时再确认一次。

但 Agent 不一定拥有这种天然的工程边界。

它接收到的目标往往是“完成任务”,于是可能把持续行动误认为持续进展。某次测试失败后,它修改实现;第二次失败后,它调整测试;第三次失败后,它开始怀疑依赖版本;接下来,任务边界便从“重构模块”逐渐扩张成“修理整个仓库”。

这就像让一个很勤奋的装修队进屋施工,却没有图纸版本、预算上限和验收节点。它未必偷懒,甚至可能一直在干活,但你无法确定它是在装修客厅,还是已经开始拆承重墙。

长时间 Agent 的核心风险,不是能力不足,而是工程约束不足。

长任务为什么会失控:三种漂移同时发生

1. 上下文漂移:它还记得最初要做什么吗

任务运行时间越长,Agent 读取的文件、错误日志、工具输出和中间结论越多。

即便模型拥有较大的上下文窗口,也不意味着所有信息始终具有相同权重。最初的任务边界可能被后续错误覆盖,临时方案也可能逐渐被当成正式目标。

典型表现包括:

  • 重复读取和修改同一个文件;
  • 已经完成的子任务被再次处理;
  • 为了让测试通过而改变原始需求;
  • 开始修改未授权目录;
  • 忘记某项改动只是临时验证。

解决这一问题,不能只依赖“再写一段更详细的 Prompt”,而要让任务状态脱离聊天记录,进入结构化检查点

2. 成本漂移:调用在继续,进度却没有同步增长

长任务的费用并不只来自生成代码。

Agent 还会反复读取文件、分析报错、调用工具、重新规划,再把越来越长的历史上下文发送给模型。进入失败循环后,调用量仍然上涨,但有效进度可能几乎停滞。

预算上限就像信用卡限额。它不是告诉 Agent 应该如何花钱,而是确保即使判断失误,损失也不会无限扩大。

3. 代码状态漂移:改得越多,越不敢合并

多轮修改叠加后,仓库很容易进入一种尴尬状态:

  • 局部测试通过,完整测试失败;
  • 新功能能运行,但旧接口被破坏;
  • 代码错误减少,改动范围却明显扩大;
  • Agent 无法解释每个文件为什么需要修改;
  • 人类接管时,只能从大量 diff 中重新理解任务。

这类仓库不是完全不能用,而是接管成本高到不值得继续使用已有改动

自动回滚的意义,正是把损失限制在最近一个安全版本,而不是让所有尝试永久叠加。

可以用三个生活化比喻理解:

  • 检查点像游戏存档;
  • 预算上限像信用卡限额;
  • 自动回滚像挑战失败后回到最近的安全存档。

三者缺一不可。

第一重保险:把大任务拆成可验证的检查点

检查点不是“Agent 每隔半小时写一句进度总结”,而是一个已经被验证、可以恢复的代码状态

比较稳妥的执行循环是:

1. 读取任务边界并生成计划;

2. 只处理一个子任务;

3. 运行对应测试和静态检查;

4. 记录修改文件与测试结果;

5. 创建 Git commit;

6. 保存结构化状态;

7. 再进入下一个子任务。

例如,“重构认证模块、补测试、修复类型错误、更新文档”不应被当成一个连续动作,而应拆成至少四个独立阶段。每个阶段失败时,都不应该污染前一个已经验收的阶段。

检查点应该保存什么

{

"checkpoint_id": "cp-007",

"task_status": "in_progress",

"completed_items": [

"add unit tests for auth service"

],

"remaining_items": [

"refactor token refresh logic",

"update documentation"

],

"changed_files": [

"src/auth/service.ts",

"tests/auth/service.test.ts"

],

"test_status": "passed",

"git_commit": "a1b2c3d",

"cost_so_far_usd": 8.42,

"next_action": "refactor token refresh logic"

}

以上数字和提交哈希仅用于说明数据结构,不代表某次真实实验结果。

相比重新向模型灌入数小时聊天记录,这种结构化状态有三个优势:

  • 恢复速度更快;
  • 无关上下文更少;
  • 人类可以快速判断任务进行到哪一步。

什么情况下应该创建检查点

检查点可以由多种条件触发:

  • 完成一个子任务;
  • 修改文件数量达到阈值;
  • 连续运行达到一定时间;
  • 上下文消耗接近预设比例;
  • 测试首次完整通过;
  • 即将进行依赖安装或大范围重构。

需要注意的是,时间到了不等于可以存档

如果测试仍然失败、代码无法构建,最多只能保存“诊断快照”,不能把它标记为可恢复的安全检查点。真正的安全检查点,至少应该关联一次明确的 Git commit,并通过预先设定的验收门禁。

第二重保险:预算熔断不能只看总金额

很多人谈成本控制,只设置一个总费用上限。这还不够。

长任务可能没有触及金额上限,却已经运行过久;也可能调用单价不高,但进入了数百次无效工具循环。因此预算控制至少应覆盖:

  • 最大运行时间;
  • 最大模型调用次数;
  • 最大 Token 用量;
  • 最大费用;
  • 最大连续失败次数;
  • 单轮最大工具调用次数;
  • 最大修改文件数量。

以下配置可以作为起点:

task:

max_runtime_minutes: 360

max_changed_files: 30

budget:

max_cost_usd: 20

max_model_calls: 300

max_consecutive_failures: 3

checkpoint:

interval_minutes: 30

after_each_subtask: true

require_tests_passed: true

rollback:

enabled: true

rollback_on_test_failure: true

rollback_after_consecutive_failures: 3

permissions:

allow_write_repository: true

allow_database_access: false

allow_secret_access: false

require_approval_for_dependency_install: true

这些数值只是演示,不是通用答案。具体阈值要根据模型价格、仓库规模、测试耗时和任务风险调整。

预算熔断也不应该直接粗暴终止进程。更合理的顺序是:

1. 停止新的代码修改;

2. 保存当前诊断信息;

3. 输出已完成与未完成事项;

4. 汇总费用、调用量和失败原因;

5. 等待人工决定继续、调整目标或结束任务。

Agent 达到预算上限后,不能为了“完成任务”自行突破限制。否则所谓上限,只是一条没有执行力的提醒。

第三重保险:失败后自动回到安全状态

预算熔断解决“还要不要继续”,自动回滚解决“已经改坏的部分怎么办”。

常见的回滚触发条件包括:

  • 连续多次测试失败;
  • 构建状态从通过变为失败;
  • 修改文件数量超出任务边界;
  • 关键目录被意外修改;
  • 未经批准新增大量依赖;
  • 出现高风险 Shell 命令;
  • Agent 无法解释当前改动与任务目标的关系。

核心逻辑并不复杂:

if budget.exceeded():

agent.stop()

agent.write_handoff_report(reason="budget_limit")

elif consecutive_test_failures >= 3:

git.reset_to(last_verified_checkpoint)

agent.replan_from(last_verified_checkpoint)

elif changed_files > MAX_CHANGED_FILES:

agent.pause()

request_human_approval()

这里有一个非常重要的安全边界:

Git 回滚只能处理版本控制覆盖的文件,不能天然撤销数据库写入、外部 API 调用、消息发送和已经发布的线上变更。

因此,以下操作不应该交给 Agent 自主执行:

  • 生产数据库迁移;
  • 真实用户数据写入;
  • 线上发布与流量切换;
  • 密钥读取和权限修改;
  • 不可逆的外部 API 操作。

这类动作应该默认禁止,或者必须经过人工审批。能 Git reset,不等于能恢复整个业务世界。

一次 6 小时实验,应该怎样记录

没有完整日志,就不应该编造“调用了多少次、花了多少钱、成功率是多少”。

一份合格的 6 小时实验报告,至少应从 Agent、模型网关、测试工具和 Git 中导出以下数据:

| 指标 | 数据来源 | 记录要求 | | 总运行时间、实际活跃时间 | 任务执行器 | 区分等待与真实执行 | | 模型调用次数 | API 调用日志 | 按阶段和模型拆分 | | 输入、输出、缓存 Token | API 返回记录 | 不只记录总量 | | 总费用与阶段费用 | 计费日志 | 与任务进度对齐 | | 子任务完成、失败数量 | 任务状态文件 | 明确验收标准 | | 检查点数量与间隔 | 检查点目录 | 区分安全点和诊断快照 | | 测试次数与通过情况 | CI 或测试日志 | 记录完整命令 | | 连续失败次数 | 执行器 | 用于触发熔断 | | 自动回滚次数 | Git 与执行日志 | 保存触发原因 | | 人工介入次数 | 审批记录 | 标明介入节点 | | 文件增删改数量 | Git diff | 按目录统计 | | 可合并、需修改、放弃的改动 | 最终验收 | 由人工确认 |

时间线同样不能靠回忆补写。可以提前设计如下记录节点,但最终时间必须以日志为准:

  • 0:00:读取仓库并生成计划;
  • 0:30:检查是否形成首个安全检查点;
  • 1:40:若测试失败,记录是否重新规划;
  • 2:30:检查改动范围是否扩大;
  • 3:20:检查连续失败是否触发回滚;
  • 4:00:确认是否从安全检查点恢复;
  • 5:30:进入最终验收;
  • 6:00:强制停止并生成交付报告。

时间、费用和进度必须放在一张图里

只看最终账单,很难识别 Agent 何时进入低效循环。

建议每次调用后写入一行 CSV:

timestamp,cumulative_cost,completed_subtasks,test_status,changed_files

再根据真实日志绘制“时间—累计费用—任务进度”曲线。如果费用持续上升,而已完成子任务长时间不变,就说明 Agent 可能正在无效探索。

这张图通常比“最终生成了多少行代码”更有价值。代码行数增加,可能只是改动变多;只有通过验收的子任务增加,才代表真实进展。

建议同时保留这些截图:

1. 执行前的任务说明;

2. 检查点状态文件;

3. 预算消耗与阈值预警;

4. 连续测试失败与回滚日志;

5. Git commit 或 worktree 变化;

6. 最终交付报告。

截图发布前,必须遮盖 API Key、仓库地址、用户名、内部域名和业务数据。

四个组件如何配合

flowchart LR

A[任务执行器] --> B[修改代码]

B --> C[测试与静态检查]

C -->|通过| D[创建 Git 检查点]

D --> A

C -->|失败| E[累计失败次数]

E -->|未达阈值| A

E -->|达到阈值| F[回滚到最近安全检查点]

F --> G[重新规划或等待人工确认]

H[预算控制器] --> A

H -->|达到阈值| I[停止修改并生成交接报告]

加入保护机制前后,区别非常明显:

| 维度 | 无保护机制 | 加入保护机制后 | | 任务状态 | 只能翻日志猜进度 | 每个检查点都有结构化状态 | | 成本 | 事后才知道花了多少 | 达到阈值自动暂停 | | 错误处理 | Agent 自由重试 | 连续失败触发回滚 | | 代码安全 | 改动持续叠加 | 只保留验证通过的状态 | | 人工接管 | 接管成本高 | 可从最近检查点继续 | | 适用场景 | 短任务、低风险 | 中长任务、受控环境 |

哪些任务可以交给 Agent,哪些仍然不行

现阶段更适合长时间运行的任务,通常具有三个特点:边界清楚、结果可测试、失败可撤销。

例如:

  • 补充单元测试;
  • 修复明确的类型错误;
  • 批量迁移可验证的 API 用法;
  • 更新与代码对应的文档;
  • 在独立分支中进行局部重构;
  • 执行只读代码分析。

不适合无人值守的任务包括:

  • 需求边界模糊的大规模架构重写;
  • 生产环境数据库操作;
  • 涉及真实资金或用户权益的流程;
  • 需要读取密钥和高权限账户的任务;
  • 缺少测试、无法自动验收的旧系统改造。

新手也不应该第一次就直接运行 6 小时。更稳妥的开放顺序是:

1. 30 分钟,只读分析

2. 允许补充测试,但不修改业务代码;

3. 开放少量文件写入;

4. 允许执行白名单命令;

5. 在独立分支或 worktree 中运行;

6. 最后再尝试数小时后台任务。

正式启动前,可以复制这份清单:

  • [ ] Agent 使用独立分支、worktree 或隔离环境;
  • [ ] 明确允许和禁止修改的目录;
  • [ ] 子任务均有可执行的验收条件;
  • [ ] 检查点关联 Git commit;
  • [ ] 设置时间、费用、调用量和失败次数上限;
  • [ ] 依赖安装与高风险命令需要审批;
  • [ ] 数据库、密钥和生产环境默认不可访问;
  • [ ] 连续失败能够自动回滚;
  • [ ] 熔断后自动生成交接报告;
  • [ ] 异常停止时能够通知人工。

我后来敢把长任务交给 Agent,不是因为它突然不犯错了,而是因为它犯错之后,不再能无限花钱、无限改代码,也不会把整个任务拖进无法恢复的状态。

如果你准备测试数小时的编程 Agent,建议先把模型调用统一接入便于管理的 API 入口,并在自己的任务执行器中保存调用日志、设置费用阈值和熔断规则。可以前往 api.884819.xyz 查看 API 接入方式,再结合本文的检查点、预算和回滚模板搭建实验环境。

8848AI 使用用户名和密码即可注册,不需要邮箱验证;平台内置 AI 对话,注册后可以直接使用。国产模型如 Deepseek、千问等完全免费,没有月租和订阅,其他调用按量付费。需要注意,具体模型、价格与页面能力应以网站实际展示为准,本文中的预算熔断仍需由你的 Agent 执行器负责。

新用户注册即送体验token。

加上检查点、预算和回滚,只解决了“一个 Agent 失控怎么办”。但当任务被拆给多个 Agent——一个写代码、一个跑测试、一个负责审查——新的问题会随之出现:它们会不会互相覆盖代码、重复消耗预算,甚至一致通过一个错误方案?

下一篇,我们将继续拆解多 Agent 协作中的任务队列、权限隔离与独立验收门禁。

本文由8848AI原创,转载请注明出处。关注8848AI,带你从零开始学AI。

#编程Agent #AI编程 #Agent教程 #成本控制 #自动回滚 #人工智能 #8848AI