别再教AI写代码了!用GEMINI.md打造你的24小时技术顾问(Node.js/React实战版)

你是否也有过这样的经历?深夜赶工,面对一个棘手的React组件状态管理问题,你向AI助手求助。它滔滔不绝地给出了一套方案,乍一看逻辑清晰,但仔细一瞧,它用的是你项目里早已弃用的Class组件写法,状态管理库推荐的是Mobx,而你的项目规范白纸黑字写着“统一使用Redux Toolkit”。你叹了口气,不得不像教一个新来的实习生一样,在聊天框里重新输入:“我们项目用的是Redux Toolkit,请按照我们的规范,用createSlice来写...” 一来二去,沟通成本甚至超过了你自己动手解决的时间。

这恰恰是当前AI辅助编程的普遍困境:AI很聪明,但它对你的项目一无所知。它就像一个拥有海量通用知识、却对你团队内部黑话和行事准则一窍不通的外援。每一次交互,你都在重复进行着低效的“背景同步”。真正的效率革命,不在于让AI变得更“通用”,而在于让它变得更“专属”——让它成为你团队里那位24小时在线、熟知一切项目细节、永不疲倦的技术顾问。

今天,我们不谈空洞的概念,直接进入实战。我们将聚焦于一个具体的工具理念:GEMINI.md。这不是一个需要复杂部署的软件,它就是一个放在你项目根目录下的Markdown文件。但正是这个文件,将成为你与AI之间最高效的“协作协议”。本文将手把手带你,为一个典型的Node.js后端 + React前端的全栈项目,配置一份深度定制化的GEMINI.md,让AI真正理解你的技术栈、你的规范、甚至你的“脾气”。

1. 超越配置文件:理解GEMINI.md的核心理念

在开始动手之前,我们需要先跳出“又一个配置文件”的思维定式。GEMINI.md的本质,是一个结构化的项目心智模型注入器。它的目标不是替代你的package.jsonREADME.md,而是专门为AI这个特殊的“协作者”量身打造一份上岗培训手册。

想象一下,你团队新来了一位顶尖的全栈工程师。你会怎么让他快速上手?你会给他看代码库,但更重要的是,你会和他同步几件事:我们为什么选择TypeScript而不是JavaScript?我们的API响应为什么统一包装成{ code, data, message }格式?前端组件库为什么是自己封装的,而不是直接用Ant Design?这些决策背后的“为什么”,就是项目的上下文约束。GEMINI.md所做的,就是系统化、文档化地将这些上下文与约束“编译”成AI能精准理解的语言。

它与普通文档的关键区别在于主动性与特异性。普通文档是人看的,需要人去查阅;GEMINI.md是给AI“看”的,会在每次你与AI交互时,被自动、静默地作为背景信息注入。这带来了两个根本性优势:

  • 消除歧义,统一语境:当你说“加个用户列表接口”,AI会立刻知道你需要一个基于Express.js、使用Prisma ORM查询、返回特定JSON格式、并需要编写相应Vitest单元测试的RESTful端点。
  • 固化最佳实践,提升代码一致性:通过明确的指令和示例,AI生成的代码会天然符合团队的代码风格、目录结构和设计模式,大幅减少后续的代码审查和重构成本。

所以,编写GEMINI.md的过程,本身就是一次极佳的项目知识梳理和团队规范沉淀。它迫使你去思考并明确那些“我们一直这么做,但没写下来”的规则。

2. 实战构建:为全栈项目编写GEMINI.md

让我们以一个虚构但典型的“电商管理后台”全栈项目为例,其技术栈为:后端使用Node.js + Express + TypeScript + Prisma + PostgreSQL,前端使用React + TypeScript + Vite + Redux Toolkit + MUI。我们将从零开始,构建一份能覆盖前后端需求的GEMINI.md。

2.1 项目全景与技术栈定义:为AI绘制地图

这是GEMINI.md的开篇,目的是让AI在宏观上理解它将要参与的是一个什么样的“世界”。这部分信息需要高度精确,避免模糊表述。

# 电商平台管理后台 - AI协作指南

