开源 Agent 套件 ECC 的根目录说明文件怎么写:一套可复制的结构

2026-07-29

本文基于 ECC 仓库 commit 591ab5c(2026-07-29)梳理,该项目仍在高频迭代,具体行为以仓库 https://github.com/affaan-m/ECC 最新代码与文档为准。

根目录那份给 Agent 看的说明文件,质量不取决于你写了多少条规则,而取决于每一条能不能被当场核对为真。 规则一旦和仓库现状脱节,Agent 不会报错,它会照着过期的说明去调一个已经不在默认加载路径里的命令,然后把失败原因归到别处。ECC 这个 MIT 许可证的开源套件把这类文件写得比多数项目细,也正因为写得细,它同时把这类文件最典型的失效方式暴露在了明面上——两件事都值得抄。

站内已经有两篇讲通用方法论的文章:CLAUDE.md 怎么写 讲的是从零起草一份说明文件的原则,Cursor Rules 最佳实践 讲的是规则文件在另一套工具里的组织方式。本篇不重复那两套方法论,它做的是另一件事:拿一个任何人都能 clone 下来逐行核对的真实项目,看它把说明文件切成了几层、每层放什么、哪些地方已经和仓库对不上,从这些具体决定里反推出一套你能直接搬走的结构。

一、它把”说明文件”切成了几层

打开 ECC 仓库根目录,跟 Agent 说明相关的入口不止一个,而是分工明确的一组。这个切法本身就是第一个可复制的决定:不要指望一份文件同时服务”在这个仓库里改代码的人”和”把这套东西装到自己项目里的人”。

组成部分它负责什么对应仓库位置你什么时候会碰到它
仓库自身的 CLAUDE.md在 ECC 这个仓库里干活时的指引:怎么跑测试、目录职责、贡献格式、文件命名CLAUDE.md你要给 ECC 提 PR,或想看它自己怎么约束自己
跨工具的 AGENTS.md通用操作规则:核心原则、可用 agent 一览、安全清单、编码风格、测试要求、工作流AGENTS.md你用的编码工具读这个通用文件,而不是 Claude 专属文件
常驻规则目录按主题和语言拆开的长期规则,避免全塞进一份文件rules/rules/common/ 下有 agents.md、security.md、testing.md、git-workflow.md 等,另有 python/golang/rust/react 等语言子目录)你想把规则模块化,只在相关语言的项目里加载对应部分
可抄走的模板给使用者直接复制到自己项目根目录的样例examples/CLAUDE.mdexamples/user-CLAUDE.mdexamples/saas-nextjs-CLAUDE.mdexamples/go-microservice-CLAUDE.md你要给自己的项目起草第一版说明文件
规则速查把”必须做/绝不做”和各类资产的格式约定压缩成一页RULES.md你要快速确认 agent、skill、hook 的文件格式要求
当下工作状态记录默认分支、当前约束、进行中的队列WORKING-CONTEXT.md你想知道这个仓库此刻在忙什么、有哪些禁区

README 里那张跨工具对照表把这层关系写死了:Claude Code 一侧的上下文文件是 CLAUDE.mdAGENTS.md,而 Cursor、Codex、OpenCode 一侧只认 AGENTS.md,GitHub Copilot 走 copilot-instructions.md。同一份文档还特意说明,ECC 不会把根 AGENTS.md 装进 .cursor/,理由是 Cursor 会把嵌套的 AGENTS.md 当成目录级上下文,这样做会把 ECC 自己的仓库身份污染进宿主项目。

这个细节比它看上去重要。它说明作者在设计时区分了两种内容:“这个仓库是什么”“在任何仓库里都该守什么”。前者绝不能外流到别人的项目里,后者才是可移植的。你自己写说明文件时也该做这道切割——把”本项目的部署地址、内部约定、当前迭代重点”和”通用工程纪律”分开放,否则模板一复制就是一堆噪声。

