复杂任务下AI Coding稳定输出:上下文管理、任务拆解与测试驱动实战
谁用 AI Coding 没翻过几次车呢我身边不少朋友一开始都以为把需求往 Copilot、ChatGPT 或者某个开源模型聊天窗口里一贴复杂功能就会自动写好。结果往往是让 AI 加个购物车它顺手把订单表删了让 AI 做用户登录它生成一套和现有项目完全不搭的代码更常见的是同一个问题问三次它给出三个不同方案。复杂任务下AI Coding 能不能稳定输出已经成了工具能不能真正提效的分水岭。这篇内容想聊聊我自己在真实项目里反复试出来的方法适合那些正在用 AI 写代码、但又经常被它“自由发挥”坑到的开发者。1. 复杂任务下AI Coding 真正难在哪1.1 “复杂”并不是代码量大很多人有个误解觉得任务越复杂就是需要 AI 生成的代码越多。其实恰恰相反AI Coding 在“写 500 行样板代码”时的稳定性往往高于“改一个隐藏依赖很深的 20 行函数”。真正让 AI 翻车的不是代码量而是三件事需求模糊、上下文缺失、验收标准不清楚。举个很常见的例子。你让 AI“做一个订单系统”这个概念太大了。订单系统里包含商品、购物车、订单状态、支付回调、库存扣减、用户权限每一个子模块之间都有依赖关系。AI 看不到你现有项目的表结构、路由风格、错误处理规范它只能按它训练数据里的“常识”去猜。猜一次可能对猜两次可能偏到了第三次可能就编出一套全新的架构。所以复杂任务下的第一个难点是AI 缺乏项目全局观。它像一个能力很强但记性很差的临时工你只给它看一小块图纸却让它把整栋楼砌出来。上下文窗口再大它也不可能主动知道你没告诉它的业务规则。1.2 我见过的三种典型翻车现场过去半年里我在给团队做 AI Coding 实践培训时见过大量重复出现的失败模式。总结下来主要有三种基本覆盖了绝大多数“复杂任务不稳定”的情况。第一种是“答非所问”。你以为在让它做 A 模块它却在代码里顺带改了 B 模块的接口结果 A 功能看起来能跑B 模块炸了。深层原因是任务边界没有描述清楚AI 不知道哪些文件能碰哪些不能碰。第二种是“自说自话”。AI 生成了一整套自洽的代码但它依赖的包、目录结构、变量命名和你现有项目完全不一样。这种代码单独看没有任何问题一合入就开始报错。深层原因是 AI 没有看到现有工程约束比如必须用 SQLAlchemy 还是用 Django ORM必须用项目里已有的工具函数而不是重新造轮子。第三种是“反复横跳”。同一个任务第一次生成方案 A你觉得不够好让它改它给了方案 B你再点一下“重新生成”它又给你方案 A 和 B 的混合体。最后修好一个 bug引入两个新 bug。深层原因是缺少稳定锚点也就是没有一份不变的验收标准跟着每一轮迭代。1.3 一个认知AI 本质是“记性很差的资深工程师”想稳定输出先得把 AI Coding 的定位搞清楚。它不是许愿机也不是一个能记住整个项目的“全能架构师”。它更像一个读过很多开源项目的资深工程师但因为某种原因只能记住你当前这一轮会话里给它看过的内容。这个认知特别重要。它解释了为什么“把需求写得越完整结果越稳定”。你给它的信息是它的全部工作记忆你给的验证方式是它避免自说自话的唯一抓手。所以后续所有方法本质上都是围绕两件事展开一是把 AI 的短期记忆补充到位二是把外部校验嵌入流程。理解了这两点再看下面的实操方法就不会觉得琐碎。2. 稳定输出的第一步把任务拆到“AI 能一次完成”的粒度2.1 拆任务拆到什么程度才算够我在实践里总结了一个标准一个任务里AI 只需要做一件可以被测试验证的小事。如果这个任务还要再拆成好几个小目标才能验证那就说明拆得还不够细。举个例子。“实现用户注册接口”听起来已经比较具体了但它仍然包含数据表、密码加密、参数校验、路由注册、错误处理、单元测试六件事。如果你把它一次性丢给 AI它很可能在某些环节上自由发挥比如密码加密方案和你项目里其他地方不一致。我更推荐拆成下面这样的小任务在现有 User 模型中新增email_verified_at字段并生成迁移文件实现register_user(email, password)函数内部完成邮箱格式校验和密码哈希为register_user编写三个单元测试覆盖成功、重复邮箱、非法邮箱在auth_router中新增/register端点返回统一格式的code message。每个任务都足够小小到 AI 不需要猜测其他模块的实现细节也小到一旦出错你能立刻定位并回滚。复杂任务不是不拆而是要拆到“AI 不需要做选择题”的程度。2.2 可执行的拆解模板输入、处理、输出、验收拆任务的时候我习惯用一张极简的四格表。别小看这个动作它能把很多隐性需求逼出来。维度说明示例任务目标一句话说清楚做什么新增更新用户邮箱的接口输入调用方会给什么user_id、new_email处理逻辑关键规则和限制校验邮箱格式、检查邮箱是否被占用、只更新自己的账号输出返回给调用方什么成功返回新邮箱失败返回具体错误码验收标准怎样算真正完成单元测试通过接口文档同步更新不破坏旧逻辑每次让 AI 动手之前先在聊天区里把这一张表写出来。哪怕只有两三行效果也比直接甩一句“帮我把邮箱更新的功能写了”强得多。因为 AI 在生成过程中会频繁回头参考这些约束等于你给了它一条稳定的轨道。2.3 一个可抄的实操示例这里我用一个真实项目里常见的“用户注册接口”来演示。项目技术栈是 Python FastAPI SQLAlchemy。我不会一上来就问它“怎么实现注册”而是按下面的顺序分步走。第一步先让 AI 确认数据模型。我给的 prompt 大概是项目使用 SQLAlchemy 2.0用户表在 app/models/user.py。请为 User 模型增加 email、hashed_password、created_at 三个字段字段类型和命名风格与项目里其他模型保持一致。先不要写业务逻辑只改模型文件和生成迁移脚本。等这一步稳定通过再做第二步在 app/services/auth_service.py 里实现 register_user(email, password)。要求 - email 统一转小写 - 用项目已有的密码哈希函数不要重新引入新的库 - 如果 email 已存在抛出项目自定义的 DuplicateEmailError - 函数返回创建成功的 User 对象。第三步再让 AI 补路由和错误处理。每一步之间我都会跑一遍测试或至少编译一次确认没有问题才进入下一步。这样看起来多花了点时间实际上远比“一次生成全项目然后修 bug 修到半夜”快得多。3. 不让 AI“自由发挥”Prompt 设计与上下文管理3.1 一套稳定的 Prompt 骨架很多人以为 prompt 越长越好其实不是。稳定输出的 prompt 要的不是字数多而是结构完整。我自己一直在用一套类似“项目交接单”的骨架每个字段都不冗长但缺一不可。# 角色 你是熟悉 Python/FastAPI/SQLAlchemy 的资深工程师。 # 任务 在现有项目里实现 update_user_email 函数。 # 背景 项目使用 FastAPI SQLAlchemy代码在 app/ 目录下。 User 模型已经存在字段id, email, hashed_password, created_at。 相关文件app/models/user.py、app/services/user_service.py。 # 约束 - 只修改 user_service.py不要动模型文件 - email 必须转小写并做格式校验 - 如果邮箱已被其他用户占用返回 USER_EMAIL_EXISTS 错误 - 错误处理必须复用项目里已有的 ApiError 类。 # 示例 输入user_id1, new_emailNEWExample.com 输出{code: 0, data: {email: newexample.com}} # 验收标准 - 新增 3 个单元测试 - 已有测试全部通过 - 不允许新增第三方依赖。这个骨架真正起作用的是“约束”和“验收标准”两块。角色和任务决定方向约束划清边界示例让 AI 模仿输出格式验收标准则告诉它“怎样才算做完”。最后我会补一句“请先给出你的实现思路确认方案后再写代码。”这一步能过滤掉大量跑偏答案。3.2 上下文不是越多越好三招控制注意力复杂项目里最忌讳把整个仓库往 AI 上下文里塞。尤其在使用支持多文件读取的 AI Coding 工具时看起来是方便了实际却可能让模型被无关代码干扰。我常用的做法是三个。第一只贴和当前任务直接相关的符号。让 AI 改一个函数就把这个函数的签名、依赖的工具函数、涉及的数据库表结构贴出来。函数内部具体实现太长的话只贴关键分支即可。第二用文件结构代替全量阅读。告诉 AI“用户相关逻辑在app/services/user_service.py路由在app/api/v1/users.py模型在app/models/user.py”它就知道该去哪找而不是猜一个不存在的位置。第三把不变的信息放到项目文档里。比如技术栈、目录规范、错误码格式、数据库连接方式这些信息每次重复粘贴既费 token 又容易不一致。更好的做法是维护一份AI_CONTEXT.md让 AI Coding 工具通过指定规则自动读取。这样每次会话开始它天然就带着这些项目语境。3.3 隐性知识要显性化AI 不知道你公司的业务规则除非你写下来。比如“同一个邮箱只能注册一次”“订单超过 30 分钟自动取消”“删除用户前要检查是否有未完成订单”这些规则看起来简单但 AI 不可能从代码里自动猜出来。我踩过一次很深的坑。让 AI 实现“删除商品”功能它只写了从数据库里删除记录的逻辑完全没有检查“该商品是否已被订单引用”。测试环境数据量小没暴露问题一上线就开始报外键冲突。后来我养成了一个习惯在 prompt 里专门写一条“业务规则”把这些隐性条件一条一条列出来。如果规则太多就先把需求文档喂给 AI再让它产出方案而不是直接写代码。4. 工程化兜底让不稳定变成可控迭代4.1 测试先行用用例把 AI 的答案“逼”到正确面对复杂任务我会先写测试再让 AI 实现代码。这里的测试不是形式主义而是给 AI 一个明确的“合格线”。没有测试的时候AI 生成一个“看起来差不多”的版本就算完成任务了有了测试它必须让代码真正跑通。举个例子我想让 AI 实现update_user_email函数就先把下面这个测试写好def test_update_user_email_success(db): user create_user(emailoldexample.com) result update_user_email(user.id, newexample.com) assert result is True assert db.get_user(user.id).email newexample.com def test_update_user_email_duplicate(db): create_user(emailnewexample.com) user create_user(emailoldexample.com) with pytest.raises(UserEmailExistsError): update_user_email(user.id, newexample.com)然后跟 AI 说“实现这个函数让下面的测试全部通过”。这时候 AI 的目标完全清晰它不会去纠结“要不要校验邮箱格式”之类的问题因为测试用例已经把边界写清楚了。实际效果比我口头描述十遍“要处理重复邮箱”都要好。4.2 小步提交把失败控制在可回滚范围内复杂任务最怕“一口气改完全部文件再统一验证”。一旦出错你根本分不清是哪个文件、哪段逻辑引起的。所以我一直强调每一次 AI 输出只要验证通过就立刻提交。提交粒度可以和任务粒度保持一致。具体操作上我会给每个子任务单独开一个分支或者至少保证当前分支是干净的。AI 开始改动之前先把原始状态提交一次相当于一个回滚锚点。AI 生成的代码只要能通过测试、通过 review就提交一个新的 commit。如果后面某一步崩了直接git revert到上一个稳定点而不是在乱麻里找 bug。还要提醒一句AI 生成的代码必须经过人肉 review。重点看三样东西——有没有导入不存在的包有没有硬编码的密钥和地址有没有绕过项目已有的日志和错误处理。测试通过只能说明逻辑正确不代表代码安全合规。4.3 一个完整迭代闭环我目前最顺手的流程是这样的规划 → 拆解 → 构建 prompt → 生成代码 → 跑测试 → 人工 review → 提交 → 进入下一个子任务。整个流程里我把自己定位成一个“工程师 产品经理”AI 是执行者。复杂任务先在我这里被拆成十几个小任务每个小任务都按同一个闭环跑。这样的好处是即使 AI 在某一步连续失败三次我也只损失了一个小任务的时间不会让整个项目陷入瘫痪。如果某个子任务连续三次都没通过测试我不会继续让它瞎试而是停下来做两件事要么把任务再拆小一级要么切到人工模式自己动手把这部分改完。比起跟 AI 较劲我更需要的是稳定推进哪怕这一小段用传统方式写更省事。4.4 卡住时的人工干预有一次AI 在一个并发锁的实现上反复出问题不是丢锁就是死锁。后来我换了思路不再让 AI 直接写最终代码而是先让它“解释这段逻辑的并发模型”。它用自然语言描述完之后我发现自己 prompt 里少了“请求级别 vs 事务级别”这个关键定义。补充约束之后第二次生成的代码就完全正确了。这给了我一个很重要的经验AI 在复杂任务上的不稳定很多时候不是模型不行而是我们给的目标不够精确。当它开始绕圈子先不要骂它回头看看自己给的上下文是不是缺了一块。如果真的缺了补齐之后它往往能很快回到正轨。5. 开源 AI Coding 工具与笔试场景的实战建议5.1 开源 AI Coding 工具怎么选现在这个领域发展很快开源 AI Coding 工具已经不只是“玩具级”了。我在真实项目里用过几类工具感受差别很大。如果你追求数据不出内网可以考虑本地部署开源模型如果图省事也可以选开源 IDE 插件只把代码索引和请求发送到云端 API。两条路线没有绝对好坏只看你的项目场景。场景建议方向注意事项本地离线和数据敏感本地模型 IDE 插件关注显存/内存模型参数越大越慢日常快速补全开源插件 云端 API注意调用费用和代码隐私自动化完成多文件任务支持代码库索引的 Agent 工具运行前必须开 git 分支做好回滚我个人建议不管用哪款工具都要想办法让它能读取项目里的关键文档和现有测试用例。工具本身不是重点重点是你喂给它的上下文质量。开源工具通常没有太多花哨功能但正因为这样你写 prompt 的认真程度反而会更严格结果也会更稳定。5.2 笔试/能力测评中的答题思路现在不少团队会把 AI Coding 作为技能测评的一部分形式是在线工程题给你一个已有仓库和几个需求要求用 AI 辅助完成。这类场景和日常开发不太一样它更考验你在时间压力下能不能稳定交付。我自己摸索出一套答题节奏。第一先审题再审 AI。拿到题目后第一件事不是打开聊天窗口而是把需求拆成验收条件。比如“完成用户登录”你要先确认它要求的接口路径、数据库字段、错误码格式和测试用例这些信息通常在题目描述或已有代码里。第二区分“核心功能”和“锦上添花”。时间有限先让 AI 把最核心的链路跑通。哪怕只返回最简单的数据也要保证它可运行、可测试。等核心闭环没问题了再让 AI 补参数校验、边界处理这些加分项。第三在代码里留下思路注释。能力测评的最终评分人大概率会看代码也会看你的答题思路。让 AI 生成代码后我会在关键函数上方补几句注释说明“这里为什么选择事务”“这里为什么先查后改”。这些注释不一定给 AI 看而是给评审看也方便自己后续 review。5.3 最后分享一个小技巧我自己用 AI Coding 写了一年多最大的体会是稳定性不是靠某个特别聪明的模型而是靠一套不依赖灵感的流程。把任务拆小、把上下文写清楚、用测试兜底、用小步提交控制风险这四件事做到位哪怕模型只是中等水平复杂任务也能稳定输出。另外如果遇到那种“大而全”的需求我建议你先让 AI 产出一份实施方案而不是直接产出代码。等方案把模块边界、接口定义、测试计划都列清楚了再开始动手。这样看起来多了一步其实是把所有不稳定因素提前暴露等真正写代码时反而会顺畅很多。