☰
从灵感到实现:构建可复现的AI辅助编程工作流
2026/10/18 13:11:01 网站建设 项目流程

我见过不少人把AI当成一个"高级补全工具":打开对话窗口,把需求随手一丢,让AI写出一大段代码,能跑就算完事。但下一次遇到类似需求,又要从零开始跟AI解释一遍,甚至上次踩过的坑、试错的结论,全留在那个再也找不到的旧对话里。这不是AI不行,而是缺少一套标准化的AI辅助编程工作流。工作流这个东西听起来很重,其实核心只有一句话:把"我想做个东西"这种模糊灵感,稳定地变成可验证、可复用、可交接的实现过程。这篇文章我以最近做的一个内部命令行工具(就叫它模拟项目X:日志摘要工具)为例,完整走一遍我现在的做法,覆盖需求澄清、任务拆解、上下文管理、AI协作编码、验证与沉淀。它适合那些已经开始用AI写代码、但总觉得"聊出来的代码不可控、不可续、不可复现"的人。

1. 为什么AI辅助编程最怕"随用随丢":可复现性陷阱在哪

1.1 对话式AI的三宗罪:上下文漂移、答案不收敛、经验不沉淀

经常用AI写代码的人都会发现一个现象:同一个需求,你换个说法问它,或者新开一个对话再问一次,它给出的方案很可能完全不同。第一次让它写个函数,它给你生成一个类;第二次让它处理同样的问题,它又换了一种风格。这不是AI"性格不稳定",而是它本质上是在当前对话上下文里,尽可能生成一个"看起来合理"的答案。上下文一变,答案就变。我把这个现象叫上下文漂移。

第二宗罪是答案不收敛。在没有验收标准时,AI会非常擅长"自圆其说"。你问它这个方案行不行,它多半顺着你说"行",除非你能主动给出反例。很多人在这一步栽跟头:以为AI说实现没问题就真的没问题,结果把代码丢进真实数据里一跑,立刻露馅。没有验证标准,AI的"自信"和"能跑"是两回事。

第三宗罪是经验不沉淀。如果你每次都在新会话里从一句"帮我看段代码"开始,那么上次试错得到的知识——比如某个解析逻辑有坑、某个配置项必须关掉、某个命令在特定环境下会失效——就全部留在了旧对话里。下次遇到同类问题,你还是个新手,还得重新试一遍。这三个问题叠加到一起,就是典型的"随用随丢":工具越来越强,使用者的经验却始终在原地打转。

1.2 我踩过的坑:同一个脚本,三版代码三种风格

我给自己做日志摘要工具的最初灵感,只有一句话:"日志太多,想快速看到错误集中在哪。"听起来很简单,对吧?但实际推进的过程完全不像这句话那么顺。

第一版,我找AI生成,它给了一个脚本,用几条命令把包含错误等级的行挑出来,能跑,但换个日志格式就失效。第三天我想加一个"错误按小时分布"的功能,于是新开一个对话把需求丢过去。AI看完说这个需求更适合换语言重写,直接生成了一百多行的新脚本。没错,它没有在原有代码上扩展,而是建议我另起炉灶,旧的逻辑被丢到一边,代码风格也和我之前写的不太一致。那个项目到这里已经有点散架了。

更离谱的是后来我为了修一个乱码问题再开新会话,AI已经完全不记得前面做过什么,甚至建议我引入一个第三方库来重新解析整个文件。那次之后我彻底意识到:这不是AI不好用,是我没有给它一张稳定的图纸。我要的不是每一轮对话的灵光一现,而是一套可复现的流程:把项目上下文固定下来,把任务拆小,把验收标准写清楚。下面就是这个流程的具体内容。

2. 把"我想做个工具"变成AI能干活的任务清单:需求澄清与拆解

2.1 一句话灵感先落成需求清单:用WWHL模板

很多人在跟AI协作时上来就是一句:"帮我写个工具,解析日志。"这句话看起来信息量足够,实际上AI会自己脑补所有细节——用什么语言、输出什么格式、要不要排序、遇到异常怎么办。它脑补得越多,你后续纠偏的成本越高。所以我现在的习惯是开工前先把一句话灵感落成一个固定的需求清单,用WWHL模板:Why(为什么做)、Who(给谁用)、What(做什么)、Limit(边界限制)。

拿模拟项目X举例,它对应的WWHL是这样的:

  • Why:后端排查问题时看日志效率太低,错误信息被大量无关输出淹没。
  • Who:主要给自己和团队里的两三位后端同事使用,不是外部产品。
  • What:支持输入一个日志文件路径,输出按日志级别统计的错误数量,并列出出现次数最多的前10条消息摘要。
  • Limit:只读操作,不修改原文件;首版不支持二进制文件;不需要图形界面。

