AI 编程工作流的瓶颈,已经从写代码变成管理上下文

优先级、精确指令、任务认领、隔离工作区、长期记忆与人工判断,决定 Agent 能否从一次性助手变成稳定的工程系统。

作者:From chaos to context: Building an AI dev workflow09-01 · 16 分钟⚑ 研究论文
🎧 听播客版0:00 / --:--
0:00 / --:--
深度 · 小互解读
一分钟速览
  • 一项任务先经过优先级选择,再装载实体历史与规则,完成 claim 和环境隔离后才交给 Agent 执行。
  • directive 管行为边界,procedure 管重复流程,工具管确定性数据操作;三者放错层都会制造新的上下文浪费。
  • 混合检索、主动注入和 boot gate 分别处理精确召回、自动到场与强制启动动作;旧记忆仍需来源、年龄和失效控制。
  • 人负责发现目标、架构和流程层错误,AI 在明确方向内快速修改与验证;团队治理属于从作者个人实践继续推导的扩展。

GitLab 博客作者 Gregory Havenga 参与过 “Explain this vulnerability” 和 “Resolve this vulnerability” 两项 AI 安全功能的早期版本。那时的 AI 更接近一个建议工具:人发出请求,模型给出一段解释或修改建议,人再把结果带回代码库。Agent 出现后,工作边界变了。它可以读取仓库、修改文件、运行测试,开始直接执行任务。

执行能力增强后,Havenga 遇到的麻烦反而更像传统软件系统故障。同一条提交信息规则在一次会话里要纠正三遍;三个并行会话可能认领同一个任务、修改同一批文件、作出互相矛盾的决定,甚至把另一个会话尚未完成的工作一起提交或删除。模型并没有少写代码,它只是缺少持续状态、资源所有权和跨会话记忆。

他随后把个人工作流逐步改造成一套上下文系统:系统先决定应该做什么,再为任务装载历史和规则;Agent 动手前认领工作并进入隔离环境;重复流程被固化成 procedure,稳定的数据搬运下沉到工具;人检查方向、架构和最终正确性;得到确认的决定、阻塞和流程再写回长期记忆。

这套系统解释了一个常见反差:模型能力在提高,日常使用却仍然充满重复解释和返工。限制吞吐量的已经不只是一轮生成质量,还包括上下文能否在正确时间抵达、多个执行者能否共享状态,以及人是否仍掌握系统级判断。

一项任务怎样穿过完整的上下文系统

Havenga 的工作入口已经从“打开编辑器,再想今天做什么”变成一条自动装配的优先级队列。新会话先读取仍在活动的其他会话、未解决阻塞、长期指令和近期决定,再从 GitLab 拉取待办、活跃 merge request 与正在跟踪的 epic。

队列顺序也被明确编码。最先出现的是长时间没有进展、可能掉出视野的陈旧事项;随后是别人请求的 review,因为拖延会继续阻塞同事;接着是等待他回复的问题、他自己被阻塞的 MR,最后才是其余工作。这一步把团队阻塞、任务老化和个人进度转成一个稳定的选择规则,已经超过普通待办展示的作用。

任务被选中后,系统才开始为它装配上下文。一项 MR 工作会经历下面的过程:

  1. 读取这个 MR、相关 issue 或 epic 的历史决定、未解决阻塞和上次留下的下一步。
  2. 检索与任务类型匹配的规则和 procedure,例如评论规范、数据库迁移流程或 review 要求。
  3. 检查该工作项是否已经被其他会话认领;未被认领时建立 claim,明确当前所有者。
  4. 为会话分配独立 git worktree 和测试数据库,让文件状态与运行时副作用彼此隔离。
  5. Agent 修改代码、运行测试并整理结果;人检查目标、架构、正确性和是否满足合并条件。
  6. 工作完成、暂停或出现新阻塞时,更新状态并释放资源,把新的决定、事实和 procedure 写回记忆。
01 选择排优先级陈旧事项、同事 review、待回复问题与阻塞 MR
02 装载带入上下文历史决定、阻塞原因、长期指令和对应流程
03 协调认领并隔离工作项 claim、独立 worktree 与测试数据库
04 执行编码并测试Agent 修改代码、运行测试并整理证据
05 控制点人审查方向与正确性架构、边界、质量与长期维护成本
06 回写保存决定与阻塞下一次会话从更新后的状态开始
审查后的决定回到下一轮上下文
Agent 的工作位于闭环中段;选择、隔离、审查和回写共同决定执行是否可复用。

