直接用 AI 写出来的 Web 应用,离“高品质”还差着十万八千里。我说的高品质,不是能跑就行,而是可维护、可测试、可部署、有安全底线、有可访问性,是真能上线给用户用的产品级代码。过去一年我用 AI 辅助做了几个完整的 Web 项目,从需求分析到部署上线全程参与,踩了不少坑,也总结出一套相对稳定的工作流。这篇文章就是把这段实战经验掰开揉碎,讲讲 AI 在 Web 应用开发里到底该怎么用,以及那些 AI 不会主动告诉你、但你必须知道的事。
先说个反直觉的结论:AI 编程最核心的价值不是帮你写代码,而是帮你做技术决策和发现盲区。很多人把 AI 当成代码生成器,输入需求,输出代码,然后复制粘贴。这么干,十个项目有九个会在中期陷入维护地狱。真正能提升开发效率和代码质量的用法,是把 AI 当成一个全天候在线的资深同事——它可以帮你理需求、画边界、做技术选型、写测试、review 代码、排查线上问题。但这有个前提:你得知道怎么正确地给它下指令,怎么验证它的输出,怎么把它融入整个研发流程。这篇文章就围绕这些展开。
1. 误区:AI 写代码不是拿来即用,而是“初稿提供者”
1.1 我从“让 AI 直接写功能”转向“让 AI 参与设计”的经历
最早接触 AI 编程那阵,我的用法很粗暴:对着对话框说“帮我写一个用户登录系统”,它哗啦啦吐出一大段代码,我用五分钟扫一眼就粘进项目里。快是真快,但问题也接踵而至——那段代码没有做输入校验、没有处理并发登录的 session 冲突、SQL 语句直接字符串拼接,放在内网 Demo 里没事,放在公网环境分分钟出事。
后来我慢慢摸出一个更靠谱的定位:把 AI 当“初稿提供者”,而不是“最终交付者”。它生成的代码,本质上等于一个能力不错但经验不足的同事写出的第一版。这版代码的价值在于:它帮你快速建立了逻辑骨架,提供了可讨论的基准线,让你能在此基础上做审查、优化和测试。真正的工作,是从拿到 AI 初稿之后才开始的。
这个改变有多重要?我举个例子。有一次我需要实现一个 OAuth2.0 授权码模式的第三方登录对接,理论上流程很标准:跳转授权页 → 回调拿 code → 用 code 换 token → 拉取用户信息。AI 一次性就写完了全部流程,逻辑看起来天衣无缝。但当我真去测的时候,发现它没有处理 state 参数的校验,这会导致 CSRF 攻击——攻击者可以诱导用户点击一个构造好的授权回调链接,让应用错误地绑定攻击者的第三方账号。这个漏洞在浏览器端几乎无法用肉眼从普通测试中发现,却真实存在于 AI 生成的代码里。
所以从那之后,我给自己定了一个规矩:AI 的产出必须经过和人工代码同等级别的 review、测试、安全审计。它提供的不是“答案”,而是“效率”——省去从零到一的打字过程,但省不了思考过程。这个认知是整个工作流的地基,地基不牢,后面全白搭。
1.2 为什么“AI 半成品”才是常态:上下文、需求、代码评审的缺失
有人可能会问:为什么不把需求描述得足够详细,AI 就能给出能用的高质量代码?这个问题的核心在于,AI 模型本质是一个基于概率的文本生成器,它并不真正“理解”你的项目上下文。它没有打开过你的数据库结构、不知道你的用户量级、不了解你的团队规范、也不清楚你的部署环境。你给它一个精确到函数级别的需求描述,它确实能写得很好,但你仍然要人肉去验证这个函数是否真的满足业务约束。
# 示例:AI 生成的用户注册接口,看着没问题但缺少基础防护 @app.route('/register', methods=['POST']) def register(): username = request.form['username'] password = request.form['password'] # 缺少:用户名/密码长度校验、密码强度校验、密码哈希策略确认 # 缺少:注册频率限制(防机器人刷接口) # 缺少:数据库唯一约束冲突处理 user = User(username=username, password=password) db.session.add(user) db.session.commit() return 'success'上面这段代码,表面上是能跑的,但任何一个资深后端看到都知道它离生产级别还差着事儿。AI 生成这种代码不是因为它笨,而是因为它在训练数据里见过太多类似的“教学示例代码”。如果你不主动在提示词中明确“这是生产级项目,需要对密码进行 bcrypt 哈希,需要处理数据库 IntegrityError,需要加入限流”,它默认给出的就是教学范式。
另一个容易被忽略的问题是代码评审的缺失。人工写的代码,在提交之前会经过同事的 Review,Review 过程能发现并发问题、异常处理遗漏、命名混乱等。AI 生成的代码如果直接绕过这个环节,等于把风险全部后置到了测试和上线阶段。所以我现在的工作流里,AI 写出的关键模块必须再过一次“AI 评审 + 人工确认”的双重关卡,这个我们后面章节细说。
2. 把 AI 当“第二个大脑”:需求澄清与架构设计阶段怎么用
2.1 用 AI 做需求澄清与边界梳理
很多人觉得 AI 在开发流程中只能做编码阶段的工具,这是一个很大的认知偏差。实际上,AI 在需求分析阶段能发挥的作用,远比写代码更重要,也更容易被低估。
拿一个实际场景举例。客户说“我要做一个博客系统”,如果直接把这个需求丢给 AI 写代码,它三五分钟就能给你生成一个带 CRUD 的博客程序。但你稍微追问一下需求细节就会发现很多空白:用户是否需要注册和登录?是开放注册还是管理员创建?文章的富文本编辑器支持哪些格式?是否需要评论、点赞、标签、搜索?需不需要草稿和定时发布?这些模糊地带如果不在写代码之前澄清,开发到中期必然会返工。
我的做法是把 AI 当成“需求追问机器人”:
提示词模板:我在开发一个博客系统,目前的用户角色是普通访客和管理员。请帮我梳理一套完整的需求澄清问题清单,覆盖用户管理、内容管理、互动功能、安全和性能等维度,尽量具体,每个问题都需要包含“为什么需要这个问题”的说明。
这样做的好处是,AI 能根据它见过的海量相似项目经验,快速生成一版覆盖度很高的需求问题列表,你再结合自己的业务知识筛一遍,几乎能补齐 90% 的隐含需求。这比从零开始开需求评审会高效得多。而且 AI 在梳理边界的时候往往能提示一些容易忽略的法律合规问题,比如 GDPR、用户隐私政策、cookie 同意弹窗等,虽然这些提示需要人工确认,但至少给团队提了个醒。
2.2 技术选型对比与权衡:让 AI 给选项,而不是给结论
技术选型是另一个 AI 能帮上大忙的环节。刚入行的开发者经常犯一个错误——问 AI “Django 和 Flask 哪个好”,然后 AI 给出一个“都很好,取决于需求”的和稀泥答案,看完等于没看。这不怪 AI,是提问方式不对。
更高效的问法是给 AI 一个决策矩阵,让它帮你分析不同技术方案的权衡点:
提示词模板:项目是一个面向中小企业的内部管理系统,预计 20 个并发用户,团队 3 人,开发周期 1 个月,团队成员熟悉 Python。请对比 Django、Flask、FastAPI 三个框架,从开发效率、数据库迁移、Admin 后台、异步支持、学习曲线、生态成熟度六个维度进行比较,最后给出推荐方案和理由。
这个 Prompt 的妙处在于,你给 AI 设定了具体的项目约束(用户规模、团队人数、开发周期、技术背景),它就不太可能给出那种“都挺好”的答案,而是会基于这些约束做具体分析。技术选型的本质不是选一个“最好的”,而是选一个“在给定约束下风险最低的”,AI 在收集和对比权衡信息这方面有天然优势。
选型完成后,还有一个容易忽略的环节——让 AI 帮你编写技术方案文档。框架定了,数据库是 PostgreSQL 还是 MySQL?缓存要不要上 Redis?部署是用 Docker 还是裸机?这些决策都应该在编码前形成一份文档。AI 可以快速生成技术方案的初稿,包括架构图文字描述、数据表设计、接口设计草案。虽然架构图它画不出来,但你完全可以把它输出的结构描述复制到图表工具里去画。这一步做完,后面开发就是照着图纸施工,效率和返工率都得到了显著改善。
3. 提升 AI 生成代码质量的提示词技巧
3.1 上下文注入:让 AI 理解“你的项目”而不是“一般项目”
同一个问题,AI 给出的答案质量可以天差地别,关键在于你给它多少有效上下文。这是我这一年来最深刻的体会之一。所谓“有效上下文”,不只是“我有个电商项目”这种一句话背景,而是让它理解你的技术栈版本、目录结构、既有代码风格、约束条件等。
我试过两种问法的对比,效果非常明显:
低质量问法:
帮我写一个用户注册接口。
高质量问法:
项目是 Django 4.2 + PostgreSQL 15,用户模型已定义,数据库迁移已经完成。views.py 里已有 login_view 和 logout_view,风格是函数视图而不是类视图。请帮我写一个 register_view,要求:1)接收 POST 请求,参数为 username、email、password、password_confirm;2)用 Django 内置的 UserCreationForm 做表单校验;3)用户名和邮箱需要检查唯一性,冲突时返回 JSON 错误信息;4)成功创建用户后自动登录并返回 JSON 成功信息;5)异常统一用 JsonResponse 返回。
后者生成代码的可直接使用率,比前者高出好几个量级,而且几乎不需要大幅重构。核心原因很简单:AI 没有眼睛,它只能通过你给的信息来推测“上下文”。你把细节喂得越足,它就越贴近你的实际情况。
还有一个提升上下文质量的小技巧——直接把现有文件粘贴进对话。比如让 AI 修改某个函数时,先贴出这个函数所在的文件全部内容或至少是相关片段,别人就能根据实际代码风格生成,而不是凭猜测写一个全新风格。听起来像废话,但真的很多人在用 AI 写代码时都默认它能“记住”之前的对话。大窗口确实能记住更多,但跨会话、跨项目它是不记得的。每次新开对话,都把必要上下文重新交代一遍。
3.2 编码规范与检查清单:用“规则卡”约束输出
AI 生成的代码,默认风格非常“教科书”——擅长写执行路径,不擅长处理边缘情况。一个有效的解决手段,是给 AI 建立一份“规则卡”,让它在生成代码前先承诺遵守这些规则。
我在项目开始时,会花十分钟整理一份项目专属的规则卡,内容大致如下:
- 所有数据库操作必须使用 ORM,禁止裸 SQL 拼接。
- 所有对外 API 必须返回统一 JSON 结构:
{"code": 0, "message": "ok", "data": ...}。 - 密码字段必须使用 bcrypt 哈希,禁止明文存储。
- 涉及用户输入的校验在视图层完成,业务校验在 service 层完成。
- 所有操作数据库的函数必须使用事务装饰器。
- 所有耗时操作(>500ms)必须记录日志。
- API 路由命名遵循
/api/v1/前缀规范。
然后每次让它写代码之前,就说一句“请遵守 project_rules 中的规则生成代码”,并附上规则文本。实测下来,生成结果靠近生产代码规范的概率显著提升,尤其是在异常处理、参数校验、日志记录这些 AI 默认容易忽略的维度上。
你可能觉得每次都贴规则卡很麻烦,但现在主流 IDE 插件都支持配置自定义提示词模板,比如 Cursor 的 Rules、其他编程助手的注记文件等。把这些规则写进项目的根目录配置里,AI 每次自动携带,不用手动复制。这一步做与不做,就是“AI 帮你写玩具”和“AI 帮你写生产代码”的分水岭。
3.3 从“一次性生成”到“迭代式对话”的代码生产方式
刚用 AI 写代码的人,习惯一次性把需求全倒给它,期望一次输出完美代码。事实证明,这个期望几乎不可能实现。AI 不是超人,它同样会受到“上下文窗口有限”的制约——需求描述得越长,它在代码里遗漏细节的概率越大。
更靠谱的方式是把开发拆成多个小步骤,一步步推进:
- 先让 AI 给出接口的数据结构和函数签名。
- 确认无误后,让它实现函数体。
- 再让它补充异常处理和边缘情况。
- 最后让它写单元测试用例。
每一步都基于上一步的产出,而不是一次生成终稿。这个“迭代式对话”的方式,既降低了单次任务的复杂度,也让每一步有明确的验证节点,你可以随时判断方向是否正确并及时纠正,避免跑偏后大规模返工。有点像开车——你不会闭着眼睛一把油门踩到终点,而是看着路况不断微调方向。AI 编程也一样,小步快跑,随时校准。
4. AI 代码的审查与测试:守住“高品质”底线
4.1 安全审查:别让 AI 给你留后门
AI 生成代码的安全问题,是最需要警惕、也最容易被忽视的。不是说 AI 会故意留后门,而是它训练数据里的“教学代码”大量存在安全问题,模型有样学样。
最常见的几类问题包括:
- SQL 注入:字符串拼接查询条件,而不是使用参数化查询。
- 脆弱的认证逻辑:token 校验不完全、session 固定攻击、密码明文存储。
- 缺失访问控制:接口只做了登录校验,却没区分普通用户和管理员权限。
- 不安全的文件处理:允许用户传任意类型文件并直接放在静态目录下。
- SSRF(服务器端请求伪造):允许用户传入 URL 让服务器去请求,但没做内网地址过滤。
我的审查方法是让 AI 自查 + 人工重点确认:
提示词模板:请以安全专家的视角审查上述代码,重点关注 OWASP Top 10 中的漏洞模式。输出格式:漏洞位置、漏洞类型、攻击场景、修复建议。
这是个非常有效的安全审查提示词。AI 的安全审计能力虽然不如专业安全工程师,但已经能发现大量常见漏洞模式。更重要的是,它能用通俗的语言解释漏洞原理和攻击场景,这对没有安全背景的全栈开发者来说,本身就是一次很好的安全教育。
不过必须强调:AI 安全审查只能作为第一道筛查,不能替代专业渗透测试。特别是有用户资金、隐私信息、企业核心业务的项目,上线前必须请专业安全团队做完整的渗透测试。AI 帮你把低级漏洞扫干净,专业团队才能集中精力测那些需要业务理解才能发现的深层次逻辑漏洞,这样配合效率最高。
4.2 自动化测试与回归:AI 写出“正确 bug”的场景
AI 生成的代码,有一类特别坑的 bug——它能通过单元测试,但业务逻辑是错的。比如一个计算订单折扣的函数,AI 写出来的逻辑完全符合常规的“整数折扣”场景,但你的业务规则其实是“阶梯折扣 + 会员叠加 + 限时活动优先”,AI 不知道这个规则,自然写不出来正确代码。这种 bug 在单测里测不出来,因为单测用例也是 AI 按同样的错误逻辑生成的——这就是“AI 自证清白”陷阱。
我的应对策略是用例必须人工设计边界条件,AI 只负责实现:
提示词模板:这是我设计的 8 个测试用例,覆盖正常路径、空值、超长字符串、并发请求、权限不足、超时等边界场景。请帮我把这些用例转换成 pytest 代码。
人工设计用例的关键在于:要提前思考“什么情况下这个函数会挂”。比如用户输入NULL怎么办?字符串超过数据库字段长度怎么办?并发请求同一个资源怎么办?权限不足的请求应该返回 403 还是 404?好的测试不是验证代码“能跑”,而是验证代码在“不该跑的时候也会正确拒绝”。
另外特别推荐一个实践——让 AI 生成测试替身(Mock)。Web 应用最麻烦的就是测试外部依赖,比如第三方支付接口、短信服务、外部 API。每次跑测试都真实调用一次既不现实也不稳定。让 AI 分析接口签名,自动生成一个 Mock 对象,预定义好返回值和超时行为,然后你在测试里注入这个 Mock,效率和稳定性都会提升很多,这也是 AI 在测试环节最能发挥作用的地方。回归测试的价值在于,你后续修改代码时能及时发现 AI 新生成的代码是否破坏了已有功能。项目越到后期,这层保护网越重要。
5. 部署、监控与 AI Agent:让 AI 不仅“写代码”,还“管代码”
5.1 自动化部署与基础设施即代码中的 AI 辅助
Web 应用开发出来只是长征第一步,能稳定上线、持续迭代才是“高品质”的完整定义。这块 AI 同样能帮上忙,而且某种程度上比写业务代码更值得用 AI——因为基础设施与部署配置有大量成熟模式,AI 对这些模式的学习效果非常好。
以前写 Dockerfile 和 CI/CD 流水线,我要翻文档、查镜像版本、试错多次才能搞定。现在我会直接向 AI 描述目标:
提示词模板:项目是 Django 4.2 + PostgreSQL 15 + Redis,需要构建一个多阶段 Dockerfile:构建阶段用 python:3.11-slim,安装 poetry 依赖并收集静态文件;运行阶段用 gunicorn 启动,暴露 8000 端口,健康检查路径是 /healthz/。请生成 Dockerfile 和 docker-compose.yml,并说明每个阶段的设计理由。
AI 生成的配置基本能开箱即用,尤其是 New Relic、健康检查、非 root 用户运行、日志输出到 stdout 这些最佳实践,它都能正确集成。如果你自己对 Docker 和部署有基础,可以直接在此基础上调整,完全可以从零搭建的繁琐工作中解脱出来。
CI/CD 流水线的编写也类似。GitHub Actions、GitLab CI 的语法看似简单,但实际跑起来总是在奇怪的步骤上失败——缓存冲突、环境变量缺失、权限不足。AI 对这些 YAML 配置的生成能力很强,你只需要在提示词里说明“在什么事件触发、跑哪些命令、需要哪些秘密变量、构建后是否要自动部署到云服务器”,它就能生成能直接用的流水线配置。
5.2 引入 AI Agent 后的新协作模式
“AI Agent”是最近的行业热词,而它在 Web 应用开发里的实际形态,比想象中更接地气。它不是那种“你说句话,整个 App 就生成了”的神器,而更像是一个能自主完成多步骤任务的数字员工。
我在一个项目里测试过让 Agent 完成“查找所有用户输入未做长度限制的接口,并自动修复”这个任务。流程是:Agent 先理解项目代码结构,找到所有接收request.form或request.json的地方,然后分析是否存在长度校验,最后一次性生成修复补丁。整体效果是——琐碎且模式化的安全加固自动化了,我只需要 review 生成的补丁,手动调整少量边界场景。
另一个我在用的典型协作模式是“AI 巡逻员”:定时让 Agent 扫描代码库的接口定义,找出那些缺少输入校验、缺少鉴权、缺少限流的接口,生成待办清单。这就像有一个细心的同事定期帮你做代码巡检,省去很多靠自觉才能维持的规范检查过程。新项目里,我更推荐用这个方式替代人工 code review 的机械性部分——把人解放出来做真正需要业务判断的工作。
不过,Agent 的使用需要设定清晰边界:它能够尝试改代码,但不能直接 push 到主分支,必须通过 MR 走代码评审;它只能访问你指定的代码目录,不能碰生产环境的敏感配置文件;它执行的每一个修改,都必须有日志记录。这些都是我在实践中逐步建立起的护栏规则,否则 Agent 犯错时你很难追责和回溯。这个问题随着 Agent 能力变强会越来越重要。
6. 设计驱动与可访问性:容易被忽略的“高品质”维度
6.1 AI 时代的 UI 设计与设计系统
Web 应用的“高品质”不只体现在后端的稳定和性能,前端界面的观感与使用体验同样决定了产品的水平。很多开发者吐槽“AI 生成的前端页面丑得像十年前的网站”,这个观察基本是对的——如果只用默认提示词让它“生成一个登录页”,出来的大概率是白底蓝按钮、居中表单那种毫无设计感的模板。
破解方法不是放弃 AI,而是给 AI 建立一个“设计系统”的语境:
提示词模板:请按照以下设计规范生成一个报价管理页面的前端代码:主色为 #2563EB,圆角 8px,字体为 Inter;卡片阴影使用 0px 4px 6px rgba(0,0,0,0.05);组件包含侧边导航、顶部搜索栏、数据表格和分页器;支持移动端响应式布局;使用 Tailwind CSS 编写,不引入额外 UI 库。
当你把设计规范细化到具体数值,AI 生成的前端页面观感会有质的提升。它已经见过海量设计优秀的页面数据,你给它清晰的约束,它就能按照约束输出。如果连设计规范都没有,建议先让它帮你生成一套:设定行业类型和风格方向,AI 会输出一套包含颜色、字体、间距、阴影的 Design Token。把这个 Token 作为后续所有前端页面的生成前提,整个应用视觉上的一致性和精致度就能把一大半产品比下去。
6.2 可访问性与国际化:AI 最容易踩的坑
可访问性(Accessibility)是国内很多 Web 开发者忽略、但在国际化产品和部分行业标准里是硬性要求的环节。AI 生成的 HTML,如果不用明确要求的话,基本不会主动带上aria-label、alt文本、键盘焦点管理这些可访问性属性。这不是 AI 的错——是训练数据里的低质量页面本来就没这些。
解决方法很简单:把可访问性检查加入规则卡和代码审查环节:
- 所有图标按钮必须带
aria-label说明。 - 表单控件必须关联
<label>元素。 - 所有图片必须有
alt属性。 - 颜色对比度必须满足 WCAG AA 标准。
- 整个应用必须支持纯键盘操作。
让 AI 在生成代码时强制加上这些属性,如果你用的是带规则的编辑器插件,AI 通常会在每个新组件里自动带上。但注意,光生成还不够,你还是需要用一个自动化的可访问性检测工具跑一遍,等于给 AI 的输出上道保险。这个工具会模拟键盘导航、检测对比度、检查 ARIA 属性的正确性,能大幅减少因为人为遗漏产生的可访问性问题。
国际化(i18n)也是同样的道理。如果一个应用要支持中英文切换,AI 默认生成的中文字符串和硬编码文案后续就会成为噩梦。正确的做法是让 AI 从一开始就生成“文字与代码分离”的结构——所有文案放进语言包文件,代码里只保留 key 引用。这样后续接新语言的时候,只需要翻译语言包,完全不用碰代码。让 AI 写这个结构的效率非常高,因为它已经理解这种模式的套路,只需要你提前说出来。
7. 我在实际项目中总结的经验与建议
7.1 小团队与个人开发者如何用 AI 提效
如果你是独立开发者或者小团队成员,没有专职 DevOps、没有专职安全工程师、没有专职测试,AI 的作用会更加突出——它相当于你一个人配备了一支虚拟的“全栈顾问团队”。
我个人的实践组合是:需求分析用 AI 做追问和清单化;技术方案用 AI 做对比和初稿;编码阶段用 AI 以迭代式对话开发;提交前用 AI 做安全自查和测试用例补全;部署阶段用 AI 写 Dockerfile 和 CI 配置;上线后用 AI 分析日志错误并给出修复建议。整个流程走下来,原来需要 6-8 周完成的小项目,现在大约 3-4 周就能达到同等质量,而且很多规范性的东西做得比以前更认真——因为我只需要动动嘴让 AI 写完,不需要亲自下笔,就有余力做审查和打磨。
但反过来也是一条重要的经验:小团队更容易过分信任 AI 的输出。因为没有专职团队做交叉验证,AI 说“这个没问题”你就信了,风险反而比大团队高。我的建议是:高风险的改动(涉及用户数据、支付、权限逻辑)一定要做小范围灰度测试或至少人工走一遍核心流程;低风险的工具类、模板类代码可以放心让 AI 全自动处理。这两种代码的风险等级完全不同,处理方式也必须区别对待。
7.2 我的失败案例与改进方向
最后分享一个真实的翻车案例,作为给所有人的提醒。
有一个内部工具项目,我为了赶进度,让 AI 直接生成了一套用户权限管理系统。当时觉得这种标准功能 AI 肯定没问题,直接放过到了测试阶段。结果安全测试发现了一个越权漏洞:普通用户可以构造特殊请求把自己提升为管理员。根因是 AI 生成的权限校验只检查了“用户是否已登录”,没有检查“用户角色是否为管理员”。这是很典型的 AI“半成品”问题——登录校验做了,业务级权限校验忘了。
这个教训让我调整了整个工作流,增加了两条硬性规则:第一,任何涉及权限、支付、用户数据的核心代码,上线前必须由人肉走一遍攻击路径——普通用户访问管理员接口、未登录访问需要登录的接口、已登录用户越权操作其他用户的数据,这三条线必须验证;第二,AI 生成的核心模块必须做一次“角色扮演评审”——让 AI 扮演攻击者,尝试用各种方式绕过它自己写的代码。这两条规则执行后,再没出现过类似的低级但致命的安全漏洞。
AI 编程这条路,本质上是一条“人机配合”的演进之路。它的边界不是由模型能力决定的,而是由你的判断力、验证力和工程素养决定的。工具会变得越来越强,但“定义什么是高品质”这件事,永远是人的职责。希望这篇文章能帮你少走一些弯路,把 AI 从“高级自动补全”变成真正的“开发搭档”。