AI 编程工作流的瓶颈,已经从写代码变成管理上下文
优先级、精确指令、任务认领、隔离工作区、长期记忆与人工判断,决定 Agent 能否从一次性助手变成稳定的工程系统。
- 一项任务先经过优先级选择,再装载实体历史与规则,完成 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 工作会经历下面的过程:
- 读取这个 MR、相关 issue 或 epic 的历史决定、未解决阻塞和上次留下的下一步。
- 检索与任务类型匹配的规则和 procedure,例如评论规范、数据库迁移流程或 review 要求。
- 检查该工作项是否已经被其他会话认领;未被认领时建立 claim,明确当前所有者。
- 为会话分配独立 git worktree 和测试数据库,让文件状态与运行时副作用彼此隔离。
- Agent 修改代码、运行测试并整理结果;人检查目标、架构、正确性和是否满足合并条件。
- 工作完成、暂停或出现新阻塞时,更新状态并释放资源,把新的决定、事实和 procedure 写回记忆。
这个顺序把“给模型更多上下文”变成了可以检查的状态转换。上下文并非在会话开始时全部塞进去;系统先选任务,再围绕选中的实体加载信息。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 会把保护机制变成阻塞
- 保存
- 历史决定、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 workflow
Lessons from iterating on AI directives, building a memory system, and discovering what AI still can't replace in software development.
There's a particular kind of frustration that happens when prompting an AI assistant with the same correction multiple times in a single session. The marvels of modern large language models (LLMs) make it so you're working with the most enthusiastic apprentice you'll ever have. However, that apprentice also happens to be an amnesiac. “Yes, I really do want my commit messages formatted that way, we've had this conversation three times already.”
Or perhaps you've experienced the trouble of trying to orchestrate several parallel AI sessions, only to watch them independently start solving the same problems and deleting each other's work.
These frustrations led me down a path of iteration. I worked on early renditions of two GitLab AI features: Explain this vulnerability and Resolve this vulnerability features. They felt naive at the time, and I wanted more from them.
Agentic AI delivered that. Instead of one-shot suggestions I had to prompt for and paste back, an agent could read the codebase, make the change, and run the tests on its own. It was doing the work rather than just advising on it. From there, I moved through GitLab Duo Custom Agents, VS Code integrations, and eventually OpenCode, an open source agent that describes itself as helping you "write code in your terminal, IDE, or desktop."
Along the way, I've distilled what's been working for me. AI coding assistants are genuinely transformative, but they need your engineering instincts to guide them. They amplify both good decisions and bad ones, so direction matters. The tools will keep changing, but here's what's helped my day-to-day engineering so far.
An optimized AI workflow
Before diving into the principles, it's worth showing what an optimized AI workflow actually looks like in practice.
Priority comes to me. When I start a session, the AI loads my active sessions, unresolved blockers, standing directives, and recent decisions. It then fetches my GitLab todos, active MRs, and tracked epics, presenting them in my defined priority order: stale items first (things falling through the cracks), review requests from others (don't block teammates), questions needing my response, my own blocked MRs, and finally everything else. I no longer spend time figuring out what I should be doing; the context comes to me.
The focus paradigm has shifted. Software development typically required hours of intense, uninterrupted focus to get anything meaningful done. That's changed. In a 15- or 30-minute window, I can ask what's at the top of the queue, have the AI load context for that item (prior decisions, blockers, relevant procedures), and start delegating coding and testing. The AI brings me up to speed nearly instantly, rather than me needing to rebuild mental context from scratch.
Parallel work on multiple merge requests. I use git worktrees with isolated test databases to have AI sessions work on multiple merge requests simultaneously. Each worktree gets its own session, its own database, and a claiming system prevents sessions from stepping on one another. The AI runs tests, ensures the code works, and I review for correctness.
Recurring tasks are made into procedures. For a priority epic I track, the AI handles weekly status updates by fetching current state from GitLab, comparing to the previous week's state to compute deltas, and drafting the update with progress metrics. The procedure is documented in my directives so any session can execute it consistently.
Token efficiency matters. I've contributed improvements to GitLab's REST and GraphQL API and the OpenCode GitLab plugin to reduce context overhead, and built a local workflow Model Context Protocol (MCP) server that encodes common patterns. Instead of the AI reconstructing how to do something from scratch each time, it calls an optimized tool that handles the data gathering, leaving reasoning to the LLM. This makes responses faster and keeps token usage manageable.
Active delegation is the underlying pattern. I preserve top-level context and alignment while the AI executes specific tasks. Before working on any merge request, the AI claims it to prevent conflicts, loads its history from memory, and checks for relevant directives. I maintain oversight of direction; the AI maintains execution velocity.
Write surgical directives, not vague instructions
Every session starts fresh. Without intervention, you'll re-explain the same preferences, the same conventions, the same quirks of your codebase.
The solution is explicit, persistent directives. Agentic AI tools have begun standardizing on AGENTS.md configuration files that load as boot context. But the key insight isn't that you need directives; it's that they need to be specific.
A vague instruction like "be careful with comments" doesn't work. The AI will acknowledge it and then do whatever it was going to do anyway. What works is something specific:
"ALWAYS verify user IDs exist before posting comments under their name. STOP and ask if unsure."
The all-caps keywords aren't just for emphasis. They seem to make the AI respond more reliably to the instruction.
Pattern to apply: When the AI tool makes a mistake, don't just correct it. Ask it what directive would prevent this mistake next time. Have that dialogue, then ask it to note it for next time. Over time, you build a set of instructions tailored to your actual workflow, not hypothetical best practices.
My agents-config repository used to contain over a dozen specialized configuration files that emerged this way: code review guidelines, merge request workflows, database review procedures, and comment writing standards. Each one exists because I was doing it often enough that it made sense to proceduralize and get the AI to execute it consistently. The memory system I describe later in this article lightened this approach; those directives now live in searchable memory rather than static files. The repository now contains practical examples and a usage guide showing how I work day-to-day.
Parallel sessions need coordination primitives
Running multiple AI sessions simultaneously can be efficient, if you can manage it well. Three terminals, three assistants, three parallel streams of work. But without coordination, you'll probably encounter familiar problems:
- Sessions editing the same files without knowing the other exists
- Multiple sessions working on the same item (assuming you have a way to claim work, which you probably don't yet)
- Contradictory decisions made in isolation
- Sessions deleting each other's work, or blithely committing it with their own changes to unrelated MRs
- Duplicated effort because neither session knows what the other did
If you've done any concurrent programming, you'll recognize these as classic coordination problems. The solutions are similar, too: You need primitives for claiming work, tracking state, and sharing context.
My first solution was file-based working notes. They worked, but they weren't searchable, weren't linked to the work they described, and didn't persist well across days. I needed something that could surface relevant context automatically.
This led me to build opencode-memory, a persistent semantic memory system. The architecture reflects solutions to problems I kept solving by directive: hybrid search (keywords for exact terms, semantics for fuzzy recall), session coordination through claim/release, and boot context that surfaces critical directives automatically.
The system has grown considerably since its first iteration. It's now a full knowledge graph with over 760,000 indexed code entities, 15,000+ memories including conversation summaries, and 27,000 links between them. When GitLab announced Orbit, a knowledge graph that indexes your entire software development lifecycle (SDLC), it lined up almost exactly with the direction I'd been taking locally. Orbit answers cross-SDLC questions like "what breaks if I change this service?" by connecting code, merge requests, and pipelines. My memory module already indexed my codebase locally for fast recall, so rather than reinvent the wider view I wired Orbit in to enhance it. The local memory holds session-level context like decisions, blockers, and procedures, and Orbit adds GitLab's broader SDLC graph on top. One of the best outcomes is that when I mention a function in conversation, the AI recalls exactly where it lives without me having to look it up.
Prior decisions also surface automatically when starting work on a merge request. Blockers persist until explicitly resolved. Procedures defined once are available forever. Reminders automatically bring themselves to my attention where they matter. And the combined graph, my local memory plus Orbit's SDLC data, answers those questions far more efficiently and effectively than a plain text search ever did.
Check before you build
No idea is unique. Searching for memory systems for AI coding assistants reveals dozens of approaches. Somebody probably already built what you were thinking about in a coffee-fueled AI rampage three weeks before you imagined it. There's even a PyPI package called opencode-memory that does something very similar to what I built, just with a different vector database backend.
The barrier to building what you need has dropped so dramatically that many people independently arrive at similar solutions. You can go from idea to working prototype in a week.
I'd recommend checking whether something already exists before spinning up a new project. If it almost solves your problem, consider whether contributing might be better than creating another variant. This advice is as old as software development itself; AI just exacerbates it a hundredfold.
My memory system barely offered much over existing solutions at first. It's only after months of iteration and deep GitLab integration that I feel it's somewhat more justified. I did at least contribute improvements back to the OpenCode GitLab plugin rather than forking it, because that's where my changes could help the most people.
The question worth asking yourself: Did I bother to look if something already exists and solves this problem, or has AI made it so easy to code that I've ignored all forms of due diligence?
From active recall to passive context
The vectorized memory search was an immediate win. I transitioned to using it the same day I built it. Recalling useful details became trivial. The next challenge was getting the AI to know there was something worth remembering implicitly, without me prompting it every time.
I'd made progress: token-efficient memory of specific procedures, a growing corpus of innate recall memories. But it felt like I was just rebuilding AGENTS.md with fancy additions. I needed something smarter.
The solution was proactive context injection. Instead of the AI calling recall tools explicitly, the system now automatically searches for relevant memories before each interaction. When I mention a merge request number, relevant prior decisions appear in context without me asking. When I'm about to write a comment, the comment-writing guidelines surface automatically. Most of the time, at any rate. It's still a work in progress, but each day I hone it a little further.
This shift from active to passive recall made a real difference. Over 30 days, the system achieved around 91% effectiveness at surfacing relevant context automatically. Sessions with proactive injection needed zero explicit recall calls on average, compared to 17 without it. It's not perfect; there are still moments where I need to tell the AI to remember something or to improve. But it's an iterative process, and it's getting better.
The remaining misses were instructive. Many happened while I was iterating on how boot context loading worked. The fix was a boot gate: a minimal trigger in the startup context that tells the AI to pause and load directives before doing anything else. Even with proactive injection, sometimes the AI needs to be told to stop and think first.
What AI still can't do
AI can execute procedures reasonably consistently, if those procedures are in context. It can improve its own instructions, if prompted to think about it. It can coordinate across sessions, if given the primitives to do so.
But AI doesn't notice things implicitly. It doesn't feel that a procedure is awkward. It doesn't recognize that you've hit this same problem three times this week. It doesn't have the pattern recognition that comes from years of debugging production systems at 2 a.m. while wondering if perhaps carpentry might have been a better career choice. At least, not yet.
The sweet spot seems to be using AI to eliminate menial work, providing the right context at the right times, and watching for what it misses. You provide strategic oversight and pattern recognition. The AI provides tireless execution and enthusiasm for tasks we once found tedious and time-consuming. That's extremely empowering.
I've watched AI enthusiastically build features while introducing concurrency bugs into its own tooling, blocking itself with synchronous operations. It had no idea. In hindsight, this was an alignment problem. I could have planned with it earlier to ensure a good async pattern. I'd hoped it would build a better pattern from the start, but I was being optimistic. One redirect from me pointing out the architectural flaw, and it was fixed in minutes.
That's the pattern: human spots the problem, AI executes the fix rapidly. I could have done it myself, just not as quickly. AI can't detect meta-inefficiencies yet, though I'm sure someone's busy writing a dedicated agent for that.
Invest in your tools
Working this way means accepting constant change. My day-to-day work has shifted completely, and repeatedly, in the space of months. Compare that to how workflows changed slowly over years earlier in my career.
Don't try to settle into a "new normal." It will change. The tools that help today may be obsolete next week at the rate we're going.
Rather, iterate on your tooling itself. The workflow that helps you work faster becomes the subject of optimization. I've contributed new API endpoints to GitLab, including group uploads and GraphQL mutations for MR workflows, specifically because I needed them for AI-assisted development.
It's a meta-loop: better tools lead to more productivity, which creates more capacity to improve tools. There's an old adage: "Give me six hours to chop down a tree and I will spend the first four sharpening the axe." I spend a fair bit of time these days sharpening my axe. I've never had a better grindstone.
The takeaway
Code is a commodity now. We're no longer paid primarily to type it. We're paid to know what code should exist. To recognize when an approach is fundamentally flawed. To spot inefficiencies before they become problems. To provide the direction that turns raw capability into useful outcomes.
I'd been working on guidance for how GitLab's CREDIT values applied to AI use, and then GitLab Act 2 retired CREDIT entirely, replacing it with new operating principles built for the agentic era. A good example of how fast this space shifts: My own guidance was overtaken before it landed. But the core insight remains: Getting this balance right matters at an organizational level, not just a personal one. AI should augment human work, not substitute for it.
The tools will keep evolving. The specifics will change. But this fundamental insight won't: AI amplifies human judgment. It shouldn't replace it, though it tries if you let it, usually at the cost of code quality and stability. Vibe coding can take you far, but even with the most thorough AI reviews, there's an assurance of quality and careful consideration in design that I've not yet seen AI provide on its own.
Several colleagues at GitLab have started using variations of this workflow, and watching them experience the same "aha" moments has been validating. One recently messaged me: "Definitely noticed an improvement in my sessions since using the plugin," meaning the opencode-memory module. I won't pretend that didn't make my entire day. The questions shift from "how do I get AI to do X" to "how do I give AI the context it needs to do X well." That's the real unlock: not the tools themselves, but the realization that context is the bottleneck.
Fascinatingly, the better you get at this, the more you start to realize that you may be the bottleneck. But sometimes that's also an indication that your own processes could be improved even more. I don't feel like I've reached a maximum yet, not by far. Different tasks benefit from different approaches, even when AI-empowered, and there's still plenty of experimenting to do.
One final note on pace: The memory system has seen 143 commits in under a month. It's built on MCP, which means it works with any agent that speaks the protocol: not just OpenCode, but Claude CLI, Cursor, and others. By the time you read this, I've probably added features I haven't thought of yet. That's the nature of working in this space right now. The tools evolve faster than the documentation.
The tools mentioned in this article are open source: agents-config for AI directive configurations, and opencode-memory for persistent session memory.
