前阵子有个做产品的朋友问我,说现在 AI 编程这么热,是不是真能从一个想法直接生成一个能用的 App。我当时正好在用 AI 辅助开发一个 Flutter 的个人记账应用,从项目初始化到核心功能落地再到上线前的一轮轮优化,一路踩了不少坑,也积累了一些方法论。这篇就围绕“AI 开发个人记账 App(基于 Flutter)”这件事,把我实际的操作过程、关键决策和排查思路完整写出来。如果你正打算用 AI 提速开发,又担心代码质量不可控、报错不会查,这篇文章应该能给你一个比较踏实的参考。
我先把结论放在前面:AI 确实能帮你写出大部分业务代码,但它不是“输入一句话就交付 App”的魔法。真正决定项目成败的,是你怎么把模糊的想法描述成 AI 能理解的指令,怎么在它生成的代码里做架构取舍,以及遇到编译报错和运行异常时,用什么样的排查链路去定位问题。下面我把整个过程拆开聊。
1. 为什么我会用 AI 从零写一个 Flutter 记账 App
1.1 记账需求驱动的技术选型
先说说我为什么要做个人记账 App。市面上的记账软件不少,但每个人的记账习惯差异很大:有人只记支出,有人要管多账户转账,有人需要周期性的预算提醒。我之前用过几款主流产品,总觉得分类逻辑、统计口径和我的使用习惯对不上,数据还不能方便地导出。干脆自己写一个,既能完全掌控功能和数据,也能顺带验证一下 AI 辅助开发在真实项目里到底靠谱不靠谱。
技术选型上,我几乎没有犹豫就选了 Flutter。Flutter 的跨平台能力意味着我只需要维护一套 Dart 代码,就能同时输出 Android 和 iOS 的应用,桌面端的支持也让我后期可以用同一套代码跑在 Windows 上做数据复盘。对我这种“以个人项目和产品原型验证为主”的场景,这是性价比最高的方案。再加上 Flutter 的组件系统非常成熟,常用的 Material 组件开箱即用,AI 模型对 Flutter 和 Dart 的训练数据也足够充分,生成出来的代码可读性和准确率明显高于一些小众框架。
还有一点很现实:个人项目基本都是零预算,Flutter 的免费开源生态和 pub.dev 上的丰富插件能把开发成本压到最低。比如我需要把记账数据导出为 CSV 或 Excel,有现成的插件可以处理;需要画饼图看支出占比,fl_chart 这种图表库是免费的。这些基础能力如果从零开发,少说要折腾几周。
1.2 第一版需求清单怎么给 AI 描述
开始动手之前,我先花了半小时把需求整理成了一份清单。这份清单不是简单的一句话“帮我写个记账 App”,而是按照功能模块拆开的、能直接作为 AI 输入的需求描述。我实际用的原始描述大概长这样:
- 支持收入/支出双类型记录,记录字段包括金额、分类、备注、日期、账户。
- 统计页面展示月度收支汇总、分类占比饼图、近 6 个月收支趋势折线图。
- 设置页支持管理自定义分类(增删改),支持切换深色模式。
- 数据存储采用本地 SQLite,不接入后端服务,不需要登录。
- 页面结构:底部 Tab 导航(首页账单流水、统计、设置),首页右上角悬浮按钮新增记账。
之所以要把需求写这么细,是因为 AI 的代码生成能力高度依赖输入的清晰度。你给它“做一个记账软件”这种宽泛指令,它只能生成一个“看起来像记账软件”的空壳;但如果你告诉它“账单列表每个 item 需要显示分类图标、金额、日期,点击 item 进详情页,详情页支持编辑和删除”,它生成的就是基本可以直接跑的业务代码。这个差距在后面的开发过程中会被持续放大。
我还做了一件事:把技术栈提前指定清楚。我在需求描述里明确写了“使用 Flutter 3.x 版本 + Provider 做状态管理 + sqflite 做本地存储 + fl_chart 做统计图表”。这样 AI 在生成代码时不会擅自引入其他状态管理库,也不会把存储方案改成我不熟悉的东西。对于 Flutter 技术栈,这是很关键的一步。因为 pub.dev 上能实现同一功能的包可能有好几个,AI 如果每次生成代码都随机挑一个,后期的依赖管理和问题排查会变得非常痛苦。
2. 从零搭骨架:AI 帮我完成项目初始化与页面路由
2.1 环境准备与项目脚手架的取舍
项目开始前,环境准备是绕不开的第一步。我本机之前装过 Flutter 3.16 版本,但这次项目想用更新的版本,于是用 FVM(Flutter Version Management)装了一个新的稳定版。强烈建议做 Flutter 项目的朋友统一用 FVM 管理多版本 SDK,尤其是当你有多个历史项目在维护时,切版本是一个很频繁的操作,而 FVM 可以针对每个项目锁定 Flutter 版本,避免“这个项目能跑、那个项目编译不过”的混乱情况。
环境变量、Android SDK、JDK 这些基础内容,网上教程一堆,我不展开。这里只提一个我遇到的典型坑:在 Windows 上用 VS Code 新建 Flutter 项目时,Android 项目构建偶尔会报 “unable to find suitable visual studio toolc” 之类的错误。这个错误通常不是你 Flutter 环境的问题,而是 Android 构建链路里缺少 C++ 相关工具链或 CMake 配置不对。我当时的排查方式是先flutter doctor -v检查各链路是否正常,再在 Android 模块的build.gradle里检查 SDK 版本和目标版本是否匹配。如果你也遇到类似报错,优先排查这两个位置,不要急着重装整个 Flutter。
项目脚手架这一块,我采用的是flutter create生成官方模板,再让 AI 基于模板做改造。你可能会问,为什么不直接用flutter create之后再让 AI 写全部代码?原因很简单:官方模板保证了 Android/iOS 原生工程的配置是完整且互相匹配的,AI 生成的工程描述再详细,也不如 flutter 官方工具直接生成的稳妥。AI 的价值在这里体现在业务代码层,而不是代替原生工程脚手架。
2.2 让 AI 生成主界面与导航的核心 Prompt 写法
项目创建完成后,我干的第一件事是让 AI 搭建基础的页面骨架和路由结构。这一步我用的 Prompt 大致是:
“我需要在 Flutter 项目里实现一个底部导航栏,包含三个 Tab:账单流水、统计、设置。请使用 go_router 管理路由,主页面结构为 Scaffold + BottomNavigationBar(或 NavigationBar),点击切换 Tab 时通过 IndexedStack 保留各页面状态。请先生成路由配置文件 lib/router/app_router.dart,再生成主页面 lib/pages/main_shell.dart,页面内容先用最简单占位文本。”
这里有两个细节值得注意。第一,我明确要求使用 IndexedStack 保留页面状态。如果不加这个要求,AI 生成的底部导航常常是在切换 Tab 时销毁并重建页面,这样一旦用户在“账单流水”页滚动到了很靠下的位置,切走再切回来,滚动位置就没了。对记账应用来说,这种状态丢失的体验非常差。第二,路由管理库我用 go_router 而不是 MaterialPageRoute 手动管理,因为后期会有编辑详情页、分类管理页等多个页面需要参数传递,go_router 的路径式管理更符合我“页面层级清晰”的需求。
AI 生成的代码质量很稳定,几个文件的代码基本可以直接编译通过。不过我在 Review 时发现它把 NavigationBar 的 selectedIndex 和 IndexedStack 的 index 绑定逻辑写在了 MainShell 内部,这本身没问题,但我希望页面切换时能通过路由感知当前 Tab,方便后期做“点击 Tab 二次刷新数据”这类操作。于是我又追加了一轮指令,让 MainShell 通过监听路由状态来同步 Tab 索引,而不是自己维护一个局部变量。这个调整 AI 也顺利完成。到这里,我对 AI 辅助开发的第一个结论已经形成了:它能解决“从无到有”的速度问题,但“架构怎么演进”仍然需要你心里有数。
2.3 表单页与列表页的实现细节
页面骨架通了之后,接下来就是核心的记账页面。记账页的表单包含金额、分类选择、日期、账户、收支类型和备注。我让 AI 一次性生成这个表单,并特别强调“金额输入框只允许输入数字和小数点,最多保留两位小数;分类选择使用底部弹窗的形式展示分类图标和名称”。
实际生成效果不错,但有一处需要我手动纠正:AI 默认把金额字段处理成了 double 类型,而我在需求里明确要求的是“金额用 int 存储,单位是分”。这是记账应用的一个经典陷阱。如果你直接用 double 存金额,0.1 + 0.2 这种浮点精度问题迟早会在汇总统计时爆雷。AI 没有业务上“金额必须用最小货币单位存整数”的常识,它只会根据你的描述“金额字段”生成一个看起来对的类型。所以我在后续所有涉及金额的 Prompt 里都加了“金额字段在数据模型中存储为整数,单位为分;界面展示时转换为元”这个约束。这是一条值得所有做记账类应用的人记住的经验:不要让任何一位小数进入你的数据库。
账单流水列表页,我要求 AI 实现分页加载,每页 20 条,使用 ListView.builder 懒加载,并通过日期分组展示(类似“今天”“昨天”“更早”的节分组)。AI 在生成列表项结构时表现很好,分类图标、金额、备注、账户等信息的位置排布合理。但它在处理“按日期分组”的逻辑时,第一次生成的是在内存里遍历全部数据再手动分组,这在小数据量下没问题,可一旦记录数到了几千上万条,内存和启动耗时都会明显变差。我后来让它改成“SQL 层先按日期倒序查出当天数据,然后由 Dart 侧做分组的轻量处理”,并且把分组逻辑封装到一个独立的工具类里,方便后期做单元测试。这个案例很典型地说明了:AI 生成的代码可以跑通,但性能和扩展性需要你主动打补丁。
3. 账本真正的难点:本地存储与数据模型设计
3.1 为什么记账 App 不需要后端
个人记账 App 和团队协作类应用最大的区别在于:数据完全属于用户个人,不存在跨设备实时同步的刚需。因此第一版我直接放弃了后端服务器,采用本地 SQLite 存储。这个决定大幅降低了开发复杂度——不需要设计接口、不需要考虑鉴权、不需要处理网络异常。数据就是用户最私密的资产,存在本地反而让人更安心。
本地存储我选择的是 sqflite 插件。sqflite 是 Flutter 生态里最成熟的 SQLite 封装库,文档全、社区活跃、遇到的问题基本都能搜到答案。有些新项目会倾向选择 drift 这种更“现代化”的 ORM 框架,它确实提供了类型安全的 SQL 操作和 migration 工具,但学习成本偏高,而且 AI 对 drift 的掌握程度明显不如传统 SQL 语句写得稳。所以如果你是靠 AI 辅助开发、又不想在数据层花太多时间 Debug,我建议先选 sqflite,把表结构和 DAO(数据访问对象)层设计好,后期如果有复杂查询需求再考虑引入更高层的封装。
3.2 用 AI 设计数据模型,然后人工 review
数据模型是整个记账 App 的基石。我在让 AI 建表之前,自己先把表结构想清楚了,然后再让 AI 据此生成建表语句。这一点想特别强调:AI 可以帮你把建表 SQL 写出来,但表字段的取舍必须由你自己决定。因为“要不要冗余一个分类名称字段”“预算表按月度还是按周期存”“账户表和账单表的关系是一对多还是多对多”这些问题,没有标准答案,完全取决于你的产品定位。
我当时设计的核心表结构如下:
- bill 表:账单记录表。字段包括 id、type(收入/支出)、amount(整数,单位分)、category_id、account_id(账户关联)、remark、billed_at(业务日期,存毫秒时间戳)、created_at。
- category 表:分类表。字段包括 id、name、icon、type(区分收入分类和支出分类)、sort_order、is_deleted。
- account 表:账户表。字段包括 id、name、initial_balance(初始余额,整数单位分)。
- budget 表:预算表。字段包括 id、category_id(可空,空表示总预算)、amount、month(格式如 2025-06)。
我给 AI 的 Prompt 是“根据以下表结构定义创建 sqflite 数据库版本 1 的建表语句和基础 CRUD 方法,注意金额字段为整数、日期字段为整数毫秒时间戳、外键关联需建立索引”。AI 返回的建表语句基本正确,但我在 review 时发现它对外键索引的创建不够主动,只对主键做了约束。后来我手动加了 category_id、account_id、billed_at 三个字段的索引。理由很简单:账单流水表最大的查询场景就是按时间范围筛选,billed_at 不建索引,数据量大后查询会走全表扫描,页面会明显卡顿。索引的建立对业务功能没有影响,但对体验影响巨大,AI 不会替你想这些。
3.3 数据库表结构与查询逻辑的坑
数据层开发中我踩了一个比较典型的坑:AI 生成的“更新记录”方法默认是整行覆盖更新,也就是把所有字段都 set 进去。这在普通编辑场景下没问题,但如果你想要“只更新备注字段”或“只更新账户关联”这种部分更新能力,就需要额外的更新方法。AI 根据“CRUD”这个宽泛指令生成的 update 方法,通常是接收一个完整的 Bill 对象。我当时因为账单详情页支持编辑金额、分类、备注等多个字段,所以整行覆盖勉强够用,但事后想想这是运气好,如果后面加一个“批量修改分类”的功能,这个结构就不够灵活了。我自己后来补了一个动态更新方法,只更新非空字段。
还有一个坑是关于事务的使用。AI 生成的批量删除方法是一个 for 循环逐条 delete。如果一次删 50 条记录,意味着 50 次独立的事务提交,速度慢且中途出错无法回滚,会留下半删半不删的脏数据。我让 AI 把整段循环包在db.transaction()里,一次性提交。这种数据一致性问题在个人项目里不容易被发现,因为数据量小、出错概率低,但既然做的是记账应用,用户数据的一致性比什么都重要,该补的还是要补。
数据库查询这块,AI 生成的“按月统计收支汇总”SQL 是:
SELECT type, SUM(amount) AS total FROM bill WHERE billed_at >= ? AND billed_at < ? GROUP BY type这个写法正确且高效。统计页的饼图数据我让它按 category_id 分组查询,同时 JOIN category 表拿到分类名称和图标,AI 也处理得不错。唯一的问题出在时区上:它按“当前时间的 0 点到 24 点”去查当天数据,但我传入的是本地时间的零点毫秒值,在存储层面我用的又是 UTC 毫秒时间戳,导致跨时区使用时统计口径可能偏差一天。这个问题对国内单一地区的用户影响不大,但最好在数据层统一约定:时间戳一律按 UTC 存储,查询时传入本地时区换算后的起始和结束毫秒值。这里加一个方法专门做时间范围计算,能省掉后面一堆隐患。
4. 让 AI 改 bug 的完整排查链路:一次状态丢失问题实录
4.1 问题表象与初步猜测
项目开发到中后期,我遇到了一个让我比较头疼的 bug。现象是:在“账单流水”页,我把某条记录删除之后,列表确实刷新了,但切到“统计”页再切回来,那条被删除的记录又出现在了列表里。这个 bug 不是每次都出现,而是偶发的,尤其当你在删除后快速切换 Tab 时更容易复现。
拿到这个 bug 之后,我的第一反应不是直接丢给 AI,而是先复现、再缩小范围。我当时的猜测有两个方向:第一,列表的数据源没有真正从数据库删除,只是界面层做了过滤;第二,IndexedStack 保留了页面状态,删除操作虽然改了数据库,但页面切回来时没有重新拉取数据。我倾向于第二个方向,因为“切回来旧数据还在”这种表现,非常符合“页面被保留了但没刷新”的特征。
为了验证,我在“账单流水”页面的生命周期方法里加了日志,打印是否会触发数据加载逻辑。最终确认:IndexedStack 模式下,页面切换不会触发默认的生命周期回调来重新加载数据,而删除操作后的局部刷新只刷新了列表,没有刷新“那个被缓存的页面状态”。根因基本锁定。
4.2 给 AI 喂上下文的正确方式
找到根因之后,我再把问题交给 AI,但不是我预期解决方式,而是让它基于现状给方案。我把项目相关代码片段(MainShell 的 IndexedStack 部分、数据仓库的加载方法、账单列表页的状态管理)粘给了 AI,并附上了现象描述和我的排查结论。Prompt 我写得比较结构化:
“我的 Flutter 记账应用使用 IndexedStack 作为底部 Tab 容器,用户删除账单后,如果切换到统计页再切回账单流水页,列表会重新显示已删除的记录。经过排查,问题不是数据库层的删除失败,而是 IndexedStack 中的页面状态未更新。请给出三种可选修复方案,并按你推荐的优先级排序。不要直接改代码,先解释方案。”
这里有个很关键的点:我给 AI 的是完整的上下文,而不是一句笼统的“列表不同步怎么办”。AI 的上下文窗口有限,如果你把整个项目几十个文件全丢给它,它反而抓不住重点。但如果你只给它这一段出问题的代码链路,它能很快定位到 IndexedStack 的状态缓存机制上。
4.3 根因发现与修复验证
AI 给出的三种方案分别是:
- 在账单流水页暴露一个刷新方法,每次切换到该 Tab 的时候调用,强制重新加载数据。
- 使用事件总线或 Provider 的 ChangeNotifier,在删除操作后通知列表页更新。
- 放弃 IndexedStack,改用每次切换都重建页面。
我最终采用了方案一和方案二的结合:MainShell 里监听 Tab 切换回调,切到“账单流水”页时调用其暴露的刷新方法;同时,删除操作的 Repo 层在成功后发出一个数据变更事件,页面收到事件后重新查询数据库。方案三被我否掉,因为“切换到列表页就重建”虽然能解决问题,但由于每次重建都会重新查库,连续切换 Tab 时会出现明显的白屏闪烁,交互体验较差。
修复后我做了三步验证:第一步,删除一条流水后立刻切到统计页再切回来,确认列表不保留已删数据;第二步,连续删除多条记录后快速切换 Tab 多次,确认无偶发复现;第三步,杀掉 App 重新启动,确认数据库层面数据确实已删除。三步全部通过后,我才把这个 commit 收尾。整个过程走下来,AI 在方案建议和代码生成上帮了忙,但定位问题的思路、复现步骤的设计、验证范围的确定,这些仍然是开发者自己的核心能力。
5. 从能跑到好用的性能与体验打磨
5.1 Flutter 内存优化和 isolate 的正确用法
基础功能和主要 bug 都处理完之后,我开始关注性能。记账 App 的数据量一般不会特别大,但如果用户连续记了几年账,流水表轻松能到几万甚至几十万条。此时如果不做性能优化,列表滑动会掉帧,统计页汇总时会卡顿,体验就像走进了一片泥沼,操作一步等半秒,谁用谁崩溃。
Flutter 的性能优化有几个基础操作必须做。第一是列表项的 build 方法尽量拆分,避免一个巨大的 Widget 承载所有内容;第二是合理使用 const 构造函数,减少不必要的 Widget 重建;第三是图片和图标资源用合适的分辨率,不要在列表里加载大图。这些优化对 AI 生成的代码来说,基本不会自动体现。AI 生成的列表 item 通常会把所有展示内容塞在一个方法里,虽然能跑,但离“流畅”有差距。
统计页的计算开销是另一个重点。月度汇总需要遍历当月所有账单做分类汇总,如果聚合逻辑放在 UI 线程,当账单量很大时,切到统计页的一瞬间会出现掉帧。Flutter 的解决办法是用 isolate 做并行计算。最简单的方式是使用compute函数,把一个纯计算任务丢到后台 isolate,计算结果再传回主 isolate。我让 AI 把月度统计的计算逻辑抽成一个独立函数,然后用 compute 调用,改造后的首帧渲染速度提升非常明显。这里想提醒一句:compute的传入参数和返回值都必须是可跨 isolate 传递的类型,比如基本类型、List、Map,如果你传一个自定义对象,需要确保它能被序列化,否则会报错。我第一版改造时就踩了这个坑,AI 生成的自定义统计结果类在compute里直接传,报了个类型转换异常,后来把结果类改成 Map 传递才解决。
5.2 为什么 AI 生成的代码需要二次封装
使用 AI 辅助项目几周之后,我逐渐形成了自己的工作流:AI 负责“功能级代码”的生成,我负责“工程级代码”的重构和维护。举一个非常现实的例子:AI 生成的数据仓库层(Repository)方法,常常是直接暴露一个Future<List<Bill>> getAllBills()给页面调用。在页面少、逻辑简单的时候,这样完全没问题。但当你需要在多个页面复用同样的查询逻辑时,比如首页列表要查“最近一个月的支出”,统计页也要查“最近一个月的支出”,如果两个页面各自调用不同的 Repository 方法,一旦查询条件变化,你要改两个地方,这种散弹式修改很容易漏。
我的做法是:让 AI 先生成一个最简版本跑通流程,然后我手动把 Repository 的查询方法统一收敛,比如定义getBillsByRange(start, end, {type})这样一个通用的方法,页面层通过参数组合获取不同维度的数据。再配合一个简单的缓存层,同一时间范围内的查询在短时间内复用结果,避免重复查库。这种封装对 AI 来说不是不能做,但需要你给它非常精确的设计指令,而且每次生成完都要 review。与其反复调教,不如自己动手把这层抽象做好。AI 的定位应该是“加速器”,而不是“架构师”。
5.3 图表统计功能的实现与账单分组逻辑
图表统计是记账 App 最容易做出成就感的模块,也是最容易让 AI 翻车的模块。我用的是 fl_chart,它支持柱状图、折线图、饼图等多种图表,自定义程度高。需求里的“月度支出占比饼图”和“近 6 个月收支趋势折线图”,我用 Prompt 描述清楚后,AI 生成的代码基本能用,图表的颜色、图例、数值标签都有了。
但有一个问题让我印象深刻:AI 在生成饼图数据时,对“空分类”的处理不够严谨。比如某个月某个分类下没有任何支出,AI 生成的逻辑会把空分类忽略掉,这没问题;但如果某个月所有分类都为空,也就是整月没有任何收支,饼图的数据源为空列表,fl_chart 在渲染空列表时会导致页面报错。这种边界情况在正常使用时很少遇到,但对一个记账应用来说,“没有记录”恰恰是很多新用户的第一状态。我后来让 AI 生成一个默认的空数据占位组件,当统计结果为空时展示“本月暂无记录”的提示,而不是渲染空图表。这种“自动补全边界逻辑”的能力,AI 目前还做不到,需要人为补漏。
账单分组逻辑在前面提过,我再补充一个经验:按日期分组后,需要显示“当天总收入/总支出”这样的小结。这个小结如果逐条累加,在大数据量下会有性能问题。我让 AI 在 SQL 层用GROUP BY date(billed_at / 1000, 'unixepoch', 'localtime')这种写法按天聚合,一下把所有日期的汇总算出来,然后 Dart 侧做匹配,避免遍历每一条账单。这个优化做完,列表滑动和分组渲染的流畅度提升了一个档次。
6. 几个可以直接抄作业的 Prompt 套路,和一句大实话
6.1 需求描述模板、Bug 修复模板与代码重构模板
用 AI 写 Flutter 项目这段时间,我沉淀了几套实用的 Prompt 模板。技术栈不同,但思路是通用的,这里直接分享给你,可以按需改造成自己的版本。
需求描述模板,适用于新功能开发:
我正在用 Flutter 开发一个个人记账应用,当前技术栈为 Provider + sqflite + go_router。请在 [文件路径] 中实现 [具体功能],要求如下: 1. 功能行为:[描述用户操作流程与预期结果] 2. 数据约定:[字段类型、单位、取值范围] 3. UI 要求:[组件风格、页面布局、交互反馈] 4. 性能要求:[是否需要分页、是否需要 isolate、是否有大数据量处理] 5. 请复用项目现有的 [某个工具类/某个样式常量],不要重复定义。Bug 修复模板,适用于遇到异常时的排查:
我在 [页面/功能场景] 中遇到了 [具体问题描述]。 复现步骤: 1. [操作步骤] 2. [操作步骤] 3. [操作步骤] 预期结果:[应该发生什么] 实际结果:[实际发生了什么,附上日志或截图] 相关代码段: [粘贴出问题区域的完整代码] 请先分析可能的原因,按可能性从高到低列出,再给出推荐的修复方案和具体代码改动。修复时请评估该改动对 [关联模块/其他功能] 的影响。代码重构模板,适用于优化已有实现:
请重构 [文件/方法名]。当前实现的缺陷是:[性能差/可读性差/重复代码多/耦合度高]。 目标是: 1. [明确的目标] 2. [约束条件,如不允许引入新依赖/保持对外接口兼容] 3. [希望采用的设计模式或规范] 请输出重构后的完整代码,并简要说明变更点。这三个模板的共同核心是:给 AI 足够的项目上下文、明确约束条件和预期结果。模板的意义不是机械套用,而是强迫你把“模糊想法”转化成“结构化需求”。这个过程本身就是代码质量的第一道保障。
6.2 AI 编程的边界,哪些能全信哪些必须人审
最后说一说我对 AI 编程边界的真实体会。经过这个项目,我认为 AI 在以下场景表现是可靠的:
- UI 页面搭建和基础业务逻辑生成。Flutter 的 Widget 组合方式、表单校验、列表渲染这些模式化代码,AI 的正确率很高。
- 标准 API 的调用方式。比如 fl_chart 的基础用法、sqflite 的 CRUD 操作,AI 对这些常见库的掌握远超一般开发者。
- 格式化代码和基础重构。变量重命名、提取方法、整理 import 这类机械性工作,AI 能省下大量时间。
但有几类内容我建议永远不要盲信 AI:
- 数据库迁移脚本。涉及已有数据升级的 ALTER TABLE、数据回填逻辑,出错了很难察觉,恢复成本高。
- 支付、权限、文件读写等涉及系统能力的代码。这些功能出错可能会有额外的合规或安全问题,必须逐行 review。
- 涉及业务计算口径的代码。比如“本月结余 = 上月结余 + 本月收入 - 本月支出”这种,AI 不了解你的业务定义,可能把收入支出算反,或在边界值处理上出错。
一句话总结:AI 是效率工具,不是兜底方案。它跑得比你快,但方向需要你把控。
做这个记账 App 的过程中,我最大的体会是:不要指望 AI 帮你“思考”,要把它当成一个执行力超强、但完全没有业务Sense的初级工程师。你描述得越清楚,它交付得越靠谱;你留给它的想象空间越大,后面要填的坑就越深。如果你想用 AI 做自己的 Flutter 项目,不妨从一个小而完整的工具类功能开始练手,跑通一整条“需求描述 -> 代码生成 -> 编译调试 -> 性能优化”的链路,亲身感受几次成功和翻车,你自然就知道该怎么用它了。