ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

AI编程工作流v2.0:从需求清洗到自动化自测的完整流水线

AI编程工作流v2.0:从需求清洗到自动化自测的完整流水线 两年前我刚开始把 AI 塞进日常开发时路子特别野哪里不会问哪里写完能跑就算赢。结果代码越补越脏上下文越聊越偏最后连我自己都看不下去。于是有了 v1.0把“随口提问”改成了“需求写清楚、边界列明白、代码分步出”但这套东西跑了一阵子又暴露了新的问题——提示词虽然规范可阶段之间没有接力AI 改完需求后经常把前面定的方案推翻。今年我把整套流程重构了一遍也就是这篇想聊的AI 编程完整工作流程 v2.0。它不再是一堆 prompt 的拼凑而是把需求清洗、方案契约、分步实现、自动化自测、文档沉淀串成一条流水线。如果你也在用 Cursor、Copilot、Trae 这类 AI 辅助工具却总觉得“生成一时爽维护火葬场”这篇应该能给你一套可以直接抄的框架。1. 为什么还要单独设计一套 AI 编程工作流1.1 从零散提问到流水线作业大部分人对 AI 编程的用法还停留在“编辑器里开个对话框把需求一句话甩过去”。比如“帮我写一个解析日志的 Python 脚本”AI 确实能给你一个能跑的版本但这里的隐患是需求不完整边界靠猜函数命名全看心情。换个人来看代码根本不知道当初为什么这么写。更麻烦的是零散提问没有状态继承。你今天让它写模块 A明天让它改模块 B它完全不记得昨天的约定。结果就是模块 A 用了parse_line()模块 B 里又出现一个parse_log_line()功能重叠、命名混乱、调用关系像一团毛线。这在单人项目里还能靠记忆力硬撑一旦代码量过万行或者团队协作就完全失控。所以我设计工作流的第一个出发点不是追求“AI 一次生成完美代码”而是“怎么让 AI 生成的代码具备人写的代码一样的可维护性”。v2.0 的核心思想是把 AI 当作一个思路清晰、但记忆力很差的实习生。你不可能指望实习生一句话就搞定所有事你得给他任务书给他反馈机制还要在关键节点验收成果。1.2 v2.0 与 v1.0 的核心差异v1.0 的时候我的流程大概是这样需求描述 → 让 AI 给方案 → 直接生成完整代码 → 报错就丢回给 AI 修。听起来好像也成体系但实际操作中会发现三个致命问题。第一AI 给的方案和它最终写的代码经常不一致。方案里说要三个模块代码里却揉成了一个函数方案里设计了错误处理代码里全是裸调用。这就是因为方案和代码生成之间没有强约束。第二需求变更是常态但 v1.0 没法处理变更。今天说日志解析用正则明天说性能不行要改成按行 splitAI 在每一轮都是全新任务根本不知道要保留哪些逻辑、替换哪些逻辑、影响哪些调用方。第三缺少“验收”环节。AI 说代码写完了你就以为真写完了。可它所谓的“写完”往往是编译器的网开一面和运行时的不测风云之间那个灰色地带。v2.0 针对这三个问题引入了三条硬规则方案必须落到“契约文件”代码生成必须基于契约文件不允许直接改代码。需求变更先改契约文件再让 AI 按增量说明去实施而不是推倒重来。每个功能模块必须带上最小自测用例AI 交付代码时同时交付测试没有测试的一律视为未完成。这三条规则看着简单其实是把我过去踩过的坑全部压扁了重新摆出来。后面我会一个个细说。2. AI 编程工作流 v2.0 的总体架构2.1 五个环节和一条纪律v2.0 把整个开发过程拆成五个环节顺序固定不允许跳步需求池清洗把所有诉求收集在一起去掉模糊表达拆成可执行、可验证的最小任务。方案契约订立针对每个任务输出技术方案方案里必须包含模块划分、数据结构、接口签名、错误处理策略。分步实现按模块逐个生成代码每生成一个模块就做一次本地编译或语法检查。自动化自测用 AI 生成的测试用例对代码做验证测试不过就不允许进入下一模块。文档与交接沉淀把关键决策、使用方式、已知问题写回项目内的文档方便后续 AI 和人都能读取。一条纪律是所有交互都以“文件状态”为准。AI 不是从头到尾在一个对话框里完成所有事而是每进入下一个环节都重新读取当前项目里最新的契约文件、最新的代码结构文件、最新的变更记录。这套做法本质上是在模拟真实团队里“口头约定全部落到文档”的管理方式。2.2 上下文管理别让 AI 只靠记忆干活AI 编程工具最容易被忽视的问题是上下文长度和记忆可靠性。你在这个会话里跟 AI 聊了两小时你以为它全都记得其实它在长对话后期对早期内容的引用准确率会明显下降。更现实的场景是你换了台机器开了新会话之前的约定全部归零。所以 v2.0 里专门有一条“上下文外置”的原则所有重要约定必须写到项目目录里的文件里比如docs/contract.md、docs/decisions.md。每次需要 AI 继续干活时先用读取指令把这些文件喂进去再提新需求。这样做有个额外好处人可以审、AI 可以读、后续加入项目的同事也能快速理解项目状态。相当于把 AI 的工作记忆和外置存储分开让 AI 专注于推理和执行让文件系统承担信息持久化。2.3 模块拆分的粒度最小可验证单元v2.0 里最费心思的是“粒度”。拆太粗一个模块几百行代码AI 生成的风格容易跑偏出错后排查范围太大拆太细一个文件十几个小函数上下文引用和调度成本反而高。我现在的标准是一个模块应该能独立编译、独立运行、独立验证。比如日志解析器拆成loader、parser、reporter三个模块就合适。parser再往下拆date_parser、level_parser就过度了。判断方法很简单如果这个模块的测试需要引入其他模块才能跑说明拆得不够如果删掉这个模块会导致另一个模块的功能不完整说明拆得太狠。每个模块的代码量我一般控制在 50 到 150 行之间。这个区间对 AI 的生成质量最友好上下文够了不会漏依赖代码短了人也容易 review。超过 200 行AI 生成内部逻辑时经常出现函数引用顺序混乱、重复定义之类的问题。3. 实操v2.0 跑通一个真实需求3.1 用一个内部脚本做完整演示理论说多了容易飘我用最近做的一个内部小工具来走一遍完整流程。需求是这样的团队在写技术博客时Markdown 文件里经常引用本地图片但图片被移动或删除后文档里留下的链接就变成死链。人工检查很烦所以想做一个小脚本扫描指定目录下所有.md文件找出引用了本地图片但文件不存在的链接。这个需求不算复杂但拿来演示 v2.0 特别合适因为它有明确的输入输出、有错误处理需求、有可验证标准。如果连这种小需求都跑不顺那大项目就更不用谈。3.2 第一步需求池清洗在让 AI 写代码之前先把这个需求写成一条一条的明确任务。我的做法是在项目目录下建立一个docs/requirements.md内容大概长这样# Markdown 图片链接检查器 ## 功能需求 - 输入参数待扫描目录 dir支持相对路径和绝对路径 - 输出结果列出所有包含本地图片引用的 md 文件以及对应缺失文件路径 - 支持链接形式![](./images/foo.png)、img srcimages/bar.jpg - 忽略远程链接以 http://、https:// 开头的图片链接跳过 ## 边界条件 - 目标目录不存在时退出码 1打印可读错误信息 - md 文件编码只考虑 UTF-8 - 图片路径包含空格时允许使用 %20 形式需要解码后判断这些信息不需要一次写全但至少要覆盖“输入是什么、输出是什么、哪些情况算正常、哪些情况算异常”。写需求池的过程本质上是在帮 AI 排除它最爱做的“自由发挥”。你越是把边界条件写清楚后面生成代码越不会跑偏。3.3 第二步方案契约订立拿到需求池之后再让 AI 做技术方案。我这里用的是 Claude 和 ChatGPT 类模型做方案设计再把方案整理进docs/contract.md。方案不需要很花哨但必须包含模块划分和接口签名让代码生成阶段有据可依。实际生成的契约文件长这样简化版# 技术契约 ## 模块划分 - walk_files.py: 遍历目录收集所有 .md 文件路径 - extract_links.py: 解析 md 内容提取本地图片引用 - check_missing.py: 判断引用文件是否存在输出缺失结果 - cli.py: 命令行入口汇总以上模块负责参数解析和错误处理 ## 接口定义 - walk_files.find_md_files(root: Path) - list[Path] - extract_links.extract_local_image_paths(md_path: Path, base_dir: Path) - list[Path] - extract_links.is_remote_url(src: str) - bool - check_missing.filter_missing(paths: list[Path]) - list[Path] - cli.main(argv: list[str]) - int ## 错误处理 - 目录不存在抛出 DirectoryNotFoundErrorcli 层捕获后返回 1 - 文件解码失败跳过该文件在 stderr 输出 warning不中断整体检查契约文件最大的价值是让 AI 在实现阶段没有“设计自由”。它只能按接口去写接口不对就是不合格。我在实际项目中见过太多 AI 自作主张改接口的行为契约文件就是用来斩断这种冲动的。3.4 第三步按契约分步实现实现阶段我不让 AI 一口气生成所有模块而是每打开一个模块对话先让它读docs/contract.md再单独实现当前模块。比如先实现walk_files.pyprompt 大概是请阅读 docs/contract.md只实现 walk_files.find_md_files 函数。要求 - 使用 pathlib.Path.rglob 方式递归查找 - 只返回后缀为 .md 的文件 - 函数类型注解必须与契约一致 - 不要写额外的函数或 import这里有一个很关键的动作限制 AI 只做一件事。不要让它在实现 walk 的时候顺带把 extract 的逻辑也写了不然模块边界立刻模糊。每完成一个函数我会让 AI 粘贴出来人工快速扫一眼有没有越界然后再进入下一个模块。这四个模块全部生成后工程结构大概是这样的. ├── cli.py ├── walk_files.py ├── extract_links.py ├── check_missing.py └── docs ├── requirements.md └── contract.md代码层面没有神奇之处但整棵文件的调用关系是清晰的每个函数都能单独读、单独改。对于一个 AI 辅助生产的项目来说结构清晰比代码惊艳重要一百倍。3.5 第四步自动化自测模块都实现完下一步是让 AI 写测试。注意这里不是“让 AI 跑一下看对不对”而是“让 AI 为每个模块给出一组最小测试用例”。测试文件我放在tests/目录下命名对应模块。拿extract_links.py来举例AI 生成的测试大概是from pathlib import Path from extract_links import extract_local_image_paths, is_remote_url def test_extract_local_image_paths_finds_missing_image(): md_path Path(tests/fixtures/sample.md) base_dir Path(tests/fixtures) result extract_local_image_paths(md_path, base_dir) assert any(p.name missing.png for p in result) def test_is_remote_url_returns_true_for_http(): assert is_remote_url(https://example.com/a.png) is True def test_is_remote_url_returns_false_for_local(): assert is_remote_url(./images/a.png) is False生成测试后我会运行pytest -q。第一次跑往往是失败的——不是因为代码错了而是因为边界条件没对齐。比如测试里创建了临时目录但代码用了相对路径解析目录基准不一致。这个时候把报错信息丢回给 AI让它修改代码或者修改测试哪个更合理需要人来判断。这一步是整个工作流里面最容易偷懒但最不能偷懒的。许多人的 AI 编程越到后面越乱就是因为缺少“验收”这道关卡。没有测试的代码AI 自己都不知道自己写错了什么更别提后续迭代了。3.6 第五步文档与交接沉淀测试跑通后工作流还没有结束。最后一步是把这次实现过程中的关键判断写进docs/decisions.md。比如为什么用Path.rglob而不是手动 os.walk写法更简洁且返回的是 Path 对象类型一致。为什么忽略远程链接内网博客不需要检查外链如果要支持后续按 http 前缀过滤即可。为什么图片路径需要做%20解码因为 Markdown 里的 URL 编码规则和本地文件系统规则不完全一致。文档不需要写成长篇小说三五行即可。但这三五行会在未来某一天救你一次。比如版本迭代到 v3.0你让 AI 重构这块逻辑时它重新读取docs/decisions.md就不会再犯一遍同样的错。4. 工具选型与搭配方式4.1 不是选一个而是组一套总有人问我“哪个 AI 编程工具最好”我的回答一直是看场景。真正用顺手的 AI 编程工作流往往是多个工具配合而不是依赖某一个全能选手。我自己目前的组合是环节工具说明方案设计Claude 或 ChatGPT善于结构化思考适合生成契约文件编辑器内补全GitHub Copilot日常写函数、补参数、写测试时效率最高多文件重构Cursor对跨文件改动、代码库规模较大的项目更好用长上下文续接Windsurf 或 Trae处理已经足够大的上下文时分段续写更稳定本地私密代码通义灵码或 CodeGeeX代码不方便出公司内网时可以靠私有化部署解决这套组合的思路是方案生成靠对话模型因为它不需要直接操作代码库具体实现靠编辑器内嵌工具因为它能拿到最近的代码上下文跨文件重构靠 Cursor因为它的索引机制在处理大型仓库时比单纯的对话模型靠谱得多。这里我特别想提醒一点不要迷信“一个工具吃遍天下”。我自己踩过最大的坑就是把所有代码工作全丢给一个对话模型去处理。它对单个文件的理解没问题但项目一复杂它不知道哪些文件被改过、哪些依赖快失效了。编辑器类工具之所以能补齐这个短板是因为它们背后有本地代码索引和文件变更感知这是纯对话模型不具备的。4.2 提示词模板库管理v2.0 里除了工具我还会维护一个prompts/目录把经常用的提示词模板沉淀下来。模板不是在 UI 里复制粘贴而是作为文件存在项目仓库里。比如prompts/implement_function.md长这样你是本仓库的资深开发。请基于 docs/contract.md 实现以下接口 {interface_signature} 要求 1. 不得修改契约中定义的函数签名和返回类型 2. 不允许新增额外模块 3. 必须处理契约 Error Handling 章节里列出的异常场景 4. 实现完成后附上 2-3 个最简测试用例这些模板最大的价值是把“可靠的 AI 使用方法”固化成团队资产。新人加入时不需要从头摸索哪些写法容易让 AI 产生幻觉直接把模板拿过去用就行。我自己维护了大概二十多个模板覆盖需求清洗、契约生成、单模块实现、测试生成、代码 review、重构扩散分析等常见场景。4.3 让 AI 理解现有代码库的方式很多人问为什么明明已经跟 AI 聊了很久它还是不理解项目里已有的代码这里的问题在于大多数对话模型并不知道你仓库里有什么。它们只能看到你在对话框里贴出来的内容。想让 AI 真正理解代码库要么用编辑器类工具的索引功能要么主动把关键文件喂给它。v2.0 的做法是在项目根目录维护一个docs/architecture.md用极简的方式描述每个目录的职责、核心模块的位置、关键数据流的方向。每次开始较大规模的修改前我会先把这张文档发给 AI。它花不了多少 token但能让 AI 在一开始就站在正确的位置上去理解问题而不是从文件名瞎猜。如果项目已经很大还可以考虑用代码检索类插件做 RAG 式问答。这类工具会把代码库切片后做向量化索引AI 回答时可以检索相关片段。不过我在实际使用时发现它对单个文件的理解尚可跨文件的调用关系分析还是经常出错。所以我的原则是RAG 工具只当检索器用真正的流程约束仍然靠契约文件。5. 常见问题与排查技巧实录5.1 AI 越改越乱需求变更没有走契约通道这个问题我在 v1.0 阶段天天遇到。需求从“检查本地图片是否存在”变成“同时检查图片体积是否超过 1MB”如果直接让 AI 改代码它大概率会把原来的链接解析逻辑重写一遍甚至把输出格式也给改了。因为你没有告诉它“哪些是不能动的”它自然以为哪里都要动。解决方式很朴素需求变更时先改docs/requirements.md和docs/contract.md然后再让 AI 读这两个文件生成一份“变更影响说明”。AI 需要列出新增了哪些模块、修改了哪些接口、影响了哪些测试。这份说明由人来确认后才允许进入实现阶段。看起来多了一道工序但恰恰是这道工序挡住了 AI 最擅长的大规模回归。5.2 编译过了运行就崩错误处理被忽略了AI 生成的代码有个很典型的问题它能保证“正常路径”通顺但几乎不做异常路径。文件不存在、目录权限受限、日志文件为空、图片链接格式异常这些边界场景 AI 一律不关心。所以很多项目出现“编译 OK、跑起来必崩”的现象。我的排查技巧是在契约阶段就把错误处理策略写死并且让 AI 在实现每个模块时额外输出一段“错误路径说明”回答“如果本函数传入空列表会怎样如果文件不存在会怎样”。这个问题会强迫 AI 去思考边界而不是只盯着主流程。测试用例里也必须至少包含一个异常输入没有异常测试的模块我会直接打回重做。5.3 上下文越用越脏旧信息污染新决策长对话进行到后半程AI 经常会受前面错误信息的影响。比如你在某个模块的调试中随口说了一句“可能是路径编码问题”AI 之后的所有代码就都开始疑神疑鬼拼命加各种编码转换搞得代码里全是无用逻辑。这就是上下文污染。避免的关键手段是“该翻篇就翻篇”。一个独立模块的实现和调试结束后直接开新会话不要让旧会话继续承载新任务。新任务开始前让 AI 读取docs/contract.md和最新的docs/decisions.md这样它拿到的是精简后的消息而不是冗长且包含大量中间试错过程的聊天记录。5.4 AI 生成了 200 行但我只需要 20 行这是特别常见的失控现象。AI 为了展示“认真负责”会把函数拆得极碎或者加上一堆你根本不需要的配置项。解决这种问题不能靠事后删得在 prompt 层面做约束。我在模板里会写明不允许新增需求里没提到的功能不允许预留 YAGNI 性质的扩展接口函数的行数上限可以写死例如“主函数体控制在 60 行以内超出则重新设计”这类约束不会百分之百生效但能显著减少 AI 的自我发挥空间。如果 AI 还是生成了大量无用代码我通常会直接点明“这段属于智能补全事故请删掉所有与需求无关的逻辑”。对大多数模型来说明确表达“你写多了”比泛泛说“精简一点”有效得多。6. 落地之后的一些个人体会这套 v2.0 工作流真正跑起来之后我最大的感觉是AI 编程从“碰运气”变成了“看流程”。同样一个需求以前直接丢给 AI 生成的代码可能能用但我不知道它是怎么得出这个方案的现在每一轮输出都有契约、有测试、有决策记录代码的可解释性和可回退性都强了很多。我也逐渐意识到AI 编程最难的点其实不在工具而在于人能不能忍住“不去问最后一个问题”的冲动。工作流是一层保险它不能消除所有意外但能让你在意外发生时快速定位是哪一环掉了链子。如果你也想试 v2.0我建议从一个小项目开始先把契约文件这条线走通再逐步加入测试和文档沉淀。流程本身不复杂真正值钱的是坚持把每一步都做到位。
返回列表