AI Agent 指令分层工程:System Prompt、总地图与条件加载

System Prompt 是每次请求发给模型的特权指令通道(Runtime Payload)。AGENTS.mdrules 不是与它并列的l提示词,而是本地源配置:Agent 工具读取它们,连同内置人格和工具定义,缝合成这一通道。两套「地图」不要混用:AGENTS.md 是每轮都在的总索引(约 100 行鸟瞰 + 指针 +「这里不存在什么」);rules 是路径命中才缝进 payload 的条件指引,注入的是规则正文,不自动挂载外部文档。Skills 是任务型操作手册,按需读取。选型看:这条句子要不要进最终 System Prompt、在什么条件下进、进了之后谁来维护。

结论先行

  1. 三者不是并列关系。 System Prompt = 运行时产物;AGENTS.md / rules / skills / 工具内置提示 = 源配置。你在 ~/.agents/AGENTS.md.cursor/rules/ 里写的每一句,本质是在模块化地重构本地 Agent 的 System Prompt。
  2. 谁能改 System Prompt,取决于入口。 API 调用通过 system / system_instruction / developer 完全重写。Agent / IDE 不要改工具源码,用 AGENTS.md、rules、以及少数工具的 SYSTEM.md 做拼装入口。
  3. AGENTS.md = 宪法 / 总地图。 约 100 行鸟瞰:慢变量、入口命令、红线、「这里不存在什么」,用指针链到专业文档。没打开任何文件时也要找得到门。1000 行单文件会挤占干活窗口。
  4. Rules = 部门规章 / 条件地图。 glob 命中时进入 payload 的是 rule 正文,不是 docs/*.md 自动挂载。正文可写成短不变量,或写成「先读某文档」的指针;后者不保证文档已在窗口里。没附匹配文件时,条件地图整份缺席。alwaysApply: true 不是微观控制。Skills 才是「按任务打开手册」的原语。排除选项比枚举选项更省上下文。
  5. 「正在读写匹配文件才注入」是简化说法。 命中判定发生在组请求、拼装 System Prompt 时,依据的是本轮已在场的文件集合,不是每一次 read/write 瞬时插一段。
  6. 可移植的是 Markdown 句子,不可移植的是条件调度器。 .cursor/rules/*.mdc 不能被 Pi / Codex / Gemini CLI 直接识别。跨工具用嵌套 AGENTS.md 或「一份正文 + 薄适配器」。
  7. 安全红线必须进常驻 System Prompt。 放在 glob rule 里等于没命中就没有红线。
  8. Rule 是提示,不是执行。 「必须走统一错误类型」真正强制的是 linter / 类型检查;rule 只告诉 Agent 怎么写才能过检查。
  9. 先问「这句要不要出现在本轮发给模型的 System Prompt 里」,再决定放哪一层源文件。

一、System Prompt:运行时产物

System Prompt(系统提示词)是大模型对话里最底层的元指令(Meta-Instruction)。它在用户消息之前进入模型的特权指令通道,预先设定角色身份、行为边界、输出格式、安全红线以及工具调用约定。

各家 API 字段名不同:OpenAI 现多用 developer(旧称 system),Anthropic 用 system,Gemini 用 system_instruction。部分 Agent 会把项目上下文做成 system 消息里的标记区块,而不是独立 role。对使用者只需记:用户提问之前、模型已经看见的那一整段系统侧指令 = 本轮 System Prompt(Runtime Payload)。

它本身通常不落盘。落盘的是用来生成它的源文件。

谁可以改

角色 能改到哪一层 入口
API 调用 100% 重写 请求里的 system / system_instruction / developer
Agent / IDE(Pi、Cursor、Codex、Claude Code、Aider) 间接、高度可控 不改工具源码。用 AGENTS.md、rules、以及 Pi 的 SYSTEM.md / APPEND_SYSTEM.md 作为拼装入口

Agent 工具的内置 System Prompt 是底膜(工具如何调用、安全策略);你写的 Markdown 是往这块底膜上缝内容,不是替换整张膜------除非工具明确提供「替换系统提示」的文件(Pi 的 SYSTEM.md)。替换底膜会丢掉工具用法,一般不要用。

运行管线:源配置 → 调度层 → Runtime Payload

它们不是三种提示词,而是配置文件与最终产物:

flowchart TB subgraph src[&#34;源配置 磁盘&#34;] direction TB s1[&#34;工具内置:底膜 + 工具定义&#34;] s2[&#34;SYSTEM.md / APPEND_SYSTEM.md&#34;] s3[&#34;全局 AGENTS.md&#34;] s4[&#34;项目 AGENTS.md 含嵌套与 override&#34;] s5[&#34;本轮命中的 rules&#34;] s6[&#34;Skill 的 name + description&#34;] end src --> sched[&#34;调度层:读取、过滤、模板化、拼接&#34;] sched --> payload[&#34;最终 System Prompt<br/>本轮 API 特权指令通道&#34;] payload --> llm[&#34;发送给 LLM&#34;] llm --> after[&#34;其后:对话 / @ 文件 / 工具结果&#34;]
典型文件 进入 System Prompt 的方式 默认是否常驻
产品底膜 工具内置 system prompt + 工具 schema 每轮整份
底膜替换/追加 SYSTEM.mdAPPEND_SYSTEM.md 每轮整份 若存在则是
用户/全局人格 ~/.pi/agent/AGENTS.md~/.claude/CLAUDE.md、Cursor User Rules 每轮整份
仓库总章程 根目录 AGENTS.md / CLAUDE.md / .github/copilot-instructions.md 每轮整份
模块化规则 .cursor/rules/*.mdc.claude/rules/*.md.github/instructions/*.md 命中才把正文缝进去 不一定
技能索引 SKILL.md 的 name / description 每轮只有短描述 描述常驻,正文否
本轮对话 用户消息、@ 文件、会话记忆、工具结果 不在 System Prompt,在后续 messages

调度层做的事:

  1. 载入工具底膜和工具 schema
  2. 按目录向上收集 AGENTS.md / CLAUDE.md
  3. 用本轮文件集合跑 glob,决定哪些 rules 正文进入 payload
  4. 把 Skill 目录(通常只有描述)挂上
  5. 拼成一条(或少数几条)系统侧消息

你维护的是左侧源文件。模型看见的是右侧产物。排障「AI 不听话」时,要问的是:这句有没有进入本轮 payload,而不是磁盘上有没有这个文件。

Pi 对「底膜」和「上下文」的拆分

Pi 把源文件分成两类,但发送时都进系统侧:

文件 作用
内置 system prompt 底膜:身份、工具用法
~/.pi/agent/SYSTEM.md.pi/SYSTEM.md 替换底膜
APPEND_SYSTEM.md(全局或项目) 追加到底膜,不替换
AGENTS.md / CLAUDE.md / AGENTS.override.md 上下文文件,拼在系统侧的项目指令区
Skills 描述进系统侧;正文按需 read,进入的是后续消息,不是 System Prompt 正文

--no-context-files / -nc 只关掉 AGENTS.md / CLAUDE.md,不停底膜。


二、三大概念对照

维度 System Prompt AGENTS.md Rules(如 .cursor/rules
本质 单次 API 请求的特权指令通道 跨工具的全局/项目宏观配置 特定 IDE / 工具内部的微观条件规则
存在形态 内存中的文本(API payload) 磁盘上的 Markdown 磁盘上的 .md / .mdc
生效机制 每次对话前整体注入 system / developer 作用域 初始化时被读取并挂进 payload 按 glob 或操作类型动态决定是否缝进 payload
控制主体 工具底层机制 / API 开发者 开发者 / 团队 / 用户 开发者 / 团队 / 用户
标准 各家 API 字段不同 跨工具(agents.md 厂商私有格式
粒度 本轮全量系统指令 一层目录一份地图(可嵌套);细则用指针 多文件、一主题一份
Token 本轮系统侧全量计费 每轮都付费;故应约 100 行 可只在命中时付费
主语 模型本轮必须服从的全部系统句 仓库 / 人;不变量用「不存在」写 文件类型
人读性 运行时才能看见完整拼接结果 高,像地图 中,目录一多就要索引

再加一层 Skills,避免和 rules 混用:

Skills
本质 任务型操作手册
进 payload 的部分 通常只有 description
正文 匹配后 read,进入对话而非 System Prompt
主语 任务类型

记忆:

  • System Prompt = 本轮发给模型的成品
  • AGENTS.md = 宪法 / 总地图(每轮在,约 100 行,指针 + 不存在)
  • rules = 部门规章 / 条件地图(命中才在;注入的是正文,不是外部文档自动挂载)
  • skills / docs = 操作手册(源,正文延迟加载)

三、AGENTS.md:给地图,不给手册

agents.md 是约定,不是某一家产品功能:仓库里给编码 Agent 看的地图。工具读取后,把它缝进 System Prompt 的项目指令区。

上下文窗口是稀缺资源。约 100 行的 AGENTS.md 充当鸟瞰,用指针链到更深层的专业文档;1000 行单文件说明书会挤占真正干活的空间,长指令还会中间遗忘。地图只展示很少变化 的内容:入口命令、安全红线、架构不变量、指向手册的路径。会随功能迭代的细则放在 docs/、子树 AGENTS.md、rules 或 Skill 里,Agent 需要时再读。根地图只负责总索引 ;按路径才出现的强调句见 [五、两套地图:总索引 vs 条件指引](#五、两套地图:总索引 vs 条件指引 "#%E4%BA%94%E3%80%81%E4%B8%A4%E5%A5%97%E5%9C%B0%E5%9B%BE%EF%BC%9A%E6%80%BB%E7%B4%A2%E5%BC%95%20vs%20%E6%9D%A1%E4%BB%B6%E6%8C%87%E5%BC%95")。

写什么(地图层)

  • 怎么构建、测试、lint、提交(唯一入口命令)
  • 鸟瞰:主要目录各干什么,细则指针指向哪里
  • 很少变化的风格与错误处理约定
  • 安全红线(禁止生产迁移、禁止提交密钥)
  • 这里不存在什么(架构不变量,见下)

用「不存在」写不变量

告诉 Agent 这个项目里不用什么,往往比枚举「用什么」更有效。排除选项比展开选项更省上下文,也更难过期:技术选型清单会变长,禁区相对稳定。

markdown 复制代码
## 这里不存在
- 不用 ORM,SQL 写在 `src/db/queries/`
- 不用 GraphQL,对外走现有 HTTP 接口
- 不引入新的状态管理库,UI 状态跟邻接文件
- 不在应用代码里读环境变量以外的密钥源

「用 Postgres + 手写 SQL + 本目录 query 文件」若还要列出所有允许的库、所有表访问模式,那是手册。地图只封死 ORM / GraphQL 这条岔路。

不写什么(手册层,用指针)

  • 某个子包的实现细节 → docs/data.mdsrc/db/AGENTS.md
  • 某文件类型的 import 顺序 → rule / linter
  • 会随重构过期的目录长文 → 架构文档,地图里留一行链接
  • 大段示例代码 → 专业文档或测试;过期示例会变成错误示范
  • 历史、愿景、架构叙事 → docs/,需要时再读

加载特征

  • 会话开始读入,拼进系统/项目上下文(即 System Prompt 的一部分)
  • 可从 cwd 向上走父目录,嵌套仓库叠多层
  • 一份文件服务多种 Agent(Codex、Pi、Claude Code 兼容层、部分 Copilot/Cursor 等)

Pi 的具体行为

  • 全局:~/.pi/agent/AGENTS.md
  • 从 cwd 向上找 AGENTS.mdCLAUDE.md,全部拼接
  • 同目录有 AGENTS.override.md 时,只替换该目录AGENTS.md/CLAUDE.md,其他层仍保留
  • --no-context-files / -nc 可关掉
  • 改完 /reload,不必重启

Pi 没有 glob rules。条件细则的对应物是 Skill,或子树嵌套 AGENTS.md,或自行写扩展扫描 .claude/rules/

推荐骨架

markdown 复制代码
# 项目名

## 地图
- 架构:`docs/architecture.md`
- 数据:`docs/data.md`(改 `src/db` 时先读)
- 前端:`docs/frontend.md`(仅前端目录;校验库等细则见该文档,不要写进根地图)

## 命令
- 开发:`pnpm dev`
- 检查:`pnpm check`(改完必须跑)
- 测试:`pnpm test -- <相关文件>`

## 这里不存在
- 不用 ORM,SQL 写在 `src/db/queries/`
- 不用 GraphQL,对外走现有 HTTP 接口
- 不引入新的状态管理库

## 硬约束
- 不要提交 .env / 密钥
- 不要在本地跑生产迁移
- 公共 API 变更必须同步更新调用方

## 代码
- 跟随邻接文件的既有模式,不引入新抽象除非消除真实重复
- 生成代码后跑 `pnpm check`

篇幅目标:约 100 行。80--150 行是舒适区,超过约 200 行就该把细则改成指针。它每轮都进 System Prompt:1000 行单文件会挤占干活空间,长指令还会中间遗忘。


四、Rules:往 System Prompt 上做条件缝合

rules 没有单一国际标准,是各家 harness 的「可拆分、可条件加载」指令。调度器决定本轮要不要把这段正文写进 System Prompt

共同设计目标:

  1. 别把所有细则塞进一份永远在场的大文件
  2. 按 glob / 路径 / 描述自动挂上
  3. 一条规则一个主题,方便评审和复用

三态调度(微观控制的状态机)

css 复制代码
flowchart LR
  A["Always<br/>alwaysApply: true"] --> A2["正文每轮进 payload<br/>不是微观控制"]
  B["Auto Attached<br/>globs"] --> B2["命中才进正文"]
  C["Agent Requested / Manual<br/>仅 description"] --> C2["模型选用或 @rule"]
类型 Frontmatter 索引是否常驻进 System Prompt 正文何时进入 System Prompt
Always alwaysApply: true 正文常驻 每轮。不是微观控制
Auto Attached globs: ... 通常只有文件名/描述 本轮上下文文件命中 glob
Agent Requested / Manual description 只有描述 模型选用,或用户 @rule

真正省窗口的是后两种。Always 只改善可维护性,对 System Prompt 体积的效果与写在 AGENTS.md 里相同。

命中集合从哪来

组请求、拼装 System Prompt 时收集文件集合再跑 glob:

flowchart LR tabs[&#34;打开的 tab&#34;] --> set[&#34;本轮文件集合&#34;] at[&#34;用户 @ 的文件&#34;] --> set rw[&#34;本轮读过或改过的文件&#34;] --> set recent[&#34;最近 tab 视产品而定&#34;] --> set set --> glob{&#34;跑 glob&#34;} glob -->|命中| inn[&#34;rule 正文缝进 System Prompt&#34;] glob -->|未命中| out[&#34;本轮 payload 无此 rule&#34;]

反直觉后果:

  1. 只问「查询层该怎么设计」、没附任何 src/db 文件 → Auto Attached 可能不进本轮 System Prompt;Agent Requested 才可能被模型拉进来。
  2. 同时改 src/db/user.tssrc/ui/Button.tsx → db rule 与 UI rule 可能同时缝进同一条 System Prompt,跨层任务上微观控制失效。
  3. Agent 先 read 了匹配文件、下一轮才组新请求 → 有的产品把已读文件算进命中集,有的要等显式 attach。不要假设「读到就立刻改写 System Prompt」。
  4. glob 写 src/db/**/*.ts,实际是 .sql.ts.bak → 不命中,本轮 payload 里没有这段。

