最近这半年,我明显感觉 AI Coding 的体验进入了一个分水岭。以前用 AI 写代码,顶多让它补个函数、写个单测,现在很多开发者已经习惯把一整个功能模块甚至一次跨文件重构都交给 AI 去做。但任务一大,问题就来了:对话刚开始时它理解得很清楚,越往后越容易胡说八道,甚至开始生成项目里根本不存在的接口和函数。很多人把锅甩给模型能力,其实根子在上下文管理——我们习惯把一大摊信息堆进一次对话,以为窗口越大模型越聪明,结果恰恰相反,上下文越杂,指令遵循质量下降得越快。这一年我在一个中等规模的跨平台系统上,把 AI Coding 的协作方式从单个 Agent 硬扛改成了 Subagents 分工协作,中间试过手动裁剪、摘要压缩、检索增强,也踩了不少坑。这篇文章把上下文管理的几种做法、Subagents 架构的设计细节、以及我真正跑通后的体感差异完整写出来,适合正被 AI 改代码改出幻觉的开发者,也适合想在团队里搭一套 AI 辅助研发流程的工程负责人。
1. AI Coding 的核心:为什么上下文管理成了头号问题
1.1 从“补全代码”到“多文件协作者”的能力跃迁
AI 编程助手刚出来的时候,核心能力是单文件补全。你在一个函数里写了一半,它帮你补剩下半截,这种场景上下文需求很低,模型只需要看到当前文件就够。到了这两年,AI 已经能在你给出的需求下跨文件创建类、改接口、调整多个模块,本质上已经从一个“补全器”变成了“协作者”。但能力跃迁的代价,就是它对上下文的要求急剧膨胀。
这件事可以类比一个刚入职的工程师。如果你只让他改一个函数,他不需要知道太多;但如果你让他去重构一个订单模块,他必须先知道项目结构、数据模型、接口约定、历史原因,而这些信息分布在很多文件里。模型的处境一模一样,你给它多少信息,它就只能基于多少信息做判断。问题在于,模型的工作记忆不是无限的,而是一个有限的上下文窗口。这个转折点,是很多人把 AI 从“玩具”当“工具”的真正分水岭。
1.2 上下文不是越大越好:窗口上限的真相与假象
现在的上下文窗口越做越大,几十万 token 已经不是新鲜事,听起来好像把所有代码都塞进去也没问题。但实际使用中,窗口大不等于用得好。模型对长上下文的注意力并不是均匀分布的,很多埋在中间位置的信息容易被忽略,这个现象我几乎每天都在项目里感受到。你明明在第一次对话时告诉过它某个模块的历史原因,写到后面它照样按自己的想法重新设计一套,因为它根本没“看见”中间那段信息。
另一个更现实的约束是成本和速度。prompt 里每个 token 都要参与计算,如果每次请求都把整个仓库塞进去,一次会话消耗的 token 量非常惊人,成本先不谈,响应速度也会慢到让人崩溃。所以我一直有个判断:所有靠“无限放大窗口”来解决问题的方案,方向上都值得怀疑。真正应该做的,是把模型窗口里有限的容量,尽量留给跟当前任务高相关的信息。这也是为什么我坚持认为,上下文管理不是可选的优化技巧,而是 AI Coding 能不能规模化的核心工程问题。
1.3 上下文失控的几种典型症状
如果你也遇到过下面这些情况,大概率是上下文策略出了问题:
- 重复造轮子:项目里已经有一个现成的工具函数,AI 完全不知道,又写了一个风格迥异的新版本。
- 改 A 坏 B:改了某个模块的接口,所有调用它的地方它都看不见,改动之间互相打架。
- 风格漂移:前 20 轮它严格遵守项目规范,后面开始自由发挥,代码风格和团队其他人差异很大。
- 幻觉引用:调用了一个项目里根本不存在的类、API 或配置项,生成出的代码复制到编辑器里全是红色波浪线。
- 需求遗忘:写到一半忘了最初的产品约束,自作主张加了一些没人要的逻辑。
这些症状不是模型变笨,而是它“眼前的世界”已经失真了。下面这套上下文管理策略,就是用来对治这些问题的。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 上下文管理的四种主流策略,手把手拆解
2.1 裁剪与滑动窗口:最朴素但必须会用
裁剪的核心思想很简单:把与本次任务无关的代码从上下文里拿掉。具体做法是把需求拆成小任务,每次对话只加载与当前小任务相关的文件列表。比如你要改登录页的样式,那就只引用页面组件和设计变量,不要顺手把整个后端模块也塞进去。项目大起来之后,这种“按需加载”的习惯比任何技巧都重要。
滑动窗口是裁剪的进阶版:随着任务推进,不断丢弃旧的、无关的上下文,只保留刚刚产生的变更摘要。我有个具体的实操习惯,在项目根目录放一个 NOTES.md,每次开工前花两分钟把目标、当前进度、下一步写进去。AI 因为对话太长开始混乱时,直接清空对话,让它先读 NOTES.md 再继续。这个方法跟很多团队的 onboarding 文档本质一样,只是服务对象从人变成了模型。
注意:裁剪最怕过早丢弃关键约束。我的经验值是,任务相关的“为什么”要长期保留,任务相关的“怎么做”可以随实现完成而丢弃。因为“怎么做”已经写进代码了,而“为什么”一旦丢了,模型很可能在下一次改动时把整个设计推翻。
2.2 摘要压缩:把历史浓缩成记忆
当对话超过一定轮次,指令遵循质量会明显下降。这时候不要硬撑,而是让模型输出一份结构化的变更摘要,然后清空对话,用摘要作为新对话的起点。这个操作本质上和人写周报一样:把一周的碎片工作浓缩成几条要点,让下次接手的人快速进入状态。
具体步骤我建议这样做:
- 让模型输出:本次完成的文件清单、接口变更、遗留问题、下一步计划。
- 人工浏览确认一遍,这一步不能省,模型写的摘要也可能遗漏关键约束。
- 保存到项目
docs/decision-log.md,按日期追加。 - 新对话首条指令固定为:先读这个文件,再开始工作。
我在实践中的体会是,摘要如果只记“做了什么”,模型下次大概率会在错误的上下文里重新发挥。一定要记录“为什么这么做”,比如“为了兼容旧版本客户端,这里保留 v1 接口”。这类决策约束一旦丢失,模型很容易按自己的喜好重构,然后埋下兼容性隐患。
2.3 检索增强:给 AI 装一个代码搜索
当代码库超过一定体量,再把相关文件手动拖进上下文就不现实了,这时候需要检索增强的思路:把代码库做成索引,处理任务时先根据任务描述检索最相关的文件片段,再注入上下文。这个思路和 RAG 本质上是一回事,只是对象从文档变成了代码。
我的建议是至少做三层索引:文件路径层、符号定义层、代码语义层。只做纯向量检索的话,经常检索到“长得像”但根本不是调用链上的文件,结果反而误导模型。混合使用路径匹配加符号索引加语义检索,效果会稳很多。另外,给每个模块补一个简短的 README 或者模块说明,让检索结果自带上下文标注,模型就知道这段代码属于哪个业务域。
实操要点:不要把所有检索结果都直接丢给模型,而是让编排层先做一次粗筛,过滤掉明显无关的片段;每个检索结果都要带上文件路径和所属模块,防止模型把无关代码当成既定事实来引用。
检索增强的上手成本最高,但它解决的是核心问题:让大代码库可以被 AI 真正“看懂”。如果你在做一个模块特别多的系统,这一步早晚躲不掉。
2.4 结构化上下文:给模型发一张项目地图
我给每个项目都维护一个项目说明文件,习惯叫 AGENTS.md,里面固定写这几块:项目概述、技术栈、目录结构、常用命令、编码约定、各模块职责。每次开始新会话时,让模型先读这个文件,相当于先看地图再进城。这比让模型在几百个文件里自己摸索要高效得多。
这个文件的格式不需要花哨,朴素一点反而更好用:
code复制# 项目指南(示例)
## 技术栈
- 前端:某框架 + 状态管理库
- 后端:某语言 + 某 Web 框架
## 目录结构
- server/:服务端代码
- client/:客户端代码
- shared/:两端共享的类型定义
## 常用命令
- 启动服务:npm run dev
- 跑测试:npm test
## 编码约定
- 所有组件必须从设计系统导入,禁止自造样式
- 接口变更必须同步更新契约文件
## 核心模块
- 认证模块:负责登录、注册、权限
- 订单模块:负责下单、支付、售后
关键点在于,这个文件要持续维护。项目结构变了,模块职责变了,必须同步更新。地图过期比没有地图更糟,因为模型会基于错误的地图做出一系列错误决策。
2.5 策略选型对比:不选单选,叠加使用
四种策略不是竞争关系,而是在不同层面解决不同问题。我做了一张简单对比表,方便你根据项目规模选型:
| 策略 | 适用场景 | 核心优点 | 主要缺点 | 上手难度 |
|---|---|---|---|---|
| 裁剪与滑动窗口 | 小任务、日常单文件改动 | 简单直接,零成本 | 信息容易过早丢失 | 低 |
| 摘要压缩 | 长对话、持续开发同一功能 | 保留主线,成本低 | 细节会被压缩掉 | 中 |
| 检索增强 | 大中型代码库、跨模块定位 | 精确定位相关代码 | 检索质量影响大 | 高 |
| 结构化上下文 | 所有项目通用 | 保证全局一致性 | 需要人工持续维护 | 中 |
实际项目里这四者应该叠加使用:结构化上下文打底,检索增强负责找代码,摘要压缩延续跨对话记忆,裁剪控制每次请求的体积。我自己的项目就是这么搭的。
3. Subagents 协作架构:从单 prompt 到多角色团队
3.1 为什么单个 Agent 撑不起大型任务
单个 Agent 在小任务上表现很强,但任务一旦涉及多模块、多阶段,单一 prompt 就会出现明显问题。首先是目标冲突:同一个 Agent 里既有“快速完成任务”的压力,又有“严格遵守规范”的约束,prompt 写得越长,指令之间越容易互相打架,模型最后只能选一个它觉得优先级最高的去执行。其次是上下文互相污染:让同一个 Agent 既写后端接口又写前端页面,它在写前端时就会带着后端的思路,很容易写出不匹配的代码。
Subagents 的核心思路,是把一个大任务拆成多个小任务,每个小任务分给一个专门的 Agent,每个 Agent 有自己的系统提示词、自己的上下文白名单,最后通过产出物协作。它的本质是把“上下文隔离”做到工程层面,每个 Agent 只负责自己那一小块,不承担全球视野,也就不容易精神分裂。在真实团队里我们不会让一个人同时兼任产品、后端、前端、测试,那为什么让一个 AI 同时干所有事?
3.2 三种常见协作模式:路由、流水线、编排器-执行器
Subagents 协作模式目前主要有三种:
- 路由模式:一个中央调度按任务类型分发给不同专家,专家返回结果后由中央调度汇总。适合类型明确、各任务之间耦合低的场景。
- 流水线模式:上一个阶段的输出直接作为下一个阶段的输入,比如设计到编码到测试,环环相扣。适合流程固定、前后依赖强的场景。
- 编排器-执行器模式:编排器维护全局任务清单和状态,动态派发任务、接收回传、校验结果、决定重试或回滚。这是实战中最稳的一种,因为每个环节都可观测,出问题了可以精准定位。
我举个例子说明编排器模式的工作方式。一个登录功能开发任务进入编排器后,编排器先生成任务票据:后端 Agent 输出接口契约,前端 Agent 根据契约生成页面和 mock,QA Agent 拿到两份产物做静态审查并生成缺陷清单,编排器检查清单后把缺陷发回对应的开发 Agent 修复,直到 QA 清单清空。整个过程像一条可追踪的生产线,而不是一锅炖。
3.3 任务切片与上下文隔离:每个 Agent 只关心一亩三分地
Subagents 架构里最关键的设计,是任务怎么切、上下文怎么隔离。我的经验是按三个维度切:
- 按模块边界切:前端、后端、数据层、运维脚本,各管各的目录。
- 按阶段切:设计、编码、审查、测试,每个阶段一个角色。
- 按文件集切:每个 Agent 的白名单只包含自己负责的文件,其他目录一律不给。
如果一个 Agent 在执行任务时频繁需要读另一个 Agent 的文件,说明切片边界设计错了。边界清晰之后,好处非常明显:一个 Agent 的幻觉不会传染到另一个;多个 Agent 可以并行执行互不等待;每个 Agent 的 prompt 都很短、很专,指令遵循质量显著提升。在单 Agent 语境里,我们总想把所有信息写进 prompt,在 Subagents 架构里恰恰相反,设计目标是把每个 Agent 的上下文做小、做专。
3.4 共享上下文与回传:协作里最难的一环
多个 Agent 之间不共享 token,它们之间只能靠产出物交流。所以产出质量直接决定协作质量。我总结了三个必须设计好的东西:
- 任务票据(Ticket):每个任务都要有明确的目标、范围、验收标准、依赖,相当于给 Agent 下的开工单。
- 契约文件(Contract):接口定义、数据结构、变更日志,都要落到文件里,成为多个 Agent 之间共同遵守的协议。
- 状态回传(Report):每个 Agent 干完活必须回传状态,包括已完成、未完成、风险、建议。
实际协作时,后端 Agent 把 API 契约写进契约文件,前端 Agent 不再直接问后端,而是读取契约文件生成客户端代码。两边都不需要了解对方内部实现,就像两个真实团队通过接口文档协作。如果契约文件缺失,Subagents 之间就会互相猜,然后就出现“我以为你已经实现了”的经典事故。所以我给契约文件加了 schema 校验,每次变更先校验格式,再继续往下走。
4. 实战改造:某跨平台系统的 Subagents 协作落地
4.1 项目背景与痛点
这个项目是一个虚构的某跨平台系统,同时包含移动端、网页端、管理后台,代码量不小,目录结构复杂。改造之前我一直用单个 Agent 对话处理需求,前 30 到 50 轮交互勉强可用,超过 100 轮基本就崩了。最典型的场景是:计划改一个底层接口,AI 改了服务端,但客户端所有调用处全部漏掉;或者自动生成的代码风格和团队其他人提交的风格差异巨大,审查起来非常痛苦。
痛点其实就两个:第一,上下文撑不住整个项目,模型永远处在“只看到局部,看不到全局”的状态;第二,即使强行把全局信息塞进一个对话,指令遵循质量也会快速衰减,改到后面都是返工。这种情况下,我决定引入 Subagents 协作架构。
4.2 架构设计:编排器加三个执行角色
改造后的结构是:一个编排器加三个执行角色。编排器负责拆任务、派单、验收、回滚,不写业务代码;后端 Agent 负责 API 设计、数据模型、服务端实现,白名单是 server 目录;前端 Agent 负责页面、状态管理、交互,白名单是 client 目录;QA Agent 负责静态检查、测试计划、契约校验,白名单是 test 目录加契约文件。
每个执行 Agent 的系统提示词都不同,比如后端 Agent 的提示词强调接口规范和数据模型一致性,前端 Agent 的提示词强调设计系统组件和交互逻辑。所有 Agent 的单次上下文窗口控制在两万 token 左右,从来不让任何一个 Agent 背负整个项目的上下文。这是与之前最大的区别。
4.3 任务票据与交接协议的设计细节
任务票据是这套架构的神经系统。我设计的每个票据都包含五个字段:目标(为什么做)、范围(涉及哪些文件)、验收标准(如何验证做完)、依赖(需要等待哪些产出物)、状态(待办、进行中、已完成、已拒绝)。
举个例子:任务是“让移动端支持暗黑模式”。票据这样写:目标是提升夜间使用体验;范围是前端样式变量和主题切换逻辑;验收标准是在设置页可切换主题、刷新后保持;依赖是需要设计侧先产出主题色板。编排器把票据分给前端 Agent,前端 Agent 完成后回传状态报告。整个过程需求不会散落在对话里,全部进了可追踪的票据。
交接协议上,我要求每个 Agent 完成时必须产出产物清单和注意事项,后一个 Agent 必须先读契约文件再动手。有一次因为前后端 Agent 对某个响应字段的命名理解不一致,接口联调出了不少问题,后来我在契约文件里加了字段级注释,问题基本消失。
4.4 踩坑记录与改造效果
这套架构不是一次跑通的,中途踩了不少坑,写几个印象最深的:
- 坑一:各 Agent 代码风格不统一。前端 Agent 和后端 Agent 各自按照自己的习惯写代码,合并后风格混搭。解决办法是在项目地图里写死规范,比如“所有组件必须从设计系统导入,禁止自造样式”,同时安排 QA Agent 做静态规则检查,不符合直接打回。
- 坑二:测试 Agent 和开发 Agent 互相踢皮球。测试 Agent 报了缺陷,开发 Agent 说不是我的问题,是旁边那个 Agent 的锅。后面定了一个仲裁规则:谁负责的代码模块出的问题,谁负责修复,不允许把缺陷清单原样转发给其他 Agent。
- 坑三:死循环。某个子任务反复自测不过,Agent 一直重试不退出,白白消耗成本。解决办法是每个任务最大重试三次,超过三次就回滚任务票据,改由人工介入。
改造前后的对比,我没有做严格的实验数据,但体感差异非常明显:上下文占用从单次会话经常接近百万 token 降到每次两三万 token,几个 Agent 可以并行干活,交付速度明显提升,缺陷率下降,最重要的是人工介入次数大幅减少。这套架构现在已经成了我处理大项目的默认方案。
5. 排查清单:上下文污染、幻觉与死循环
5.1 问题速查表
日常使用中遇到问题,我基本都会对照这张表快速定位:
| 症状 | 可能原因 | 处理对策 |
|---|---|---|
| 重复生成已有代码 | 上下文里缺少全局符号信息 | 在项目地图中补充模块清单与函数索引 |
| 改接口后全局报错 | 契约文件没有同步更新 | 变更时先检索所有调用点,再更新契约 |
| 行为前后不一致 | 规范只存在于口头,没进项目地图 | 把编码规范固化到 AGENTS.md |
| 子 Agent 传错数据格式 | 交接协议缺少 schema 校验 | 为契约文件加 JSON Schema 校验 |
| 卡死循环不退出 | 重试上限未知或指令冲突 | 设置最大重试次数,超限回退人工 |
这张表的价值在于把模糊的“AI 不靠谱”转化成可定位、可修复的工程问题。我碰到大多数问题时,第一反应都是先查上下文,而不是怪模型笨。
5.2 上下文污染的检测与修复三步法
上下文污染是 AI Coding 里最隐蔽的问题,因为它不像显式报错那么直接,而是让模型基于错误的事实做推理。我的修复方法分三步:
第一步,让模型先输出它认为的当前状态,包括项目结构、相关接口、已改文件;第二步,把它的描述和真实代码库做对比,找出所有事实偏差;第三步,清空对话,写一份“当前事实快照”文件,让模型重新加载。
这个方法是踩了很多次坑之后总结出来的。上下文污染不是删掉某句话就能解决的,因为模型已经对错误事实形成了路径依赖,你在原对话里怎么纠正它都容易反复。不如直接重置,给它一份干净且权威的事实来源。事实快照文件平时不用动,出问题时它就是唯一的救火工具。
5.3 防止信息过时的机制
防止信息过时,核心原则是:所有重要决策都进入文件,而不是留在对话里。对话是会丢的,文件不会。我用代码库当前的版本状态作为“唯一事实源”,任何修改都以实际提交为准。当 Agent 声称“我已经改了某个文件”时,我会要求它先执行一次差异对比,确认确实改了,再继续下一步。
另一个机制是给每个 Subagent 设置产物输出路径,路径对应任务票据编号。比如票据 TASK-42 的产物统一放在 artifacts/TASK-42/ 下,这样每次改动都可追踪,回滚时也有据可查。加上时间戳或者版本号,整个流程的可观测性就有保障了。
6. 聊聊未来:上下文管理会变成工程基础设施
6.1 从技巧到基础设施
我判断未来一两年的 AI IDE 和持续集成系统,会把上下文索引、摘要压缩、任务调度做成内置能力。开发者可能不再需要手动写 NOTES.md、手动裁剪 prompt,但这些策略背后的原理还是值得掌握的。因为工具只是把这些策略自动化了,底层逻辑没有变:给模型设计一个良好的工作环境。
我见过不少团队把 AI 当“超级员工”使唤,指望它自己搞定一切,结果项目越大越失控。真正跑得稳的团队,都是在做信息管理:哪些信息进上下文,哪些信息不进,由谁来提供权威事实。这个思维迟早会变成研发流程的一部分,就像版本控制一样成为默认配置。
6.2 团队协作结构的重构
传统研发流程是人写代码给机器跑,未来的流程更有可能是人编排 Agent 产出代码。项目经理的核心工作会从管理人变成管理任务票据,代码审查者的一部分职责会变成给契约文件把关。Subagents 协作模式和真实团队的协作模式正在互相靠近,两边分享同一套语言:职责边界、接口契约、验收标准、缺陷闭环。
这不是什么遥远的事。如果你现在已经在用任务票据加契约文件的方式管理 Agent,那你实际上已经在用未来的工作方式做开发了。
6.3 给个人开发者的三条实操建议
如果你准备开始实践,我给三条建议:第一,从今天开始,把每个项目的上下文策略当成一等工程问题来对待,至少先把 AGENTS.md 建起来;第二,不用一次性上全套 Subagents 架构,先在一个模块里做两个 Agent 的流水线,比如后端 Agent 输出契约、前端 Agent 消费契约,跑顺了再扩展;第三,不要迷信“窗口越大越好”,判断标准始终是:一次改动之后,返工的成本高不高。
我在这一系列改造里体会最深的,不是模型能力提升得多快,而是工程思维在 AI 时代变得更重要了。上下文管理本质上是在为模型设计一个良好的工作环境,Subagents 协作则是在为多个模型设计一套高效的组织结构。无论工具未来怎么演进,这个底层逻辑大概率不会变。如果你现在就开始用这套思路去对待 AI,那等到工具成熟的时候,你已经走在前面了。