二、一份项目级说明文件该有哪些块

examples/ 目录里那几份模板是这篇文章最有复制价值的部分。把通用模板和真实技术栈模板并排看,能反推出一套稳定骨架。

examples/CLAUDE.md 是骨架版,块序是:Prompt Defense Baseline(提示注入防御基线)、Project Overview、Critical Rules(下分代码组织、代码风格、测试、安全四小节)、File Structure、Key Patterns、Environment Variables、Available Commands、Git Workflow。Project Overview 那一栏直接留的是方括号占位符,摆明了要你自己填。

examples/saas-nextjs-CLAUDE.md 是同一骨架填上真实技术栈之后的样子,块名几乎一一对应,但内容颗粒度完全不同。它的 Project Overview 只有两行:Stack 一行列清 Next.js(App Router)、TypeScript、Supabase、Stripe、Tailwind CSS、Playwright;Architecture 一行说清”默认 Server Components,只有需要交互时才用 Client Components,webhook 走 API routes,写操作走 server actions”。这两行干的事,是把后面所有规则的适用前提一次交代完。

examples/user-CLAUDE.md 则是另一个维度——它示范的是用户级(~/.claude/CLAUDE.md)该放什么:个人编码偏好、你希望在所有项目里都生效的通用规则、以及指向模块化规则文件的索引表。文件里那张表把 ~/.claude/rules/ 下每个文件负责的内容列了出来,本身就是一种”目录即导航”的写法。

把三份放在一起,可复制的骨架是这样的:

  1. 技术栈与架构判断(两三行,不写历史沿革)
  2. 关键规则(按数据库、认证、计费、代码风格这类真实边界分节,不按”好习惯”分节)
  3. 目录结构(带注释的树,注释写职责不写重复的目录名)
  4. 关键模式(真实存在于代码里的类型定义和函数骨架)
  5. 环境变量(分组列出,敏感项标注”仅服务端”)
  6. 测试策略(怎么跑、跑哪几类、关键流程有哪些)
  7. 工作流与 Git 约定(提交前缀、分支策略、CI 跑什么)

注意第 4 项的写法。examples/saas-nextjs-CLAUDE.md 里的 API 响应格式不是泛泛描述,而是一段真实的判别联合类型:

type ApiResponse<T> =
  | { success: true; data: T }
  | { success: false; error: string; code?: string }

examples/go-microservice-CLAUDE.md 同理,直接给出 domain 层哨兵错误和 handler 层映射到 gRPC 状态码的完整函数。这类片段的作用不是教学,而是消歧义——Agent 生成新接口时有一个可对齐的形状,不用猜。

三、规则写到什么颗粒度才有约束力

对比两类写法就能看出差距。AGENTS.md 里的 Coding Style 那节写的是”函数小于 50 行、文件小于 800 行、嵌套不超过 4 层”,这类规则可判定,Agent 能自查。而同一节里”Readable, well-named identifiers”这种就只是态度表达,落不了地。

真正有约束力的规则集中在语言与技术栈模板里,特征是每条都能被一次 grep 或一次 code review 判定真伪

  • SaaS 模板的数据库节:查询必须走开启了 RLS 的 Supabase 客户端,不得绕过;迁移只能放 supabase/migrations/,不许直接改库;select() 必须写显式列名而不是 select('*');面向用户的查询必须带 .limit()
  • 认证节里那条尤其典型:受保护路由用 getUser() 校验,不要单独信任 getSession()。这是一条真实踩过坑才写得出来的规则,Agent 照做就能避开一类安全问题。
  • Go 模板的错误处理节:用 %w 包装错误、禁止对错误做字符串匹配、禁止 init() 函数、context 必须是第一个参数并贯穿各层。

同样值得抄的是 ECC 自己 CLAUDE.md 末尾那张表——它把文件模式直接映射到该调用的技能:

