很多同学在使用 LLM 辅助编程时,应该都有过类似的体验:开一个新对话,把需求粘贴进去,模型生成一段代码,运行报错,再把报错复制回去,让模型继续改,改完又抱一个新错误……如此循环十几轮之后,功能似乎终于能跑了,但代码里已经堆满了临时补丁,变量命名前后矛盾,甚至不敢再让 AI 动任何一行。这种情况,就是我们常说的 LLM Coding Rat Race——LLM 编码仓鼠轮。它描述的不是某个大模型的缺陷,而是一种普遍存在的工作方式:靠“聊天 + 试错”驱动开发,看起来一直在忙碌,实际产出却越来越低。
本文想聊的正是如何逃离这个循环。核心思路不是换一个更强的模型,也不是彻底放弃 AI 编程,而是把“对话式编码”升级成“可规划、可验收、可沉淀”的工程化流程。文章会从问题根因、spec coding 与 Coding Plan 的概念讲起,再通过一个网页抓取与智能摘要的小项目,完整演示如何按计划驱动 LLM 开发,最后给出高频问题排查清单和团队协作建议。无论你是刚接触 AI 编程的新手,还是已经在用 Cursor、Trae、Cline 等工具的开发者,这套方法都值得收藏。
1. LLM Coding 的“仓鼠轮”现象
1.1 什么是 LLM Coding Rat Race
先给一个比较直接的定义:LLM Coding Rat Race,是指在人机协作编程过程中,因为缺少任务边界、验收标准和上下文管理,导致开发者与模型陷入“反复对话、反复修改、反复试错”的低效循环。
这里的典型表现非常清晰:
- 用户把需求发出去,模型返回第一版代码,但不符合预期。
- 用户粘贴报错,模型给出补丁,同一个函数被改了四五遍。
- 聊天记录越来越长,模型开始“忘记”最初的需求,甚至出现前后矛盾的逻辑。
- 功能最终能跑通,但代码不可读、不可测试、不可维护。
- 用户一旦想加新功能,又不敢让 AI 随便改,整个项目变成僵局。
本质上,问题不在于模型能力,而在于开发流程没有为 LLM 设计好“轨道”。人跟人协作时,我们会写需求文档、拆分任务、约定接口、写单元测试,这些工程手段在 AI 编程里同样重要,只是很多人没有意识到。
1.2 为什么会陷入“无限试错”的循环
要逃离仓鼠轮,得先看清它形成的四个根因。
第一个根因是上下文失控。大模型的注意力机制决定了,当一段对话中堆积了几十条历史消息,每条消息又包含大量报错和代码片段时,模型很难分辨哪些信息是当前真正需要的。于是它开始“平均用力”,回复质量随上下文增长明显下降。
第二个根因是反馈回路缺失。不少 AI 编程工具的使用方式是:让模型写代码,然后人工复制到项目中运行,看到报错再拷回去。这个回路里,缺少自动化的验证手段。换句话说,模型本身并不知道自己写的代码是否通过测试,它只是在“猜”。
第三个根因是目标漂移。最初你可能只想实现一个简单的命令行工具,但随着对话推进,你开始纠结 CSS 样式、日志格式、异常提示文案,最后甚至变成了“调 prompt”而不是“写代码”。目标一漂,所有后续修改都会失去方向。
第四个根因是没有验收标准。很多需求描述停留在“帮我写一个爬虫”“做一个登录页面”这种模糊表达,模型只能靠猜。猜对了算运气,猜错了就进入下一轮试错。
1.3 逃离内卷的正确方向
既然问题出在流程,解法自然也在流程。这里给一个总的结论:想把 LLM Coding 用出生产力,必须从“模型中心”转向“工程中心”。
所谓“模型中心”,是指开发者把大模型当作一个神通广大的对话对象,期望它理解一切、完成一切。而“工程中心”正好相反,开发者负责定义边界、拆解任务、设计验收标准,模型则负责在每个明确的小步骤中输出代码。前者靠运气,后者靠系统。
接下来的章节,我们会围绕这条主线,展开一套 LLM 编程工作流,包括:
- 用 spec 明确“做什么”。
- 用 Coding Plan 明确“分几步做”。
- 用可执行的验证命令明确“做到什么程度算完成”。
- 用版本管理、知识沉淀把结果固化下来。
2. 从 vibe coding 到 spec coding
2.1 vibe coding 的舒适区与危险区
最近一年,“vibe coding”是个非常热门的词,由 Andrej Karpathy 提出。它描述的是一种“跟着感觉走”的编程方式:开发者把主要意图告诉 AI,让 AI 顺着上下文自然地把代码写出来,人再根据整体感觉做调整。这种方式适合快速验证想法,也非常适合初学者体验 AI 编程的威力。
但 vibe coding 有一个隐藏前提:项目足够小、生命周期足够短、使用者对代码质量没有太高要求。一旦进入生产环境、多人协作或长期维护,只靠“vibe”就会出问题。因为模型生成代码时会保留它自己惯用的风格,不同会话之间的命名方式、模块划分、异常处理策略都可能不一致。时间一长,项目就会变成一团乱麻。
这并不意味着 vibe coding 要被全盘否定,而是提醒我们:在“原型验证”和“生产交付”之间,需要一座桥梁,这座桥梁就是规格和计划。
2.2 spec coding:先写规格,再写代码
spec,即规格说明(Specification)的缩写。所谓 spec coding,就是在让 LLM 写代码之前,先把功能需求、接口定义、验收条件、边界情况写成一份清楚的文件,再让模型按规格实现。
为什么要这样做?因为大模型本质上是“对齐任务”的工具,它的输出质量高度依赖你对任务的描述是否清晰。你可以把大模型理解为一位非常聪明但过于听话的新同事:需求里没写清楚的地方,它不会反问,而是会主动按自己的理解补全。补全对了是惊喜,补全错了就是返工。
来看一个对比。
模糊的需求描述:
帮我写一个网页抓取工具,能从 URL 抓取内容,还能用 LLM 总结。清晰的 spec 描述:
# 网页内容抓取与智能总结工具 ## 功能要求 - F1: 通过命令行参数接收 URL - F2: 抓取并解析新闻/博客正文,去掉导航、广告等无关内容 - F3: 调用 LLM 生成 3 条要点式总结 - F4: 输出结果保持 Markdown 格式,支持写入文件 ## 技术约束 - 使用 Python 3.9+ - HTTP 请求使用 requests 库 - 正文提取使用 readability-lxml - LLM 调用封装为独立模块,便于替换供应商 ## 验收标准 - 输入无效 URL 时,输出友好错误信息 - 本地网络异常时,程序不崩溃,给出可读提示 - 摘要输出必须为 Markdown 列表格式两份描述之间的差距,就是一次“顺利开发”和“无限试错”之间的差距。
2.3 Coding Plan:把大任务拆成可执行步骤
光有 spec 还不够,因为一个稍大的功能仍然包含多个模块,直接让模型“一口气写完”又回到了 vibe coding。这时需要引入 Coding Plan。
Coding Plan 的核心理念是分而治之:把一个大任务拆成一连串小步骤,每个步骤都有明确的输入、输出和验收条件。模型按计划逐个执行,开发者则按步骤审查和验证。这样做有几个明显好处:
- 每次上下文都聚焦在单个步骤上,模型不容易跑偏。
- 每个步骤都能用测试或命令验证,反馈回路变短。
- 出错时可以精准定位到某个步骤,而不是整段推倒重来。
- 多个开发者或 Agent 可以并行处理不同步骤。
现在,很多 AI 编程平台也开始把 Coding Plan 作为内置能力,例如阿里云百炼的 coding plan、火山方舟的 agent plan / coding plan。使用者只需给出目标,平台会自动生成带步骤的执行计划。不过,依赖平台的前提是理解“规划”本身的价值,否则即使平台生成了计划,你也很难判断它是否合理。
3. 建立 LLM Coding 的工程化工作流
3.1 上下文瘦身:让模型只看到关键信息
前面提到,上下文过长是 LLM Coding 进入仓鼠轮的重要原因。要想解决,一个非常有效的手段是“上下文瘦身”。
上下文瘦身的核心原则是:模型不需要知道你这几天的全部聊天记录,只需要知道“当前步骤要完成什么”和“当前代码长什么样”。具体做法包括:
- 把 spec 与 Coding Plan 保存为仓库内的 Markdown 文件,作为唯一事实源。
- 每个步骤开启新的会话,只粘贴“当前步骤的要求 + 相关代码 + 报错信息”。
- 不要在一个会话里不断追加需求,而是把需求变化先写回 spec,再开启新任务。
举个例子,假设你正在让模型实现第 2 步“正文提取”。新会话中,你应该这样组织上下文:
# 角色 你是一名资深 Python 开发者。 # 当前步骤 请根据 spec.md 中的功能 F2,实现网页正文提取。 # 相关依赖 - readability-lxml - BeautifulSoup4(仅做辅助) # 代码现状 项目根目录下已有 fetch.py,实现了 fetch_page(url) 函数, 返回原始 HTML 文本。 # 验收标准 python -m pytest tests/test_extract.py 全部通过这样模型看到的是一个范围清晰、目标明确的小任务,而不是整段“帮我写一个爬虫”的模糊对话。上下文长度变短了,生成质量反而会提升。
3.2 可验证的分步执行
工程化工作流的第二根支柱,是“可验证”。简单来说,每个步骤不能只停留在“看起来差不多”,而是要有可执行的验收命令。
对于 Python 项目,验收命令通常是 pytest;对于前端项目,可能是 eslint 或 tsc;对于接口类项目,可能是 curl 或 Postman。这些命令要提前写在 Coding Plan 的每个步骤里,模型在执行完代码后,能够自己运行并确认结果。
来看一个典型的步骤设计:
## Step 2:正文提取 - 目标:实现 extract_main_content(html: str) -> str 函数 - 输出:src/extract.py - 验收: 1. pytest tests/test_extract.py -k "extract_main_content" 通过 2. 提取结果中不包含 <script>、<style> 标签内容 3. 对空字符串输入,返回空字符串而不是抛异常要注意,验收标准必须是机器可检查的,而不是“代码质量不错”这种主观描述。当模型能自动验证自己的输出时,LLM Coding 的质量上限会显著提高。
3.3 多 Agent 协作与职责划分
当任务规模进一步扩大,单个 Agent 处理不过来时,可以考虑引入多 Agent 协作。这个思路并不复杂:每个 Agent 负责一个角色,所有 Agent 共享同一份 spec 和 Coding Plan,并且通过文件系统或版本管理工具交接中间产物。
常见的角色划分方式如下:
- 需求分析 Agent:负责把用户描述翻译成 spec 和验收用例。
- 编码 Agent:按照 Coding Plan 的某个步骤实现功能。
- 评审 Agent:检查代码是否符合规范、是否覆盖边界条件。
- 测试 Agent:编写和执行测试用例,输出测试报告。
这里最容易踩的坑是“让多个 Agent 同时改同一个文件”,必然产生冲突。正确做法是让每个 Agent 在独立分支或独立目录中工作,然后由开发者统一合并。如果你想使用更复杂的工具链,也可以关注 MCP(Model Context Protocol)等协议,它能让 Agent 以标准化方式访问文件、数据库、Git 仓库等外部工具资源。
4. 完整实战:抓取网页内容并用 LLM 总结
为了把前面讲的方法串起来,我们来实现一个命令行小工具:输入一个 URL,抓取网页正文,再用 LLM 生成 Markdown 格式的摘要。作为演示项目,我会把 LLM 调用部分做成“可替换接口”,并提供一个演示模式,保证没有任何 API Key 时也能跑通整个链路。
4.1 定义 SPEC
首先,在项目根目录创建 spec.md。
# 网页内容抓取与智能总结工具 ## 背景 用户需要快速了解一篇文章的核心内容, 希望用一个命令行工具,输入 URL 后自动生成 3 条要点式摘要。 ## 功能要求 - F1: 通过命令行参数接收 URL - F2: 抓取并解析新闻/博客正文,去掉导航、广告等无关内容 - F3: 调用 LLM 生成 3 条要点式总结 - F4: 输出结果保持 Markdown 格式,支持写入文件 ## 技术约束 - 使用 Python 3.9+ - HTTP 请求使用 requests 库 - 正文提取使用 readability-lxml - LLM 调用封装为独立模块,不绑定具体供应商 ## 验收标准 - 输入无效 URL 时,输出友好错误信息,退出码非 0 - 网络异常时,程序不崩溃,给出可读错误提示 - 演示模式下,不依赖任何 API Key 也能跑完整流程 - 摘要输出格式为 Markdown 列表这份 SPEC 的核心价值,是让模型和开发者对“完成”有统一的定义。
4.2 编写 Coding Plan
接下来创建 plan.md,把整个开发拆成 4 个步骤。
# Coding Plan ## Step 1:项目骨架与网络请求模块 - 目标:初始化项目结构,实现 URL 校验和 HTML 抓取 - 输出:fetch.py - 验收: 1. 能抓取 example.com 首页,返回字符串 2. 对非法 URL 抛出 ValueError ## Step 2:正文提取 - 目标:实现正文提取函数,过滤无关标签 - 输出:extract.py - 验收: 1. 提取结果中不包含 <script>、<style>、<nav> 标签 2. 对空输入返回空字符串 ## Step 3:LLM 摘要接口 - 目标:封装 LLM 调用,提供演示模式与真实模式 - 输出:llm.py - 验收: 1. 提供 build_summary_prompt(content) 生成提示词 2. 提供 demo_summarize(content) 返回演示摘要 3. 真实调用使用独立函数 call_llm(prompt) ## Step 4:CLI 组装与输出 - 目标:串联完整链路,支持 --output 参数 - 输出:cli.py - 验收: 1. python cli.py --url "https://example.com" 正常输出 2. --output 参数能将结果写入文件按照这份计划,每一步都短小精悍,模型比较容易高质量完成任务。
4.3 创建项目结构并安装依赖
项目结构非常简单:
llm-scraper/ ├── cli.py ├── extract.py ├── fetch.py ├── llm.py ├── requirements.txt ├── plan.md └── spec.md在 requirements.txt 中写入:
requests>=2.28.0 readability-lxml>=0.8.1然后创建虚拟环境并安装依赖:
python -m venv .venv source .venv/bin/activate # Windows 系统使用:.venv\Scripts\activate pip install -r requirements.txt4.4 编写核心代码
创建 fetch.py。
# 文件路径:llm-scraper/fetch.py import requests def fetch_page(url: str, timeout: int = 10) -> str: """抓取指定 URL 的 HTML 原始内容。 Args: url: 目标网页地址。 timeout: 请求超时时间,单位秒。 Returns: 网页的 HTML 文本。 Raises: ValueError: URL 格式非法时抛出。 requests.RequestException: 网络请求异常时抛出。 """ if not url.startswith(("http://", "https://")): raise ValueError("URL 必须以 http:// 或 https:// 开头") headers = { "User-Agent": "Mozilla/5.0 (compatible; LLMScraper/1.0)" } resp = requests.get(url, headers=headers, timeout=timeout) resp.raise_for_status() return resp.text这里需要注意两点:一是加了 User-Agent,避免部分站点默认拒绝爬虫;二是对 URL 做了前缀校验,减少无意义的请求。
创建 extract.py。
# 文件路径:llm-scraper/extract.py from readability import Document def extract_main_content(html: str) -> str: """从 HTML 中提取正文内容。 基于 readability-lxml 的正文识别算法, 可以自动过滤导航、广告、脚本等无关信息。 Args: html: 原始 HTML 文本。 Returns: 提取后的正文 HTML 片段。 """ if not html.strip(): return "" doc = Document(html) return doc.summary()readability-lxml 会返回一段包含正文的 HTML 片段,这个片段里已经没有主要的导航和脚本内容。
创建 llm.py,这里是整个项目中最值得展开的文件。
# 文件路径:llm-scraper/llm.py from typing import Protocol class LLMClient(Protocol): """定义 LLM 客户端的统一接口。 实际项目中,可以把 OpenAI、通义千问、本地 Ollama 的 SDK 适配成这个协议。 """ def chat(self, prompt: str, system: str = "") -> str: ...然后添加提示词构建函数和演示模式函数。
def build_summary_prompt(content: str) -> str: """构造让 LLM 生成摘要的提示词。""" return ( "请阅读以下网页正文内容,提取 3 条核心信息," "使用中文要点列表输出,不要添加原文没有的内容。\n\n" f"正文内容:\n{content[:8000]}" ) def demo_summarize(content: str) -> str: """演示模式:不依赖任何 LLM,直接截取正文前 200 字作为摘要。 这样做的目的是让整个流程在没有 API Key 时也能跑通, 验证抓取、提取、输出三个环节是否正常。 """ plain_text = content[:200].replace("\n", " ").strip() return "## 摘要(演示模式)\n\n" + plain_text def call_llm(prompt: str, client=None) -> str: """调用真实 LLM 的示例函数。 不同云厂商、不同本地推理框架的 SDK 差异较大, 这里刻意不绑定具体实现,读者可以按自己使用的模型服务替换。 注意不要将 API Key 硬编码在代码中,建议通过环境变量注入。 """ raise NotImplementedError("请替换为你自己的 LLM 客户端实现")这里要特别说明,真实项目中的 LLM 调用,一般需要我们自己根据所选供应商的 SDK 来实现。不同厂商的接口、鉴权方式、模型名称都不一样,直接给出某一家 SDK 的写法,反而容易误导读者。所以本文把调用点抽象出来,后续接 OpenAI、通义千问、Moonshot、Ollama 时,只需要实现这个函数即可。
创建 cli.py,把前面的模块串起来。
# 文件路径:llm-scraper/cli.py import argparse from fetch import fetch_page from extract import extract_main_content from llm import build_summary_prompt, demo_summarize def main() -> None: parser = argparse.ArgumentParser( description="抓取网页并生成 LLM 摘要" ) parser.add_argument("--url", required=True, help="目标页面地址") parser.add_argument( "--output", default="", help="输出 Markdown 文件路径" ) parser.add_argument( "--real", action="store_true", help="启用真实 LLM 调用(需要自行实现 llm.call_llm)", ) args = parser.parse_args() try: html = fetch_page(args.url) content = extract_main_content(html) if args.real: # 真实模式:需要先在 llm.py 中实现 call_llm from llm import call_llm # 延迟导入,避免无实现时影响演示模式 prompt = build_summary_prompt(content) result = call_llm(prompt) else: result = demo_summarize(content) if args.output: with open(args.output, "w", encoding="utf-8") as f: f.write(result + "\n") else: print(result) except ValueError as e: print(f"输入错误:{e}") raise SystemExit(1) except Exception as e: print(f"执行失败:{e}") raise SystemExit(1) if __name__ == "__main__": main()这里把异常处理放在了 CLI 入口处,保证网络错误、解析错误不会让程序直接抛出毫无可读性的堆栈。
4.5 运行与验证
先运行演示模式:
python cli.py --url "https://example.com"预期输出类似:
## 摘要(演示模式) Example Domain This domain is for use in illustrative examples in documents. You may use this domain in literature without prior coordination or asking for permission.再测试写入文件:
python cli.py --url "https://example.com" --output summary.md cat summary.md如果需要真实 LLM 摘要,则需要先在 llm.py 中实现 call_llm,然后运行:
export LLM_API_KEY=your-key-here python cli.py --url "https://example.com" --real完成这个实战项目后,你可以回顾一下:整个开发过程的核心,是先写 spec 约束目标,再用 Coding Plan 拆分步骤,最后才让模型逐步实现。即使换成更高难度的项目,这套工作流也是通用的。
5. 常见问题与排查思路
| 问题现象 | 常见原因 | 解决思路 |
|---|---|---|
| Agent 一直改代码,但越改越差 | 上下文堆积过多历史修改记录,目标漂移 | 重新开启会话,只粘贴原始 SPEC、当前代码和最新报错 |
| 生成的代码能跑,但后续维护困难 | 只强调功能交付,没有约定模块结构和代码风格 | 在 SPEC 中增加“技术约束”,提前约定文件名、函数签名、异常策略 |
| 提示词越来越长,效果却没有提升 | 提示词内卷,缺少可执行的验收标准 | 把“希望模型怎么做”改成“希望模型输出什么”,用测试命令做约束 |
| 多 Agent 协作时出现重复代码或冲突 | 职责边界不清晰,多个 Agent 同时修改同一份文件 | 用 Coding Plan 固定每个 Agent 的输入输出目录,让开发者统一合并 |
| 敏感信息被拼进提示词 | 代码中硬编码了 API Key 或数据库密码 | 使用环境变量注入,禁止把密钥文件提交到 Git |
| 模型生成了项目里不存在的依赖 | SPEC 没有规定技术栈,模型自由发挥 | 在 SPEC 中写死依赖清单,新增依赖必须由开发者批准 |
下面挑三个最容易反复出现的坑仔细展开。
第一个是“越改越差”问题。很多人以为给模型更多报错信息就能解决问题,但实际并非如此。当对话中已经存在几百行失败代码时,模型很难分清哪些是“废弃方案”,哪些是“当前方案”。我建议的做法是:一旦连续两轮修改都失败,就果断开启新会话,把 spec.md 中对应步骤的验收标准、当前文件的完整代码、最新一条报错粘贴进去,重新开始。这比在旧会话里强行续命高效得多。
第二个是可维护性问题。LLM 生成代码的风格往往不稳定,可能这次生成一个 fetch_data 函数,下次生成一个 get_html 函数。因此,在 SPEC 的技术约束中,应该尽可能明确模块文件名、核心函数签名和返回类型。这相当于给模型规定了“施工图”,而不是让它自由创作。
第三个是安全问题。如果你使用云端 LLM,任何拼入 Prompt 的内容都会发送到第三方服务。不要将数据库密码、内部接口 Token、用户隐私数据直接放进提示词。更稳妥的方式是先用程序读取环境变量,再在代码内部引用,而不是让模型把密钥写死在配置文件里。
6. LLM Coding 的最佳实践与工程建议
6.1 设定“轮次预算”,避免无限返工
既然是逃离 Rat Race,就必须约束“这个任务最多尝试几次”。我建议每个步骤设置一个轮次预算,例如最多让模型修改 3 轮。如果 3 轮之后仍然无法通过验收,那就不要再继续调试提示词,而是停下来做三件事:
- 检查当前 SPEC 和 Coding Plan 是否足够清晰。
- 检查是否有过时的上下文干扰了模型判断。
- 考虑换一个模型或换一种思路重新实现。
轮次预算的意义,不只是控制时间,更是强制你把注意力从“调 prompt”拉回“调方案”。很多看似是模型能力不足的问题,根源其实是任务描述不合理。
6.2 用“LLM Wiki”沉淀长期知识
AI 编程中还有一个非常容易被忽视的点:知识沉淀。我们自己学到的报错解决方案、项目中的架构决策、常用的命令片段,如果每次都要靠重新聊天让模型再生成一遍,那就等于反复做同样的事情。
一个有效实践是建立个人或团队的 LLM Wiki。它本质上是一个 Markdown 目录,比如放在 docs/wiki/ 下,包含命令、踩坑记录、代码片段、项目决策等内容。在开启新的 LLM 会话时,将相关条目粘贴进 Prompt,作为模型可读取的长期上下文。
举个例子,假设你的团队经常处理 Electron 打包失败问题,那么可以在 wiki 中写一条“electron-builder 在 Windows 下报 winCodeSign 错误的解决方案”。下次模型再遇到同类问题时,直接把这条记录丢给它,可以大幅压缩试错成本。这其实和 Andrej Karpathy 提到的 LLM Wiki 范式很相似:把知识外部化、结构化,让 LLM 不再是每次从零猜测的“脑子”,而是配合一套可检索的外部知识库。
6.3 团队协作:让 Coding Plan 成为事实源
如果你们团队已经在用 AI Agent 协作编码,那 Coding Plan 的重要性会进一步提升。建议约定几条基本规则:
- 所有需求变更先修改 spec.md,再让 Agent 动手。
- Agent 每次只领取 Coding Plan 中的一个步骤,并在独立分支上工作。
- 合入主分支前,必须有开发者人工 review,并由 CI 运行测试。
- 任何 Agent 生成的代码,都要能通过原有测试和新增测试。
把 Coding Plan 当作团队的事实源,本质上是把流程约束前置。开发者不再需要靠嘴记“上次让 AI 改了哪里”,只需要看 plan.md 和 Git 提交记录即可。
6.4 安全与权限边界
最后强调一下安全和权限。无论是个人还是团队,在使用 AI Coding 工具时都要注意:
- 密钥注入使用环境变量,不要写死在代码或 Prompt 中。
- 涉及数据库、线上环境变更的操作,必须严格遵循最小权限原则,先在测试环境验证。
- 在真实模式下调用云端模型前,先检查代码中是否可能包含敏感信息。
- 对 Agent 生成的代码,执行删除、覆盖、迁移数据等操作时,务必先备份。
这些建议不是限制开发效率,而是为了避免“为了快几秒钟,赔上整个晚上”。
7. 总结与下一步
回到文章开头那个场景:当你发现自己正陷入 LLM Coding 的仓鼠轮,真正要改变的不是“换一个更强的模型”,而是工作流本身。
这篇文章介绍了几个核心概念:vibe coding 适合原型验证,spec coding 适合生产交付,而 Coding Plan 是连接两者的桥梁。围绕这三个概念,我们拆解了一套工程化工作流:先写规格文件约束目标,再拆成带验收条件的小步骤,每次只让模型处理一个明确任务,最后用测试命令验证结果。为了帮助大家落地,还完整演示了网页抓取与智能摘要项目的开发过程,覆盖了从 spec.md 到 cli.py 的全部代码。
接下来你可以从三个方向继续深入:
- 把这套方法用在一个你正在进行的真实项目中,看看多久能脱离“无限试错”状态。
- 学习多 Agent 协作和 MCP 等工具链,让 Agent 能访问文件、数据库和外部 API,进一步提高自动化程度。
- 为你的团队制定一份 AI 编程规范,明确 SPEC 模板、Coding Plan 格式和代码评审流程。
如果这篇文章对你有帮助,建议收藏备用,尤其是第 4 节的模板代码和第 5 节的排查表格,在实战中可以直接对照使用。接下来最重要的,是找一个小任务亲自动手试一次。逃离仓鼠轮,从来不是靠想清楚,而是靠跑通一个完整的小项目。