一、引言

你可能有过这样的经历:明明已经详细描述了需求,AI 却返回了一段与期望相去甚远的代码;或者 AI 生成的代码虽然基本符合功能要求,却总是缺少关键细节,需要反复修改才能使用。有的时候还修改不对,最终需要推倒重来。其实可能不是 AI 能力有问题,更可能的是使用方法不对。本文会从 PM 的视角出发,分析为什么会出现这种情况,并提供实用的解决方案,帮助你更有效地利用 AI 进行原型开发与验证。

二、为什么 AI 会“乱写”

2.1 AI 不理解你的需求

AI 不会读心术。虽然它功能强大,但依然依赖于你提供的需求描述来理解任务。当 PM 使用过于宽泛或含糊的描述时,AI 会基于自己的“理解”填补细节空白。比如,当你说“帮我做一个登录页面”时,AI 必须自行假设:需要哪些表单字段?实现什么样的校验逻辑?页面设计风格是什么?这些自行假设的细节很可能与你实际期望的大相径庭,导致生成的代码与你的真实需求不符。

2.2 视角差异

PM 习惯从用户体验和业务价值角度思考,而 RD 则从技术实现和代码结构出发。这种思维方式的差异导致:PM 更关注“做什么”而忽略“怎么做”,倾向于使用业务术语而非技术术语,描述问题的方式往往从结果出发,而非从实现路径出发。

以下是一个典型的思维差异示例:

PM 思维:“我需要一个能展示用户购买历史的页面,可以按月筛选,并显示消费总额。”

RD 思维:“需要实现一个用户订单历史组件,使用 Redux 管理状态,通过 GraphQL 查询按月分组的订单数据,实现过滤逻辑,计算每月总额并在 UI 中展示汇总数据。”

AI 生成优质代码需要明确的技术约束和参数,这恰恰是 PM 的技能盲区。当缺乏这些关键技术参数时,AI 往往会生成“看似正确”但在技术实现上存在深层次问题的代码:代码可能能够运行,但缺乏可扩展性和可维护性;可能没有考虑性能优化和边界情况处理;可能使用过时或不适合项目长期发展的技术方案。

2.3 上下文缺失

AI 对项目的了解仅限于你明确告诉它的内容。它无法自行查看你的整个代码库(Agent 除外),理解你公司的设计规范,知道你团队的编码约定,或了解你产品的历史背景。

这种上下文缺失导致 AI 生成的代码虽然功能上可能正确,但可能不符合项目的技术标准和风格规范。对 PM 来说这个问题尤其棘手,因为可能不完全了解所有技术标准和规范细节,难以识别出这些不符合项目要求的地方,导致后续集成时出现各种兼容性问题。

这三个因素相互影响,导致开发 Prototype 时的困境。理解这些根本原因后,我们就能有针对性地解决“AI 乱写”问题。接下来,我们将探讨具体的解决方法。

三、解决 AI 乱写的方法

在解决方案之前,我们已经理解了为什么 AI 会“乱写”——主要源于三个核心问题:需求不明确、视角差异,以及上下文缺失。现在,我们可以针对性地解决这些问题。

3.1 提示词优化

假期刚好在用 Cursor 克隆一个项目,需要修改配置文件,我已经沟通且修改了一些比如 Supabase 的内容,我不知道 Redis 是不是也要修改,这时候发生了下面的对话。

我 Add to Chat 了对应的代码,并说:“env 文件里的我需要处理吗?”想表达的意思是我还需不需要修改 Redis 啊?

与 Cursor 关于 env 配置疑问的对话示例

Cursor 没明白<处理>其实是我要问是不是<修改>,因为之前上下文的交互,我会天然以为他能理解,结果并没有,最后是我做了澄清,然后解决了问题。

对话澄清后的解决结果示例

