软件持续迭代的三层循环

14 阅读30分钟

AI 写代码已经很好,但在复杂项目上快速持续迭代,同时保证软件的质量和可维护性,仍然没有统一且成熟的解法(在 AI 出现之前,这也一直很难)。最近几个月很流行的说法是 Loop Engineering,网上也有文章分享 Loop 的概念定义、实现方式,大多比较抽象,实操成本较高。

近期在几个项目中有一些实践,目前感觉比较适合个人开发者或产品仍处于快速试错阶段的小团队。

Loop 这个概念被命名之前,大家已经有很多的探索尝试,共同的目标都是释放 Agent 的能力、解放人。也就是说,在人和 Agent 协作过程中,减少人介入的时间,延长 Agent 连续工作的时间。

最近大半年,从 ralph loop 开始,到不同层次、不同类型的 Loop,已经有很多讨论。本文不再重复叙述他们的内容,感兴趣可以看看文末材料链接。

定义

为了方便后续内容的展开,减少理解的歧义,先约定几个概念的定义。

任务:指的是软件工程中一个开发任务,可能是一个 feature 或者 bug,也可能是性能优化、文档优化任务等,有明确的目标和验收标准。

任务队列:一批任务正式启动前,会使用项目管理工具,汇总记录,按照优先级排序。

任务生命周期与准出条件 任务生命周期与准出条件

任务的生命周期:如上图所示,一个任务通常会从暂存(pending)进入启动(start),经过方案定义(spec)、开发(dev)和测试(test),完成代码审核(review)与 CI 检查并合并 PR 后进入完成(done)。每个节点都有准出条件,满足条件才能进入下一个节点,否则需要继续当前节点,或者回退到之前的节点。

Loop 的 3 个层

Loop 三层循环的嵌套关系 Loop 三层循环的嵌套关系

  • L1: 单个任务的 Agent Loop。是指一个 feature、bug 等任务,交给 Agent,Agent 进行 推理 -> 使用工具 -> 推理 -> 使用工具 -> … -> 推理 -> 完成 的循环,完成任务的整个生命周期,从启动到完成。
  • L2: 任务队列的 Task Loop。是指 Agent 不断从队列中取出任务,通过 L1 Agent Loop 完成开发,直到任务队列被清空。可以简单想象成,过去我们说的一个迭代(Iteration),规划的任务列表,L2 要做的是完成这个列表的所有任务开发。
  • L3: 软件持续演进的 Iteration Loop。是指通过用户调研、A/B 实验、体验监控等手段,发现软件的新需求或者优化项,持续规划新迭代,往任务队列添加新任务。

实现

下面分别介绍三层循环的实现思路:

L1 完成任务

让 Agent 能够独立完成任务,有 2 个关键点:基建代码和状态管理。

基建代码,有种说法叫 Code as Agent Harness,让代码仓库成为 Coding Agent Harness 工作机制的一部分,最近有一篇综述详细介绍了这部分概念和做法,文末附链接。

基建代码需要解决什么问题:

  1. 提供充分、清晰的上下文和规范,Agent 能够快速了解项目信息,才能设计出符合要求的方案,写出干净的代码。
  2. Agent 需要明确的验证手段,验证不通过可以自行修复,直到所有的验证通过。

解决的方法:

  1. 设计合理的 Repo 结构和技术架构

monorepo 对 Agent 有明显好处:一个任务常常同时涉及产品文档、前后端代码、接口定义、数据库变更和测试,放在同一个 repo 里,Agent 能一次检索到完整上下文,在一个工作区完成跨模块修改,并用同一个 PR 让接口、实现、测试和文档一起更新,统一的构建和测试命令也省去了多仓库之间切换的成本。但它的价值不在于把代码堆在一起,而在于让完整上下文和清晰的模块边界同时可见——如果模块职责、依赖方向和测试入口混乱,一个边界不清的 monorepo 反而比多个职责清楚的 repo 更难用。