写 rule 时把触发源想成:人类或 Agent 已经把哪些路径放进了这轮上下文,而不是「磁盘上存在匹配文件」。

各家形态

Cursor --- .cursor/rules/*.mdc

yaml 复制代码
---
description: 修改 src/db 下查询与迁移时使用
globs: src/db/**/*.ts
alwaysApply: false
---
SQL 只放本目录 queries/。禁止改已合入的旧迁移文件。

四种挂载:Always / Auto Attached(globs)/ Agent Requested(description)/ Manual(@rule)。

Claude Code --- CLAUDE.md(≈ AGENTS.md)+ .claude/rules/*.md

yaml 复制代码
---
paths:
  - src/db/**/*.ts
---

用户级:~/.claude/CLAUDE.md

GitHub Copilot

  • .github/copilot-instructions.mdAGENTS.md
  • .github/instructions/*.instructions.md + applyTo ≈ rules

Windsurf --- .windsurf/rules/*.md,字段名随版本变,精神同 glob。

Cline / Roo --- .clinerules.clinerules/,条件能力弱于 Cursor .mdc

Pi --- 原生不读上述目录。官方示例扩展 claude-rules.ts:启动扫描 .claude/rules/,把清单 追加进 System Prompt,正文仍要模型 read。这是 Agent Requested,不是 Auto Attached。

锁定不只是路径不同,还有:glob 语法、多条命中是拼接还是覆盖、description 是否进入可点选目录、用户规则/项目规则/团队规则的合并顺序。即使人工搬运正文,触发器也会丢------触发器属于调度层,不属于可移植的 System Prompt 句子。


五、两套地图:总索引 vs 条件指引

AGENTS.md 的指针和 rules 的「先读某文档」看起来都像地图,调度器不同,缺席时的后果也不同。混用会导致:总索引里没有门、干活时手册没加载、或者同一段细则进 payload 两次。

区别

AGENTS.md 总地图 Rules 条件地图
出现时机 每轮都在 System Prompt 本轮文件集合命中 glob(或 Agent 选用)才在
没打开匹配文件时 指针仍在,问「API 怎么设计」也找得到门 整份缺席,包括指针
调度器注入的内容 地图正文本身 rule 正文本身 ,不是外部 docs/ 自动挂载
专业文档何时进窗口 Agent 按指针 read(不保证) 同左;若把手册贴进 rule,则命中时整份在
主语 仓库:门在哪、禁区是什么 文件类型:碰这类路径时强调什么
跨工具 否(厂商 Frontmatter)
失败形态 地图过长,挤占干活窗口 假触发 / 漏触发;或把 1000 行手册贴进 rule

根地图回答:任何任务 如何找到专业文档。

条件地图回答:已经在改这类文件时,还要强调哪几条、要不要再去读哪份文档。

Rules 的两种写法(不要当成同一种)

正文即短手册。 glob 命中 → 这些句子一定在 payload 里。适合 5--15 条路径级不变量(统一日志、错误类型、禁止越层访问)。这是条件加载约束,不是加载 docs/data.md

正文当指针。 命中后 payload 里只有「先读 docs/data.md」。文档进不进窗口,取决于模型是否 read。多数编码 Agent 会跟,调度器不强制。排障时不要把「rule 在磁盘上」当成「专业文档已在上下文里」。

把 1000 行 docs/data.md 贴进 glob rule:拥挤从「每轮」挪到「每次碰 src/db」。条件地图同样给地图、不给全书。

没有通用 Frontmatter 如 attach: docs/data.md。要保证长文在窗口里,只能:短约束写进 rule 正文、或让 Agent/Skill 去 read

和 Skill 的边界

意图 放哪
任何任务都要找得到入口 AGENTS.md 一行指针
碰某类文件时强调短不变量 / 再读哪份文档 glob rule(短正文)
长流程、多文件必读清单(先 A 再 B 再跑 C) Skill

Skill 的主语是任务类型;rule 的主语是文件类型。修 Bug、发版、导翻译用 Skill,不要用 glob 假装任务触发。

叠法(总索引留门,条件层强调,手册不常驻)

rust 复制代码
flowchart TB
  root["根 AGENTS.md<br/>每轮在:总索引<br/>数据细则见 docs/data.md"]
  rule[".cursor/rules/db.mdc<br/>仅 src/db/**/*.ts<br/>短不变量 + 先读 docs/data.md"]
  doc["docs/data.md<br/>专业文档,按需 read"]
  root -.->|"指针始终可见"| doc
  rule -.->|"命中后提醒再读"| doc