这个小插曲其实很能说明问题 —— 不是 AI 能力不行,而是我没有“说人话”。AI 不像人类同事,没法通过经验和语境猜测我们真正的意图。当 PM 提供模糊需求时,AI 只能自行填补空白,结果往往偏离我们的预期。那么,如何让 AI 更好地理解我们的意图呢?答案是结构化需求描述。因为结构化的描述可以给到更多的需求信息,也限制了 AI 的“胡乱补全”,这里有两种实用方法:

方法一:结构化模板

想让 AI 帮你写好代码,最好用结构化模板来描述需求。这样做有两个好处:一是逼着我们把脑子里模糊的想法变成具体的细节,二是帮助我们不仅说明“要做什么”,还要说明“怎么做”。用这种方式提供的明确指导大大减少了 AI 需要自行猜测的空间,也就一定程度上避免了 AI “乱写”的问题。下面是一个实用的模板,你可以直接套用:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
【需求背景】
- 业务目标:这个功能要解决啥实际问题
- 用户痛点:用户现在遇到什么困难
- 成功指标:怎么判断这个功能做得好

【功能需求】
- 核心功能:具体要做哪些事,越详细越好
- 用户流程:用户会怎么用这个功能,步骤是啥
- 交互反馈:各种操作后会有什么反应,比如成功/失败提示
- 边界场景:异常情况怎么处理,比如网络错误、数据为空

【技术参数】
- 技术栈:用什么框架和库
- 数据模型:需要存储什么数据,结构是怎样的
- 集成点:跟哪些系统对接
- 参考实现:有没有类似的已有功能可以参考

【验收标准】
- 功能验收:具体测试哪些点
- 性能要求:速度要求,比如加载时间
- 兼容性:支持哪些设备和浏览器

比如当我们要做一个登录页面的时候,使用不同提示词描述的效果👇

提示词结果
普通提示词做一个登录页面图片3
结构化提示词
展开查看【需求背景】
业务目标:提高用户账户安全性并简化登录流程
用户痛点:现有登录流程繁琐,缺乏安全性提示,用户经常忘记密码
成功指标:登录成功率提升15%,密码重置请求减少30%

【功能需求】
核心功能:
邮箱/用户名输入字段
密码输入与实时强度检测
“记住我”选项保存登录状态
忘记密码重置流程
第三方账号快速登录选项

用户流程:
用户访问登录页面
输入邮箱/用户名和密码
可选勾选“记住我”
点击登录按钮
系统验证凭据并反馈结果

交互反馈:
输入框即时验证格式,显示错误提示
密码强度实时可视化展示
登录按钮点击后显示加载状态
验证失败时显示具体错误信息和解决建议
成功登录后重定向到首页

边界场景:
用户多次登录失败时的账户保护机制
不同设备同时登录的会话管理
登录超时处理
浏览器自动填充兼容性

【技术参数】
技术栈:React 18 函数组件,TypeScript
组件库:Material UI 表单组件
状态管理:Formik 处理表单状态
验证库:Yup 实现表单验证
认证方案:JWT 认证,支持刷新令牌
数据模型:
User: { id, email, username, passwordHash, lastLogin }
Session: { id, userId, token, expiresAt, device }
集成点:
认证 API:/api/auth/login, /api/auth/refresh
第三方登录:Google OAuth, Facebook Connect
参考实现:
现有注册页面组件结构
设计系统的表单交互规范

【验收标准】
功能验收:
所有表单字段验证正确工作
密码强度检测准确
“记住我”功能在浏览器关闭后依然生效
第三方登录成功将用户重定向到首页
性能要求:
页面加载时间 < 1.5 秒
登录处理响应时间 < 1 秒
兼容性:
支持 Chrome、Firefox、Safari、Edge 最新两个版本
响应式设计,适配移动端和桌面端
支持键盘导航和屏幕阅读器
图片4

可以直接体验或查看代码,其实仅仅从前端展示的样子就能看出来优劣了。以及不要一句话描述需求,你的同事都猜不出来你要的是啥,更何况是没有上下文的AI。

方法二:让 AI 帮你写需求(套娃法)