技术架构仍然需要关注领域建模、业务/框架/基建分层,以及合理的模块与组件拆分。相比之下,具体使用哪种语言、框架和中间件没有过去那么关键,因为 AI 能显著降低常规实现的成本。

  1. 维护指导性 md 文件。目前主流的做法有:
文件名内容作用
README.md项目简介、快速开始、常用命令、主要能力和文档入口作为人和 Agent 进入项目时的第一张地图,帮助快速运行项目并找到更详细的资料
AGENTS.mdAgent 的项目级工作规则,包括环境准备、编码约束、验证命令、禁止事项和文档导航给不同 Coding Agent 提供稳定、可自动发现的操作说明,减少每次任务都要重复探索和提示
PRODUCT.md目标用户、核心问题、产品范围、主要能力、非目标和产品原则为需求取舍和优先级判断提供产品上下文,避免把技术上可做误认为产品上应该做
DESIGN.md产品或界面的设计原则、用户流程、交互规则、视觉规范和关键设计取舍让实现结果符合预期体验,避免 Agent 只根据局部代码猜测设计意图
ARCHITECTURE.md当前系统的模块划分、接口、依赖方向、数据流、存储方式和技术约束帮助 Agent 判断改动应该落在哪个模块,避免破坏边界或在多个入口重复实现同一规则
DOMAIN.md核心概念、一致语言、领域边界、重要生命周期和业务不变量统一代码、文档和任务中的业务语义,让不同 Agent 对同一概念和责任边界有一致理解
  1. 引入通用 Skill 帮助 Agent 用更专业的方式完成工作,例如:

    • 使用 mattpocock 做的 codebase-designdomain-modeling 等 skills 来帮助建立初始的结构。

    • 配置 superpowers skill,让模型开发前先进行充分的探索、brainstorm 和沟通,确定方案写好 spec。

    • 使用 TDD skill,开发之前先写好测试方案和测试用例。

  2. 将架构、代码规范和测试步骤固化为工具

    • 新模块的创建和各种 target 产物的构建,往往有特定规则和步骤,可以封装成脚本或 {project}-create-module{project}-build 等内部 Skill。

    • 环境准备和测试流程可以放在 .agents/skills/{project}-localtest Skill 中,说明如何启动服务、准备测试数据、访问本地环境,以及涉及不同模块时需要运行哪些测试。

    • CI 配置可以放在 .github/workflows/ci.yml 等文件中,执行 lint、不同平台的构建和测试。

    Tip:

    1. 实操过程中把 {project}-localtest 这个 Skill 做好,性价比最高。因为本地 Agent 在工作过程中,可以使用已经准备好的环境,还可以使用高级工具进行集成验证,包括 browser-use、computer-use 等。

    2. 如果同时使用 Claude code 和 Codex,可以做 symlink 实现 CLAUDE.md -> AGENTS.md 以及 .claude/skills -> .agents/skills,避免不同 Agent 的规范文件不同产生文件冗余。

      例如 ln -s AGENTS.md CLAUDE.md

    3. 项目内使用的 skills,放在 .agents/skills 下,在 SKILL.md 的 front matter 里配置内部属性,避免被当做外部 skills:

    metadata:
      internal: true
    

状态管理,主要是解决 LLM 上下文限制、输出随机性等问题:

  1. Agent 经过多轮工具调用,会有很多琐碎的上下文,甚至触发 compaction,需要时刻知道当前进行到什么节点,以及前置节点的信息,比如技术方案、已尝试方案、失败原因等,让 Agent 能够快速继续工作。
  2. 让关键节点有明确的准出条件,而不是靠模型自己说“我觉得完成了”。
  3. 架构设计和排查 bug 时,需要能够检索过去的记录,了解变更过程的细节。

解决方案是项目管理工具,由外部服务来持久化状态、文档和任务的操作记录,相当于给 Agent 外挂状态机。