根上不写某目录的实现细则(那是手册)。rule 上不承担「没打开对应文件时也能找到门」(那是总索引)。docs/data.md 不进常驻 System Prompt。

跨 Cursor / CLI 时:条件层用 src/db/AGENTS.md 代替 .mdc,总索引仍然在仓库根。不要在根地图复制 rule 正文。


六、Token 与服从度

System Prompt 按本轮全量计费。常驻源文件有硬成本:200 行 AGENTS.md × 每轮请求,长会话里重复吃几万 token。模型对长指令会中间遗忘,越长越容易只记住头尾。

经验阈值:

载体 建议
全局 / 仓库 AGENTS.md 约 100 行地图;80--150 舒适,超 200 改成指针。1000 行单文件会挤占干活窗口
单条 rule 一屏能看完,约 30--80 行
Skill description 短触发条件;正文按需加载,不进 System Prompt

账本示例(尚未计底膜和工具 schema):

css 复制代码
flowchart LR
  subgraph all["全缝进 payload"]
    a["AGENTS 400 + API 200 + UI 200 + DB 300 + 测试 150 = 1250 / 轮"]
  end
  subgraph globbed["只改 src/db 且 db rule 为 glob"]
    b["AGENTS 400 + API 200 = 600 / 轮"]
  end