这个顺序把“给模型更多上下文”变成了可以检查的状态转换。上下文并非在会话开始时全部塞进去;系统先选任务,再围绕选中的实体加载信息。Agent 也不能读完说明就直接工作,它必须先完成认领和隔离。审查则发生在经验写回之前,避免一次未经确认的输出变成以后所有会话都会继承的规则。

作者称自己现在可以利用 15 或 30 分钟的空档推进复杂任务:询问队列顶部是什么,让系统恢复相关背景,然后委派编码和测试。这个时间来自个人经验,不能当作普遍生产率指标。它揭示的变化很具体:过去短时间主要消耗在回忆“做到哪里、为什么这么做、谁还在等我”,现在这些重建工作由系统承担,人可以更快进入判断和委派。

这种工作方式依赖“主动委派”。人保留跨任务的最高层目标,决定当前工作是否仍服务于正确方向;Agent 接受边界清楚的任务,维持执行速度。系统让任务状态、历史和约束脱离人的短期记忆,同时保留人的方向控制。

指令如何从一次纠错变成长期控制

每个新会话都可能从近似空白的状态开始。没有持久指令时,团队约定、代码库习惯和个人偏好只能被反复解释。问题还不只是“模型忘了”,很多给人的提醒本身就无法执行。

“小心评论”“注意安全”“写得专业一点”没有清楚的触发条件,也没有失败后的动作。Agent 可以口头同意,却不知道该检查什么、检查不到时能否继续。原文给出的规则更加具体:代表某个用户发表评论前,必须确认该用户 ID 存在;不能确认就停止并询问。

触发条件:准备以某个用户身份发表评论
必须动作:验证用户 ID 确实存在
停止条件:无法确认时停止,不得猜测,转而询问

这类规则同时控制“做什么”和“什么时候不能继续”。ALWAYS、STOP 等大写词在作者的使用中似乎能提高遵循率,但原文没有提供对照测试。能够稳定迁移的做法是:把抽象偏好改写成任务触发器、必须动作、停止条件和可检查结果。

指令也不应在项目开始时凭想象写满。Havenga 的做法来自事故复盘:Agent 犯错后,先修正当前任务,再问它哪一条指令可能阻止同类错误复发;人和模型一起校正措辞,确认不会误伤其他场景,随后才保存。持久规则因此对应一次真实失败,并带着明确的适用范围。

他的 agents-config 曾经包含十多个专门配置文件,分别处理代码审查、MR 工作流、数据库操作、评论写作和状态更新。当前公开配置还能看到更细的触发方式:开始 review 前召回 review procedure,处理数据库迁移前召回数据库规范,接触 MR、issue 或 epic 前先加载实体历史。规则由任务类型触发,每个会话只加载当前需要的规范。

当规则继续增长,静态文件会出现两个问题。第一,启动成本不断升高,与当前任务无关的规范也占用上下文;第二,规则的新鲜度难以管理,旧流程可能覆盖新决定。作者后来把不少 procedure 和细节迁入可搜索记忆,启动上下文只保留少量必须执行的 gate。稳定、短小、所有任务都适用的约束留在启动层;与某类任务或实体相关的知识按需召回。

这形成了一条可维护的规则演化路径:失败产生纠正,纠正形成局部 directive,高频操作沉淀为 procedure,procedure 再由任务触发和记忆检索加载。规则不再只是提示词附件,而成为工作流的控制面。

多 Agent 并行,需要工作认领和环境隔离

同时打开三个终端、运行三个 Agent,只增加了三个执行者,并没有自动得到并行系统。原文列出的故障包括:会话修改同一文件;两个会话选择同一工作项;各自在隔离信息中作出矛盾决定;一个会话删除或提交另一个会话的工作;多个会话重复调查已经解决的问题。

这些故障分布在不同层,不能靠一个 worktree 全部解决:

冲突发生在哪里 对应机制 机制边界
文件与 Git 状态 独立 worktree 分离分支、目录和未提交修改 仍可能重复选择同一 MR
测试运行时 每个会话使用独立测试数据库 不记录任务所有权和历史决定
工作所有权 用 claim / release 认领 MR、issue 或 epic 不隔离文件和数据库
决定与阻塞 共享当前阶段、前置决定、阻塞和下一步 不代替排他认领与资源隔离