本文实现了一个简单的项目管理工具 taskline,给模型提供 CLI 和 taskline-management skill,要求模型按照任务生命周期走,每个阶段需要做哪些事情,交付哪些东西,设置对应的准出条件:

阶段阶段要求与交付物准出条件
pending不可执行的暂存态,用于保存尚未准备好的想法、未来任务,以及等待信息、判断或外部条件而临时挂起的任务;任意阶段都可以退回该状态,且不会进入可执行队列阻塞解除、上下文补齐并确认可以继续执行后,未启动的任务进入 start,已经开始执行的任务回到适合继续工作的阶段
startAgent 通过 task next --claim 原子认领任务,确认身份与租约;同步 main,创建独立分支并确认工作区干净任务已由当前 Agent 成功认领,代码基线和工作分支准备完成;进入 spec。满足快速通道条件时可以直接进入 dev
spec基于 Proposal 进一步明确用户需求、范围、非目标、交互行为和验收标准;比较具体方案并完成架构复核;创建 Spec 文档,记录详细的产品设计、技术设计、IDL/API、实现计划和测试用例产品契约不存在阻塞性歧义,方案符合项目架构和模块边界,Spec 文档已经写入 taskline;进入 dev
dev按测试优先的方式实现;先补充失败测试,再完成代码并让相关测试通过;创建 Dev Notes,记录实现内容、遇到的问题,以及相对原方案的调整和原因功能实现完成,相关测试通过,代码已经具备完整本地验证条件,Dev Notes 已更新;进入 test
test复核测试覆盖,运行受影响范围内的完整单测、模块测试、E2E、浏览器或真实运行环境检查;完成自我 Code Review 并修复问题;创建 Test Report;提交、推送代码,创建并绑定真实 PR所有相关检查通过,失败项已经修复或明确需要退回 devTest Report 已记录,远端 PR 已创建并绑定任务。没有有效 PR 时,服务端拒绝进入 review
review等待 CI 和至少一次人工或 Bot Review;读取并处理所有评论,发现真实缺陷时退回 dev;满足条件后合并 PR,并创建 Review Report 记录评论、CI、合并结果及设计偏差skill 要求至少一次 Review 已发布,所有评论均已处理或说明理由;taskline 服务端确认 CI 成功或未配置、Review Thread 已处理且 PR 已合并后,才能进入 done
done任务已经完成并留下完整交付证据;同步本地 main,清理本地开发分支终态

taskline 任务管理看板 taskline 任务管理看板

状态不只能单向前进。测试、Review 或 CI 发现真实问题时,任务可以退回 dev,修复后重新进入 test。对于只修改单个文件、不影响外部行为、也不引入测试脚手架或新依赖的机械变更,可以跳过独立的 spec 阶段,但不能跳过测试、PR、Review、CI 和合并等交付证据。

其中,specdevtestreview 阶段的文档和工作要求目前主要由 taskline-management skill 约束;从 review 进入 done,taskline 服务端会强制校验任务的有效 PR、PR 已合并、Review Thread 已处理、CI 成功等条件。

taskline 已完成任务详情 taskline 已完成任务详情

一个已完成的任务会保留认领信息、阶段文档、PR 和依赖关系。这些结构化记录既是 Agent 恢复上下文的外部记忆,也是任务进入下一阶段和最终完成的交付证据。

关于 Code Review

Code Review 应重点检查架构边界、模块与接口之间的通信、对既有设计的修改,以及关键技术难点,确认实现是否与 Spec 和技术评审中的判断一致;如果不一致,需要说明原因并判断是否合理。AI 已经能稳定完成大量系统性的代码检查,可以在 GitHub 中配置 Codex、Claude 等 Code Review Bot,作为持续执行的基础审查。

对于复杂任务,人仍然需要参与 Review,重点判断产品目标、架构取舍和高风险变更,而不是重复检查所有代码细节。如果评审者对 repo 和本次变更缺少足够上下文,Review 质量未必高于 AI;人的不可替代价值在于提供更高层次的判断。

