你发现没有,现在聊AI Coding的人已经分成两种:一种还在问“AI到底能不能正经写代码”,另一种已经把项目从需求到上线全跑完了。我属于后者。过去两个月,我用一套自己总结的工作流跑通了一个真实项目,这套工作流我给它起了个名字,叫“即先AI Coding”。
这里的“即先”不是某个工具的名字,而是一种工作方式:不是等自己想明白再动手,也不是把AI当自动补全用,而是每一个环节都先让AI交出一版初稿——需求分析稿、技术方案稿、代码稿、测试稿、部署稿——然后由我来做评审和裁决。如果你把“AI全搞定”理解成“全程无人看管”,那多半会翻车;正确理解是“全流程有人把关、由AI垫底执行”。下面我会用一个会议室预约系统的例子,把我实际用到的Prompt、数据模型、排障过程和踩坑点都摊开讲,适合正在试用AI编程工具的独立开发者、全栈工程师,以及想提升小团队交付效率的团队负责人。
1. AI Coding不是自动补全,是一整个“虚拟开发小组”
1.1 从“补全下文”到“Agent式干活”
早期AI编程工具大家都用过,本质是“下一行预测”,光标停在那里,AI帮你补一个函数名、补一段样板代码。这种用法省事,但没有改变开发流程,AI更像一个高级输入法。
但现在的AI Coding工具已经变了。我常用的方式是:给AI一个任务描述,它能自己读取项目目录、搜索相关文件、生成改动计划、改完以后自己跑测试,再把报错拿回来修。这个形态已经不是“补全”,更像是有一个“虚拟开发小组”在你机器上开工。“即先AI Coding”的核心理念也是从这里来的:既然AI已经能整包干活,那就让它承担“先写第一版”的角色,人不再逐行敲基础逻辑,而是做需求定义、技术评审和最终验收。
1.2 它能干什么,不能干什么
AI Coding现在的边界在哪里?我按自己实际跑项目的经验做了个划分:
- 能干的:内部管理系统、MVP原型、活动落地页;数据报表、后台管理、批量脚本;给已有项目补测试用例、修bug、做模块重构;生成Dockerfile、CI流水线、部署手册。
- 不建议让它单独干的:没有人工review就直接上生产的核心交易链路;需要严格审计、强合规、强低延迟的场景;完全没人理解业务边界和影响范围的“黑盒交付”。
我把AI当成“能力很强、但经验判断不足的实习生”来用。它执行力强,可如果方向错了,会一本正经地把错的方向执行完。所以人负责“方向感”,AI负责“把方向快速变成代码”。这个定位想清楚后,后面每一步的工作方式都会顺很多。
2. 需求阶段:把一句“我想做个会议室预约”变成AI能执行的任务书
2.1 让AI先当“需求分析师”,而不是急着写代码
很多人拿到需求就急着说“帮我写个会议室预约系统”,AI会顺着话头猜,写出来自然跑偏。我的做法正好相反:先让AI把需求结构化成任务书,再谈写代码。
最初的原始需求只有一句话:“我要做一个内部用的会议室预约系统,能看到哪些房间空着,谁预约了,预约了还能取消。”我把这句话原样丢给AI,指令是:
请把下面这段原始需求整理成结构化需求文档。 要求: 1. 按“用户故事 / 验收标准 / 隐藏假设”三类输出; 2. 用户故事要覆盖普通员工可能的所有操作路径; 3. 验收标准必须可以验证,不能出现“友好、流畅”这类形容词; 4. 最后向我提出至少10个澄清问题,帮助我确认边界。AI给的输出比我想象中靠谱,关键几则用户故事是这样的:
- 作为员工,我想查看未来7天所有会议室的空闲时段,以便快速锁定可用的会议室。
- 作为员工,我想提交一个指定时间段的预约申请,以便安排团队会议。
- 作为员工,我想取消自己发起的、尚未开始的预约,以便释放资源。
- 作为管理员,我想查看所有预约记录,以便处理异常占用的会议室。
验收标准也落地了很多,例如“若时间段与已有预约冲突,系统应拒绝并提示冲突的预约ID与时间段”“员工只能取消自己创建的预约”“会议室列表为空时展示空状态提示”等等。原来我脑子里只有个大方向的“预约系统”,被AI这么一拆,忽然清楚多了。
2.2 用“反向提问”逼出隐藏假设
这个环节是价值最高的。AI提的澄清问题里,有几条我一开始完全没想过:
- 是否所有员工都能预约所有会议室,还是按部门限制?
- 预约是否需要管理员审批?审批通过前算不算占用?
- 预约时间粒度是按小时、30分钟还是15分钟?
- 会议超时未结束,下一场预约怎么处理?
- 取消预约有没有时间限制,比如开始前30分钟内不允许取消?
这些就是典型的“隐藏假设”。如果跳过这一轮直接写代码,后面至少要返工两三次。我挨个回答了之后,又让AI根据答案生成一个里程碑式的迭代计划:
- M1:会议室列表 + 空闲查询 + 预约 + 取消,先跑通主流程。
- M2:预约冲突校验 + 管理员审批流 + 预约记录管理。
- M3:导入公司组织架构、按部门控制权限、会议室状态看板。
到这里,一个可以执行的“任务书”就有了。我把它存成项目根目录的REQUIREMENTS.md,后面每一轮开发开始前,都把对应段的验收标准回贴给AI,确保它不会在执行过程中自己加戏。
3. 技术选型与数据建模:让AI先出方案,人只做裁决
3.1 让AI做“技术选型报告”
需求清楚了,下一步是技术选型。我的原则是:不要让AI直接拍脑袋给答案,而是先给它约束条件,让它产出可对比的方案,再做裁决。
我当时给的约束是这样的:
我要开发一个公司内网用的会议室预约系统。 约束条件: 1. 团队熟悉Python,不引入Java/Go; 2. 预估用户量100人以内,不需要高并发; 3. 交付周期两周,代码要容易维护; 4. 部署在内网服务器,不希望依赖外部云服务; 5. 需要数据库存预约记录。 请给出3个技术栈组合,输出一张对比表,包含:开发效率、部署复杂度、扩展性、维护成本、是否适合本场景。最后给出你的推荐和理由。AI给的对比表大致如下:
| 方案 | 技术栈 | 开发效率 | 部署复杂度 | 扩展性 | 适合场景 |
|---|---|---|---|---|---|
| A | FastAPI + SQLite | 高 | 极低 | 低 | 小型内网工具 |
| B | FastAPI + PostgreSQL | 高 | 中 | 中 | 长期演进的内网业务 |
| C | Django + PostgreSQL | 中高 | 中 | 中 | 需要内建后台管理 |
| D | Flask + MySQL | 中 | 中 | 低 | 旧团队迁移场景 |
我最后选了方案B,理由很实际:SQLite确实部署最简单,但预约数据有强一致性要求,而且后续大概率要扩展统计报表,PostgreSQL能省掉很多坑。这一步的价值在于,AI把备选项、成本和权衡一次性摆在了桌面上,“拍板”这件事仍由人来做。
3.2 数据模型先画出来,再让AI当评委
技术栈定了,我让AI按照REQUIREMENTS.md里的验收标准,先设计数据模型,不急着写业务接口。它给的表结构非常直接,核心就三张表:
CREATE TABLE rooms ( id SERIAL PRIMARY KEY, name VARCHAR(100) NOT NULL, capacity INT NOT NULL, location VARCHAR(200), has_projector BOOLEAN DEFAULT FALSE, is_active BOOLEAN DEFAULT TRUE ); CREATE TABLE users ( id SERIAL PRIMARY KEY, email VARCHAR(255) UNIQUE NOT NULL, name VARCHAR(100) NOT NULL, department VARCHAR(100), role VARCHAR(20) DEFAULT 'employee' ); CREATE TABLE bookings ( id SERIAL PRIMARY KEY, room_id INT NOT NULL REFERENCES rooms(id), user_id INT NOT NULL REFERENCES users(id), start_time TIMESTAMP NOT NULL, end_time TIMESTAMP NOT NULL, status VARCHAR(20) DEFAULT 'pending', created_at TIMESTAMP DEFAULT NOW() );三张表其实已经能覆盖核心流程。但让AI当评委时,它又抛出了几个边界问题:跨天预约怎么处理?start_time和end_time是允许跨天还是按天分拆?冲突检测要不要考虑“某预约结束时间等于另一预约开始时间”这种情况?这些问题直接影响了后面check_booking_conflict函数的实现。数据建模这步没省掉,直接让后面编码阶段少走了很多弯路。
4. 编码闭环:一条四段式Prompt,把我从反复改代码里解放出来
4.1 目标、约束、交付物、验收,四段缺一不可
编码阶段最常见的错误是把需求说得太模糊,比如“帮我写个接口,检测会议室时间冲突”。AI跑出来的代码十有八九只是简单查询,边界根本没处理。我后来固定下来一套四段式Prompt模板,用了很久,效果很稳:
目标:在 booking_service.py 中新增一个函数 check_booking_conflict(room_id, start_time, end_time, exclude_booking_id=None)。 约束: - 项目使用 FastAPI + SQLAlchemy 2.0,ORM模型已存在; - 时间类型为 datetime; - 调用方需要在冲突时拿到冲突预约的ID列表,而不是只返回布尔值; - 不允许全表加载到内存再判断,必须用数据库查询解决。 交付物:函数代码 + 最小单元测试文件 tests/test_booking_conflict.py,测试数据用简单工厂构造。 验收:运行 pytest tests/test_booking_conflict.py -q 全部通过。同样的需求,改造前和改造后,AI的行为差别非常大。改造前它可能给你一个SELECT * FROM bookings WHERE ...然后自己慢慢过滤的把法,这在数据量小的时候没问题,但本质上是逃避数据库设计。改造后它知道要用区间重叠条件,更贴近生产环境。
4.2 给AI建一套“项目记忆”
AI的上下文窗口再大也有限,一个新会话开始后,它并不会记住你昨天聊过的所有内容。我的做法是在项目根目录维护几个固定文件:
PROJECT_CONTEXT.md:记录技术栈、目录结构、启动命令、关键约定;REQUIREMENTS.md:记录需求文档、用户故事、验收标准;CODE_STYLE.md:记录命名规范、错误处理方式、日志风格;DEBUG_LOG.md:记录历史bug的原因和修复方案。
每次新开会话,我做的第一件事是让AI读取这四个文件,再开始干活。成本很低,但AI给出的代码风格会空前一致。有一次我忘了做这步,结果AI在同一个文件里一会儿用save()一会儿用insert(),命名也是create_booking和add_new_booking混着来,非常痛苦。
4.3 让AI先行代码审查
代码写完之后,AI的活还没完。每次提交前,我会把Diff整个丢给它,要求它按四个维度找问题:
请审查下面这段diff,按这四类问题输出: 1. bug风险:逻辑错误、边界条件没覆盖; 2. 安全性:SQL注入、权限绕过、敏感信息泄漏; 3. 可维护性:命名混乱、重复代码、职责不清; 4. 性能问题:不必要的N+1查询、内存占用过大。有一次它抓出了一个特别隐蔽的问题:我的预约取消接口只判断了user_id和预约信息是否匹配,但没有判断预约状态是否为pending或confirmed。如果预约已经开始或者已经结束,员工依然能“取消”,这在业务上是不允许的。这种细节让我自己review还真不一定能在第一时间发现。
5. 测试与调试:AI写完的bug,让AI自己修
5.1 “AI生成测试用例”是性价比最高的一件事
很多开发者自己写业务代码还行,一提写测试就头大。AI恰好相反,它特别擅长根据函数签名和需求文档生成大而全的测试用例。以check_booking_conflict为例,我让它先列出应该覆盖的边界场景,它给得很完整:
- 完全空闲时,返回空列表;
- 开始时间落在已有预约区间内;
- 结束时间落在已有预约区间内;
- 新预约完全包含已有预约;
- 新预约的开始时间等于已有预约的结束时间(边界,应不冲突);
- 新预约的结束时间等于已有预约的开始时间(边界,应不冲突);
- 传入
exclude_booking_id时,该预约不参与冲突判断。
然后我让它按这些场景直接生成pytest参数化测试。结果一次跑通,后面改逻辑时回归也特别快。严格来说,这比我自己手写测试还省力。
5.2 调试的正确姿势:把上下文喂够
AI写完代码,测试跑挂很正常。但很多人调试时的姿势是错的,就甩一句“运行报错了,帮我看看”。AI看不到你的运行环境,只能猜。我的做法是把这几样东西一起喂给它:
运行 pytest tests/test_booking_conflict.py -q 后,test_overlap_start 失败。 报错信息: ============ FAILURES ============ tests/test_booking_conflict.py::test_overlap_start - AssertionError: assert [] == [1] 相关代码在 booking_service.py 第42-60行: [把代码贴进来] 调用链是:router -> booking_service.check_booking_conflict -> db.query(Booking). 我怀疑是时间比较的方向写反了,但不确定。请先分析可能原因,再给最小修复补丁。按这种方式,AI基本都能定位到问题。实测下来,AI最擅长修的bug是接口参数不匹配、依赖升级后的API变更、语法错误、组件状态不同步这类“可机械排查”的问题;最怕的是“需求理解本身就错了”导致的bug——这种它改来改去反而会把代码改得更乱。遇到后一种,我的建议是回到需求层对齐,而不是在代码层死磕。
5.3 用DEBUG_LOG.md沉淀历史问题
跑完一个项目后,DEBUG_LOG.md已经积累了不少案例。比如:
- QASQLAlchemy连接池未释放导致内存持续增长;
- 前端日期字符串传成了UTC格式,后端没做时区转换;
- 钉钉机器人回调签名校验失败,原因是消息体用JSON字符串化了两遍。
这些经验沉淀下来,再遇到类似问题,直接把DEBUG_LOG.md丢给AI当参考,它的修复建议会准确很多。这也是“即先AI Coding”里面容易被忽略但很关键的一环:AI的长期记忆是靠这些项目文件实现的,不是靠对话历史。
6. 部署上线:AI能写出能跑的部署文件,但验收线要握在手里
6.1 从“编写”Dockerfile到“审查”Dockerfile
部署这块,我基本不手写部署文件了。让AI根据项目技术栈生成多阶段Dockerfile,外加docker-compose编排,效率高得离谱。前端Vite构建产物直接打进后端静态目录,一条命令就能启动整个服务。
一个典型的多阶段Dockerfile长这样:
FROM node:20-alpine AS frontend-builder WORKDIR /app COPY frontend/package*.json ./ RUN npm ci COPY frontend/ ./ RUN npm run build FROM python:3.12-slim WORKDIR /app COPY backend/requirements.txt ./ RUN pip install -r requirements.txt COPY --from=frontend-builder /app/frontend/dist ./static COPY backend/ ./ CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]再用docker-compose把PostgreSQL编排进去:
services: db: image: postgres:16-alpine env_file: .env healthcheck: test: ["CMD-SHELL", "pg_isready -U $POSTGRES_USER"] interval: 5s timeout: 3s retries: 5 volumes: - pgdata:/var/lib/postgresql/data api: build: . ports: - "8000:8000" depends_on: db: condition: service_healthy volumes: - ./data:/app/data volumes: pgdata:这类文件AI只要读一遍PROJECT_CONTEXT.md基本就能一次写对。我真正要花时间的地方,反而在“验收”和“排障”。
6.2 上线前必须人工盯的三个验收项
AI写部署文件有一个特点:它能保证“能启动”,但不保证“能上线”。我在这个项目里总结出三个必须人工把关的验收项:
第一,敏感信息扫描。AI有时候会把数据库地址、密钥、Token硬编码写进配置模板里,甚至顺手提交进代码库。上线前我用一段扫描脚本检查所有env、配置文件和提交历史,任何形如AK/SK、password=、token=的痕迹都不能放过。
第二,数据库迁移确认。AI写的初始化表结构只是“当前可用”,但后面每次改表结构都必须有迁移记录。我让AI生成了Alembic迁移目录,并要求每次数据模型变更必须同时产出对应迁移脚本,否则不merge。这样线上数据结构和代码版本才能对得上。
第三,健康检查与自恢复。容器崩了能不能自动重启?数据库暂时连不上API是直接崩还是重试?这些如果没有配置,光有Dockerfile也是白搭。我会要求AI把healthcheck、restart策略、日志落盘一并配置好再谈上线。
6.3 一个真实排障:容器内存持续走高
这个项目上线后遇到过一个典型问题:服务跑两天,容器内存一路涨到接近上限,重启之后又正常,周而复始。我没有直接去看代码,而是先把本地的线程dump和内存统计丢给AI,限定范围让它排查。
AI定位到SQLAlchemy的连接池没有正确释放。每次请求都会创建新的数据库连接,连接池默认行为又没有回收策略,长期运行自然越来越慢。修复方式就是在数据库引擎里加上:
engine = create_engine( DATABASE_URL, pool_size=5, max_overflow=10, pool_pre_ping=True, pool_recycle=3600 )同时,FastAPI在shutdown事件里调用engine.dispose()。改完以后内存曲线平稳多了。这种问题在没有AI辅助时花半天都可能找不到,现在把日志和数据一贴,它很快能给出方向。这进一步验证了我那套“先让它写、我再来查”的工作流是成立的。
7. 单独说说两个话题:踩过的坑,和面试里怎么聊AI Coding
7.1 六个最常见的坑,以及怎么绕开
AI编程远不是“全程躺赢”,我也踩过不少坑。整理一份最常见的,一条条说清楚:
| 现象 | 根因 | 对策 |
|---|---|---|
| AI用了不存在的API,代码跑不起来 | 模型记住了旧版SDK或自己“编造”方法 | 明确要求它“只使用项目依赖中已安装的包”,并让它自查版本 |
| 对话长了以后开始乱改无关代码 | 上下文窗口里的约束失效 | 新开会话,重新加载项目记忆文件,拆小任务 |
| 无意识删掉“看起来没用”的样式或函数 | 对任务理解过窄 | 让它先输出改动计划,再手动确认改动范围 |
| 需求变更后被要求直接改数据模型 | 忽略数据迁移约束 | 增量变更,每次先出迁移脚本再动表结构 |
| 生成的代码里出现硬编码密钥 | 模型从示例中复制 | 提交前扫描所有敏感字段 |
| AI自己写测试,自己也通过 | 测试和实现同源缺陷 | 引入少量变异测试思路,让它故意改错几处再跑 |
这些坑基本属于“流程可以规避”的类型。只要每一步都保留人工验收,问题不会被带到生产环境。
7.2 面试被问AI Coding,怎么展开回答
最近“AI Coding答题思路”在技术圈聊得很多,我也被几个朋友问过面试该怎么讲。我的建议很简单:不要背概念,用真实项目经验展开。一个稳妥的叙事框架是:
- 项目背景:什么业务、什么技术栈、多大规模、交付周期多长;
- 我的用法:需求分析、技术选型、编码、测试、部署,每个环节AI具体承担了什么;
- 效率对比:相同类型的功能以前大概要多久,现在要多久;
- 风险规避:设置哪些验收关卡,如何防止AI乱写乱改;
- 踩坑与复盘:挑一个具体问题,讲清楚现象、定位思路和修复方案。
比如你可以这样讲:“我在一个预约系统里让AI负责冲突检测的编码,我提供四段式Prompt,它生成实现和测试。发现边界用例没覆盖后,我让它先列举所有边界场景再写用例,最终把问题收敛了。”这一句话,既体现了你会用AI,也体现了你会驾驭AI。面试官真正想看的其实就这件事。
写在最后的一点个人体会
整套流程跑下来,我最深的感受是:AI Coding带来的不是“不用写代码”,而是“把写代码这件事的起点变高了”。过去完成一个功能,最耗时间的往往是从空白文件到第一版能跑的代码;现在这段路AI走得比人快得多,真正拉开差距的反而是需求分析、技术评审、验收把关这些“人在回路”里的事。
所以我现在的态度很明确:大胆用,但永远保留一个能看懂全部代码的人。AI负责把“想清楚的事”快速变成第一版,人负责把“还没想清楚的事”想清楚。
如果你想完整跑一遍这套“即先AI Coding”工作流,我的建议是别从大项目开始。找一个两周内能交付的内部小工具,严格按照需求拆解、方案裁决、四段式Prompt、测试验收、部署上线这个顺序走一遍。走完以后,你会形成自己的节奏,也会比我更快找到这套方法里哪些环节最值得你投入时间。