编程 Agent 跑 6 小时不可怕,可怕的是你没有这三道保险
编程 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