关于知识和记录

现在也有一种实践,是把每个需求的产品设计、技术方案和 ADR(架构决策记录) 放在项目 repo 里。这样做的好处是信息不再分散,需要的内容都可以在 repo 中找到。

但这也会增加模型检索的负担和出错概率。判断内容是否应该进入 repo,关键在于区分知识与记录:repo 应维护系统当前有效的知识,而不是保存所有过程记录。

知识应持续沉淀到 AGENTS.mdPRODUCT.mdARCHITECTURE.md 等反映当前状态的文档,以及注释和代码本身,以确保 Agent 能准确工作。

记录应该存在单独的系统中,有需要回溯的时候再检索,否则会持续膨胀,变得冗余和复杂。

L2 清空队列

L2 的目标,是让 Agent 持续完成任务队列中的任务。

这里需要区分两层的管理边界:L1 管理单个任务内部的阶段、交付物和准出条件;L2 管理任务之间的可执行性、依赖、优先级、所有权和租约。

实现这一层循环,需要解决几个问题:

  1. 全局状态能够恢复:任务数量增加、执行时间变长以后,不能依赖某个 Agent 的上下文记住什么已经完成、什么正在进行、什么曾经失败。Agent 重启或经历 compaction 后,仍然要能恢复项目当前状态。
  2. 知道下一步应该做什么:任务之间可能有依赖和优先级。前置任务没有完成时,下游任务不能启动;多个任务同时可执行时,需要确定先做哪一个。
  3. 避免多 Agent 冲突:多个 Agent 并行消费同一个队列时,不能重复领取同一任务,也要隔离各自的代码工作区,避免互相覆盖修改。
  4. 能够从异常中恢复:Agent 可能中断、崩溃或长时间没有进展。任务不能永久被占用,需要有过期、续期、释放和重新认领机制。

解决方式,是把项目管理状态外置成 Agent 可以直接读写的任务系统:

  1. 用结构化的任务状态、文档和操作记录保存全局上下文,让不同 Agent 可以恢复和接续工作。
  2. 显式记录任务依赖和优先级,只把当前满足条件的任务放入可执行队列。
  3. 通过原子认领确定任务所有权,并为并行 Agent 提供相互隔离的工作区。
  4. 为任务所有权设置租约,Agent 正常工作时续期,异常中断后允许其他 Agent 重新认领。
  5. 把 L1 的工作流程固化成 Skill,让 Agent 认领任务后按照统一生命周期完成,并将交付物和验证结果写回任务。
  6. 每完成一个任务就重新查询队列;队列中没有可执行任务时结束本轮,并报告队列已经清空还是仍有阻塞。

传统项目管理工具主要帮助人查看任务、更新状态和协调分工。面向 Agent 的任务系统还需要回答:现在什么任务可以执行、谁拥有这个任务、所有权什么时候失效、进入下一阶段需要什么证据,以及中断后由谁继续。它管理的不只是任务列表,还要提供可以被 Agent 可靠执行的并发和生命周期语义。

taskline 是这一思路的一种实现。它通过改造项目管理工具的机制,将任务状态、依赖、优先级、认领、租约、交付物和准出条件变成 Agent 可以操作的结构化契约。Agent 根据 Skill 的描述,使用 taskline CLI,查看可处理的任务,认领并持续更新任务状态,如果任务在中途长期没有更新,服务器会自动释放认领状态,让后续可被重新认领。通过这种方式,让任务分配、并行协作、异常恢复和停止条件都由外部系统可靠管理。

taskline 是我为个人日常开发实现的一种方案,机制相对简单和固定,不一定适合所有项目。读者可以复用这些原则,扩展现有项目管理工具,或者使用 AI 开发适合自己的实现。taskline 本身主要通过 Codex 和 taskline 迭代完成,也可以作为 L1 工程基建的一个参考案例,文末附 GitHub 链接。

