IDE 配置与 Rules 记忆体系
AI 编程工具的效果取决于两个因素:模型能力和上下文质量。模型能力你无法控制(由 Anthropic/OpenAI 决定),但上下文质量完全在你手里。Rules 文件(
.cursorrules、CLAUDE.md、Windsurf 的.windsurfrules)就是你向 AI 注入项目上下文的核心机制——告诉 AI 你的技术栈、代码规范、架构约定、常见陷阱。写好 Rules,AI 输出质量提升 3-5 倍不是夸张。
1. Rules 的本质
1.1 为什么需要 Rules
没有 Rules 的 AI 编码像是一个刚入职的高级工程师——能力强,但不了解你的项目:
| 没有 Rules | 有 Rules |
|---|---|
用 useState 管理全局状态 | 知道用 Pinia + useState 做 SSR 安全状态 |
| 生成 Options API 代码 | 遵循 <script setup> + Composition API |
用 axios 发请求 | 用 $fetch / useFetch |
| 随意的文件命名 | 遵循 server/api/[resource]/[id].[method].ts 约定 |
| 不处理 SSR/CSR 差异 | 用 import.meta.client 守卫浏览器 API |
Rules 本质上是一份持久化的系统提示词——每次 AI 开始工作时都会自动加载,不需要你每次重复说明。
1.2 各工具的 Rules 机制
| 工具 | 文件 | 位置 | 加载方式 |
|---|---|---|---|
| Cursor | .cursorrules | 项目根目录 | 每次对话自动加载 |
| Claude Code | CLAUDE.md | 项目根 / 子目录 | 启动时自动读取,支持分层 |
| Windsurf | .windsurfrules | 项目根目录 | Flow 启动时加载 |
| Copilot | .github/copilot-instructions.md | 项目根目录 | Chat 时加载 |
2. Cursor Rules 编写
2.1 .cursorrules 结构
# Project: AI Video Platform
## Tech Stack
- Nuxt 4 (Vue 3.5+, Nitro, TypeScript)
- Drizzle ORM + PostgreSQL
- Tailwind CSS v4 + Nuxt UI
- pnpm monorepo (apps/web, apps/admin, packages/*)
## Code Style
- Always use `<script setup lang="ts">` for Vue components
- Use `defineProps` with TypeScript generics, not runtime declaration
- Use `useTemplateRef()` instead of template refs with string
- Use `$fetch` for client-side requests, `useFetch` for SSR-safe data fetching
- Use `import.meta.client` / `import.meta.server` guards, NEVER `process.client`
- All API handlers use Zod validation with `readValidatedBody`
## File Conventions
- API routes: `server/api/[resource]/[id].[method].ts`
- Composables: `composables/use[Name].ts` (auto-imported)
- Components: PascalCase, `.client.vue` suffix for client-only
- Types: `packages/shared/types/[domain].ts`
## Architecture Rules
- Server state: Drizzle queries in API handlers, NEVER direct DB access from client
- Auth: `requireAuth(event)` in all protected API routes
- Caching: `defineCachedEventHandler` for read-heavy, rarely-changing data
- Error handling: `createError({ statusCode, message })` for API errors
## Common Mistakes to Avoid
- Do NOT use `ref()` for props destructuring, use `defineProps` with reactive destructure
- Do NOT use `v-html` with user input
- Do NOT import from `vue` what Nuxt auto-imports (`ref`, `computed`, `watch`, etc.)
- Do NOT use `useAsyncData` when `useFetch` suffices (useFetch = useAsyncData + $fetch)
- Do NOT forget to handle SSR hydration mismatches for browser-only components2.2 编写原则
具体胜过抽象:不要写"遵循最佳实践",要写具体的代码约定。
# 差:
Use best practices for error handling.
# 好:
All API handlers must:
1. Validate input with Zod: `readValidatedBody(event, schema.parse)`
2. Throw errors with: `createError({ statusCode: 400, message: 'xxx' })`
3. Wrap external API calls in try-catch with specific error messages示例胜过描述:展示正确的代码比描述规则更有效。
# 差:
Use the Nuxt data fetching pattern.
# 好:
## Data Fetching Pattern
Server-rendered pages:
```vue
<script setup>
const { data } = await useFetch('/api/videos', {
query: { page: 1 },
transform: (res) => res.items,
})Client-side actions:
const result = await $fetch('/api/videos', {
method: 'POST',
body: { title: 'xxx' },
})
**包含反模式**:告诉 AI 不要做什么,比告诉它要做什么更重要。
```markdown
## Anti-Patterns
- NEVER: `import { ref } from 'vue'` (auto-imported in Nuxt)
- NEVER: `process.client` (use `import.meta.client`)
- NEVER: `localStorage.getItem()` without `import.meta.client` guard
- NEVER: raw SQL strings (use Drizzle query builder)
2.3 Cursor 项目级 Rules
Cursor 还支持更细粒度的 Rules(.cursor/rules/ 目录),可以按文件类型或目录触发:
<!-- .cursor/rules/api-routes.md -->
---
globs: ["server/api/**/*.ts"]
---
# API Route Rules
- Every handler must start with auth check: `const session = await requireAuth(event)`
- Use `readValidatedBody(event, schema.parse)` for POST/PUT
- Use `getQuery(event)` for GET parameters
- Return typed objects, never raw database rows
- Always include pagination for list endpoints: `{ items, total }`<!-- .cursor/rules/vue-components.md -->
---
globs: ["**/*.vue"]
---
# Vue Component Rules
- Use `<script setup lang="ts">` exclusively
- Props: `defineProps<{ ... }>()` with TypeScript generics
- Emits: `defineEmits<{ ... }>()` with TypeScript generics
- Template refs: `useTemplateRef<HTMLElement>('name')`
- Client-only logic: wrap in `onMounted` or use `.client.vue` suffix3. CLAUDE.md 分层体系
3.1 分层架构
Claude Code 的 CLAUDE.md 支持目录级分层——不同目录可以有不同的 Rules:
project/
├── CLAUDE.md # 全局 Rules(技术栈、通用规范)
├── apps/
│ ├── web/
│ │ └── CLAUDE.md # Web 应用特定规范
│ └── admin/
│ └── CLAUDE.md # 管理后台特定规范
├── packages/
│ ├── database/
│ │ └── CLAUDE.md # 数据库层规范
│ └── shared/
│ └── CLAUDE.md # 共享包规范
└── tests/
└── CLAUDE.md # 测试规范
Claude Code 在进入某个目录时,会自动加载该目录及其所有父目录的 CLAUDE.md。
3.2 全局 CLAUDE.md
# AI Video Platform
## Project Structure
pnpm monorepo with:
- `apps/web` - Nuxt 4 user-facing app (SSR)
- `apps/admin` - Nuxt 4 admin dashboard (SPA)
- `packages/database` - Drizzle ORM schema and migrations
- `packages/shared` - Shared types and utilities
- `packages/ui` - Shared UI components (Nuxt Layer)
## Commands
- `pnpm dev` - Start dev server (apps/web)
- `pnpm build` - Build for production
- `pnpm test` - Run all tests
- `pnpm typecheck` - TypeScript type check
- `pnpm lint` - ESLint check
- `pnpm db:migrate` - Run database migrations
- `pnpm db:generate` - Generate migration from schema changes
## Code Style
- TypeScript strict mode, no `any` unless unavoidable
- Vue: `<script setup lang="ts">`, Composition API only
- API: Zod validation, typed responses, proper error codes
- Database: Drizzle ORM, never raw SQL in application code
## Git Conventions
- Conventional Commits: `feat:`, `fix:`, `refactor:`, `docs:`, `test:`
- One logical change per commit
- Run `pnpm typecheck && pnpm test` before committing3.3 子目录 CLAUDE.md
<!-- packages/database/CLAUDE.md -->
# Database Package
## Schema Location
All schemas in `schema/` directory, one file per domain entity.
## Schema Conventions
- Table names: snake_case plural (`videos`, `ai_tasks`)
- Column names: snake_case (`created_at`, `user_id`)
- Primary key: `text('id').$defaultFn(() => createId())`
- Timestamps: `created_at` and `updated_at` with defaults
- Foreign keys: always define `.references(() => table.column)`
- Indexes: define at table level with `pgTable` index option
## Migration
After schema changes, run: `pnpm db:generate`
Review generated SQL in `drizzle/` before applying.3.4 Claude Code 专属命令
CLAUDE.md 中可以定义自定义 slash 命令:
<!-- .claude/commands/add-feature.md -->
---
description: "Add a new feature end-to-end"
---
When adding a new feature:
1. Create/update database schema in `packages/database/schema/`
2. Generate migration: run `pnpm db:generate`
3. Create API routes in `server/api/`
4. Create composable in `composables/`
5. Create page/component in `pages/` or `components/`
6. Run `pnpm typecheck` to verify types
7. Run `pnpm test` to verify tests pass
8. Commit with `feat: [description]`4. Windsurf Rules 与记忆
4.1 .windsurfrules
<!-- .windsurfrules -->
# Nuxt 4 AI Video Platform
## Framework
Nuxt 4 with TypeScript, Nitro server, Drizzle ORM, Tailwind CSS v4.
## Key Patterns
- Data fetching: `useFetch` for SSR pages, `$fetch` for client actions
- State: Pinia stores for complex state, `useState` for simple shared state
- Auth: `nuxt-auth-utils`, session-based, `requireAuth()` server middleware
- Validation: Zod schemas for all API input
## File Structure
server/api/[resource]/index.get.ts → List
server/api/[resource]/[id].get.ts → Detail
server/api/[resource]/index.post.ts → Create
server/api/[resource]/[id].put.ts → Update
server/api/[resource]/[id].delete.ts → Delete4.2 Windsurf Memory
Windsurf 有内置的持久化记忆系统(create_memory 工具),可以跨会话记住:
- 项目偏好("总是用 Tailwind,不用内联样式")
- 架构决策("视频处理用 BullMQ 队列")
- 调试经验("PostgreSQL 连接超时通常是连接池耗尽")
记忆由 AI 自动管理,也可以主动要求"记住这个"。
5. Rules 同步策略
5.1 问题
同时使用 Cursor、Claude Code、Windsurf 时,三份 Rules 要保持同步——这很痛苦。
5.2 方案:共享核心 + 工具适配
.ai/
├── core-rules.md # 核心规范(技术栈、代码风格、架构)
├── cursorrules.md # Cursor 专属(IDE 相关的规则)
└── claude-commands/ # Claude Code 专属命令
├── add-feature.md
└── fix-bug.md
.cursorrules # 引用 .ai/core-rules.md + Cursor 专属
CLAUDE.md # 引用 .ai/core-rules.md + Claude 专属
.windsurfrules # 引用 .ai/core-rules.md + Windsurf 专属
核心规范写一份,各工具的 Rules 文件引用核心 + 添加工具专属内容。虽然没有真正的"引用"机制(各工具都是纯文本读取),但可以通过脚本自动生成:
#!/bin/bash
# scripts/sync-rules.sh
CORE=$(cat .ai/core-rules.md)
# 生成 .cursorrules
echo "$CORE" > .cursorrules
cat .ai/cursorrules.md >> .cursorrules
# 生成 CLAUDE.md
echo "$CORE" > CLAUDE.md
echo "" >> CLAUDE.md
echo "## Claude Code Specific" >> CLAUDE.md
cat .ai/claude-specific.md >> CLAUDE.md6. 实战:AI 视频平台 Rules 模板
6.1 完整的 .cursorrules
# AI Video Platform - Cursor Rules
## Tech Stack
- **Framework**: Nuxt 4 (Vue 3.5+, TypeScript strict)
- **Server**: Nitro with Node.js preset
- **Database**: PostgreSQL + Drizzle ORM
- **UI**: Tailwind CSS v4 + Nuxt UI
- **Auth**: nuxt-auth-utils (session-based)
- **Monorepo**: pnpm workspace
## Vue Components
- Always `<script setup lang="ts">`
- Props: `defineProps<{ prop: Type }>()` with TS generics
- Emits: `defineEmits<{ (e: 'update', value: string): void }>()`
- Refs: `useTemplateRef<HTMLElement>('name')`
- Never import auto-imported composables: ref, computed, watch, onMounted, etc.
## Data Fetching
- SSR pages: `const { data } = await useFetch('/api/...')`
- Client actions: `await $fetch('/api/...', { method: 'POST', body: {} })`
- Never use axios or fetch directly
## API Routes
- Path: `server/api/[resource]/[id].[method].ts`
- Auth: `const session = await requireAuth(event)`
- Validation: `const body = await readValidatedBody(event, schema.parse)`
- Errors: `throw createError({ statusCode: 400, message: '...' })`
- Caching: `defineCachedEventHandler` for read-heavy endpoints
## Database
- Schema: `packages/database/schema/[entity].ts`
- Always use Drizzle query builder, never raw SQL in app code
- Relations: define in schema with `relations()`
- IDs: `text('id').$defaultFn(() => createId())`
## SSR Safety
- Browser APIs: guard with `import.meta.client` or use `.client.vue`
- Dynamic imports: `const Lib = await import('lib')` in onMounted
- No `window`, `document`, `localStorage` without client guard
## Don't
- Don't use Options API
- Don't use `process.client` (use `import.meta.client`)
- Don't use `v-html` with user content
- Don't put business logic in components (use composables)
- Don't access database from client-side code本章小结
- Rules 本质:持久化系统提示词,注入项目上下文,提升 AI 输出质量 3-5 倍
- 编写原则:具体胜过抽象、示例胜过描述、反模式比正确模式更重要
- Cursor:
.cursorrules(全局)+.cursor/rules/(按文件类型),支持 glob 匹配 - Claude Code:
CLAUDE.md分层(根目录 + 子目录),自动继承父级,支持自定义命令 - Windsurf:
.windsurfrules+ 内置 Memory 系统,跨会话记忆 - 同步策略:核心规范写一份,脚本自动生成各工具的 Rules 文件