上面的模板虽然好用,但对不太懂技术的 PM 来说填起来可能有点吃力。特别是“技术参数”那块,可能完全不知道该写什么。这时,我们可以走个捷径:把最初的粗略想法告诉高级 AI 模型(比如 Claude 3.7),让它帮你转换成结构化需求!

具体怎么操作:

  1. 先把你的原始想法写下来
  2. 用下面这个提示词让 AI 帮你转换
  3. 检查一下 AI 生成的结构化需求,做些必要的调整
  4. 把这个结构化需求用于 AI Coding

转换提示词:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
你是拥有10年全栈开发经验的资深技术架构师,擅长将产品需求转化为精确的技术规格。

请将以下业务需求转换为结构化的技术需求文档,遵循以下格式:
1. 【需求背景】- 包含业务目标、用户痛点和成功指标
2. 【功能需求】- 详细的功能点列表、用户操作流程、交互反馈规则和边界场景处理
3. 【技术参数】- 推荐合适的技术栈、数据模型设计、与现有系统的集成点,以及可参考的现有实现
4. 【验收标准】- 具体的功能测试点、性能要求和兼容性标准

在转化过程中请:
- 分解模糊的业务需求为明确的技术任务
- 添加开发者需要但PM可能忽略的技术细节
- 识别并补充潜在的边界场景
- 使用业内最佳实践推荐适合的实现方案
- 保持语言简洁明了,每个要点用1-2句话表达

以下是需求:
<粘贴你的原始需求>

可以拿一个真实的 case 来试试。

详细内容结果
最初的想法做一个用户可以管理自己订阅的页面,可以看到当前状态,进行续订和升级操作。图片5
AI转换后
转换后提示词用户订阅管理技术需求文档

【需求背景】
业务目标:提供一个集中式界面,让用户便捷地管理其所有订阅服务,提高订阅转化率和续订率。
用户痛点:用户难以追踪多个订阅的状态、到期时间,无法方便地进行续订或升级,导致非主动流失。
成功指标:订阅续订率提升15%,套餐升级转化率达到8%,用户订阅管理相关的客服咨询减少30%。

【功能需求】
订阅总览
以卡片或列表形式展示用户当前所有订阅,包括订阅名称、类型、价格、状态(有效/即将到期/已过期)、到期日期
允许用户筛选和排序订阅(按状态、到期日期、价格等)
提供订阅消费总额统计和每月/年支出预估
订阅详情
点击单个订阅可查看详细信息,包括订阅历史、账单记录、自动续费状态
展示该订阅可用的所有权益和使用情况
显示当前套餐与其他套餐的对比信息
操作功能
续订流程:点击续订按钮→选择续订周期→确认支付方式→完成付款→展示成功状态和新到期日
升级流程:点击升级→展示可升级套餐对比→选择目标套餐→显示差价→确认→完成付款
自动续订管理:开启/关闭自动续订,设置提前提醒时间(默认7天)
订阅取消预约:允许用户提前设置到期不续,但保留随时反悔的选项
边界场景处理
处理降级请求时提供挽留策略(优惠券/折扣/免费延期等)
支持处理订阅支付失败/订阅恢复的状态通知和操作引导
针对即将到期(7/3/1 天)的订阅发送状态提醒和续订建议
订阅权益变更时的通知机制和处理方案