taskline 任务依赖图 taskline 任务依赖图

通过 /goal、定时任务或其他持续执行机制触发 taskline-management skill 后,Agent 会不断领取下一个可执行任务,通过 L1 完成并记录结果,再继续领取,直到本轮没有可执行任务。

使用多个 Agent 并行工作时,Agent太多难以管理,目前尝试下来,3个工作空间,配置3个Agent并行,是比较合理的。还可以选其中一个作为主Agent,日常沟通产品和技术方向,更新任务 和 Proposal;另外两个 Agent 并行干活。

L3 持续迭代

L3 在 L1、L2 这些执行层面之上,解决软件下一步应该做什么,以及系统是否在朝正确方向演进的问题。L1 保证任务被正确完成,L2 保证任务队列被持续完成,L3 则要保证进入队列的是值得完成的任务。

要实现这一层循环,需要解决几个问题:

  1. 反馈来源分散:外部调研、用户反馈、产品和体验指标、PR/CI、线上告警、文档腐烂和架构债务分布在不同系统中,需要被持续收集。
  2. 反馈中存在噪声:一次用户投诉、一次指标波动或一条失败记录,不一定意味着需要创建任务。反馈需要聚合、去重、补充证据,并区分偶发问题和持续问题。
  3. 价值无法自动确定:Agent 可以整理信息、分析数据和提出方案,但问题是否值得解决、目标是什么、边界如何划分、不同价值之间如何取舍,仍然需要人的判断。
  4. 反馈不能直接交给开发:为了减少 L1、L2 中人的介入和返工,L3 形成的 Proposal 需要有明确的背景、目标、产品和技术方向、预期影响范围、具体用例和验收标准。
  5. 任务生产不能失控:不能每发现一个现象就创建一个新任务。需要判断是忽略、合并重复问题、更新已有任务,还是创建新任务,并设置合理的依赖和优先级。
  6. 发布以后需要验证结果:代码完成和任务关闭不代表真实问题已经解决。需要重新观察线上数据和用户反馈,判断目标是否实现,以及是否需要进入下一轮。

对应的解决方式,是建立一条从真实反馈到任务,再从发布结果回到真实反馈的路径:

  1. 明确需要观察的反馈来源,并通过定时任务、webhook、监控告警或人工调研持续触发检查。
  2. 让 Agent 收集和整理反馈,聚合相似问题、检索历史记录、补充数据,并生成可能的改进方向。
  3. 由人结合业务目标、用户理解和项目上下文,判断问题是否值得解决,确定目标、边界、产品和技术方向、依赖及优先级;Agent 可以继续帮助补充信息和比较可能的方向。
  4. 使用统一的 Proposal 把判断转化为 Agent 可以执行和验证的任务,再交给 L2 编排。
  5. 发布后对照任务目标和验收指标重新检查真实结果。达到目标则结束这次改进,没有达到则更新任务或产生后续任务。

L3 和 L1 都会涉及方案,但粒度不同。Proposal 回答为什么要做、要实现什么结果,以及产品和技术上沿什么方向推进;Spec 则在这个方向内回答具体怎么实现,包括详细产品设计、技术方案、接口定义、实现计划和测试方案。

在工程系统里,L3 可以从一次 daily observe 开始。它不是清理任务,而是观察反馈、形成判断,并决定是否需要创建或调整任务:

  • 回看最近合并的 PR:有没有重复修同一类 bug,是否需要新增测试或架构约束。
  • 回看 CI 失败:是否是 flaky test、环境问题、模块边界不清、还是某类变更缺少质量关卡。
  • 回看用户反馈和线上指标:哪些需求是假需求,哪些痛点应该提升优先级。
  • 回看文档和代码差异:文档是否已经落后,是否需要新建 docs task。
  • 使用 improve-codebase-architecture skill 分析当前的架构问题,提出优化项。

