第一次使用 AI 编码工具做"真项目"时,摆在你面前的通常有两条路:从零做一个边界清晰的新应用(MVP,最小可行产品是这类项目的标准形态),或者在现有庞杂系统上动刀改造。两条路线在难度、风险与收获上差别巨大,选错起点往往以"项目烂尾"或"改崩系统"收场。本教程从第一次 AI 编程的特殊性出发,完整对比这两条路线,分别给出实操要点与风险控制方法,并提供一个五问决策框架与推荐进阶路径,帮你为第一次 AI 编程选对目标应用。
前置教程
如想快速开始学习本教程,你可能需要先完成以下前置教程:
- VibeCoding 从 MD 开始,Vibe Coding 工作流与 Markdown 文档驱动方法,是两条路线共同的协作基础。
- 一个好的需求文档应该是什么样的?,无论目标应用选哪条路线,先写清需求与验收标准都是第一步。
- DeepSeek Harness 安装与使用教程,DeepSeek Harness 是本教程实战示例使用的 AI 编码工具。
- Context上下文及相关概念详解,理解上下文窗口的限制,有助于明白 AI 在庞杂系统中翻车的根本原因。
1. 第一次AI编程,选错目标比写错代码更致命
1.1 "第一次"的特殊性
第一次 AI 编程时,你在同时学习两件事:一是与 AI 工具的协作方式,包括怎么下指令、怎么验证结果、怎么迭代修正;二是项目本身的领域知识。两条学习曲线相互叠加,认知负荷远高于单独的任何一件。
目标应用选得对,两条曲线会互相促进:项目小而清晰,你有余力琢磨协作技巧,协作技巧又反过来加速项目推进。目标应用选得错,两条曲线会互相拖累:系统本身的复杂度占满了你的注意力,AI 生成的东西对不对都来不及判断,最后只能盲信或者放弃。
一个适合作为"第一次"的目标应用,应同时满足以下四个条件:
| 条件 | 为什么重要 |
|---|---|
| 边界清晰 | AI 需要明确的输入与输出约定,边界模糊的需求会让它自由发挥 |
| 验证容易 | 你必须有能力判断 AI 产出的对错,否则协作无从谈起 |
| 失败可承受 | 第一次的失败率很高,项目错了应当能丢弃重来 |
| 周期短 | 快速拿到可用成果,才能建立对 AI 编程的正确手感 |
1.2 两条典型路线
现实中,"第一次 AI 编程做什么"的答案大多落在两条路线上:一条是从零开始的新项目,MVP(Minimum Viable Product,最小可行产品)是这类项目的标准形态;另一条是在现有庞杂系统上做改造,也就是通常说的存量系统维护与重构。
验收客观
失败可丢弃] B --> B1[价值直接
风险集中
依赖验证能力] style Start fill:#e8f4f8,stroke:#1a6b8a,stroke-width:2px style A fill:#d5f5e3,stroke:#27ae60,stroke-width:2px style B fill:#fadbd8,stroke:#c0392b,stroke-width:2px style A1 fill:#d5f5e3,stroke:#27ae60,stroke-width:1px style B1 fill:#fadbd8,stroke:#c0392b,stroke-width:1px
两条路线练的能力并不相同。路线A练的是"把意图讲清楚并快速拿到成果",路线B练的是"在约束下安全地改变一个你未完全理解的系统"。第一次 AI 编程应当先补前一种能力,因为它恰好是后一种能力的前提。
1.3 一个常见误区
不少开发者第一次就选择存量系统改造,理由是"真实项目才有练习价值"。这个方向本身成立,问题出在顺序:存量改造对验证与回滚能力的要求极高,而这两样恰恰是新手最缺的。在缺乏安全网的情况下让 AI 修改一个没有测试覆盖的核心模块,等于闭着眼睛走钢丝——出了问题你甚至说不清是 AI 改错的,还是原本就坏的。
第一次 AI 编程的核心任务是建立"描述-验证-迭代"的协作手感,目标应用应当让这个循环转得越快越好,MVP 正是转得最快的那一类。
2. 路线A:从零做一个MVP
2.1 什么是MVP,为什么它适合作为第一次的目标
MVP(Minimum Viable Product,最小可行产品)指用最少的功能量跑通"核心价值闭环"的可用产品。判断一个 MVP 是否合格,看两条:砍掉任何一块功能,它就不再解决核心问题;留下的每一块,都直接服务于核心价值。
举一个具体的例子:一个记账应用,核心问题是"钱花到哪去了"。它的 MVP 只需要两个功能——记一笔支出、看本月合计;分类统计、预算预警、多账本同步这些功能都很有价值,但砍掉它们,"记一笔、看总额"依然完整回答了核心问题,所以它们都不属于 MVP。
把 MVP 作为第一次 AI 编程的目标,有五个具体的好处:
| 维度 | MVP 的表现 | 说明 |
|---|---|---|
| 范围最小 | 核心闭环一页纸说清 | 功能数量被压到下限,需求描述与认知负荷都最低 |
| 模式常见 | AI 生成质量高 | 小工具、小服务是训练语料中最常见的软件形态,生成代码的规范度高 |
| 验收客观 | 用起来立见对错 | 你自己就是第一个用户,操作一遍即知结果 |
| 成果即用 | 立刻进入你的日常 | 做完就能解决自己的一个真实小问题,形成正向反馈 |
| 失败廉价 | 删掉重来 | 没有生产环境与真实用户,错了推倒重来的成本几乎为零 |
其中"验收客观"这一条对新手尤其重要。第一次 AI 编程最容易卡住的地方,是不知道 AI 给的东西对不对;MVP 把功能压到最小,你自己就能完整验证每个行为,对错立见。
2.2 一个最小可行示例
以上面提到的记账应用 MVP 为例,先用 Markdown 写清需求三要素:
# 命令行记账小工具需求
## 功能描述
通过命令行记录日常支出,并随时查看本月合计。
## 输入输出
- 记账:python ledger.py add --amount 25 --note 午餐,输出"已记录 25 元:午餐"
- 汇总:python ledger.py total,输出"本月合计 386.5 元"
## 约束
- 仅用 Python 标准库,数据存 SQLite 文件
- 命令行用 argparse 子命令组织(add、total)
## 验收标准
- [ ] add 记录后,total 能统计到该笔
- [ ] total 只统计当月记录
- [ ] 空数据库执行 total 输出 0
把这份需求交给 DeepSeek Harness,它能直接生成如下核心代码:
import argparse
import sqlite3
from datetime import datetime
DB_PATH = "ledger.db"
def init_db():
# 建表(幂等,可重复执行)
with sqlite3.connect(DB_PATH) as conn:
conn.execute(
"CREATE TABLE IF NOT EXISTS expense ("
"id INTEGER PRIMARY KEY AUTOINCREMENT, amount REAL NOT NULL, "
"note TEXT, created_at TEXT)"
)
def add_expense(amount: float, note: str) -> str:
# 记录一笔支出
with sqlite3.connect(DB_PATH) as conn:
conn.execute(
"INSERT INTO expense (amount, note, created_at) VALUES (?, ?, ?)",
(amount, note, datetime.now().isoformat()),
)
return f"已记录 {amount} 元:{note}"
def month_total() -> str:
# 汇总当月支出
month = datetime.now().strftime("%Y-%m")
with sqlite3.connect(DB_PATH) as conn:
row = conn.execute(
"SELECT COALESCE(SUM(amount), 0) FROM expense WHERE created_at LIKE ?",
(f"{month}%",),
).fetchone()
return f"本月合计 {row[0]} 元"
def main():
parser = argparse.ArgumentParser(description="命令行记账小工具")
sub = parser.add_subparsers(dest="command", required=True)
p_add = sub.add_parser("add", help="记一笔支出")
p_add.add_argument("--amount", type=float, required=True)
p_add.add_argument("--note", default="")
sub.add_parser("total", help="查看本月合计")
args = parser.parse_args()
init_db()
if args.command == "add":
print(add_expense(args.amount, args.note))
else:
print(month_total())
if __name__ == "__main__":
main()
接着按验收标准逐项验证:执行 python ledger.py add --amount 25 --note 午餐,再执行 python ledger.py total 确认合计变化;把系统时间越界的场景留给"只统计当月"这条标准的检验。全部代码零第三方依赖,Python 3.10 以上版本直接可跑。
MVP 的价值顺序是:先跑通核心闭环,再考虑加功能。第一次的目标是体验"需求文档、AI 生成、上手验证"的完整循环,功能多寡在其次;验证通过后你想继续迭代(比如加分类统计),MVP 就自然长成了更大的产品。
2.3 MVP路线练不到的东西
把 MVP 作为第一次的目标,同样要清楚它的局限,避免把"能做 MVP"误当成"能做 AI 编程":
- 练不到读别人的代码:从零项目没有历史包袱,你接触不到"为什么这里写得这么怪"的处境。
- 练不到保护既有行为:没有存量调用方,就无所谓回归风险,也练不出小步验证的习惯。
- 练不到真实用户的约束:MVP 的用户就是你自己,无需协商需求变更,也无需向后兼容,而这些恰是真实项目的常态。
因此,MVP 是很好的第一课,但它只是第一课。它建立的手感需要尽快在更复杂的项目中接受检验,这正是路线B要补的课。
3. 路线B:改造现有庞杂系统
3.1 存量改造的真实价值与真实风险
存量系统改造的价值直接而现实:绝大多数团队的工程人力花在维护与演进上,新项目只占少数;改好一个庞杂系统的某个痛点,收益立刻体现在业务上。对 AI 编程而言,这也是最能体现"人机分工"的场景——AI 读代码、写改动、跑验证,人负责判断与决策。
风险同样集中:
| 风险 | 成因 | 后果 |
|---|---|---|
| 隐含约定 | 大量行为约定存在于配置、脚本与"祖传"调用方中,代码本身看不出来 | AI 改动破坏了看不见的依赖 |
| 上下文有限 | 模型一次能"看到"的代码只是系统的一小部分 | 跨文件、跨服务的连锁影响被忽略 |
| 测试缺失 | 存量系统往往缺少自动化测试 | 改对了没有证据,改坏了没有警报 |
| 伪合理代码 | AI 生成的代码语法正确、风格得体,语义错误难以肉眼发现 | 错误被合并进主干,延迟爆发 |
3.2 为什么AI在庞杂系统里容易翻车
理解 AI 翻车的机理,才能对症下药。核心原因在于上下文窗口的物理限制:模型每次推理能装载的代码量有限,而庞杂系统的关键信息往往散布在远超窗口范围的地方——一个字段的真实含义可能写在三年前的提交说明里,一个接口的隐含调用方可能在另一个仓库。
AI 面对看不全的系统,会基于"最常见的情况"补全它看不到的部分。这在从零 MVP 里通常无害(因为没有"真实情况"可违背),在存量系统里则意味着:它可能按它认为合理的方式"修复"一段你刻意保留的兼容逻辑。
3.3 降低风险的五个做法
如果决定在存量系统上动刀,用以下五个做法把风险压到可接受范围:
- 先读后写:第一阶段只让 AI 输出分析产物——模块结构 Mermaid 图、接口清单、调用关系说明,禁止修改任何代码。这份分析同时校验你对系统的理解。
- 补特征测试:改造之前,先为即将改动的模块编写固化现有行为的测试(characterization tests),把"现在是什么样"钉死。
- 小步提交:一次只改一个模块甚至一个函数,每步通过验证后立即用 Git 提交,保证任何一步都可回滚。
- 圈定范围:在需求文档中写明"禁止触碰"清单,如核心表结构、支付链路、权限校验模块,并把该文档置于项目上下文中让 AI 始终可见。
- 人审关键路径:数据写入、金额计算、鉴权相关的代码差异必须逐行人工审查,这部分不信任任何"看起来没问题"。
特征测试的写法示例,以固化一个用户接口的现有行为为例:
def test_get_user_existing(client, sample_user):
# 固化现有行为:存在用户时返回 200 与固定字段集合
resp = client.get(f"/api/users/{sample_user.id}")
assert resp.status_code == 200
assert resp.json()["name"] == sample_user.name
assert set(resp.json().keys()) == {"id", "name", "email", "created_at"}
完整的改造工作流如下:
3.4 改造任务的分级
并非所有改造任务的风险都一样。把任务按风险分级,能帮你判断哪些适合现在交给 AI,哪些需要攒够经验再说:
| 风险等级 | 典型任务 | 是否适合第一次 |
|---|---|---|
| 低 | 补注释、补测试、抽取公共函数、统一格式、修复明确报错 | 适合 |
| 中 | 单模块内部重构、接口实现替换、局部性能优化 | 有条件适合,需完成第3.3节全部动作 |
| 高 | 跨模块数据流变更、核心表结构变更、并发模型调整、鉴权体系改动 | 不适合,需资深工程师主导并完整评审 |
一个务实的起步方式是:第一次存量改造只做"低风险 + 明确验收标准"的任务,比如"为某个模块补齐单元测试"。这类任务出错代价小、验收客观,练的是流程,风险却是全流程里最低的。
4. 五问决策框架
4.1 五个问题
面对一个具体的目标应用候选,依次问自己五个问题,答案会自然指向其中一条路线:
| 序号 | 问题 | 偏向路线A的回答 | 偏向路线B的回答 |
|---|---|---|---|
| 1 | 验收标准能否在一页纸内写清? | 能,边界清晰 | 难,牵一发动全身 |
| 2 | 出错的代价是否可承受? | 可丢弃、可重来 | 影响生产或他人 |
| 3 | 你是否熟悉目标系统的地形? | 一知半解或全新 | 熟悉多年 |
| 4 | 有没有现成的验证手段? | 用一遍即知 | 需要先补测试才能验证 |
| 5 | 两周内能否拿到可用成果? | 能 | 周期以月计 |
判定方法:第 1、2 问任一为"否",直接选路线A——边界不清加上失败不可承受,是新手项目的致命组合。第 3、4 问决定路线B的可行性:系统地形熟悉且验证手段就位,改造才具备开工条件。第 5 问用于校准预期,避免把一个实质上的长期工程当成"第一次练手"。
4.2 决策流程图
再回到本流程评估] Q3 -->|是| Q4{两周内能出可用成果} Q4 -->|否| A Q4 -->|是| B[选路线B:存量系统改造] style S fill:#e8f4f8,stroke:#1a6b8a,stroke-width:2px style A fill:#d5f5e3,stroke:#27ae60,stroke-width:2px style B fill:#fadbd8,stroke:#c0392b,stroke-width:2px style P fill:#ffecd6,stroke:#e67e22,stroke-width:2px
注意流程图中的节点 P:它对应的动作(补测试、画结构图)本身就是路线B的低风险任务,是两条路线之间的天然桥梁。当你的候选项目卡在这里,先做这些准备工作,做完再评估一次。
4.3 推荐的进阶路径
综合两条路线的能力模型,推荐按以下顺序安排你的前几次 AI 编程:
MVP小工具
建立协作手感] --> S2[第二次
中型新项目
如FastAPI应用] S2 --> S3[第三次
存量系统低风险改造
补测试抽函数] S3 --> S4[进阶
存量核心模块改造
在评审保护下进行] style S1 fill:#d5f5e3,stroke:#27ae60,stroke-width:2px style S2 fill:#d6eaf8,stroke:#1a6b8a,stroke-width:2px style S3 fill:#ffecd6,stroke:#e67e22,stroke-width:2px style S4 fill:#fadbd8,stroke:#c0392b,stroke-width:2px
各阶段的配套教程:MVP 起步参考本教程第 2 节即可,零依赖直接可跑;中型新项目参见Python+FastAPI在Windows环境下创建一个基础后端服务教程;版本控制基础参见Git的安装与基本使用教程,它是存量改造阶段安全网的地基。
5. 两条路线的共同前提
5.1 需求文档先行
无论选哪条路线,动手指令之前先有需求文档。路线A的文档重点是功能描述、输入输出与验收标准三要素;路线B的文档还要额外写清改造范围、禁止触碰清单与回滚预案。文档的具体写法与模板,参见一个好的需求文档应该是什么样的?。
5.2 版本控制是安全网
路线A里 Git 是好习惯,路线B里 Git 是生死线。开始改造前确认:仓库有远端备份、当前分支干净、你熟悉回滚命令。AI 改动必须全部经过提交节点,禁止在长时间不提交的状态下叠加修改。
5.3 AI是能力很强的实习生,责任在人
两条路线共享同一条元规则:AI 负责产出,人负责判断。验收标准由人定,结果由人验证,合并由人批准。把这条规则刻进习惯,路线A的成果会更快,路线B的风险会更低。工具层面的协作机制(上下文、权限、执行循环)的原理说明,参见Harness概念详解。
6. 总结
6.1 核心内容回顾
- 第一次 AI 编程的目标应用应当满足边界清晰、验证容易、失败可承受、周期短四个条件。
- 路线A(MVP):范围最小、模式常见、验收客观、失败廉价,适合作为第一次的目标,但练不到读代码、护行为与应对真实用户的能力。
- 路线B(存量庞杂系统改造):价值直接,风险集中在隐含约定、上下文限制、测试缺失与伪合理代码,需要先读后写、特征测试、小步提交、圈定范围、人审关键路径五个动作护航。
- 五问决策框架:验收可写清、出错可承受、地形熟悉、验证就位、两周出成果,按序自问,答案自然指向路线。
- 推荐路径:MVP 小工具、中型新项目、存量低风险改造、核心模块改造,逐级上难度。
6.2 常见问题与解答
问:我手头正好有存量系统要改,又想从 MVP 练起,怎么安排?
答:两者不冲突,按顺序做。先用一两周完成一个小 MVP 建立手感,再回到存量系统,从低风险任务(补测试、抽函数)起步。直接跳过第一阶段并非不可行,但你为流程错误付出的返工成本,大概率超过省下的这一两周。
问:AI 改动存量系统后编译通过、测试也过了,还能出什么问题?
答:能。编译与测试只能覆盖你想到的行为,存量系统的危险在于没被测试固化的行为——某个下游系统依赖的隐含字段顺序、某个定时任务假设的接口耗时。这正是第3.3节强调特征测试与禁止触碰清单的原因:先把"现在是什么样"钉死,再允许改动。
问:MVP 和练手玩具项目的区别是什么?
答:区别在核心价值闭环与验收标准。玩具项目以"跑起来"为目标,做完即弃;MVP 以"解决一个真实问题"为目标,有明确的验收标准,做完你会真的用它。同样是记账工具,随手写的演示脚本算玩具,能替代你手工记账的那个才算 MVP。
问:MVP 验证通过后,要继续迭代成完整产品吗?
答:由它是否仍解决你的问题决定。继续解决,就按需求文档逐个功能迭代下去;不再解决(问题消失或你有了更好的工具),果断归档,这次练手的价值已经全部拿到。第一次的目标是走通流程,产品的命运是第二位的事。
举手提问