写完之后,把这段内容存成一个叫 requirement.md 的文件。这一步看起来很笨,但它其实是后续所有Prompt的根:你给AI的每一段背景描述,都可以从这里复制。没有这个文件,你每次跟AI解释需求时措辞都会变,AI交付的东西自然也会漂移。

2.2 把需求拆成15分钟内能验证的小任务

需求清单只是"做什么",真正让AI稳定输出的是"任务的粒度"。我的经验是:一个超大任务交给AI,它最容易自嗨。比如"实现日志分析工具"这种任务,AI可能顺手生成一堆你想不到的功能,也可能漏掉你真正需要的那部分。正确的做法是把需求拆成一系列互不纠缠的小任务,每个任务都满足三个条件:单一职责、可独立验证、相互之间有明确边界。

模拟项目X的完整需求,我拆成了下面几个任务:

  1. 编写日志文件读取模块:读取文件,过滤出所有包含错误或警告级别的行。
  2. 实现级别统计函数:输入过滤后的行列表,输出各等级出现次数的字典。
  3. 实现摘要提取函数:从错误消息里提取核心信息,按出现次数降序排列。
  4. 组装命令行输出:把统计结果和Top摘要输出为易读的文本表格。
  5. 为每个函数编写对应测试用例。

你可能觉得"读取日志文件"也算任务?对AI来说,它在实现这样一个函数时需要考虑编码、换行、空文件、超大文件等一堆细节,所以把它单独拿出来是有意义的。每次只让AI做其中一件,再通过验收确认,可以明显降低它犯糊涂的概率。

2.3 每张任务卡都带验收标准:这是可复现的开关

任务拆完还不够,每个任务都要配一张"任务卡",而且卡片上必须有验收标准。没有验收标准,"可复现"就是空话:AI这次交的代码和你预期之间到底差多少,完全没有客观判断方式。有验收标准之后,判断就变成了"跑一下就知道"。

我的任务卡模板长这样,用纯文本就能写:

任务编号:T3 任务名称:从错误消息中提取摘要并排序 背景: 项目目录 /sample_project/ 下已存在 parse_log.py, 其中 load_lines(filepath) 已返回日志行列表。 任务: 在 parse_log.py 中新增 extract_summary(lines), 返回按出现次数降序排列的 [(错误消息摘要, 次数)] 列表。 验收标准: 1. python -m pytest tests/test_extract_summary.py 全部通过; 2. 不修改已存在的函数签名; 3. 不新增第三方依赖; 4. 空列表输入时返回 []。 约束: 如果方案需要更改现有数据结构,先说明理由,不要直接替换。

这里最容易被忽略的是最后一行"约束"。AI在实现某个功能时,经常顺手重构周边代码,导致你辛苦搭好的结构被改得面目全非。在任务卡里明确"不修改已存在函数签名",本质上就是给AI画了一条不能越过的红线。

3. 供AI稳定发挥的项目上下文:三段式Prompt与项目记忆库

3.1 为什么AI总在会话后半段"失忆":聊聊上下文管理

即使你把任务卡写得再清楚,还有一个问题逃不掉:AI的上下文窗口是有限的。对话框里的历史消息都会作为上下文参与生成,但窗口有上限,越聊越长之后,前面的项目背景反而会被大量中间讨论挤占。最典型的情况是,你从"帮我实现A"聊到"A有个bug改成B",又聊到"顺便加个C功能",AI到后面已经完全忘了A最初的接口长什么样。

我现在的解决方式很粗暴:一个会话只做一件事,背景信息用固定模板重发,不指望AI"记得住"。换任务就新开会话,然后把项目背景重新贴一遍。这件事看起来麻烦,但它每次都给AI一个干净、一致的起点,结果的可预期性会高很多。

3.2 三段式Prompt框架:背景、任务、验收

为了让每个AI会话都能在同样的起跑线上开始,我把Prompt固定成了三段的框架:背景、任务、验收。前两段是给AI的信息输入,最后一段是给它的自我检查标准。

背景: - 项目:模拟项目X(命令行日志摘要工具) - 技术栈:Python 3.10,不使用第三方库 - 现有结构:src/parse_log.py,tests/test_parse_log.py - 编码约定:函数加类型注解,日志内容用 print 输出,不要使用 logging 模块 任务: - 在 src/parse_log.py 中实现 count_by_level(lines) - 返回值类型为 dict[str, int],统计每个日志级别的出现次数 - 新增测试文件 tests/test_count_by_level.py 验收: - pytest 全部通过 - 函数签名为 count_by_level(lines: list[str]) -> dict[str, int] - 空列表输入时返回空 dict - 不修改其他文件