一次 daily observe 不一定要创建新任务。它可以不做处理、更新已有任务、调整依赖和优先级、创建待审核任务,或者把无法自动判断的问题交给人。

在当前实践中,Agent 先分析问题,找到可以优化的方向并生成 Proposal。它们在 taskline 中先以 pending 任务存在,由人审核并与 Agent 沟通调整;背景、目标、产品和技术方向、用例及验收标准足够清晰后,任务才进入 start,加入 L2 的可执行队列。没有想清楚或价值不足的 Proposal 继续留在 pending,或者直接删除。

每次 L3 检查会在反馈处理完、判断结果被记录后结束,但软件的持续迭代不会结束。新的用户行为、线上数据和工程变化会再次触发 L3。L3 不是再加一个更大的 Agent,而是让 Agent 辅助收集和转换信息,由人负责价值判断,再把真实世界的反馈变成任务生产和任务排序。

完整视图

下图把反馈、任务队列和 Agent 执行连接起来,展示三层循环在一次持续迭代中的完整运行过程。

完整的 Loop Engineering 三层循环 完整的 Loop Engineering 三层循环

下面用一个“报表导出经常超时”的示例,串起完整的三层循环。示例中的数据只用于说明机制:

  1. 发现问题(L3):用户持续反馈报表导出很慢,线上监控也显示导出接口的 P95 延迟达到 42 秒,并且存在超时失败。
  2. 形成判断(L3):人结合用户影响、调用量和实现成本,决定优先解决这个问题,将目标定义为“P95 降到 10 秒以内,成功率达到 99% 以上”,并把背景、目标、产品和技术方向写入 Proposal。Proposal 审核通过后,再拆分为“补充导出指标”“优化查询和文件生成”“补充性能回归测试”三个任务,设置优先级、依赖关系和验收标准。
  3. 调度任务(L2):Agent A 从可执行队列认领“补充导出指标”,在独立工作区中完成并合并。前置任务完成后,“优化查询和文件生成”自动变为可执行,Agent B 随后认领;其他 Agent 可以同时处理没有依赖冲突的任务。
  4. 完成任务(L1):每个 Agent 都按照 spec -> dev -> test -> review -> done 推进所认领的任务,记录 Spec、Dev Notes、Test Report 和 Review Report,并通过测试、CI、Review 和 PR 合并等准出条件。
  5. 清空队列(L2):Agent 完成当前任务后继续领取下一个可执行任务,直到这组任务全部完成;被依赖阻塞的任务会在前置任务完成后自动进入可执行队列。
  6. 验证结果(L3):新版本发布后,daily observe 再次检查导出延迟、成功率和用户反馈。如果指标达到目标,这次改进完成闭环;如果仍未解决真实问题,则更新现有任务或创建后续任务,重新进入 L2 和 L1。

实施清单

按 L1 → L2 → L3 逐层推进,不必一开始就搭全套;先把 L1 做扎实,再逐步扩展。

L1 · 项目基础(让 Agent 能独立完成一个任务)

☐设计清晰的 Repo 结构、领域边界、模块职责和依赖方向;采用 monorepo 时,同时提供按模块运行构建和测试的入口

☐维护 README.mdAGENTS.mdARCHITECTURE.mdPRODUCT.mdDESIGN.mdDOMAIN.md 六类指导性文档

☐配置 codebase-design、domain-modeling、TDD 等通用 Skill,并根据项目需要提供内部 Skill

☐将模块创建、构建、环境准备、测试数据生成和本地服务启动等步骤固化为脚本或项目 Skill

☐提供单元测试、集成测试、端到端测试和 CI,并通过项目 localtest Skill 告诉 Agent 如何完成验证

L2 · 任务系统与队列调度(让 Agent 持续清空任务队列)

☐用结构化的任务状态和附件,让 Agent 感知当前阶段和上下文

☐编排任务依赖和优先级,让多个 Agent 并行工作、减少冲突。

☐使用原子认领和租约管理任务所有权,租约过期后自动释放任务