## 🗺️ 项目全景
本项目是一个面向内部运营人员的电商平台管理后台,核心功能包括商品管理、订单处理、用户权限控制及数据看板。系统采用前后端分离架构,追求高可维护性与清晰的职责边界。

## 🛠️ 核心技术栈与版本
请严格基于以下技术栈和版本提供解决方案:

| 层级 | 技术 | 主要用途/版本 | 关键说明 |
| :--- | :--- | :--- | :--- |
| **后端** | Node.js | 运行时 (v18+) | 所有代码需兼容此版本。 |
| | TypeScript | 开发语言 (v5+) | 严格模式,所有API和模块必须提供清晰类型定义。 |
| | Express.js | Web框架 (v4.x) | API路由组织遵循RESTful风格。 |
| | Prisma | ORM (v5.x) | 数据库操作的唯一入口,禁止使用原生SQL查询。 |
| | PostgreSQL | 数据库 (v15+) | 数据库设计规范见下文。 |
| **前端** | React | UI框架 (v18+) | 优先使用函数组件和React Hooks。 |
| | TypeScript | 开发语言 (v5+) | 与后端共享类型定义(通过API类型生成)。 |
| | Vite | 构建工具 (v5.x) | 项目配置已固化,无需调整。 |
| | Redux Toolkit | 状态管理 (v2.x) | 全局状态必须使用RTK,禁止直接使用Context或useState跨组件共享。 |
| | MUI (Material-UI) | 组件库 (v5.x) | UI组件优先从`@mui/material`导入,自定义主题已配置。 |

提示:技术栈表格不仅能清晰罗列信息,更能通过“关键说明”一栏,提前植入重要的约束性指令(如“禁止使用原生SQL”),从源头引导AI的行为。

2.2 分层配置:前端与后端的专属“教练”

这是GEMINI.md的精华所在。通用指令对全栈项目来说粒度太粗,我们需要为前端和后端设置差异化的“行为准则”,让AI能在不同上下文中切换角色。

针对后端Node.js/TypeScript的指令:

## ⚙️ 后端AI助手配置
**角色**:你是一位严谨的Node.js后端架构师,对系统安全、性能和数据一致性有极高要求。

**核心指令**:
1.  **类型安全第一**:提供的所有代码示例必须包含完整的TypeScript类型定义(接口、类型、泛型)。对于Prisma模型返回的数据,必须使用`Prisma.Validator`或`Prisma.GetPayload`来生成精确的类型。
2.  **错误处理规范化**:所有API路由必须使用异步处理器,并使用统一的错误处理中间件。抛出业务错误时,使用`AppError`自定义类,包含`statusCode`和`isOperational`属性。
3.  **Prisma最佳实践**:
    *   查询必须包含`select`或`include`来明确指定返回字段,避免`select *`。
    *   对于更新操作,优先使用`update`而非`upsert`,除非业务逻辑明确要求。
    *   在列表查询中,必须考虑分页,使用`skip`和`take`参数。
4.  **API设计规范**:所有RESTful端点路径前缀为`/api/v1/`。响应体统一格式为:
    ```typescript
    {
      code: number, // 200表示成功,其他为业务错误码
      data: T | null, // 成功时返回的数据
      message: string // 对本次请求的说明,成功时为"Success"
    }
    ```

针对前端React/TypeScript的指令:

## 🎨 前端AI助手配置
**角色**:你是一位注重用户体验和代码可维护性的React高级工程师。

**核心指令**:
1.  **组件设计原则**:
    *   优先创建功能专注、可复用的Presentational组件。
    *   组件文件结构:`[ComponentName].tsx`(主组件)、`[ComponentName].styles.ts`(样式)、`[ComponentName].types.ts`(类型)、`[ComponentName].test.tsx`(测试)。