【技术参数】
技术栈推荐
前端:React/Vue 框架,配合 Redux/Vuex 状态管理
后端:REST API 架构,Node.js/Spring Boot 实现
数据库:主数据 MySQL,缓存 Redis,考虑分表存储历史订阅数据
支付集成:Stripe/PayPal API 用于处理续订和升级支付
数据模型设计
用户订阅表(UserSubscription):
- id: UUID
- userId: 外键关联用户
- planId: 外键关联订阅计划
- status: ENUM(active, expiring, expired, cancelled, payment_failed)
- startDate: TIMESTAMP
- endDate: TIMESTAMP
- autoRenew: BOOLEAN
- paymentMethod: VARCHAR
- lastBillingDate: TIMESTAMP
- nextBillingDate: TIMESTAMP
- reminderDays: INT
订阅计划表(SubscriptionPlan):
- id: UUID
- name: VARCHAR
- description: TEXT
- price: DECIMAL
- billingCycle: ENUM(monthly, quarterly, yearly)
- features: JSON/TEXT
- rank: INT (用于比较套餐层级)
订阅历史表(SubscriptionHistory):
- id: UUID
- subscriptionId: 外键关联UserSubscription
- action: ENUM(created, renewed, upgraded, downgraded, cancelled)
- fromPlanId: UUID
- toPlanId: UUID
- timestamp: TIMESTAMP
- amount: DECIMAL
- transactionId: VARCHAR
集成点
用户系统:获取用户信息和认证状态
支付系统:处理续订/升级交易,查询交易历史
通知系统:发送订阅状态提醒和操作确认
权限系统:验证用户对特定订阅的操作权限
分析系统:埋点跟踪用户行为和转化率

【验收标准】
功能测试点
所有订阅状态正确显示,且实时同步支付系统变更
续订流程可完整执行,支持多种支付方式
升级/降级能正确计算价格差异并完成套餐切换
自动续订设置成功后实际按设定执行
提醒通知按用户设置的时间准确推送
性能要求
订阅页面首屏加载时间 < 1.5 秒
订阅列表渲染 (10+ 项) 时间 < 500 ms
支付操作响应时间 < 3 秒
系统需支持每秒 100 次的订阅状态查询
兼容性标准
支持主流浏览器最新两个版本 (Chrome, Safari, Firefox, Edge)
响应式设计,兼容桌面及移动设备 (最小支持 320px 宽度)
支持 iOS 14+ 和 Android 8.0+
适配暗黑模式和高对比度视觉模式
符合 WCAG 2.1 AA 级无障碍标准
图片6

是不是感觉瞬间清晰了很多?原本模糊的需求被展开成了全面的规格说明,涵盖了 AI 需要的细节。

这种“套娃”方法有几个明显优势。首先,即使你不具备深厚的技术背景,也能创建出 AI 友好的需求文档,这对技术知识有限的 PM 来说非常友好。其次,AI 会自动帮你填补可能忽略的边界场景和技术考量,让需求更加全面。有了这些明确的指导方向,AI 生成的代码质量自然会高很多,不再需要频繁返工。你可以根据自身的情况灵活选择这两种方法,比如你对技术比较了解或你的项目有明确的技术栈,可以直接用模板;如果技术不是很熟,可以用套娃法,当然合并起来使用也完全没问题。关键是避免给 AI 过于模糊的指令,让它不得不自己“脑补”细节。

3.2 为 AI 提供上下文

当谈到使用 AI 去 coding 的时候,一个常被忽视但极其重要的问题就是上下文缺失。AI 可能很擅长单独编写功能,但如果不了解整个项目的架构和约定,它生成的代码往往难以与现有系统集成,甚至技术栈可能也有偏差。解决这一问题的关键是为 AI 提供充分的项目上下文。在不同场景下可以采取不同的策略。

场景一:初次接手项目或者展开一个新的对话

刚接手项目时,如果有 README、Cursor Rules 这类项目文档,直接把它们 @ 给 AI 是最省事有效的方法。AI 能快速了解整个项目的架构设计和代码规范,避免生成的代码和项目风格不匹配。

如果项目中还没有这样的文档,可以使用 Cursor 的 /Generate Cursor Rules 功能,它会自动分析项目并生成规则文件。假期在看「Suna」这个 agent 项目就试了一下,Cursor 直接生成了 4 个 rules 文件,包含了项目结构、LLM配置、数据库和身份验证、部署和环境配置的详细说明。将这些 rules 提供给 AI 后,它立即就能理解整个项目架构。

如果你使用的是其他 coding 工具,也可以先让 AI 浏览项目的关键文件,然后请它总结项目架构。这样 AI 就能建立起对项目的基本认知,后续生成的代码也更容易与项目集成。