☐为并行 Agent 提供相互隔离的独立工作区,避免修改互相覆盖

☐保留可检索的操作记录,便于排查问题和复盘

☐提供 CLI:认领、查看和维护任务状态,管理附件、依赖和记录

☐提供 Skill:让 Agent 理解统一生命周期,并用 CLI 驱动整个流程

☐定义停止条件:没有可执行任务时结束本轮,并报告队列已经清空还是仍有阻塞

L3 · 反馈机制(让进入队列的是值得完成的任务)

☐明确反馈来源,包括用户访谈、客服和 Issue、产品与体验指标、PR/CI、线上告警、文档漂移和架构债务

☐设置检查节奏和触发方式,例如 daily/weekly observe、webhook 或监控告警;允许一次检查没有产生新任务

☐定义筛选和判断规则,对反馈去重,补充证据,评估影响范围、紧急程度和实现成本,由人决定是否值得进入任务队列

☐统一 Proposal 输出,至少包含背景、目标、非目标、产品和技术方向、具体用例、验收指标、依赖关系和优先级

☐发布后重新检查指标和用户反馈,判断目标是否实现;没有实现时更新任务或创建后续任务,让结果重新进入下一轮

反思

这套思路尝试解决当前 LLM / Coding Agent 的几个问题:

  • 上下文窗口有限:用文档、任务状态、docs、links、PR、测试结果做外部记忆。
  • 模型容易漂移:用 spec、状态机、验收标准和准出条件约束循环。
  • 自我验证不可靠:用编译器、测试、CI、review、浏览器 smoke 这些确定性信号做检查。
  • 并行容易冲突:用独立工作区、claim、lease、依赖 DAG 隔离任务。
  • 交付物不可复用:把计划、ADR、测试说明、PR 记录沉淀成后续任务的上下文。

优势:

  • 不需要改变工作环境,本地 repo、CLI、GitHub、CI、现有 Agent 都能接入。
  • 任意 Agent 都可以执行,只要能跑 CLI、读写文件、跑测试。支持 /goal 或类似持续执行能力会更好,但不是前提。
  • 复杂度集中在项目已有文档、测试和一个小的状态机里,而不是堆很多神秘脚本。

缺点:

  • L1、L2 执行过程中,人很少介入,因此 L3 的 Proposal 必须把目标、产品和技术方向想清楚;如果方向存在偏差,spec 很差,Loop 只会更快地把错误方向放大。
  • 测试和质量关卡不完整时,Agent 可能“通过所有检查”但仍然做错事。

整体来看,这套方法目前更适合 L1/L2 高度自治、L3 由人把关 的个人开发者或小团队:执行层可以大胆交给 Agent,方向和价值判断需要人深度参与。

未来值得优化的方向:

  • 事件驱动:有新任务、新反馈主动通知空闲 Agent,而不是只靠定时任务轮询。
  • 异步的 Human in the loop:Agent 遇到需要人判断的问题时,例如讨论方案,需要人确认,或者代码需要人 Code Review,排查问题需要提供更多上下文时,自动 stash / 释放 claim / 挂起任务;用户回复后,任务重新变成可执行状态。
  • 一些非结构化节点,如 PRD、技术方案、测试报告的审核,使用 Agent 检查准出条件。

这几项也会使整个流程变得更加复杂,因此暂时处于 pending 状态。

讨论

前面讲的是怎么把三层循环搭起来、跑起来;这一节跳出具体实现,谈两点更长期的延伸思考:当 Agent 成为新的协作单元后,人的沟通协作会发生什么变化,以及在这种分工下,什么才是真正稀缺的能力。

沟通协作的方式

软件工程中很多沟通成本,本质上来自信息、状态和认知不一致。每个人只掌握部分上下文,同一份信息在人与人之间传递时又会产生损失和偏差,于是团队需要反复对齐和纠正。

