单一事实源:在一个项目里同时管理 AGENTS、CLAUDE、GEMINI 和 Cursor Rules
2026-02-11
· 585 words · ~ 3 min read
在同一个仓库里同时支持 Claude Code、Codex、Gemini CLI、Cursor 时,最容易遇到的问题是:同一条规则写了四份,最后四份不一致。
本文给一个可落地方案:单一事实源 + 多工具适配层 。
目标
只维护一份核心规则。
允许各工具保留少量差异补丁。
自动生成目标文件,减少手工编辑。
子目录可以加增量规则,不污染全局。
推荐目录
1
2
3
4
5
6
7
8
9
10
11
12
docs/ai/
core.md
tooling/
claude.md
codex.md
gemini.md
cursor.md
scopes.list
scopes/
content/blog.md
scripts/
sync-ai-configs.sh
工作流
在 docs/ai/core.md 写所有工具共享规则(单一事实源)。
在 docs/ai/tooling/*.md 写各工具专属补丁。
在 docs/ai/scopes.list 列出需要子目录增量规则的路径。
在 docs/ai/scopes/*.md 写对应子目录的增量规则。
运行脚本生成目标文件。
生成命令
1
2
3
4
5
6
7
8
# 只预览,不落盘
scripts/sync-ai-configs.sh
# 实际写入
scripts/sync-ai-configs.sh --apply
# 强制覆盖已有手工文件(谨慎)
scripts/sync-ai-configs.sh --apply --force
脚本全文(可直接复制)
点击展开 sync-ai-configs.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
#!/usr/bin/env bash
set -euo pipefail
ROOT_DIR = " $( cd " $( dirname " ${ BASH_SOURCE [0] } " ) /.." && pwd ) "
AI_DIR = " $ROOT_DIR /docs/ai"
APPLY = 0
FORCE = 0
while [[ $# -gt 0 ]] ; do
case " $1 " in
--apply) APPLY = 1; shift ;;
--force) FORCE = 1; shift ;;
*) echo "Usage: $0 [--apply] [--force]" >& 2; exit 2 ;;
esac
done
require_file() { [[ -f " $1 " ]] || { echo "Missing file: $1 " >& 2; exit 1; } ; }
read_file() { cat " $1 " ; }
is_generated_file() {
[[ -f " $1 " ]] || return 1
head -n 1 " $1 " | rg -q "AI-CONFIG: GENERATED"
}
write_target() {
local target = " $1 " content = " $2 "
mkdir -p " $( dirname " $target " ) "
if [[ -f " $target " && $FORCE -ne 1 ]] ; then
if ! is_generated_file " $target " ; then
echo "SKIP (manual file): ${ target # $ROOT_DIR / } "
return 0
fi
fi
if [[ $APPLY -eq 1 ]] ; then
printf "%s\n" " $content " > " $target "
echo "WRITE ${ target # $ROOT_DIR / } "
else
echo "PLAN ${ target # $ROOT_DIR / } "
fi
}
build_root_doc() {
local tool = " $1 "
cat <<EOF
<!-- AI-CONFIG: GENERATED. DO NOT EDIT DIRECTLY. -->
# $(tr '[:lower:]' '[:upper:]' <<<"$tool") Instructions
$(read_file "$AI_DIR/core.md")
$(read_file "$AI_DIR/tooling/$tool.md")
EOF
}
build_scope_doc() {
local tool = " $1 " scope = " $2 " scope_file = " $3 "
cat <<EOF
<!-- AI-CONFIG: GENERATED. DO NOT EDIT DIRECTLY. -->
# Scope Instructions: $scope
本文件仅定义当前目录的增量规则,不重复全局规则。
$(read_file "$scope_file")
$(read_file "$AI_DIR/tooling/$tool.md")
EOF
}
build_cursor_rule() {
local scope = " $1 " scope_file = " $2 "
cat <<EOF
---
description: Generated scope rule for $scope
globs:
- $scope/**
alwaysApply: false
---
<!-- AI-CONFIG: GENERATED. DO NOT EDIT DIRECTLY. -->
# Cursor Scope Rule: $scope
$(read_file "$scope_file")
EOF
}
require_file " $AI_DIR /core.md"
require_file " $AI_DIR /scopes.list"
require_file " $AI_DIR /tooling/claude.md"
require_file " $AI_DIR /tooling/codex.md"
require_file " $AI_DIR /tooling/gemini.md"
require_file " $AI_DIR /tooling/cursor.md"
write_target " $ROOT_DIR /AGENTS.md" " $( build_root_doc codex) "
write_target " $ROOT_DIR /CLAUDE.md" " $( build_root_doc claude) "
write_target " $ROOT_DIR /GEMINI.md" " $( build_root_doc gemini) "
while IFS = read -r scope || [[ -n " $scope " ]] ; do
[[ -z " $scope " || " $scope " = ~ ^# ]] && continue
scope_id = " ${ scope // \/ /- } "
scope_file = " $AI_DIR /scopes/ ${ scope } .md"
require_file " $scope_file "
write_target " $ROOT_DIR / $scope /AGENTS.md" " $( build_scope_doc codex " $scope " " $scope_file " ) "
write_target " $ROOT_DIR / $scope /CLAUDE.md" " $( build_scope_doc claude " $scope " " $scope_file " ) "
write_target " $ROOT_DIR / $scope /GEMINI.md" " $( build_scope_doc gemini " $scope " " $scope_file " ) "
write_target " $ROOT_DIR /.cursor/rules/generated- ${ scope_id } .mdc" " $( build_cursor_rule " $scope " " $scope_file " ) "
done < " $AI_DIR /scopes.list"
[[ $APPLY -eq 0 ]] && echo -e "\nDry run only. Use --apply to write files."
生成结果
脚本会生成或更新:
根目录:AGENTS.md、CLAUDE.md、GEMINI.md
子目录:<scope>/AGENTS.md、<scope>/CLAUDE.md、<scope>/GEMINI.md
Cursor 规则:.cursor/rules/generated-<scope>.mdc
说明:
默认会跳过手工文件(非模板生成文件),避免误覆盖。
目标文件头部有 AI-CONFIG: GENERATED 标记,便于识别。
子目录规则示例
如果 content/blog 有特殊约束,只需要写增量:
文章要有明确日期锚点。
能用表格/列表时优先表格/列表。
工具能力对比要优先引用官方链接。
这样全局规则继续在根目录生效,子目录只补差异。
为什么不建议一份文件硬链给所有工具
可以共享大部分内容,但不建议 100% 共用单文件,原因有三个:
工具语义不同,同一句规则执行效果可能不同。
各工具有专属能力(rules/policy/skills),需要少量补丁。
版本迭代快,强耦合会增加回归风险。
实践上,建议共享 80%-90%,剩下 10%-20% 留给工具适配层。
流程图
flowchart TD
A[docs/ai/core.md<br/>单一事实源] --> B[docs/ai/tooling/*.md<br/>工具差异补丁]
A --> C[docs/ai/scopes/*.md<br/>子目录增量]
B --> D[scripts/sync-ai-configs.sh]
C --> D
D --> E[AGENTS.md]
D --> F[CLAUDE.md]
D --> G[GEMINI.md]
D --> H[.cursor/rules/generated-*.mdc]
E --> I[本地/CI 使用]
F --> I
G --> I
H --> I
I --> J[CI 漂移检查<br/>sync 后 git diff --exit-code]
#AI 配置
#AGENTS.md
#CLAUDE.md
#GEMINI.md
#Cursor Rules
#Skills
← Previous
Claude Code、Codex、Gemini、Cursor 记忆与规则配置对比
Next →
Ubuntu Server 忘记密码后如何重置密码
Table of Contents