你会发现这个模板和任务卡几乎是同构的,差别只在开头多了技术栈和项目结构。这才是关键:如果任务卡是给"人"读的,那段式Prompt就是给"AI"读的。在实际操作中,你只需要把当前任务卡粘贴进来,再把项目根目录的CONTEXT文档内容贴到背景部分,就可以开聊了。

3.3 项目级CONTEXT文档:一劳永逸的上下文记忆

为了让"背景"这一段不用每次临时写,我会在项目根目录维护一个很小但很关键的 CONTEXT.md 文件。它不是设计文档,不写长篇大论,只写"AI需要知道、但对话里从来没人主动告诉它的约定"。

# 项目目标 命令行日志摘要工具:输入日志文件路径,输出各等级统计和Top摘要。 # 技术栈与约束 Python 3.10,只用标准库,禁止新增第三方依赖。 # 目录结构 src/parse_log.py 主实现 tests/ 单元测试 docs/ 需求与决策记录 # 编码约定 - 所有函数必须带类型注解 - 不引入 logging,统一用 print - 错误消息摘要需要去除 ANSI 转义符 - 只读文件,不在任何路径下写文件 # 常用命令 python -m pytest python src/main.py sample.log # 当前进度 已完成 T1、T2,正在进行 T3。

这个文件通常只有几十行,但对AI的"定向能力"提升非常大。每次新开会话,我先把CONTEXT.md的关键部分粘到Prompt背景里,再给具体任务,AI就不容易跑偏。有一点需要提醒:这个文档必须由人工维护,不要让AI帮你更新。AI很容易把"它打算实现"的东西写进"已完成"里,然后污染后续所有对话的上下文。

4. 人机协作编码的分工边界:哪些代码敢让AI写,哪些必须自己写

4.1 适合交给AI的活:样板代码、测试用例、单文件工具

不少人让AI写代码的姿势是"把整个项目丢给它",这其实是把AI放在了它最不擅长也最危险的位置。我的原则是:AI适合做接口清晰、逻辑局部性强、失败迹象明显的活。具体到模拟项目X里,下面这些我放心交给AI:

  • 文件读取的骨架代码。比如遍历每一行、按正则匹配日志级别,这类代码重复性高,AI写得又快又完整。
  • 单元测试用例,尤其是边界条件。我只要在任务卡里写明"包含空列表、ANSI转义符、超长行三个测试",AI生成的测试基本能覆盖到位。
  • 把数据组装成命令行表格输出的格式代码。这种逻辑不复杂,但很琐碎,AI很擅长,出了问题也容易被测试发现。

这些活的共同点是:你看一眼就能知道对不对,跑一遍测试就能验证,即使AI写得不好,纠偏成本也很低。

4.2 需要自己掌控的部分:核心逻辑、数据流向、安全与边界

反过来说,有几类东西我几乎不会让AI直接拍板。第一是数据结构选型。模拟项目X里,摘要需要按次数排序,那到底用列表套元组还是用字典套计数器,这会直接影响后面所有代码的写法。这类决定我会自己先想清楚,再作为约束写进任务卡,而不是让AI自由发挥。

第二是错误处理策略。AI默认生成的代码通常是"假设输入格式正常"的,它会忽略文件不存在、编码异常、日志行格式不一致等情况。这些边界策略需要人根据真实使用场景拍板,因为AI不了解这些日志文件实际从哪里来、会遇到什么脏数据。

第三是涉及安全性或系统命令的代码。如果任务里包含执行外部命令、删除文件、网络请求等动作,我必须自己控制边界。AI不知道这个工具会被什么人、什么环境使用,它很可能自信地忽略掉一些潜在风险。关键路径上,我的做法是先自己用文字描述数据流向,再让AI实现里面特定的一环,而不是让它自己设计整条链路。

4.3 让AI改代码的反馈闭环:一次只反馈一个问题

AI第一次生成的代码很少能直接通过所有验收,所以"让它改"也是工作流里频率最高的环节。但大部分人在这个环节会犯一个致命错误:把一大段报错日志直接贴给AI,然后说"帮我修一下"。AI面对模糊的报错信息,只能东试西撞,很可能改好一个bug同时引入新bug。

我的反馈规则很简单,每次修改只给AI四样东西:问题位置、复现输入、实际输出、期望输出。而且一次只反馈一个问题。比如:

问题位置:src/parse_log.py 的 extract_summary 复现输入:包含 ANSI 颜色的日志行 "\x1b[31m[ERROR]\x1b[0m disk full" 实际输出:摘要包含转义符 \x1b[31m 期望输出:摘要为 "[ERROR] disk full",不含转义符 请修改 extract_summary,只处理 ANSI 转义符的剥离,不要重构其他函数。

你直接把这个反馈模板发给AI,它基本不会再东拉西扯。这里还有一个经验:收到AI的修改后,不要只看它的解释,一定要在代码里确认改动范围。我会用版本管理工具查看这次改动了哪些行,如果发现它改了任务卡里明确禁止改的东西,就立刻让它回退,而不是继续往下走。

5. 验证、记录与沉淀:把偶然的顺利变成下一个项目也能复用的流程

5.1 验证不是"能跑就行":三层检查

"能跑就行"这个标准太低,因为AI生成代码最擅长的恰恰是"在正常输入下看起来能跑"。真正的验证至少要分三层。

第一层是自动化测试。每个任务卡都配有对应的测试文件,AI写完功能后,我跑一遍测试套件,看它有没有满足验收标准。第二层是边界输入。我会主动喂一些刁钻数据:空文件、只有一行的文件、包含大量重复错误的文件、带转义符的文件。AI很容易在这类输入上暴露问题。第三层是真实文件实测。拿一份真实的日志文件跑一遍,把工具产生的统计结果和人工肉眼扫出来的重点做对比。这一步能发现测试用例没覆盖到的现实问题,比如日志格式里某个特殊前缀没被识别。

这三层每一层都不可省。测试通过只能证明"逻辑符合预期",真实文件实测才能证明"对用户有价值"。模拟项目X里,我们最初的测试全过了,但一跑真实日志,发现很多消息里有终端颜色控制符,摘要里全是乱码。这个坑后来被写进CONTEXT文档里的编码约定,再往后所有任务都不会再踩一次。

5.2 把AI生成的关键决定记进变更记录

我在很多团队里看到过一个现象:代码提交信息写得规规矩矩,但"为什么选择这个写法""AI当时给出了什么方案""我们为什么否决了另一个方案"这些信息全丢了。代码本身只记录了结果,没记录决策过程。下次遇到类似问题,又要重新用AI试一遍。

所以我在项目里会维护一个简短的决策记录,不用写长文档,每一条只要几行:

日期:2025-06-10 任务编号:T3 Prompt要点:要求返回 [(消息摘要, 次数)],禁止第三方依赖 AI首次输出:不符合,它返回了 dict[str, int] 主要偏差:误解了"摘要"的含义,把完整日志行当成了摘要 修正方式:补充"摘要需要去除 ANSI 转义符,且只保留最前面的原因字段" 沉淀结论:涉及"摘要/提取"类需求时,必须在任务卡里明确摘要的粒度

有了这种记录,工作流才真正有了记忆。下次任何人接到T3类似任务,不需要重新踩一遍"摘要到底指什么"的坑,直接把沉淀结论复制到任务卡里就行。

5.3 定期把工作流本身当项目来迭代

最后一步容易被忽略:工作流本身也要做版本迭代。我每周会花十来分钟做一次复盘,看的不是代码量,而是流程里最容易卡住的地方。比如我们发现AI经常在"读取日志文件"这个任务上翻车,原因是真实日志文件编码不统一,后来就在任务卡里加了"文件以 UTF-8 读取,忽略无法解码的行"这个约束。又比如AI总在摘要排序的问题上产生误解,那就在CONTEXT文档里补一条排序规则的约定。

这些看似微小的调整,积累起来就是一套越来越精准的标准化流程。当这套流程被整理成一份简单SOP后,新加入的人不需要跟AI聊几十轮,只要按任务卡和CONTEXT文档走一遍,就能在半小时内复现一个接近一致的实现路线。对我来说,这才是"可复现"的真正含义:它不依赖某个人灵光一现的Prompt技巧,也不依赖某次恰好愉快的对话,而是把验证过的经验固化到流程里。

我现在每次开工,依然会先打开需求清单、任务卡和CONTEXT文档,再把它们复制进AI对话。有人觉得这是绕远路,但前面多花十分钟,后面至少少走半天弯路。尤其当项目换了一批人、隔了几个月再捡起来时,这套流程的价值会更明显——你甚至不需要回忆起当时怎么想的,照着任务卡和决策记录走,AI就能在同样的约束下交出稳定的结果。这就是从灵感到实现之间,最值得花时间搭起来的一条路。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询