GEMINI.md 语法实战5个真实项目案例教你打造高效AI助手你是否曾有过这样的体验向AI助手描述一个复杂的项目需求得到的回复却总是隔靴搔痒要么过于通用要么偏离了你的技术栈和架构偏好对于中高级开发者而言通用AI模型的“万金油”式回答在真实的、复杂的项目面前往往显得力不从心。问题的核心在于AI缺乏对项目专属语境的深度理解。它不知道你的团队为何选择TypeScript而非JavaScript不清楚你的微服务边界如何划分更不明白你代码库中那些约定俗成的“潜规则”。这正是GEMINI.md存在的意义。它不是一个简单的配置文件而是一份为AI量身定制的“项目入职手册”和“编码规范指南”。通过这份文档你可以系统性地向AI灌输项目的灵魂——从业务目标、技术选型到代码风格和行为准则。今天我们不谈空洞的理论我将带你深入五个截然不同的真实项目场景从电商秒杀到医疗数据分析手把手演示如何运用GEMINI.md语法将AI从一个“聪明的实习生”训练成与你并肩作战的“资深架构师”。你会发现当AI真正理解了你的项目DNA它的产出将精准得令人惊喜。1. 高并发电商秒杀系统定义性能与安全的铁律电商秒杀场景是检验系统架构的试金石它要求极致的性能、坚如磐石的数据一致性以及严密的安全防护。一个通用的AI助手可能会给出使用Redis缓存的建议但我们需要的是能精确到毫秒级延迟、支持库存防超卖、并能抵御恶意请求的定制化方案。1.1 构建坚不可摧的项目上下文在GEMINI.md的开篇我们必须用最清晰的语言为AI勾勒出战场全景。这不仅仅是技术栈列表更是决策背后的深层逻辑。项目目标与核心挑战我们的目标是构建一个能支撑瞬时百万级请求的秒杀系统。核心业务价值在于在极短时间内如1秒内完成数万件热门商品的抢购同时保证绝对公平先到先得杜绝机器人和绝对准确库存不超卖订单不丢失。主要的挑战包括瞬时流量洪峰常规系统架构无法承受。库存竞争高并发下的数据一致性问题。防刷与安全识别并拦截黄牛脚本和恶意请求。系统韧性任何单点故障都可能导致灾难性后果。技术栈与选型理由这里需要详细说明“为什么”这能引导AI在后续建议中遵循同样的技术哲学。后端语言Go。选型理由是其卓越的并发原语goroutine, channel和接近C的性能特别适合高并发、低延迟的IO密集型场景。缓存与库存扣减Redis Lua脚本。选型理由是Redis的高性能内存读写结合Lua脚本的原子性执行可以确保库存查询和扣减在单次原子操作中完成是解决超卖问题的关键技术。消息队列Apache Kafka。选型理由是其高吞吐、持久化和分区能力用于将秒杀成功的请求异步化削峰填谷确保核心下单流程快速返回后续订单处理由消费者服务异步完成。数据库MySQLInnoDB引擎。选型理由是事务支持用于最终订单落库和成熟的生态。配合读写分离架构写主库读从库。网关与限流Nginx Lua (OpenResty)。选型理由是利用Nginx的高性能在接入层实现基于IP、用户ID的限流和恶意请求过滤。1.2 设定不容妥协的行为准则在这一部分我们要为AI塑造一个具有“秒杀系统架构师”思维的角色。AI角色定义你是一位专注于高并发、分布式系统与云原生架构的资深后端工程师。你的思维模式始终围绕性能、一致性、可用性、安全性PCAS四大原则展开。在给出任何方案时必须优先评估其对系统吞吐量、延迟和稳定性的影响。具体规则示例关于库存扣减所有涉及库存扣减的逻辑必须优先推荐使用Redis Lua脚本实现原子操作。禁止提出“先查询后判断再更新”的非原子化方案。关于响应设计所有核心秒杀接口如/seckill/submit的响应时间必须低于50毫秒。接口响应体应极度精简仅包含必要状态如success,code,requestId商品详情等富信息通过异步消息或后续查询接口获取。关于限流与降级当被问及如何保护系统时必须提及多层次防御接入层Nginx限流、服务层Sentinel/Hystrix熔断降级、以及业务层的队列缓冲。必须提供具体的配置片段或代码示例。1.3 通过关键示例进行“肌肉记忆”训练对于秒杀系统我们需要用示例固化最关键的模式。以下是一个“用户提交秒杀请求”的Few-shot Example用户提问 “帮我实现秒杀请求提交的核心处理函数需要检查库存并生成一个排队号。”期望的AI回答// services/seckill_service.go package services import ( context github.com/go-redis/redis/v8 strconv ) type SeckillService struct { rdb *redis.Client } // SubmitSeckillRequest 处理秒杀提交 func (s *SeckillService) SubmitSeckillRequest(ctx context.Context, userId int64, itemId string) (string, error) { // 1. 参数校验 (略) // 2. 使用Lua脚本原子化扣减库存并获取资格 luaScript : local stockKey KEYS[1] -- 库存键如 seckill:stock:..itemId local userQueueKey KEYS[2] -- 用户排队集合键 local userId ARGV[1] local stock tonumber(redis.call(GET, stockKey)) if not stock or stock 0 then return 0 -- 库存不足 end -- 原子操作库存减1并将用户加入排队集合 redis.call(DECR, stockKey) redis.call(SADD, userQueueKey, userId) return 1 -- 成功 stockKey : seckill:stock: itemId userQueueKey : seckill:queue: itemId result, err : s.rdb.Eval(ctx, luaScript, []string{stockKey, userQueueKey}, userId).Int() if err ! nil { return , err } if result 0 { return , errors.New(seckill item sold out) } // 3. 生成唯一的排队号例如结合时间戳、用户ID和随机数 queueNumber : generateQueueNumber(userId) // 4. 发送异步消息到Kafka由下游服务处理订单创建、支付等 // sendToKafka(seckill-success-topic, message) return queueNumber, nil } // generateQueueNumber 生成排队号示例 func generateQueueNumber(userId int64) string { // 实际项目可能使用雪花算法等分布式ID生成器 return strconv.FormatInt(time.Now().UnixNano(), 10) _ strconv.FormatInt(userId, 10) }关键点提示这个示例向AI强调了几个核心原子操作是生命线、响应要快操作主要在Redis内存中完成、成功后的复杂逻辑要异步化。AI在后续遇到类似问题时会优先采用这种模式。2. 金融数据实时分析平台确保准确性与可审计性金融领域对数据的准确性、处理时效和操作可追溯性有着近乎苛刻的要求。这里的GEMINI.md需要引导AI成为一个严谨、细致且极度重视数据一致性的“金融系统专家”。2.1 上下文定义不可撼动的数据原则项目核心目标构建一个处理实时交易流水、进行风险指标计算和生成监管报表的平台。首要原则是数据100%准确任何计算错误或数据丢失都是不可接受的。所有数据变更必须有完整的审计日志。技术栈与选型深意流处理框架Apache Flink。选型理由是其精确一次Exactly-Once的状态一致性保证这对于金融计算至关重要。同时其事件时间Event Time处理和状态后端State Backend能力适合复杂的时间窗口计算。数据存储时序数据库 InfluxDB 用于存储指标数据关系型数据库 PostgreSQL 用于存储维度数据和最终结果两者结合。选型理由是InfluxDB对时间序列数据的高效压缩和查询优化PostgreSQL满足复杂的关联查询和事务需求。消息中间件Apache Pulsar。选型理由是其原生的分层存储、多租户支持和强一致性适合金融级的数据管道。开发语言Java (Flink生态) 和 Python (用于数据分析脚本)。选型理由是稳定性和丰富的金融计算库如Pandas, NumPy。2.2 行为准则植入金融级开发规范AI角色定义你是一位具有金融行业背景的数据平台架构师。你对数字极其敏感坚信“垃圾进垃圾出”。你的代码必须包含完善的错误处理、数据校验和监控埋点。任何可能产生歧义或近似计算的地方都必须明确标出并给出误差范围说明。强制性规则列表数据完整性所有从消息队列消费数据的入口函数必须实现幂等性处理逻辑防止因重试导致数据重复计算。计算可追溯所有关键指标的计算公式必须在代码中以注释或配置文件的方式明确写出并注明数据来源和计算周期。审计日志任何对核心数据如账户余额、交易状态的修改操作必须在数据库事务提交前向专用的审计日志表或发送审计事件写入一条不可篡改的记录包含操作人、时间、旧值、新值和变更原因。数值处理涉及货币计算必须使用BigDecimalJava或decimal.DecimalPython等精确数据类型严禁使用float或double进行直接计算。2.3 示例定义一个风险指标计算任务让我们通过一个“计算实时交易波动率”的例子来示教AI。用户提问 “需要实现一个Flink作业实时计算某个交易对在过去5分钟内的滚动波动率标准差数据源来自Kafka。”期望的AI回答// RiskVolatilityJob.java import org.apache.flink.streaming.api.datastream.DataStream; import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment; import org.apache.flink.streaming.api.windowing.assigners.TumblingEventTimeWindows; import org.apache.flink.streaming.api.windowing.time.Time; import org.apache.flink.util.Collector; // ... 其他导入 public class RiskVolatilityJob { public static void main(String[] args) throws Exception { StreamExecutionEnvironment env StreamExecutionEnvironment.getExecutionEnvironment(); // 启用Checkpoint这是实现Exactly-Once语义的基础 env.enableCheckpointing(60000); // 每分钟一次Checkpoint // 1. 定义数据源假设Trade对象包含price和eventTime DataStreamTrade tradeStream env.addSource(new FlinkKafkaConsumer(trade-topic, new TradeDeserializer(), properties)) .assignTimestampsAndWatermarks(WatermarkStrategy.TradeforBoundedOutOfOrderness(Duration.ofSeconds(5)) .withTimestampAssigner((event, timestamp) - event.getEventTime())); // 2. 关键计算滚动窗口波动率 DataStreamVolatilityAlert volatilityStream tradeStream .keyBy(Trade::getSymbol) // 按交易对分组 .window(TumblingEventTimeWindows.of(Time.minutes(5))) // 5分钟滚动窗口 .process(new ProcessWindowFunctionTrade, VolatilityAlert, String, TimeWindow() { Override public void process(String key, Context context, IterableTrade trades, CollectorVolatilityAlert out) { ListDouble prices new ArrayList(); for (Trade t : trades) { prices.add(t.getPrice()); } // 使用Apache Commons Math或自定义函数计算标准差 double stdDev calculateStandardDeviation(prices); double mean calculateMean(prices); double volatility stdDev / mean; // 相对波动率 // 3. 审计与输出记录窗口时间、交易数量、计算结果 if (volatility THRESHOLD) { out.collect(new VolatilityAlert(key, context.window().getStart(), context.window().getEnd(), prices.size(), volatility, System.currentTimeMillis())); } // 同时可以将结果写入InfluxDB用于监控 } }); volatilityStream.addSink(new InfluxDBSink()); volatilityStream.print(); // 用于调试 env.execute(Real-Time Trade Volatility Calculation); } // 使用BigDecimal进行精确计算 private static double calculateStandardDeviation(ListDouble values) { // ... 实现细节注意使用高精度计算 } }注意这个示例不仅给出了代码框架更重要的是传递了金融数据处理的关键模式事件时间、精确一次语义、窗口计算、审计输出。AI在后续处理类似流计算任务时会自然地引入这些元素。3. 跨平台移动应用开发统一代码风格与组件契约当团队使用React Native或Flutter开发跨平台应用时最大的挑战之一是如何保持iOS和Android两端体验一致以及如何管理日益庞大的组件库。GEMINI.md在此处的使命是让AI成为团队代码规范的“守护者”和“活文档”。3.1 上下文确立多端一致的体验标准项目目标使用React Native开发一款面向全球用户的社交应用要求iOS和Android双端在UI/UX上保持高度一致性能流畅并具备良好的可访问性A11y。代码库需要良好的可维护性以支持数十名开发者的协同工作。技术栈与设计系统框架React Native 0.72。选型理由是一次编写多端运行拥有活跃的社区和丰富的第三方库。状态管理Zustand React Query。选型理由是Zustand的简洁API适合管理客户端状态React Query完美处理服务器状态数据获取、缓存、同步。UI组件库自定义组件库基于React Native Paper 自研主题封装。选型理由是实现设计统一和快速构建。导航React Navigation。选型理由是社区标准功能全面。类型系统TypeScript。选型理由是在大型项目中保障类型安全减少运行时错误。3.2 行为准则定义组件开发的“宪法”AI角色定义你是一位注重细节、对用户体验有极致追求的前端技术专家。你深谙React Native的最佳实践并致力于编写声明式、可复用、可测试的组件。你时刻考虑性能如列表优化和可访问性。核心开发规则组件设计所有通用UI组件必须使用React.forwardRef暴露Ref以便父组件进行必要的控制。组件属性Props必须使用TypeScript接口明确定义并为其提供详细的JSDoc注释。样式管理禁止在组件内部使用内联样式style{{}}。所有样式必须通过StyleSheet.create创建或引用自全局主题Theme文件。颜色、字体、间距等必须使用主题变量如theme.colors.primary。列表性能当渲染可能很长的列表时必须优先使用FlatList或SectionList并正确实现keyExtractor和getItemLayout如果可行以优化性能。可访问性所有可交互元素按钮、链接必须包含accessible和accessibilityLabel属性。图片必须提供accessibilityHint。3.3 示例创建一个标准的按钮组件通过一个按钮组件的创建示例我们可以固化团队的UI开发规范。用户提问 “我们需要一个通用的PrimaryButton组件支持不同尺寸、加载状态并且要符合我们的设计主题。”期望的AI回答// src/components/Buttons/PrimaryButton.tsx import React from react; import { TouchableOpacity, Text, ActivityIndicator, StyleSheet, ViewStyle, TextStyle } from react-native; import { useTheme } from ../../theme/ThemeContext; /** * 主按钮组件用于应用中最主要的操作。 * param {Object} props - 组件属性 * param {string} props.title - 按钮显示的文本 * param {() void} props.onPress - 点击回调函数 * param {small | medium | large} [props.sizemedium] - 按钮尺寸 * param {boolean} [props.loadingfalse] - 是否显示加载状态 * param {boolean} [props.disabledfalse] - 是否禁用按钮 * param {ViewStyle} [props.style] - 额外的容器样式 */ interface PrimaryButtonProps { title: string; onPress: () void; size?: small | medium | large; loading?: boolean; disabled?: boolean; style?: ViewStyle; } const PrimaryButton: React.ForwardRefRenderFunctionTouchableOpacity, PrimaryButtonProps ( { title, onPress, size medium, loading false, disabled false, style }, ref ) { const theme useTheme(); // 根据尺寸和状态决定样式 const getButtonStyle (): ViewStyle { const baseStyle: ViewStyle { backgroundColor: disabled ? theme.colors.disabled : theme.colors.primary, borderRadius: theme.borderRadius.medium, justifyContent: center, alignItems: center, flexDirection: row, }; const sizeMap: RecordPrimaryButtonProps[size], { paddingVertical: number; paddingHorizontal: number } { small: { paddingVertical: theme.spacing.xs, paddingHorizontal: theme.spacing.sm }, medium: { paddingVertical: theme.spacing.sm, paddingHorizontal: theme.spacing.md }, large: { paddingVertical: theme.spacing.md, paddingHorizontal: theme.spacing.lg }, }; return { ...baseStyle, ...sizeMap[size], ...style }; }; const getTextStyle (): TextStyle ({ color: theme.colors.onPrimary, fontSize: theme.typography.button[size], fontWeight: 600, marginLeft: loading ? theme.spacing.xs : 0, }); const handlePress () { if (!disabled !loading) { onPress(); } }; return ( TouchableOpacity ref{ref} style{getButtonStyle()} onPress{handlePress} disabled{disabled || loading} accessible{true} accessibilityLabel{loading ? ${title}加载中 : title} accessibilityRolebutton {loading ActivityIndicator sizesmall color{theme.colors.onPrimary} /} Text style{getTextStyle()}{loading ? 处理中... : title}/Text /TouchableOpacity ); }; export default React.forwardRef(PrimaryButton);这个示例向AI展示了几个关键模式使用TypeScript接口定义强类型的Props、从主题上下文获取样式、实现完整的可访问性支持、处理加载和禁用状态。当开发者后续请求创建其他组件如Card、InputField时AI会遵循同样的结构和规范进行输出。4. 物联网设备管理后台处理异构数据与复杂状态机物联网项目通常需要对接成百上千种型号、协议各异的设备后台系统要处理海量的遥测数据、设备状态变更和反向控制指令。这里的GEMINI.md需要帮助AI理解“物模型”的概念和复杂的状态流转逻辑。4.1 上下文抽象设备定义统一语言项目核心构建一个管理智能家居设备的云平台支持设备注册、状态监控、固件升级和规则引擎。核心挑战是设备协议的多样性和设备状态管理的复杂性。技术架构与选型设备接入MQTT Broker (EMQX)。选型理由是MQTT协议轻量、适合物联网场景EMQX支持集群和高并发连接。数据管道Apache Kafka用于接收设备上报的海量遥测数据Telemetry和事件Event。核心服务使用Go编写设备影子Device Shadow服务。选型理由是Go的高并发能力适合处理大量设备连接。数据存储时序数据库TDengine存储设备遥测数据PostgreSQL存储设备元数据、关系和状态。选型理由是TDengine对时序数据的高效处理能力。物模型采用JSON Schema定义设备的属性Properties、服务Services和事件Events这是平台与设备交互的“合约”。4.2 行为准则成为物联网领域的“协议转换器”AI角色定义你是一位物联网平台架构师擅长将物理世界的设备抽象为数字世界的模型。你对MQTT、CoAP等物联网协议有深刻理解并善于设计最终一致性的分布式状态管理系统。关键设计规则设备影子模式所有设备状态必须通过“设备影子”服务进行中介。设备上报状态更新影子“期望状态”应用下发指令也是修改影子“期望状态”由影子服务负责与设备同步解决网络不稳定带来的状态不一致问题。物模型驱动所有设备相关的业务逻辑如数据解析、指令下发必须基于物模型Thing Model的定义来开发不能硬编码设备型号。消息处理处理设备消息时必须考虑消息的QoS等级和可能的重试机制。对于关键指令如固件升级必须实现确认和超时重传逻辑。数据降采样长期存储的遥测数据必须提供降采样策略如将1秒级数据聚合成1分钟、1小时的平均值以节省存储空间。4.3 示例实现一个设备影子状态更新服务让我们通过一个设备影子服务处理状态更新的例子来训练AI。用户提问 “设备通过MQTT上报了它的在线状态和温度属性影子服务该如何处理这条消息并更新数据库”期望的AI回答// internal/shadow/handler.go package shadow import ( encoding/json context github.com/emqx/emqx-webhook-client/client gorm.io/gorm log ) // DeviceShadow 表示设备影子结构 type DeviceShadow struct { gorm.Model DeviceID string gorm:uniqueIndex Reported JSONB gorm:type:jsonb // 设备上报状态 Desired JSONB gorm:type:jsonb // 应用期望状态 Metadata JSONB gorm:type:jsonb // 时间戳等元数据 Version int64 // 影子版本用于乐观锁 ConnectionStatus string // 在线/离线 } // HandleDeviceReport 处理设备上报消息 func (s *ShadowService) HandleDeviceReport(ctx context.Context, msg *client.Message) error { var report map[string]interface{} if err : json.Unmarshal(msg.Payload, report); err ! nil { return err } deviceID : msg.Topic.GetDeviceID() // 假设从Topic解析出设备ID if deviceID { return errors.New(invalid topic, cannot extract device id) } // 1. 根据物模型验证上报数据 thingModel, err : s.modelRepo.GetByDeviceID(ctx, deviceID) if err ! nil { return err } if !thingModel.ValidateReported(report) { return errors.New(reported data does not conform to thing model) } // 2. 开启事务更新设备影子 tx : s.db.WithContext(ctx).Begin() defer func() { if r : recover(); r ! nil { tx.Rollback() } }() var shadow DeviceShadow // 使用乐观锁防止并发更新冲突 result : tx.Where(device_id ?, deviceID).First(shadow) if result.Error ! nil { // 设备影子不存在创建新的 shadow DeviceShadow{ DeviceID: deviceID, Reported: JSONB(report), ConnectionStatus: online, Version: 1, } if err : tx.Create(shadow).Error; err ! nil { tx.Rollback() return err } } else { // 更新现有影子 updateData : map[string]interface{}{ reported: report, connection_status: online, version: gorm.Expr(version 1), metadata: gorm.Expr(jsonb_set(metadata, {reported, timestamp}, to_jsonb(now()), true)), } // 使用版本号进行乐观锁更新 if err : tx.Model(DeviceShadow{}).Where(device_id ? AND version ?, deviceID, shadow.Version).Updates(updateData).Error; err ! nil { tx.Rollback() return err // 更新失败可能版本冲突由调用方决定重试或告警 } } // 3. 检查上报状态与期望状态是否一致若一致则清除期望状态delta同步完成 if shadows.ReportedMatchesDesired(shadow.Reported, shadow.Desired) { if err : tx.Model(shadow).Update(desired, nil).Error; err ! nil { tx.Rollback() return err } } // 4. 将状态变更事件发布到Kafka供规则引擎等其他服务消费 event : ShadowUpdatedEvent{DeviceID: deviceID, Reported: report, Timestamp: time.Now()} if err : s.producer.SendEvent(ctx, event); err ! nil { tx.Rollback() return err } return tx.Commit().Error }提示这个示例涵盖了物联网后台的核心模式物模型验证、影子文档的乐观锁更新、状态同步delta处理以及事件驱动架构。AI在理解这个模式后对于处理设备离线、指令下发、固件升级状态跟踪等场景都能举一反三。5. 内容管理系统CMS与无头架构解耦与灵活性的艺术现代内容管理不再局限于简单的文章发布而是需要支持多终端Web、APP、小程序、多渠道分发的“无头CMS”Headless CMS。GEMINI.md在这里要指导AI如何设计一个内容模型驱动、API优先、高度可扩展的后台系统。5.1 上下文拥抱无头CMS的设计哲学项目愿景构建一个为公司官网、博客、帮助中心、移动端提供统一内容源的后台系统。编辑人员在一个后台创建内容多个前端通过API消费。核心需求是内容模型的灵活定义和强大的版本管理能力。技术选型与架构核心框架Strapi (Node.js) 或 Directus。选型理由是它们提供了开箱即用的无头CMS能力支持自定义内容类型、角色权限和REST/GraphQL API。我们选择基于Strapi进行二次开发。数据库PostgreSQL。选型理由是对JSONB字段的良好支持便于存储灵活的内容结构。前端消费Next.js (SSG/SSR) 用于官网React Native用于APP。它们都通过GraphQL API从Strapi获取内容。媒体存储AWS S3 或 Cloudinary。选型理由是可扩展的对象存储支持图片、视频等资源的优化和CDN分发。部署Docker容器化部署在Kubernetes上便于水平扩展。5.2 行为准则塑造内容领域的“建模专家”AI角色定义你是一位精通无头CMS和现代前端架构的全栈开发者。你深刻理解“内容即数据”的理念善于将复杂的业务内容抽象为可复用、可组合的内容模型Content Type。你注重API设计和开发体验。核心开发原则模型先行在编写任何代码之前必须先定义清晰的内容模型Content Type。每个模型应具有明确的用途字段设计需考虑前端展示的便利性如提供富文本、图片、关联字段等。API设计所有内容API必须支持国际化i18n和草稿/发布状态。提供灵活的过滤、排序、分页参数。优先考虑提供GraphQL API以获得前端数据获取的最大灵活性。Webhook与事件驱动当内容发布、更新或删除时必须触发Webhook事件以便同步到搜索引擎、刷新CDN缓存或通知其他系统。权限控制基于角色的访问控制RBAC必须精细到字段级别。例如市场人员可以编辑文章内容但无法修改SEO设置而SEO专家则相反。5.3 示例定义一个“博客文章”内容模型及其API通过定义最常见的“博客文章”模型我们可以展示如何将业务需求转化为技术实现。用户提问 “我们需要在Strapi中创建一个‘BlogPost’内容类型支持多语言、作者关联、标签分类并生成对应的GraphQL API。”期望的AI回答 首先在Strapi后台或通过代码方式定义内容模型 (api/blog-post/content-types/blog-post/schema.json){ kind: collectionType, collectionName: blog_posts, info: { singularName: blog-post, pluralName: blog-posts, displayName: 博客文章, description: 用于发布博客文章 }, options: { draftAndPublish: true // 启用草稿/发布功能 }, pluginOptions: { i18n: { localized: true // 启用国际化 } }, attributes: { title: { type: string, required: true, pluginOptions: { i18n: { localized: true } } }, slug: { type: uid, targetField: title }, content: { type: richtext, required: true }, excerpt: { type: text }, coverImage: { type: media, multiple: false, required: false }, publishedAt: { type: datetime }, author: { type: relation, relation: manyToOne, target: plugin::users-permissions.user, // 关联用户表 inversedBy: blogPosts }, tags: { type: relation, relation: manyToMany, target: api::tag.tag, // 关联标签表 inversedBy: blogPosts }, seo: { type: component, repeatable: false, component: shared.seo // 复用SEO组件 } } }然后AI可以进一步说明如何通过Strapi自动生成的GraphQL API进行查询# 前端如Next.js中的GraphQL查询示例 query GetPublishedBlogPosts($locale: I18NLocaleCode!, $limit: Int!, $start: Int!) { blogPosts( locale: $locale publicationState: LIVE # 只查询已发布的内容 sort: publishedAt:desc pagination: { limit: $limit, start: $start } ) { data { id attributes { title slug excerpt publishedAt coverImage { data { attributes { url formats } } } author { data { attributes { username avatar { data { attributes { url } } } } } } tags { data { attributes { name slug } } } } } meta { pagination { total pageSize pageCount page } } } }注意这个示例不仅展示了模型定义还关联了前端消费的GraphQL查询。它向AI传递了无头CMS的核心工作流定义模型 - 自动生成管理界面和API - 前端通过API消费。当需要创建“产品”、“案例”等内容类型时AI会遵循同样的模式。通过这五个跨度极大的项目案例我们看到了GEMINI.md如何像一位经验丰富的导师在不同领域为AI助手注入特定的领域知识和工程原则。从电商的毫秒级性能要求到金融的数据洁癖再到物联网的状态机复杂性每一份GEMINI.md都是项目独特DNA的编码。其力量不在于语法的复杂性而在于描述的精确性和思维框架的传递。当你开始为自己的项目编写GEMINI.md时不妨从回答这几个问题开始我的项目最不能妥协的原则是什么我的团队有哪些心照不宣的最佳实践我最希望AI在哪些地方发挥最大价值回答这些问题本身就是一次宝贵的项目复盘与架构梳理。最终你会发现最好的GEMINI.md就是把你最希望团队成员拥有的那种思维模式清晰无误地告诉你的AI伙伴。