三种情况把账打穿:

  1. Always 规则过多 --- 拆文件零收益,System Prompt 体积不变
  2. glob 过宽 --- **/*.{ts,tsx} 等于 always
  3. Agent Requested 描述目录过长 --- 50 条 × 80 token 描述 = 4000 token 索引,可能比直接注入几条正文更贵

最优形态:少量 always(宪法)+ 少量窄 glob(部门法)+ 少量高价值 Agent Requested(判例) 。规则文件数量不是专业度。System Prompt 应瘦,源文件可以多------前提是调度器真的会过滤。


七、优先级与冲突

拼进同一条 System Prompt 之后,模型看到的是平铺文本。没有宇宙统一优先级,多数工具接近:

flowchart TB u[&#34;1. 用户当轮明确指令<br/>在后续 messages&#34;] --> sec[&#34;2. 工具内置安全策略<br/>底膜,一般不要替换&#34;] sec --> near[&#34;3. 更近目录的 AGENTS.md&#34;] near --> user[&#34;4. 用户级全局 AGENTS / User Rules&#34;] user --> root[&#34;5. 仓库根 AGENTS.md&#34;] root --> rules[&#34;6. 模块 rules / Skill 描述&#34;]

用户当轮指令通常压过系统侧的风格偏好,但压不过工具硬编码的安全策略。更近的目录上下文(如 packages/app/AGENTS.md)压过仓库根。

仓库根建议写死:

lua 复制代码
冲突时:用户本轮指令 > 本目录 AGENTS.md > 仓库根 AGENTS.md > 全局 AGENTS.md
path-specific rules 只补充,不推翻更高层的安全红线。

安全类句子(密钥、生产破坏、许可证)必须进入常驻 System Prompt,不要只放在可能不被缝合的 rule 里。

同一约束不要在 AGENTS.md 和 rule 里复制。两处都会进 payload 时,改一处漏一处,模型还会收到矛盾句。

SYSTEM.md 替换底膜时,确认工具用法和安全句还在。缺工具说明的 System Prompt 会让 Agent 不会用工具。


八、微观控制:能做 / 不能做

能做(且值得做成 rule,条件缝进 System Prompt)

  • 该路径上的 API 形状、校验库、错误码
  • 测试文件的放置与命名
  • 某目录禁止的依赖或模式(src/db 不许直接碰外部 HTTP)
  • 生成代码的局部格式(迁移文件只追加、不改已合入版本)

不能做

意图 应放
任何任务都要找得到某手册 AGENTS.md 一行指针(总索引)
碰某类文件时的短不变量 glob rule 正文(条件地图,5--15 条)
碰某类文件时再读哪份文档 glob rule 里一行指针;文档本身不贴进 rule
安全红线 AGENTS.md / always(保证进每一轮 System Prompt)
替换工具底膜 仅当明确需要时用 SYSTEM.md;默认用 AGENTS.md 追加
跨目录重构 更粗的 rule,或 Skill
长流程、多文件必读清单 Skill(正文不要常驻 System Prompt)
与打开文件无关的问答 根地图短入口;不要只写在 glob rule 里
「必须走统一错误类型」的强制执行 linter / 类型检查;rule 只给写法
把专业文档全文条件灌入 无此原语;短约束进 rule,长文按需 read

rule 的主语应是文件类型,不是任务类型。

  • 「写查询时 SQL 只放 src/db/queries」→ rule(条件进入 System Prompt)
  • 「修 Bug 先下日志」→ Skill(不要撑大 System Prompt)
  • 「永远用中文回复」→ AGENTS.md(每轮 System Prompt 都需要)

九、怎么写才叫微观

glob 要窄到误挂成本低

makefile 复制代码
# 差:几乎任何前端改动都挂上,等于 always 进 System Prompt
globs: "**/*.{ts,tsx}"