1
2
@rules
请分析这些文件,总结一下这个项目的整体架构、技术栈和主要模块,这样你才能帮我更好地开发新功能。

结果

图片7

场景二:实现具体需求

当你已经比较熟悉项目,在改实际需求的时候,就没必要每次都把整个项目结构告诉 AI 了。这时候直接把与当前需求相关的文件都 @ 出来就够了。

Cursor 的设计主管有这样的说明:

1
Use @ file, @ folders, @ git to scope Cursor's attention to the right parts of your codebase.

意思就是在解决对应问题或者需求的时候,应该把具体的内容 @ 出来,也可以从控制台把 API 响应数据扒出来,这些都是非常好的方式,可以把 Cursor 的注意力集中在最相关的代码上。比如我在改 AI coding 订阅管理系统的时候,就使用了这种方式:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
数据库中已经有了,你可以看下 `crud.py` 怎么修改。以及,这段响应代码的 amount 是 900,为什么页面上展示 20?我现在已经在数据库里增加了一个字段是"expired_reason",是 varchar,这个字段表示的是用户的过期原因。过期原因有三种:natural(自然过期)、link_expired(支付链接过期)、account_anomaly(账号异常过期)。

过期原因对应的展示文案:
- natural:订阅到期
- link_expired:链接过期,请提交最新的支付链接
- account_anomaly:账号异常,请更换新账号并使用新支付链接重新申请

用户的操作:
1. 在 `SharePage.tsx` 页面上点击"账号异常"按钮,在 `UserDashboard.tsx` 页面的状态处展示"account_anomaly"对应的文案。
2. 在 `SharePage.tsx` 页面上点击"链接过期"按钮,在 `UserDashboard.tsx` 页面的状态处展示"link_expired"对应的文案。

你需要做的:
1. 理解我的需求,并提出合理的方案先不要写代码。
2. 增加"账号异常"按钮
3. 不要额外增加接口,在 `share.py` 里增加相关函数即可。
4. 应该需要在 `subscriptions.py` 里增加 expired_reason 字段, `crud.py` 应该也要处理。
5. 不更改 `SharePage.tsx` 页面的过滤逻辑。
6. 不需要过度设计。

用这种方式就可以明确告诉 AI 可以在哪里看什么,要怎么增加功能,以及最重要的,先让 AI 别写代码,先来聊方案。这一点是避免 AI 乱写的重要技巧——先确认方案再写代码,可以大大减少返工和调整的时间。

四、总结

AI 在编程过程中“乱写”的问题并非源于能力不足,而是使用方法不当。本文分析了三个核心原因:需求描述不明确、PM 与开发视角的差异、以及项目上下文的缺失。针对这些问题,我们提供了两个解决方案:

首先,通过结构化需求描述,可以大幅提升 AI 的理解准确度。无论是直接使用结构化模板详细说明业务目标、功能需求、技术参数和验收标准,还是采用"套娃法"让 AI 帮你将模糊想法转化为清晰需求,都能显著减少 AI 需要“脑补”的空间,从而降低代码偏离预期的可能性。

其次,为 AI 提供充分的项目上下文同样至关重要。在初次接手项目或展开新对话时,可以直接把 READMECursor Rules 这类项目文档分享给 AI,或使用 “/Generate Cursor Rules” 等功能自动分析项目结构;而在实现具体需求时,则应该把与当前需求相关的文件都 “@” 出来,并坚持“先聊方案再写代码”的原则。这些方法能帮助 AI 更好地理解项目环境,生成与现有系统高度兼容的代码。

通过这些方法,PM 可以更有效地利用 AI 进行原型开发,减少不必要的返工,提高沟通效率。实践证明,AI 并非不能写好代码,关键在于我们是否能够“说人话”——用结构化、明确的方式表达需求,并提供足够的上下文信息。这样,AI 就能成为 PM 高效开发的得力助手,而不是“乱写”代码的困扰源头。