1. 为什么 Flutter 项目需要 Cursor AI Skills
Flutter 项目写页面这件事,重复度其实非常高。一个标准的 GetX 页面至少包含view.dart、controller.dart、index.dart三个文件,再加上路由注册、全局导出、目录结构,每次新建业务模块都要手动复制粘贴一遍。我统计过自己上个电商项目,光是「购物车历史」「订单详情」「地址管理」这类页面骨架,就写了将近四十次几乎一样的模板代码。
Cursor AI Skills 能做什么?简单说,它把「一套固定的代码生成规则」写成 Markdown 文件放进项目里,Cursor 在对话时自动读取这些规则,按你定义的目录结构、命名规范、代码风格生成文件。适合谁?适合已经在用 Cursor 写 Flutter、并且项目有明确分层规范(比如 GetX + 目录约定)的开发者。不适合完全没定规范、每次写页面都随心所欲的场景,因为 Skill 的价值恰恰在于「把规范固化下来」。
这篇会给出 Skills 配置骨架(含settings.json片段)、可复制的提示词模板,并完整演示一次从需求到页面加文档的生成与验证流程。目标很直接:你照着做,能在自己的 Flutter 项目里跑通。
2. TaoToken 前置:给 Cursor 配一个稳定的模型入口
Cursor 本身支持自定义模型接入,但如果你想让 Skills 在长上下文里稳定工作(读目录、读多个文件、生成多文件代码),模型接口的稳定性很关键。我试过在高峰期用默认通道,生成到一半断流,view.dart写了一半就停了,还得重新描述需求。
TaoToken 在这里的作用是提供一个统一的 API 入口,Cursor 通过它调用模型。配置方式不复杂,核心是拿到 API Key,然后在 Cursor 的模型设置里填 Base URL 和 Key。
先到控制台创建 Key:
https://taotoken.net/console?utm_source=taotoken_aicg_blog_end&utm_content=console&utm_campaign=rewrite创建后复制 Key,接入地址用:
https://taotoken.net/api注意这个 API 地址后面不加 UTM 参数,直接填就行。如果你对 Cursor 自定义模型的完整接入步骤不熟,可以对照接入文档操作:
https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_content=doc&utm_campaign=rewriteKey 管理页面在这里,方便后续轮换或查看用量:
https://taotoken.net/api-keys?utm_source=taotoken_aicg_blog_end&utm_content=api-keys&utm_campaign=rewrite提示:Skills 生成多文件代码时会连续发起多次请求,建议在 Cursor 里把模型超时时间调大一点,避免生成中途被截断。
3. 可复制配置:Skills 骨架与 settings.json 片段
3.1 开启 Cursor 的 Agent Skills 支持
进入 Cursor 的Settings -> Beta,把Update Access选成Nightly,升级后重启。然后在Rules, Subagents, Commands面板下,打开Import Agent Skills开关。开启后,.codex/skills和.cursor/skills目录下的 Skill 就会全局可用。
3.2 settings.json 片段
在项目根目录的.cursor/settings.json(没有就新建)里加上 Skills 扫描路径和模型接入配置:
{ "cursor.skills.enabled": true, "cursor.skills.paths": [ ".cursor/skills", ".codex/skills" ], "cursor.models.custom": [ { "name": "taotoken-default", "baseUrl": "https://taotoken.net/api", "apiKey": "你的_API_KEY", "model": "claude-sonnet" } ] }baseUrl就是前面说的接入地址,apiKey填你在控制台创建的那串。model字段按你实际要用的模型名填,这里只是示例。
3.3 Flutter 创建页面组手 Skill
新建文件.codex/skills/Flutter创建页面组手/SKILL.md,内容如下:
--- name: "Flutter创建页面组手" description: "Flutter 项目中创建页面" --- # Flutter创建页面组手 按规则生成空页面脚手架代码。 ## 读取变量 - 读取 [保存目录] - 读取 [业务名称] - 通过 [业务名称] 生成 [业务代码] (我的页面 -> my_page) - [业务代码] 使用规则举例如下: - 文件名 my_page - 类名 MyPage - 变量名 myPage - 接口名 IMyPage ## 约束规则 页面必须包含在 lib/pages 目录下面 ## 页面目录 如果 [业务代码] 是 my_page,目录结构如下: - [保存目录] - my_page // 业务目录 - widget // 业务组建 - view.dart // 视图代码 - controller.dart // 控制器代码 - index.dart // index 导包代码 ## 页面代码 - index.dart ```dart library; export './controller.dart'; export './view.dart';- controller.dart
import 'package:get/get.dart'; class MyPageController extends GetxController { MyPageController(); _initData() { update(["my_page"]); } void onTap() {} @override void onReady() { super.onReady(); _initData(); } }- view.dart
import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'index.dart'; class MyPagePage extends GetView<MyPageController> { const MyPagePage({super.key}); Widget _buildView() { return const Center( child: Text("MyPagePage"), ); } @override Widget build(BuildContext context) { return GetBuilder<MyPageController>( init: MyPageController(), id: "my_page", builder: (_) { return Scaffold( appBar: AppBar(title: const Text("my_page")), body: SafeArea( child: _buildView(), ), ); }, ); } }保存总导包
index 文件 lib/pages/index.dart 追加在这个文件中即可
这个 Skill 的关键在于「读取变量」和「约束规则」两段。前者告诉 Cursor 从你的提示词里提取目录、业务名、业务代码;后者把目录结构和代码模板固定下来,避免每次生成风格漂移。 ### 3.4 编写技术说明 Skill 再建一个 `.cursor/skills/编写技术说明/SKILL.md`,用于自动维护项目文档: ```markdown --- name: 编写技术说明 description: 对当前项目进行技术整理并保存到文档中。 --- # 项目技术说明 你是一名资深 Flutter 架构师和技术文档专家。 ## 文档保存位置 docs/技术说明.md ## 输出要求 ### 一、项目整体结构 - 结构分层 - 模块职责 - 关键设计原则 ### 二、本次迭代技术变更 - 新增内容 - 修改内容 - 废弃或替代方案 ### 三、关键代码设计解读 - 重要类 / 模块职责 - 状态流转说明 - 数据流 & 依赖方向 ### 四、文档版本记录 - 文档版本号 - 更新时间 - 本次更新摘要4. 验证请求:从需求到页面加文档的完整流程
4.1 用 Skill 生成购物车历史页面
在 Cursor 对话框里输入提示词:
用 skill 在 lib/pages/cart 中创建页面 业务 购物车历史,业务代码 cart_historyCursor 会读取Flutter创建页面组手这个 Skill,按规则生成目录lib/pages/cart/cart_history/,里面包含view.dart、controller.dart、index.dart,并在lib/pages/index.dart追加导出。
生成后先别急着跑,检查三个点:类名是不是CartHistoryPage、GetBuilder的id是不是cart_history、index.dart的导出路径对不对。我踩过的坑是业务代码里带了下划线但类名没转驼峰,导致GetView<CartHistoryController>找不到控制器,编译直接报错。
4.2 验证页面能否编译
在终端执行:
flutter analyze lib/pages/cart/cart_history如果输出No issues found,说明语法和导入都没问题。接着跑一次热重载:
flutter run在路由里临时把首页指向CartHistoryPage,确认页面能正常渲染出 AppBar 和居中文本。
4.3 用 Skill 生成技术文档
页面验证通过后,输入:
使用 skill 编写技术说明Cursor 会扫描当前项目结构,在docs/技术说明.md里生成一份包含项目分层、本次新增cart_history模块、关键代码解读的文档。生成后打开看一眼,重点确认「本次迭代技术变更」里有没有把新增页面列进去。
4.4 模型对话辅助排查
如果生成过程中遇到报错,比如控制器注入失败、路由找不到,可以把报错信息贴到模型对话里让它帮你定位:
https://taotoken.net/model-chat?utm_source=taotoken_aicg_blog_end&utm_content=model-chat&utm_campaign=rewrite5. 本篇常见错排查
5.1 Skill 不生效,Cursor 没读取到
先确认settings.json里cursor.skills.enabled是true,paths数组包含了你放 SKILL.md 的目录。然后检查 SKILL.md 的 frontmatter 格式,---必须独占一行,name和description不能少。我遇到过因为 frontmatter 里多了一个空格导致整个 Skill 被跳过的情况。
5.2 生成的目录层级不对
Skill 里的「页面目录」段落用的是相对路径描述,Cursor 有时会理解成绝对路径。解决办法是在提示词里明确写「在 lib/pages/cart 中创建」,把父目录说清楚,而不是只给业务代码。
5.3 GetX 控制器报Controller not found
检查view.dart里GetBuilder的init和id是否与controller.dart里update(["xxx"])的字符串一致。这两个地方不一致时,页面能渲染但数据不刷新,而且不报错,很难查。
5.4 文档生成覆盖了旧内容
编写技术说明Skill 默认是增量更新,但如果提示词里没说清楚,Cursor 可能整篇重写。建议在提示词里加一句「在已有文档基础上增量更新,标注新增和修改」,并在生成后对比 git diff 确认没丢内容。
5.5 长上下文生成中断
Skills 生成多文件时请求次数多,如果模型通道不稳定容易断。确认baseUrl填的是https://taotoken.net/api,没有多余斜杠或路径。如果频繁中断,可以在 Cursor 设置里把单次请求超时调到 120 秒以上。
6. 长期编码与 Agent 场景的接入建议
如果你只是偶尔生成几个页面,按上面的配置就够了。但如果你打算把 Skills 用在长期维护的项目里,比如让 Agent 持续帮你补页面、写文档、做代码审查,那模型调用的稳定性和额度管理就变得重要。Coding Plan 适合这种高频、长周期的编码场景:
https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_content=coding-plan&utm_campaign=rewrite另外,如果你在用 Claude Code 或 Anthropic 系的工具链做 Flutter 开发,接入方式可以参考:
https://taotoken.net/claudecode-anthropic?utm_source=taotoken_aicg_blog_end&utm_content=claudecode-anthropic&utm_campaign=rewrite最后给一个实用建议:Skill 文件本身也要进 git。每次调整了目录规范或代码模板,提交一次,这样团队成员拉下来就能用同一套规则生成代码,避免「你生成的页面和我生成的不一样」这种协作摩擦。