# 差:包含了测试,测试文件会吃到运行时约束
globs: "src/db/**"

# 好:只覆盖实现文件
globs:
  - "src/db/**/*.ts"
  - "!src/db/**/*.test.ts"

不是所有产品支持否定 glob。不支持就拆成 api.mdcapi-test.mdc

正文只写可执行约束

好:

markdown 复制代码
- SQL 只放 `src/db/queries/`,不要在 handler 里拼字符串
- 错误走仓库统一的 Result/错误码,不要 throw 字符串
- 日志走项目 logger,不要 `console.log`

差:愿景、考古、40 行易过期示例。Rule 是编译器警告的自然语言版:短、可违反时可被发现、不讲故事。它一旦命中,就是 System Prompt 的一部分,废话会占窗口。

description 给调度器用

makefile 复制代码
# 差
description: API 相关规范

# 好
description: 编写或修改 src/db 下查询与迁移时使用。SQL 只放 queries/,禁止改已合入迁移。

Agent Requested 全靠这一句决定要不要把正文拉进 System Prompt。空泛 = 乱触发或永不触发。

一条 rule 一个变化轴

api-validation.mdcapi-response.mdc 只有总是同时适用才合并。合并后无法单独关闭,微观控制变粗,System Prompt 也无法按轴裁剪。