一次安全的并行任务需要按生命周期组合这些机制。会话先检查 claim,再读取实体历史;成功认领后才创建或进入对应 worktree,并把测试连接指向该会话自己的数据库;执行期间持续记录阶段和阻塞;结束时保存结果、释放 claim,并清理不再使用的工作区。异常退出还需要过期、接管或人工释放策略,否则保护机制本身会留下永久锁。

作者公开的测试基础设施把这种隔离具体化:不同会话拥有不同 worktree 和以会话命名的测试数据库,共享底层 Postgres 与 Redis 服务,但不共享测试写入。创建会话、运行测试、诊断配置和删除会话由脚本统一处理。这样做的价值不只在“能同时跑测试”,还在于环境可以被枚举、检查和回收。

作者最早使用文件式工作笔记来共享状态。文件能跨会话保存,却有三项明显限制:难以按不同措辞搜索,无法稳定关联到具体 MR 或函数,跨天后也不容易自动出现在需要它的任务里。并行系统需要能够围绕实体保存状态、检索历史并主动提醒的共享服务,继续扩充 notes 文件无法提供这些能力。

这条需求最终推动了 opencode-memory。它同时承担长期记忆和会话协调:多个 Agent 连接同一个后台服务,工作项 claim、实体历史和相关 procedure 因而可以被不同会话看到。文件隔离解决“不要改到一起”,共享记忆解决“不要在不知道彼此决定的情况下各做一遍”。

记忆怎样从被动搜索变成主动上下文

长期记忆的难点不在于把聊天记录保存下来,而在于下一次任务发生时,系统能否找回少量、相关、仍然有效的内容。全量加载会迅速占满上下文窗口;只靠人主动搜索,又会把“记得去查记忆”变成新的人工负担。

记忆里保存什么

作者的系统保存决定、阻塞、procedure、事实和会话结果,并把它们关联到 MR、issue、epic、函数和其他代码实体。一次工作结束后,系统需要留下的不只是“完成了”,还包括为什么选择这个方案、哪些条件尚未满足、下个会话从哪里继续、哪一种错误以后应触发停止。

在原文发布时,作者称图谱已经包含超过 76 万个代码实体、1.5 万条记忆和 2.7 万条关系。这是个人系统的发布时快照。公开仓库可以核对其功能和架构,无法独立复现当时的数据库规模。

精确实体和模糊经验怎样同时被找到

opencode-memory 采用混合检索。MR 编号、函数名、错误字符串等具有稳定形式的信息适合全文搜索;“上次为什么没有采用这个方案”之类措辞会变化的问题,需要语义相似度补充。关键词检索保证精确实体不被向量近似淹没,向量检索让不同表述仍有机会命中同一决定。

当前公开实现把文本和结构化状态放在带 FTS5 的 SQLite 中,向量索引放在 LanceDB;新记忆先立即持久化,embedding 由后台任务异步计算。这种分工缩短了写入路径,也允许尚未完成向量化的记忆先通过精确检索出现。公开实现还会显示记忆年龄,并关联 GitLab 实体,帮助会话判断一条结果是否可能已经过时。

从主动 recall 到调用前注入

第一版向量搜索已经让作者当天就开始使用,但它仍要求 Agent 明确调用 recall。只要会话没有意识到“这里可能有历史”,记忆库就等于不存在。作者后来增加了主动上下文注入:每次模型交互前,系统根据当前请求和实体自动检索候选记忆,再把相关结果放进上下文。

提到某个 MR 时,相关决定和阻塞自动出现;准备撰写评论时,评论规范自动到场;开始处理一类重复工作时,相应 procedure 被召回。主动注入把记忆从一个等待调用的工具变成了请求处理管线的一部分。

作者称在 30 天内部记录中,主动呈现相关上下文的有效率约为 91%;启用主动注入的会话平均需要 0 次显式 recall,未启用时平均为 17 次。原文没有给出样本量、有效性标注规则和其他控制变量,这组数字只能描述他的个人系统。它仍然说明了所测对象:主动注入减少的是会话发现和调用记忆工具的次数,不等于代码质量提高了 91%。

剩余失败促成了 boot gate。系统在启动上下文中保留一个极短的强制触发器,要求 Agent 在执行前暂停并加载关键 directive。主动检索寻找“可能相关”的内容,boot gate 保证“必须发生”的启动动作;两者分别处理相关性和强制执行。

