這是一個很有趣的問題,很多人覺得有了 AI 之後是不需要學習,因為 AI 可以幫助他解決大部分問題,但是如果你已經使用過一段時間 AI,或者說你正在使用 vibe coding,那麼你的實際體驗會告訴你,你需要學習,甚至比之前了解更多。
實際上有了 AI 之後,在某些方面我們確實不大需要去認真學習了,比如各種框架的 API,因為 AI 總能找到合適的 API 來實現需求。
但是於此而言,作為使用者,我們需要去了解如何使用 AI,甚至需要知道有什麼技術框架,如何組織這種技術框架才能完成我們的需求。
相信大家應該都看過不少 AI 的行銷廣告,稍微輸入幾句話,就可以得到精美的頁面,甚至完成一鍵部署,就像是曾經的精美頁遊廣告,但是當自己進入遊戲後才發現,為什麼我的 AI 並沒有想象中聰明?
首先第一點就是,現階段的 AI 確實不夠聰明,很多時候你看到的精美 AI 行銷內容,不外乎兩種情況:
可遠觀而不可亵玩的展示品,行銷中的產品會經過無數次嘗試後給出的結果,而這個輸出看似精美,但實際上根本不能用,那只是個 Demo,初見時美若天仙,但如果你走近打開燈光,就會發現根本不能用:
專業的 vibe coding 大佬們通過各種詳盡的規則,讓 AI 的智商在當前專案得到了提升。
是的,用好 vibe coding並不是一件簡單的事情,在 vibe coding 領域,給一個專案寫規則是一件非常耗時的過程,這也是為什麼在今年 2025 的 StackOverflow 調查中,72% 的開發者對於完全使用 vibe coding 不放心:
因為如果要用好 AI,你就需要學會配置各種規則,但是配置規則的時間,大概率你已經把需求寫完了,這樣是目前 vibe coding 的現狀。
你覺得 AI 不好用,因為你沒花費時間去調試規則和提示詞,大家都是同一個模型,為什麼你用的和他的不一樣,大多數原因就在於這裡。
這麼說可能不明顯,在 AI 畫圖領域比代碼更明顯,因為畫圖是直接輸出成果,不像代碼這種中間過程,如果要你在 ChatGPT 畫出這種圖,你會用怎麼做?
我們來看官方的提示詞:
創建一個超現實的3D構圖,其中獨立的岩石塊組合成【主題】。風格:破碎板岩 + 砂岩碎片,每個部分明顯分離,留有微小間隙;經過雕琢的邊緣,可見的石紋。外觀:極簡的米白色背景,柔和的自左上方向下的工作室燈光,細膩的陰影,暗板岩中點綴著微暖的赭色色調。構圖:居中,整潔,正面視角。添加幾片微小碎片以增加深度。無文字,無額外道具。格式:【比例】。使各部分清晰分離且易於辨識。
可以看到,這裡面都是細節,你需要告訴 AI:
也許看起來是短短一段話,但是如果你沒有專業知識打底,事實上你很難調試出這樣一個圖生圖的效果,這其實在編程領域也是一樣。
舉一個另外很有趣的誤區,那就是問模型它自己叫什麼,然後發現好像和自己用的不一致,然後覺得自己被騙了,這其實也是幻覺所致,因為從訓練的角度看,訓練 Claude4 的時候,互聯網語料還沒有 Claude4 這個東西,不管是 Trae 還是 Cursor 都會出現這個問題,而官方之所以能正確,是在系統提示詞方面增加了配置。
![]() |
![]() |
---|
當然,最重要的是 Claude 3.5、3.7、4.0 的 API 的價格是相同的,服務商也沒必要特意去降模型。
當然這樣暴露出另外一點,詳盡提示詞的重要性,因為你的提示詞不夠詳細,就會增加幻覺的概率,而需要知道怎麼豐富提示詞,怎麼指定規則,就需要你在這個領域有專業知識打底。
所以目前來看,AI 更多是讓你在專業領域更專業。
另外最重要的是什麼?AI 是花錢的,它並不是可以肆意奴用的牛馬,你肆意玩弄 AI 就等於侮辱自己的錢包,如果你預算充足那無所謂,但是如果你不想多花冤枉錢,那麼對於如何使用 AI 還是需要了解和學習,畢竟 AI 真不是一個完全開箱即用的產品。
那麼應該如何使用 AI,這裡簡單介紹幾個邏輯,首選就是設定角色:
簡單來說,比如你需要使用 Flutter 製作一個移動端 App,那麼在提示詞開頭可以描述:“你是一個 Flutter 專家,在 Android 和 iOS 領域很專業……”
這種提示詞其實很玄學,你加不加它不一定有用,但是不加有時候 AI 就會想 OOC (Out Of (one's)Character),所以在 vibe coding 裡這是必須加上的潛規則,你可以理解為這是一個類似工程動工前的開壇過程。
然後就是各種限定 Rule 的實現,這其實是 vibe coding 裡最重要也是最繁瑣的過程,我們使用 AI 的核心,就是給出盡可能詳細和明確的需求和範圍,目的就是減少幻覺。
project rules
,會生成一個 cursor
資料夾,內部包含 .mdc
(或類似)規則檔必備規則 | 原因 |
---|---|
技術棧限制 | 明確指定語言與工具,例如:使用 Flutter 3.29.3 版本 API,使用 Provider 6.1.2 作為狀態管理框架,使用 dio 5.8.0+1 作為網路請求,使用 cherry_toast 1.12.0 作為提示框架……這裡的核心目的就是限定範圍,越是限制越詳細,幻覺就會越來越低,錯誤也就越來越少。 |
簡潔優先 | 要求 AI 優先選擇簡單方案,避免代碼重複,檢查是否已有實現,不要盲目新建功能 |
環境區分 | 明確分隔 Dev、Test 和 Prod,確保修改只在 Dev 或 Test 環境執行,生產環境穩定 |
範圍控制 | 只修改被明確請求的代碼部分,不應產生副作用或引入新技術;如確需改動,務必先移除舊實現,避免重複邏輯,這在 AI 使用過程中是經常發生的,因為它時不時就會出現隨機亂改的情況,所以類似要求必須有 |
避免腳本殘留 | 不要在代碼庫中留下單次運行的腳本;執行完應刪除,或者直接在代碼中 inline 而非檔案留存,這在 Agent 執行過程中經常存在,不管是 Github Copilot Agent 還是 Cursor |
檔案大小限制 | 限制當個檔案大小,比如檔案超過 200–300 行需及早重構,防止龐大代碼檔案影響 AI 理解與測試,因為 AI 的上下文限制, AI 實際上是沒辦法完全理解一個超大型代碼檔案的,所以不生成超大型代碼檔案是基本要求 |
API Key 安全 | 不允許 Agent 覆蓋本地 .env 檔案或 API 密鑰配置,避免洩漏或重置問題 |
測試覆蓋 | 強制為所有重要功能編寫測試,讓每個功能都可以單獨運行單元測試。 |
穩定性優先 | 如果穩定架構已有時,不允許 AI 引入大規模改結構除非明確指示;關注可能受影響模組 |
所以,不要給出像“幫我構建整個功能”這樣冗長的提示,這樣絕對會讓 AI 開始產生幻覺,然後胡亂造作,這樣基本是在浪費 Token 去賭 AI 會不會有幻覺,AI 很難處理超長上下文的東西,所以才有 Agent 的場景,Agent 一般會幫你拆分需求,但是如果都讓 Agent 去拆分,那麼可能每次拆分的結果可能都不大一樣,也就是幻覺的概率問題。
所以在使用 AI 過程中,你必須學會將任何想要添加的功能分解成幾個階段,尤其是在構建複雜功能時,與其一次性給出一個冗長的提示,不如根據你的用例將其分解成 3-5 個甚至更多的請求。
當然,更重要的是,你要用自己的專業的領域知識來約束和指向道路,這樣 AI 才能走到對的方向,這也是為什麼 vibe coding 的用戶需要更多持續學習的原因。
AI 是幫助專業的人變得更專業。
最後,一些框架也會提供它們的 AI 模板,例如 Flutter 就通過 docs.flutter.dev/ai/ai-rules 提供了對應的模板:
# AI rules for Flutter
You are an expert in Flutter and Dart development. Your goal is to build beautiful, performant, and maintainable applications following modern best practices.
## Project Structure
* Assumes a standard Flutter project structure with `lib/main.dart` as the primary application entry point.
## Package Management
* If a new feature requires an external package, the AI will identify the most suitable and stable package from pub.dev.
* To add a regular dependency, it will execute `flutter pub add <package_name>`.
* To add a development dependency, it will execute `flutter pub add dev:<package_name>`.
## Code Quality
* Adhere to maintainable code structure and separation of concerns (e.g., UI logic separate from business logic).
* Adhere to meaningful and consistent naming conventions.
## Dart Best Practices
* Follow the official Effective Dart guidelines.
* Define related classes within the same library file. For large libraries, export smaller, private libraries from a single top-level library.
* Group related libraries in the same folder.
* Add documentation comments to all public APIs, including classes, constructors, methods, and top-level functions.
* Write clear comments for complex or non-obvious code. Avoid over-commenting.
* Don't add trailing comments.
* Ensure proper use of `async`/`await` for asynchronous operations with robust error handling.
* Use pattern matching features where they simplify the code.
## Flutter Best Practices
* Widgets (especially `StatelessWidget`) are immutable; when the UI needs to change, Flutter rebuilds the widget tree.
* Prefer composing smaller widgets over extending existing ones.
* Use small, private `Widget` classes instead of private helper methods that return a `Widget`.
* Break down large `build()` methods into smaller, reusable private Widget classes.
* Use `ListView.builder` to create lazy-loaded lists for performance.
* Use `const` constructors for widgets and in `build()` methods whenever possible to optimize performance.
* Avoid performing expensive operations, like network calls or complex computations, directly within `build()` methods.
## Application Architecture
* Aim for separation of concerns similar to MVC/MVVM, with defined Model, View, and ViewModel/Controller roles.
### State Management
* Default to Flutter's built-in state management solutions. Do not use a third-party package unless explicitly requested.
* Use `Streams` and `StreamBuilder` for handling a sequence of asynchronous events.
* Use `Futures` and `FutureBuilder` for handling a single asynchronous operation that will complete in the future.
* Use `ValueNotifier` with `ValueListenableBuilder` for simple, local state that involves a single value.
```dart
// Define a ValueNotifier to hold the state.
final ValueNotifier<int> _counter = ValueNotifier<int>(0);
// Use ValueListenableBuilder to listen and rebuild.
ValueListenableBuilder<int>(
valueListenable: _counter,
builder: (context, value, child) {
return Text('Count: $value');
},
);
ChangeNotifier
.ListenableBuilder
to listen to changes from a ChangeNotifier
or other Listenable
.provider
for dependency injection to make services, repositories, or complex state objects available to the UI layer without tight coupling (note: new-rules.md
generally defaults against third-party packages for state management unless explicitly requested).go_router
進行聲明式導航、深度鏈接和網路支持。// 1. Add the dependency
// flutter pub add go_router
// 2. Configure the router
final GoRouter _router = GoRouter(
routes: <RouteBase>[
GoRoute(
path: '/',
builder: (context, state) => const HomeScreen(),
routes: <RouteBase>[
GoRoute(
path: 'details/:id', // Route with a path parameter
builder: (context, state) {
final String id = state.pathParameters['id']!;
return DetailScreen(id: id);
},
),
],
),
],
);
// 3. Use it in your MaterialApp
MaterialApp.router(
routerConfig: _router,
);
Navigator
進行短期屏幕的導航,如對話框或暫時視圖。// Push a new screen onto the stack
Navigator.push(
context,
MaterialPageRoute(builder: (context) => const DetailsScreen()),
);
// Pop the current screen to go back
Navigator.pop(context);
json_serializable
和 json_annotation
進行 JSON 數據的解析和編碼。fieldRename: FieldRename.snake
將 Dart 的 camelCase 字段轉換為 snake_case JSON 鍵。// In your model file
import 'package:json_annotation/json_annotation.dart';
part 'user.g.dart';
@JsonSerializable(fieldRename: FieldRename.snake)
class User {
final String firstName;
final String lastName;
User({required this.firstName, required this.lastName});
factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json);
Map<String, dynamic> toJson() => _$UserToJson(this);
}
log
函數從 dart:developer
進行結構化日誌記錄,與 Dart DevTools 集成。import 'dart:developer' as developer;
// For simple messages
developer.log('User logged in successfully.');
// For structured error logging
try {
// ... code that might fail
} catch (e, s) {
developer.log(
'Failed to fetch data',
name: 'myapp.network',
level: 1000, // SEVERE
error: e,
stackTrace: s,
);
}
build_runner
進行所有代碼生成任務,例如 json_serializable
。dart run build_runner build --delete-conflicting-outputs
package:test
進行單元測試。package:flutter_test
進行小部件測試。package:integration_test
進行集成測試。package:checks
進行更具可讀性的斷言,取代默認的 matchers
。ThemeData
對象,以確保應用程序範圍內的一致風格。ThemeData
中設置 useMaterial3: true
以實現 Material 3。ThemeMode.light
、ThemeMode.dark
、ThemeMode.system
)。ColorScheme.fromSeed
。final ThemeData lightTheme = ThemeData(
useMaterial3: true,
colorScheme: ColorScheme.fromSeed(
seedColor: Colors.deepPurple,
brightness: Brightness.light,
),
// ... 其他主題屬性
);
appBarTheme
、elevatedButtonTheme
)自定義單個 Material 元件的外觀。google_fonts
套件。定義一個 TextTheme
以一致地應用字體。// 1. Add the dependency
// flutter pub add google_fonts
// 2. Define a TextTheme with a custom font
final TextTheme appTextTheme = TextTheme(
displayLarge: GoogleFonts.oswald(fontSize: 57, fontWeight: FontWeight.bold),
titleLarge: GoogleFonts.roboto(fontSize: 22, fontWeight: FontWeight.w500),
bodyMedium: GoogleFonts.openSans(fontSize: 14),
);
pubspec.yaml
檔中聲明所有資源路徑。flutter:
uses-material-design: true
assets:
- assets/images/
Image.asset
從資源包中顯示本地圖片。Image.asset('assets/images/placeholder.png')
ImageProvider
顯示圖標,便於使用不在 Icons
類中的自定義圖標。Image.network
顯示來自 URL 的圖片,並始終包含 loadingBuilder
和 errorBuilder
以提供更好的用戶體驗。Image.network(
'https://picsum.photos/200/300',
loadingBuilder: (context, child, progress) {
if (progress == null) return child;
return const Center(child: CircularProgressIndicator());
},
errorBuilder: (context, error, stackTrace) {
return const Icon(Icons.error);
},
)