十、按工具落地

你想表达 Cursor Claude Code Copilot Pi Codex
改工具底膜 少用 少用 少用 SYSTEM.md 替换 / APPEND_SYSTEM.md 追加 产品设置
跨工具项目章程 AGENTS.md AGENTS.mdCLAUDE.md 可另写 copilot-instructions.md,或让工具读 AGENTS AGENTS.md AGENTS.md
全局个人习惯 User Rules ~/.claude/CLAUDE.md VS Code user instructions ~/.pi/agent/AGENTS.md 用户级 AGENTS
某目录细则 .cursor/rules/*.mdc + globs .claude/rules/ .github/instructions/ + applyTo Skill,或嵌套 AGENTS.md 嵌套 AGENTS / skills
专项流程 Skills Skills 自定义 agent Skills Skills

Monorepo:AGENTS.md 写公共命令和红线;apps/web/AGENTS.mdpackages/db/AGENTS.md 写局部。这是不依赖厂商 rules 的可移植拆分,各工具仍把它们缝进 System Prompt。

覆盖同目录旧文件: Pi 用 AGENTS.override.md,避免再写一份补充说明造成双重指令同时进入 payload。

对抗厂商锁定

不要维护三份语义不同的规则。维护一份正文,多份薄适配器。正文是未来 System Prompt 的句子;适配器只提供调度器能读的 Frontmatter。

flowchart TB subgraph portable[&#34;可移植层 进 git&#34;] d1[&#34;docs/agent/rules/api.md<br/>纯约束,无 frontmatter&#34;] d2[&#34;根 AGENTS.md<br/>地图:慢变量 + 指针 + 这里不存在&#34;] d3[&#34;src/db/AGENTS.md<br/>零锁定的子树约束&#34;] end subgraph adapters[&#34;调度层薄包装&#34;] c1[&#34;.cursor/rules/api.mdc&#34;] c2[&#34;.claude/rules/api.md&#34;] c3[&#34;.github/instructions/api.instructions.md&#34;] end d1 --> c1 d1 --> c2 d1 --> c3

嵌套 src/db/AGENTS.md 不是 glob 那么精准(进了子树就可能带上),但 Codex、Pi、Claude、部分 Cursor 都会沿目录树上卷,零锁定 。微观控制要求极高再上 .mdc;要跨工具先用嵌套 AGENTS.md

Pi 等价物:

意图 Pi
替换/追加底膜 SYSTEM.md / APPEND_SYSTEM.md
宪法(进 System Prompt 项目区) AGENTS.md
某子树默认约束 src/db/AGENTS.md
任务型流程 Skill(description 进 System Prompt,正文按需读)
仿 Cursor glob 自己写扩展,按当前文件集合注入 System Prompt

十一、决策流程

flowchart TD start{&#34;这句要进本轮 System Prompt 吗?&#34;} start -->|&#34;是,且每个任务都要&#34;| always{&#34;改的是什么&#34;} always -->|&#34;工具底膜 / 工具用法&#34;| leave[&#34;不要动<br/>必要时 APPEND_SYSTEM.md&#34;] always -->|&#34;项目约定 / 总索引 / 这里不存在&#34;| agents[&#34;仓库 AGENTS.md&#34;] always -->|&#34;个人习惯&#34;| global[&#34;全局 AGENTS.md / User Rules&#34;] start -->|&#34;否,或只要有时出现&#34;| sometimes{&#34;触发条件&#34;} sometimes -->|&#34;匹配某些路径&#34;| path{&#34;内容多长&#34;} path -->|&#34;5-15 条不变量或先读&#34;| glob[&#34;glob rule 条件地图&#34;] path -->|&#34;整份专业文档&#34;| pointer[&#34;不要贴进 rule<br/>指针 + 按需 read&#34;] sometimes -->|&#34;某类任务长流程&#34;| skill[&#34;Skill&#34;] sometimes -->|&#34;某子树且跨 CLI&#34;| nested[&#34;该子树 AGENTS.md&#34;]

检查清单:

  • 删掉这句,Agent 会在任意任务上找不到门或犯错吗?会 → 根 AGENTS.md 总索引
  • 没附 src/db 文件时还需要这句吗?需要 → 不能只写在 glob rule 里
  • 这句会随功能迭代经常改、或超过几行才能说清?→ docs/ + 总索引一行指针;rule 里最多再留一行「先读」
  • 能用「不用 X」代替「用 A/B/C/D」吗?→ 写排除,不写枚举
  • 只在碰某类文件才错、且能写成短句?→ rule 正文(条件地图)
  • 只在「发版 / 翻译导入 / 查 Jira」这类任务才需要?→ Skill
  • 这句是在教模型「你是谁、工具怎么用」?→ 底膜;不要写进 AGENTS.md 重复一份,更不要用 SYSTEM.md 覆盖后丢掉工具说明
  • 根地图和 rule 是否复制了同一段细则?复制则删成「根指针 + rule 短约束」
  • 写完后:有没有和更高层对打、或过期路径?有就删

十二、失败模式与反模式

管线层

  • 以为磁盘有文件就等于模型看见了。 没命中 glob、被 -nc 关掉,本轮 System Prompt 里没有这句。
  • SYSTEM.md 整段替换底膜。 工具调用说明消失,Agent 变成不会用工具的聊天模型。
  • 把 Skill 正文粘进 AGENTS.md 长流程常驻 System Prompt,窗口被操作手册撑满。
  • AGENTS.md 写成 1000 行单文件手册。 地图变成全书,干活空间被挤占;细则应指针化。

Rules 特有

  • 假触发。 glob **/*route*src/ui/Router.tsx 算进去,错误句子进了 System Prompt。
  • 漏触发。 文件在 src/data/,规则写 src/db/。看起来像「AI 不听话」,其实 payload 里没有规则。排障第一步:看产品「本轮已附加 rules」UI,或导出本轮 system 消息。
  • 跨层任务失效。 「给这个 API 补前端表单」会同时缝两侧,或只缝打开的那一侧。
  • 规则互殴。 src/db/v2/** 同时命中 v1 与 v2,两条矛盾句出现在同一条 System Prompt。各家很少做最长前缀获胜。自己保证 glob 互斥。
  • 用 rule 当 linter。 模型会忘。强制约束放机器检查。
  • 在 Auto Attached 里写安全禁令。 没打开匹配文件时,本轮 System Prompt 没有禁令。
  • 把条件地图当成总索引。 只在 glob rule 里写 docs/data.md 指针:没附匹配文件时门也不见。
  • 把总索引当成条件加载。AGENTS.md 写满某子域实现细则:改 CSS 也每轮付费。
  • 以为 rule 指针 = 文档已加载。 注入的是「先读」四个字,不是 docs/data.md 正文。
  • 把专业文档全文贴进 glob rule。 碰该目录时窗口被手册挤占,与 1000 行 AGENTS.md 同类。

通用

  • AGENTS.md 写成第二份 README 或全书(全部常驻进 payload)
  • 用枚举技术栈代替「这里不存在」:允许列表会膨胀,禁区更稳、更短
  • 全部 alwaysApply: true(System Prompt 体积与不拆相同)
  • rules 与 AGENTS 复制同一段(地图里应只留指针)
  • 用 400 行 always-on rule 模拟 Skill
  • 为「完整」塞示例 diff
  • 为了「专业」堆规则文件(描述索引本身会撑大 System Prompt)

十三、最小落地模板

三层不要互相抄正文。

仓库根 AGENTS.md总地图 ,约 100 行,每轮进 System Prompt):入口命令、红线、「这里不存在」、指向 docs/ 的指针。不要抄全局人格,不要把某子域实现细则贴进来。

markdown 复制代码
## 地图
- 数据:`docs/data.md`(改 `src/db` 时先读)

.cursor/rules/db.mdc条件地图 ,命中才进 System Prompt):短不变量 + 再读哪份文档。不要贴 docs/data.md 全文。

yaml 复制代码
---
description: 修改 src/db 下查询与迁移时使用
globs: src/db/**/*.ts
alwaysApply: false
---
先读 `docs/data.md`。
- SQL 只放 queries/
- 禁止改已合入的旧迁移文件
- 错误走仓库统一 Result,不要 throw 字符串