主动注入也引入新的治理要求。旧决定可能已经失效,语义相似可能只是词汇接近,跨项目记忆还涉及权限边界。因此每条记忆需要来源、时间、实体作用域和失效状态,召回结果需要数量限制与相关性阈值。记忆系统的质量取决于能否拒绝错误上下文,不只取决于保存了多少内容。

慢变化启动指令
保存
少量高优先级规则、停止条件、权限边界
读取
会话启动时常驻
风险
规则过多会挤占任务上下文
快变化活跃工作状态
保存
认领者、当前阶段、阻塞、待回复与资源占用
读取
选中任务和执行前
风险
过期 claim 会把保护机制变成阻塞
长期积累可检索记忆与 SDLC 图谱
保存
历史决定、procedure、代码实体关系与跨项目依赖
读取
按实体、关键词和语义相关性检索
风险
旧决定和误召回必须带来源、时间与失效状态

Orbit 补充跨 SDLC 的分析图谱;实时任务所有权仍由工作状态负责。

上下文不是一个大文件。变化速度越快,越需要独立状态与明确失效机制。

本地记忆与 GitLab Orbit 负责的范围也不同。本地层保存会话级决定、阻塞、procedure 和低延迟代码召回;Orbit 把项目、用户、MR、流水线、工作项、安全发现和源代码组织为跨 SDLC 属性图,可以回答服务变更会影响什么、哪些 MR 修改过某个文件等跨对象问题。GitLab 当前把 Orbit 标记为 Beta,并说明它按上次索引周期提供分析快照,不用于实时事务。任务 claim 仍然必须由共享状态系统完成。

procedure、工具与“先查后建”各解决什么

指令、procedure 和工具常被混在一起,作者的工作流实际上把它们分成三个层次。指令规定行为边界,例如发布评论前必须验证用户身份;procedure 规定一项重复任务的完整步骤;工具承担稳定的数据读取、分页、字段选择和机械转换。

作者跟踪一个高优先级 epic 时,周报不再从空白提示词开始。procedure 先从 GitLab 获取当前状态,读取上周快照,计算一周内的变化,再生成包含进度指标的更新草稿。数据来源、比较基线和输出结构被固定下来,任何会话都能执行同一流程。人仍需判断异常变化是否需要解释,以及最终表述是否准确。

当流程中的数据采集方式足够稳定,作者继续把它下沉到 API、OpenCode GitLab 插件和本地 MCP 服务。他还为自己的 AI 开发需要向 GitLab 补过 group uploads API 和 MR 工作流相关 GraphQL mutation。模型直接调用返回结构化结果的工具,省去每次重新探索端点、处理分页和猜测字段关系,把上下文窗口留给比较、解释和决策。

三层之间可以用失败方式区分:

层 最适合保存什么 放错位置会怎样
directive 权限、停止条件、不可违反的工作规则 写得太多会让启动上下文臃肿并产生冲突
procedure 有稳定阶段、但仍含判断的重复流程 每次临时提示会遗漏步骤和比较口径
tool 可以确定执行和机械验证的数据操作 留给模型会反复消耗 token,并引入格式与分页错误

工具变便宜还产生了一个反作用:从想法到可运行原型可能只需一周,重复造轮子的成本也随之下降。作者搜索 AI 编程记忆系统时发现了大量相似方案,甚至已有同名的 PyPI 包使用另一种向量数据库。自己的系统在早期并没有比现有项目多提供多少能力,直到数月迭代并深度连接 GitLab 后,独立维护才逐渐有了清楚理由。

因此,开工前的第一步应是检查现有方案。一个项目已经覆盖大部分需求时,贡献缺失能力通常比再造一个近似副本更有效。Havenga 对 OpenCode GitLab 插件的改动选择了上游贡献,因为这些改动可以服务更多用户。AI 加快了实现速度,却没有取消依赖评估、维护成本和生态协作。

作者把这种持续投入称为优化工具本身。更好的 API 和 MCP 工具提升日常效率,释放出的时间又能继续修正工作流,形成复利循环。他在原文结尾提到,记忆系统不到一个月已有 143 次提交。这个数字不能证明质量,却能说明工具与流程仍在高速变化,任何静态“最佳配置”都会很快过时。

AI 能修代码,人要发现系统层错误

Agent 在 procedure 已经进入上下文时,可以稳定执行许多重复步骤;人给出清楚的改进方向后,它也能快速修改实现和补测试。困难出现在程序本身需要被怀疑的时候。