2.  **状态管理铁律**:
    *   **全局状态**:必须使用Redux Toolkit (RTK) 创建。每个功能模块对应一个`slice`,使用`createSlice` API。异步逻辑使用`createAsyncThunk`。
    *   **示例模式**:
        ```typescript
        // 正确:使用RTK的createSlice
        import { createSlice, PayloadAction } from '@reduxjs/toolkit';
        interface CounterState { value: number };
        const initialState: CounterState = { value: 0 };
        export const counterSlice = createSlice({ name: 'counter', initialState, reducers: { increment: (state) => { state.value += 1; }, }, });
        ```
    *   **局部状态**:使用`useState`, `useReducer`。当状态需要跨两个及以上紧密关联的兄弟组件共享时,考虑提升状态到父组件或使用RTK。
3.  **API交互**:使用项目中已封装的`axios`实例(位于`src/libs/api-client.ts`)进行网络请求,它已处理了基础URL、请求拦截和统一的错误响应处理。**禁止**在组件中直接使用`fetch`或创建新的`axios`实例。
4.  **样式方案**:使用Emotion(`@emotion/react`)进行CSS-in-JS样式编写。**禁止**使用行内style或导入普通的`.css`文件。

通过这样清晰的划分,当你在前端目录下提问时,AI会自动代入前端工程师的角色,遵守React和Redux的规范;当切换到后端目录,它又会以后端架构师的思维来思考问题。

2.3 TypeScript深度集成:让AI成为你的类型守卫

对于TypeScript项目,GEMINI.md可以发挥更强大的作用,迫使AI产出类型安全的代码,甚至帮你发现类型设计问题。

## 📐 TypeScript专项要求
本项目的TypeScript配置非常严格(`strict: true`)。请确保所有建议都通过类型检查。

**关键规则**:
- **禁止使用`any`**:在任何情况下都不允许使用`any`类型。如果暂时无法确定类型,优先使用`unknown`,并通过类型守卫进行收窄。
- **泛型应用**:在编写工具函数、自定义Hooks或API层代码时,积极使用泛型来增强代码的通用性和类型安全。
- **类型导入与导出**:为所有重要的数据模型、函数参数和返回值定义清晰的接口(`interface`)或类型别名(`type`),并集中管理在`src/types/`目录下。
- **示例:API响应类型**:
    ```typescript
    // src/types/api.ts
    export interface ApiResponse<T = any> {
      code: number;
      data: T;
      message: string;
    }

    // 使用示例:获取用户列表
    export interface User {
      id: string;
      name: string;
      email: string;
    }
    export type UserListResponse = ApiResponse<User[]>;
    ```
    AI在提供涉及API调用的代码时,必须引用或符合这些预定义的类型。

注意:你可以要求AI在给出代码后,附带一句“以上代码已通过假设的类型检查”,这虽然不能百分百保证,但能显著提高AI对类型问题的注意力。

2.4 通过示例教学:固化团队特有的模式

文字指令有时不如一个生动的例子。在GEMINI.md中提供“少样本示例”,是教会AI团队特有模式的最快方法。例如,你们团队可能有一种特殊的Redux异步状态处理模式。

## 🧪 实战问答示例

**场景一:使用RTK创建异步Thunk并处理加载状态**
用户提问:“需要在商品模块添加一个`fetchProducts`的异步action,要处理加载中和错误状态。”

期望的AI回答应包含:
1.  在对应的slice中,使用`createAsyncThunk`创建`fetchProducts`。
2.  在slice的`extraReducers`中,处理`pending`、`fulfilled`、`rejected`三种状态,更新相应的状态字段(如`loading`, `error`)。
3.  提供一个在组件中调用该action、并访问加载状态的示例。
4.  **关键模式**:错误信息应存储为字符串,并在下一次请求开始前清空。