docs/data.md:专业文档,按需 read

跨 CLI 时,条件层用 src/db/AGENTS.md 代替 .mdc,总索引仍在仓库根。

前端 TypeScript HTTP 层若使用 Zod 一类校验库,只写在该目录的 rule / docs/frontend.md 里,作为路径级特例,不要写进根地图或当成所有仓库的统一模板。

需要追加底膜而不替换时(Pi):~/.pi/agent/APPEND_SYSTEM.md.pi/APPEND_SYSTEM.md


十四、一句话选用

System Prompt 是成品;AGENTS.md / rules / skills 是源。

两套地图:AGENTS.md 是每轮都在的总索引 (约 100 行慢变量 + 指针 +「这里不存在」);rules 是路径命中才出现的条件指引 (注入 rule 正文,不自动挂载 docs/)。宪法进总索引,路径级短约束进 rule,长手册进 docs/ / Skill 按需读。

Rules 的微观控制 = 用 glob/description 当调度器,决定哪些局部句子写进本轮 System Prompt。精度取决于「本轮文件集合 ∩ glob」。Always 没有微观;过宽 glob 没有微观;没附匹配文件时条件地图整份缺席。任务型流程用 Skill,不要用 glob 假装。排除比枚举更省窗口。调度器可以锁在厂商目录里,即将进入成品的句子必须另有一份无 frontmatter 的来源。