| File(s) | Skill |
|---------|-------|
| `README.md` | `/readme` |
| `.github/workflows/*.yml` | `/ci-workflow` |
| `*.tsx`, `*.jsx`, `components/**` | `react-patterns`, `react-testing` — for React-specific work invoke `/react-review`, `/react-build`, `/react-test` |

紧跟着一句 When spawning subagents, always pass conventions from the respective skill into the agent's prompt.(派生专项 agent 时,务必把对应技能里的约定带进它的提示词)。这句话解决的是委派场景下最常见的丢失:主线程知道规则,被派出去的 agent 不知道。关于这类委派的机制细节,可以对照 Claude Code 的专项 agent 用法Skills 机制 一起看。

顺带一提,这套仓库里技能的落盘位置有专门的策略文件 docs/SKILL-PLACEMENT-POLICY.md,它把技能分成 curated、learned、imported、evolved 四类,只有 curated 那类放在仓库 skills/ 下并随安装清单分发,其余三类一律落在用户主目录、不进仓库,且来源必须可追溯——learned 与 imported 强制要求在 SKILL.md 旁放一个 .provenance.json,evolved 则从它的来源继承。这是个值得学的分界:仓库里的东西必须是经过审的,机器生成的东西留在本机、并且要带着自己是从哪来的记录。

四、边界与代价:这套写法放弃了什么

写得细是有账要还的,ECC 仓库里能直接看到这笔账。

第一笔是文档漂移。 CLAUDE.md 的 Key Commands 一节列了 /tdd/plan/e2e/code-review/build-fix/learn/skill-create。但仓库里 commands/ 目录下并没有 tdd.mde2e.md——它们躺在 legacy-command-shims/commands/ 里。那个目录的 README 写得很清楚:这些入口”不再由默认插件命令面加载”,只为还有肌肉记忆的老用户保留,建议直接用规范技能。legacy-command-shims/commands/tdd.md 自己也标注了维护中的工作流在 skills/tdd-workflow/SKILL.md。同样,CLAUDE.md 里映射表提到的 /readme/ci-workflow 也不在 commands/ 目录中。这就是本文开头那句判断的现场证据:说明文件跑在了仓库前面。

漂移不止一处。AGENTS.md 开头写着 67 个 agent、281 个技能、94 个命令,与 agents/skills/commands/ 目录实际数量对得上;但 WORKING-CONTEXT.md 顶部那行 Last updated 时间戳停在了几个月前,它 Current Truth 一节里记录的公开目录规模也明显是更早的一版,和 AGENTS.md 自己的数字对不上。这个仓库自己的 docs/ARCHITECTURE-IMPROVEMENTS.md 干脆把”说明文件里的计数与仓库实际不一致”列成了待办条目。这不是黑它,而是说明一件事:凡是写进说明文件的可数事实,都会过期,要么用脚本生成,要么别写。

第二笔是指令与执行的落差。 CLAUDE.mdexamples/CLAUDE.md 开头那段 Prompt Defense Baseline,内容是让模型不要变更身份、不要泄露密钥、把外部抓取的内容一律当不可信数据处理。这是一段文字约定,不是一道拦截。README 的对照表里也承认,Codex 一侧因为没有钩子执行能力,ECC 的约束只能是指令式的,靠 AGENTS.md 和沙箱审批设置来补。你如果需要真正的强制,得走钩子和权限那条路,可参考 Claude Code hooks 的机制

第三笔是它往你机器上写东西。 这类套件的本质是把大量文件铺到你的项目和主目录:仓库根有 install.shinstall.ps1,有 hooks/hooks.jsonmcp-configs/ 下的外部服务配置,技能策略文件里还明确规定生成物落在 ~/.claude/skills/learned/ 之类的路径。钩子意味着某些工具调用前后会执行本机脚本,MCP 配置意味着可能连出外部服务。装之前值得先看清这三处,不是因为它有问题,而是因为你要为自己机器上跑的每一行脚本负责