模型通常不会主动感到一条流程很别扭,也不容易意识到“这已经是本周第三次发生同类问题”。它可能完成了当前任务,却没有把多次局部失败识别为同一个系统缺陷。长期参与生产系统的人会从摩擦、重复和异常组合中发现模式,而这些信号很少完整写在一条任务描述里。

Havenga 曾看到 AI 为自己的工具加入并发 bug。局部代码能够工作,但同步操作阻塞了整个工具。Agent 没有意识到自己采用的并发模型存在架构问题,仍在沿着既定任务继续实现。人指出应改用合适的异步模式后,Agent 在几分钟内完成了修复。

这个案例把人机分工分成了两个不同层级:

  • Agent 擅长在给定目标和约束内执行修改、运行测试并快速迭代。
  • 人负责判断当前目标是否正确、架构是否合理、局部成功是否正在制造系统问题。
  • Agent 可以根据明确反馈改进自己的指令,但人仍要发现哪一种重复失败应该上升为新规则。
  • 合并前的人类审查不只检查测试是否通过,还要检查正确性、设计质量和长期稳定性。

作者用“代码正在成为商品”表达这种价值迁移。生成代码的边际成本下降后,工程价值更多集中在决定什么代码应该存在、识别方案何时根本不成立、提前发现低效模式,以及为原始执行能力提供方向。模型同时放大好决定和坏决定;执行越快,错误方向积累得也越快。

这也解释了为什么自动 review 不能完全替代人工保证。模型可以发现大量局部问题,仍可能接受一个从目标或架构上就不该存在的实现。人类控制点需要前移到任务选择和设计阶段,同时保留在最终合并之前。

工具会快速过时,判断与反馈回路留下来

作者几个月内多次改变自己的日常工作方式。他原本还在撰写 GitLab CREDIT 价值观如何适用于 AI 的指南,GitLab Act 2 随后直接用面向 Agent 时代的新原则替换了 CREDIT,尚未落地的指南已经过时。这个例子说明,围绕具体工具写死一套永久流程并不现实。

变化中相对稳定的是反馈回路:观察重复摩擦,把故障变成 directive 或 procedure;把确定的数据操作变成工具;用实际工作验证它们是否减少上下文重建和冲突;发现副作用后再修改控制面。作者的记忆系统建立在 MCP 上,因此可以服务 OpenCode、Claude CLI、Cursor 和其他支持该协议的 Agent。客户端会变化,持久状态、任务认领和可检索 procedure 仍然可以留在共享层。

一些 GitLab 同事已经开始采用这套工作流的变体,并反馈记忆插件改善了会话体验。这些反馈无法构成团队级生产率实验,但说明作者以外的人也能使用其中的机制。迁移到团队时,还需要把个人系统里的隐含前提显式化:谁可以写入共享记忆,哪些决定需要批准,claim 如何过期,敏感上下文如何隔离,旧 procedure 由谁复审,以及用什么指标判断返工和冲突是否真的减少。这些是从作者实践继续推导出的团队治理问题,不属于原文已经验证的结果。

问题也随之发生变化。早期问题是“怎样让 AI 完成某个动作”;上下文系统建立后,问题变成“怎样让它在执行前获得足够且正确的信息”。当优先级、历史、规则和工具都能自动到场,人自己又可能成为等待审查和决策的瓶颈。团队随后需要检查哪些判断可以更早形成标准,哪些决策必须继续由人承担责任。

Havenga 的工作流没有提供一个可以原样复制的最终模板。它提供的是一套从真实故障长出来的工程方法:用状态管理并行工作,用记忆保存跨会话决定,用 procedure 固化重复过程,用工具降低机械上下文成本,再让人持续观察系统本身哪里仍然不对。Agent 的能力会继续变化,这条从故障、约束、执行到反馈的回路仍然成立。

来源
From chaos to context: Building an AI dev workflowGregory Havenga·2026-08-19·查看主材料
本站说明
基于 GitLab 博客作者 Gregory Havenga 的个人工作流复盘;系统规模和 30 天效果数字均为作者自报,未做独立复现。
↑ 正文结束
✓ 本篇全文免费开放

会员可复制、下载全文 Markdown,还能让你的 AI 订阅和提问。

阅读原文 ↗
📮 新解读第一时间进邮箱

读完觉得有用?留个邮箱,每篇新解读发布就送达,随时退订。