相关推荐
Lambert2811 小时前
AgentScope Java 从零(07):官方有权限引擎,我却在工具里写了个 if
java·后端·ai编程
青梅煮酒论英雄1 小时前
我们是怎么让 AI 找到那个 Bug 的
agent·ai编程·harness
赵赵4301 小时前
AI 写前端,优化的是演示,不是交付
ai编程
ClouGence1 小时前
从 Prompt 到可复用作业辅导助手:我搭了一个 AI 作业批改工作流
人工智能·aigc·ai编程
9i编程2 小时前
1. 把 DDD 开源脚手架化为自己的:先读懂它——Spring Boot 4.1 的四层架构、多数据源与领域事件
人工智能·openai·ai编程
wangruofeng2 小时前
开源看板 Multica:让人和 26 个 AI Agent 共用一个团队
aigc·agent·ai编程
wangruofeng2 小时前
Pro 七个月没转正,Flash 四个月连发四代 Stable,写代码怎么选?拆解 Gemini 两条产品线分化逻辑。
google·aigc·ai编程
OpsEye3 小时前
公司内部全员使用 AI,如何保证会话合规、行为可审计?
javascript·ai编程
DO_Community3 小时前
DigitalOcean vs OpenRouter:2026 年 AI 模型路由对比
人工智能·agent·ai编程·agi