新的协作单元不再是一项职能,而是一个能够独立闭环的结果。一个人或一个 Agent 可以围绕这个结果完成问题定义、产品设计、数据分析、开发测试、发布上线,以及收集和分析线上的数据与反馈。不再先问这个责任主体属于哪个职能,而是看它是否对结果负责,并能够根据反馈继续迭代。

Loop 能不能跑起来,取决于这个闭环是否具备自治所需的信息、权限、工具和反馈,以及边界是否足够清楚。

沟通真正不可替代的价值是碰撞。两个或多个拥有不同信息、专业视角和生活经验的人聚在一起,把原本不相邻的认识连接起来,提出任何一方单独无法提出的问题、解释和方案。此时,沟通不再只是搬运已有信息,而是在创造新的信息。

文档、接口和状态机负责对齐,人的沟通负责碰撞和创造。

信息是第一要素,判断是第一能力

以前的生产流程,下游节点需要的信息往往由上游提供。下游的工作,往往是将上游的高层抽象信息逐层展开为更具体的表达。

比如开发需要的信息主要来自产品,测试需要的信息主要来自产品和开发。开发将产品和技术方案映射到子系统、模块与函数,最终落到代码。测试则根据产品和技术方案中的系统变更、约束与条件分支,展开运行路径和测试用例。

这并不意味着下游不需要判断,但大量工作消耗在不同抽象层级之间的信息转换与展开上。因此,LLM 会越来越多地承担这部分工作。

当信息转换和执行的成本下降,软件工程的瓶颈也会向上游移动:问题是否值得解决、目标是否正确、边界应该如何划分、不同价值之间如何取舍。

工作的重心会更多地转向问题定义、关键判断和基础能力建设。

人人都是产品经理,人人都是架构师。

AI 很好,但 AI 只是手段;人,才是目的。

有了新的工具,软件工程的挑战并没有消失,对人的要求反而在急剧提高。我们依然需要学习抽象与组合、原则、模式、简洁架构、DDD 等方法,并持续探索新的方法。

创造的成本降低,不代表创造出对人有意义、受人喜爱的产品变得简单。我们依然需要用同理心和想象力,去理解人、理解人与人的连接、理解世界。

这些知识和思考,依然是我们理解所创造之物,并把它变得越来越有意义的必经过程。

在一边学习一边构建的过程中,慢就是快。

总结

Loop Engineering 的核心,是为软件工程建立可以持续运行的闭环:任务有明确的状态,执行过程能够获得反馈,结果可以被验证,失败时能够修正或回退,完成后又能从真实世界获得新的信息。

本文把这个闭环分成三个层次:L1 让 Agent 独立完成一个任务的完整生命周期;L2 让多个 Agent 持续消费任务队列,处理依赖、优先级和并行协作;L3 从用户反馈、线上数据和工程问题中发现新的工作,形成判断,再把任务送回队列。L1 完成任务,L2 清空队列,L3 持续产生值得完成的任务。

三层循环的建设成本并不相同。L1 承担了大部分基础工作,包括仓库结构、架构边界、项目文档、Skills、测试环境、任务状态和准出条件。L2 在这些能力之上增加调度,主要依赖外部工具实现。L3 则主要由人驱动。可以先把 L1 做好,再逐步扩展到 L2 和 L3,不需要一开始就构建完整系统。

良好的工程基建让持续迭代变得可靠,AI 让实现变得越来越便宜,而人的注意力则应该更多地留给理解问题、做出判断,以及创造真正对人有意义的产品。

材料链接

  1. 吴恩达,按照时间尺度划分 Loop 类型 Three Key Loops for Building Great Software
  2. Claude,按照实现机制划分 Loop 类型 Loop engineering: Getting started with loops
  3. 综述:Code as Agent Harness
  4. obra/superpowers:探索、brainstorm、TDD 等开发工作流 Skill
  5. mattpocock/skills:codebase-design、domain-modeling 等工程 Skill
  6. taskline:本文用到的任务系统实现