它明确不管的部分也要说清:这套说明文件不管你的业务领域知识,examples/CLAUDE.md 的 Project Overview 就是个空占位符;它给的硬指标(80% 覆盖率、文件 200 到 400 行典型上限、不可变更新优先)是一种取向,脚本工具、原型仓库、数据分析项目照搬多半会难受;它也不替你决定模型和服务商,涉及额度与限制的部分各家规则不同且会调整,以官方最新说明为准。

五、上手与避坑清单

别把命令名当稳定接口写进说明文件。 会踩,是因为斜杠命令看起来像 API,实际上它是随仓库结构迭代的软链接——ECC 自己就把 /tdd 挪进了兼容层。避法:说明文件里写”做 TDD 时使用测试驱动工作流技能”,把具体入口名放在一个单独的、离实现最近的位置,或者干脆让 CI 校验命令名存在。

别在说明文件里手写可数事实。 会踩,是因为写下”目前有 N 个模块”的那一刻它就开始过期,而 Agent 会照着这个数字做判断。避法:要么让脚本生成这段,要么改写成不依赖数字的描述。

通用模板和真实栈模板要分开维护。 会踩,是因为你会忍不住把公司内部路径、部署地址写进那份准备给所有项目复用的文件。ECC 的处理是 examples/ 下按栈拆成独立文件,并且刻意不把仓库自身身份注入到宿主项目。避法:起草时先问一句”这条规则换个项目还成立吗”,不成立的进项目级文件,成立的才进通用层。

规则要写成能判定的句子。 会踩,是因为”代码要可读""注意性能”这类句子读起来很对,但 Agent 无法据此做取舍,最后等于没写。避法:照 SaaS 模板那条”用 getUser() 校验、不要单独信任 getSession()”的格式改写——给出该做的动作、不该做的动作、以及边界。

给关键结构留一段真实代码。 会踩,是因为纯文字描述接口形状时,Agent 每次生成的字段名和错误处理方式都会飘。避法:像那份判别联合类型一样,直接贴出项目里真实存在的类型定义或函数骨架,贴的必须是仓库里跑得通的版本,不能是顺手编的。

装之前先读安装脚本和钩子配置。 会踩,是因为这类套件默认会改动主目录和项目目录,而钩子会在工具调用时执行本机命令。避法:先看 install.sh / install.ps1 干了什么、hooks/hooks.json 注册了哪些触发点、mcp-configs/ 里有哪些外部连接,确认能接受再装;不确定的部分优先用选择性安装而不是全量铺开。

收束

真要从这个仓库带走一件东西,是这个判断顺序:说明文件的每一条规则,先问”它可判定吗”,再问”它会过期吗”,最后才问”它写得好不好看”。前两问不过关,写得再漂亮也是给 Agent 制造幻觉。

给你一份落地前的自检清单:技术栈与架构前提是否在开头两三行讲清;关键规则是否每条都能被一次检查判定真伪;目录树的注释写的是职责还是重复目录名;关键接口有没有一段仓库里真实存在的代码;有没有手写会过期的计数;通用规则和本项目专属内容是不是分开放的;说明文件里提到的每一个入口名,是不是刚刚亲自确认过它还在。

想继续往下看,仓库里三份文件的信息密度最高:RULES.md 是压缩到一页的格式约定,docs/SKILL-PLACEMENT-POLICY.md 讲清了”审过的进仓库、生成的留本机”这条分界,WORKING-CONTEXT.md 则示范了如何把”当前约束和进行中的队列”单独成文——这一份恰恰是多数项目缺的那层。

本文属于 ECC 开源 Agent 套件专题(共 40 篇,从选择性安装一直拆到内部机制)。同一批还写了另一种取向的项目——不给你资产、只给你纪律的 superpowers 方法论专题

想系统学会用 AI?报名体系课或加入会员,照着学、照着用。