**示例代码框架参考**:
```typescript
// productSlice.ts
export const fetchProducts = createAsyncThunk(
  'products/fetchAll',
  async (params: FetchParams, { rejectWithValue }) => {
    try {
      const response = await apiClient.get<ApiResponse<Product[]>>('/api/v1/products', { params });
      return response.data.data;
    } catch (error) {
      return rejectWithValue((error as Error).message);
    }
  }
);

const productSlice = createSlice({
  name: 'products',
  initialState: {
    items: [] as Product[],
    loading: false,
    error: null as string | null,
  },
  reducers: { clearError: (state) => { state.error = null; } },
  extraReducers: (builder) => {
    builder
      .addCase(fetchProducts.pending, (state) => { state.loading = true; state.error = null; })
      .addCase(fetchProducts.fulfilled, (state, action) => { state.loading = false; state.items = action.payload; })
      .addCase(fetchProducts.rejected, (state, action) => { state.loading = false; state.error = action.payload as string; });
  },
});

场景二:在后端创建一个具有验证和错误处理的RESTful端点 用户提问:“创建一个POST /api/v1/products 端点,用于创建商品,需要验证请求体,并处理可能出现的重复商品名错误。”

期望的AI回答应包含:

  1. 使用express-validator或类似中间件进行输入验证。
  2. 在控制器中,使用Prisma创建记录,并捕获PrismaClientKnownRequestError(如唯一约束冲突)。
  3. 将业务错误抛给统一的错误处理中间件。
  4. 返回符合ApiResponse格式的响应。

通过提供这样具体、高质量的示例,AI不仅能学会“做什么”,更能学会“怎么做”以及“按照我们的风格做”。

## 3. 高级技巧:让GEMINI.md动态化与智能化

一份基础的GEMINI.md已经能带来巨大提升,但我们可以更进一步,让它“活”起来。

**技巧一:利用文件包含规则聚焦上下文**
如果你的项目很大,每次都将所有代码作为上下文给AI既不经济也容易超出限制。你可以在GEMINI.md中指定关键目录。

```markdown
## 📁 文件上下文范围
为了让你更高效地理解项目,请优先关注以下目录的文件:
- `src/`:所有源代码。
- `prisma/`:数据库Schema和迁移文件。
- `public/locales/`:国际化文件。

以下目录和文件通常无需关注,除非问题明确涉及:
- `node_modules/`
- `dist/`、`build/`
- `*.config.js` 或 `*.config.ts` (构建配置)
- `.env.*` 文件

技巧二:集成项目特有的脚本与命令 将常用的开发命令也告诉AI,让它能给出更落地的操作建议。

## 🚀 项目常用命令
- **启动开发**:`npm run dev` (同时启动前后端开发服务器)
- **数据库迁移**:`npx prisma migrate dev`
- **生成Prisma客户端**:`npx prisma generate`
- **运行所有测试**:`npm test`
- **代码检查与格式化**:`npm run lint` 和 `npm run format`

技巧三:维护与迭代 GEMINI.md不是一成不变的。它应该随着项目演进而更新。

  • 当团队引入新的技术(如TanStack Query替换部分Redux逻辑),立即更新GEMINI.md。
  • 当发现AI在某个模式上反复犯错,就在“实战示例”部分增加一个针对性的正面示例。
  • 鼓励团队成员在遇到与AI的低效交互后,反思是否可以通过补充GEMINI.md的内容来避免未来类似问题。

4. 从工具到范式:重塑开发者与AI的协作关系

当你坚持使用并不断完善GEMINI.md后,你会发现,你与AI的协作模式发生了根本性变化。你不再是一个“提问者”,而更像是一个“技术主管”,在向一位能力超强、且完全理解项目背景和团队文化的“下属”布置任务。你节省下来的,不仅仅是重复解释技术栈的时间,更是那些因上下文误解而产生的代码返工、逻辑纠错和风格调整的隐性成本。

这份文件的价值,甚至会溢出到团队的人力协作中。它成为了一份最实时、最具体、最贴近代码的“项目编码规范手册”和“架构决策记录”。新成员 onboarding 时,除了看代码,研读这份GEMINI.md能让他以最快的速度理解团队的工程哲学。

最终,GEMINI.md代表的是一种思维转变:从期望AI去适应我们模糊、随性的表述,转变为由我们主动为AI构建一个清晰、精确、富含规则的协作环境。当你下次再遇到难题时,打开终端,你的“24小时技术顾问”已经就位,它熟知项目的每一个细节,正等着你用最精炼的语言,下达最高效的指令。

更多推荐