23 万 Star 的仓库里没有一行业务代码,ECC 把 prompt 固化成了文件

发布于 2026年07月29日 01:20 #Github 解读#Agent 框架 原文链接

23 万 Star 的仓库里没有一行业务代码,ECC 把 prompt 固化成了文件 封面图
  • ECC 将 prompt 工程升级为持久化系统,通过 Agent、Skill、Rule、Hook 四层结构约束 AI 行为
  • Hook 层在模型上下文之外强制执行,如 GateGuard 强迫 Agent 先调查再改文件
  • Continuous Learning 从用户习惯中提取 instinct,实现项目级隔离避免跨项目污染
  • 项目 bus factor=1,高度依赖单人,商业化与社区贡献需平衡可持续性
  • 安装使用有隐藏成本,建议从 minimal profile 开始,逐步测试 hook 兼容性

如果你打开一个 23 万 Star 的 GitHub 仓库,期待看到精妙的算法、高性能的内核、或者至少一个像样的框架,ECC 会让你愣一下。

它的 agents/ 目录里是 67 个 Markdown 文件,skills/ 里是 281 个 Markdown 文件,commands/ 里是 94 个。真正能跑的代码,藏在 scripts/hooks/ 里,加起来还不到整个仓库体积的一个零头。

这不是一个 bug,这是它的全部设计哲学。

ECC 全称 Everything Claude Code,现在改名叫「the agent harness operating system」。它不解决任何具体的业务问题,它解决的是一个更底层的问题,当你每天和 Claude Code、Codex、Cursor 这些 AI 编程助手打交道时,那些你反复在 prompt 里叮嘱的事情,能不能固化下来,变成 Agent 自动遵守的纪律。

大家好,我是若风。今天拆的这个项目很特殊,它代表了一类正在兴起的工程实践,把 prompt 工程从「每次重打字」升级成「装一次,永久生效」。

一个 Agent 到底缺什么

先说清楚 ECC 要解决的问题。

你让 Claude Code 帮你加个功能,它很能写代码。但它不会主动先写测试。你提醒它用 TDD,它这次照做了,下一个会话又忘了。你让它 review 自己刚写的代码,它会一边写一边夸自己写得好,因为上下文里全是它刚才的产出,它没有「抽离感」。

这些问题的根源是,Agent 的能力全在上下文窗口里。上下文一刷新,一切归零。你花十分钟精心组织的 prompt 指令,换个会话就没了。

ECC 的作者 affaan-m 想明白了一件事。与其每次在 prompt 里重复「请先写测试」「请 review」「请检查安全」,不如把这些要求变成 Agent 运行时的一部分。它的核心理念浓缩成一句话,放在 README 最显眼的位置。

Optimize the context window. Persist everything else.

优化上下文窗口,把其他一切持久化下去。这句话基本概括了 ECC 的全部设计逻辑。

四层「外挂系统」是怎么搭起来的

理解 ECC 最关键的一点,是搞清楚它的四个核心概念,agent、skill、hook、rule,它们各自负责什么,为什么不能合成一个。

我读完源码后的理解是这样的。

Agent 是「专职外包」。每个 agent 是一个带 frontmatter 的 Markdown 文件,定义了角色、可用工具、使用的模型。比如 agents/planner.md,它的 frontmatter 是 tools: Read, Grep, Globmodel: opus。注意它只有读和搜索权限,没有 Edit 和 Write。这是刻意的,planner 只负责出方案,不负责动手写代码。这种权限隔离,是 ECC 控制质量的第一道闸门。

Skill 是「按需加载的工作流」。281 个 skill 覆盖了从 TDD 到安全审查、从 Django 模式到 PyTorch 构建修复。关键在于它们不是常驻上下文的。你用到 tdd-workflow 的时候它才被加载进来,用完就释放。这跟下面要讲的 rule 形成对比。

Rule 是「永远在场的纪律」。放在 rules/common/rules/typescript/ 这些目录里,比如 testing.md 规定了 80% 覆盖率硬指标,security.md 规定了必须检查的安全项。这些是常驻上下文的,所以作者反复强调「只装你真正需要的」,装多了会吃掉你的上下文窗口。

Hook 是「模型管不到的强制执行层」。这是整个系统最硬核的部分,也是真正让它从「一堆 Markdown」变成「操作系统」的东西。

前三个概念,agent、skill、rule,说到底都是往上下文窗口里塞文字。你写了再漂亮的 rule 说「不准跳过测试」,模型照样可能跳过,因为它「觉得」这次不需要。Hook 不一样,hook 是在模型调用工具的那个瞬间,由 harness 本身执行的脚本,模型完全管不到。

ECC 在 hooks/hooks.json 里注册了 17 个以上的 hook,覆盖了 PreToolUse、PostToolUse、PreCompact 等多个事件。我挑几个最能说明问题的讲。

GateGuard,一个会拦住 Agent 改文件的看门人

pre:edit-write:gateguard-fact-force 是我最感兴趣的一个 hook。

它做的事情很反直觉。当 Agent 第一次尝试 Edit 或 Write 某个文件时,这个 hook 会拦住它,要求它先交代清楚三件事,谁在 import 这个文件、它的公开 API 是什么、数据 schema 长什么样。

我读了 scripts/hooks/gateguard-fact-force.js 的源码。它的设计思路写在文件开头的注释里,原话是这么说的。

Forces Claude to investigate before editing files or running commands. Instead of asking “are you sure?” (which LLMs always answer “yes”), this hook demands concrete facts: importers, public API, data schemas. The act of investigation creates awareness that self-evaluation never did.

翻译过来就是,与其问 Agent「你确定吗」(它永远回答确定),不如逼它拿出具体事实。调查这个动作本身,会创造出自我评估永远给不了的认知。

源码里有几个实现细节值得讲一下。状态存在 ~/.gateguard 目录下,每个文件只拦第一次,会话超时设了 30 分钟(SESSION_TIMEOUT_MS = 30 * 60 * 1000),为了防止状态无限膨胀,最多记录 500 个条目(MAX_CHECKED_ENTRIES = 500)。对破坏性的 Bash 命令,它还会额外识别 drop tabledelete fromtruncatedd if= 这些模式。

这套机制解决的是 Agent 编程里一个很实在的痛点。Agent 改代码太快了,快到它自己都不知道改这一行会牵连什么。GateGuard 强迫它在动手前先做一遍影响分析,不是靠 prompt 唠叨,而是物理上不让你写进去,除非你先调查清楚。

但这个 hook 也是 ECC 最有争议的部分。我翻 issue 区的时候发现,它拦人拦得太狠了。issue #2049 报告说在 Cursor 里,gateguard 会永久拒绝所有 Edit 和 Write,因为它的 PPID 会话 key 在不同工具调用之间永远无法收敛。issue #2608 刚提出来没几天,标题直白地写着「Edit/Write 第一次触碰应该在每次会话拒绝 N 次后停止,而不是对每个新文件永远拦下去」。issue #2043 报告 Windows 上 Git Bash 环境下,CLAUDE_PLUGIN_ROOT 解析成 POSIX 路径,node.exe 直接报 C:\c\Users\ 这样的 MODULE_NOT_FOUND

这些 issue 说明一个事实,hook 这层「模型管不到的强制执行」是把双刃剑。它能真正卡住 Agent 的坏习惯,但一旦它自己的逻辑出了问题,也会把整个工作流卡死,而且因为发生在模型上下文之外,Agent 自己还修不了。

Continuous Learning,让 Agent 从你的习惯里长出「直觉」

第二个让我觉得有意思的设计是 continuous-learning-v2。

v1 的做法是在会话结束时,用 Stop hook 分析整个会话,提取出「学到的技能」。问题是 Stop hook 在实际环境里不够可靠,会话经常异常退出,提取就丢了。

v2 换了个思路,改成 PreToolUse 和 PostToolUse 双 hook,号称 100% 可靠。它不再提取完整的 skill,而是提取更细粒度的「instinct」,直译是直觉或本能。

一个 instinct 长这样,有一个 id、一个触发条件、一个置信度分数、一个领域标签。比如 prefer-functional-style,触发条件是「写新函数时」,置信度 0.7,领域是 code-style。置信度用 0.3 到 0.9 的加权,观察到的次数越多、模式越稳定,分数越高。

v2.1 又加了一个关键改进,project-scoped instincts。我读了 skills/continuous-learning-v2/SKILL.md,它用 git remote URL 或者仓库路径做 hash,把 instinct 隔离到每个项目里。你的 React 项目里学到的模式,不会污染你的 Python 项目。只有当某个 instinct 在 2 个以上项目里都出现过,才会被「提拔」成全局 instinct。

存储位置也变了,从 v1 的 ~/.claude/homunculus/ 迁到了 ${XDG_DATA_HOME:-~/.local/share}/ecc-homunculus/projects/<hash>/。homunculus 这个词用得很妙,炼金术里的「人造小人」,暗示这是 Agent 从你的行为里自己长出来的知识。

不过这里也有一个现实问题。issue #2036 报告说 instinct-cli.py 静默切换了存储路径,旧版本安装的用户读取的是一个空的过时目录,没有任何警告。issue #2037 说 /instinct-statusCLAUDE_PLUGIN_ROOT 没设置时会 fallback 到手动安装模式,把插件的实际状态给掩盖了。一个学习系统的前提是它能被正确观测,这两个 issue 说明 v2 到 v2.1 的迁移并不平滑。

一个人扛起来的「操作系统」

ECC 的数据很漂亮。23 万 Star,3.5 万 Fork,覆盖 7 个主流 harness(Claude Code、Codex、Cursor、OpenCode、Gemini、Zed、Kimi),67 个 agent,281 个 skill。

但扒开贡献者数据,画面就不一样了。我用 gh api 拉了前 100 名贡献者的 commit 统计,affaan-m 一个人 1516 次提交,占总量的 71.7%。第二名 dependabot 是个机器人,50 次。真正的人类第二贡献者 pangerlkr 只有 47 次。

bus factor 等于 1。这是一个完全依赖单人的项目。

这不是什么坏事,很多伟大的开源项目起步阶段都是一个人。但 ECC 的体量已经不适合用「个人项目」来形容了,它有商业化(ECC Pro 私有仓库每月 19 美元每席位)、有赞助商(CodeRabbit、Greptile、Moonshot AI、Itô)、有 Discord 社区、有 12 种语言的 README 翻译。一个人的产出带宽,撑起这么大的盘子,背后是极高的 burnout 风险。

而且它的迭代速度惊人地快。从 2026 年 1 月 18 日建仓,到 7 月底发布 2.1.0,半年时间从 v1.0 走到 v2.1。每个版本的 release notes 都是一长串功能清单。这种速度的代价,就是前面提到的那些迁移问题和边界 case,hook 在某些环境里失灵、路径在跨平台时出错、文档和实际状态不一致。

说到文档不一致,我在仓库里发现了一个挺有意思的矛盾。SOUL.md 里写的是「30 agents, 135 skills, 60 commands」,这是项目的早期规模。但 README 里已经更新到「67 agents, 281 skills, 94 commands」。SOUL.md 没跟着更新,成了项目膨胀速度的一个化石标本。这种小细节其实挺能说明问题的,当一个人同时维护 agent 定义、skill 工作流、hook 脚本、跨 7 个平台的安装器、Rust 重写的控制面原型(ecc2/)、商业化的 GitHub App,总有一些角落会顾不上。

装一个「配置即产品」的东西,要付出什么

ECC 是 MIT 开源的,仓库本身永远免费。但「免费」这个词在这里需要打折扣理解。

最基础的安装,Claude Code 用户两行命令搞定,/plugin marketplace add/plugin install。但 README 花了大量篇幅讲「不要叠加安装方法」,因为插件安装和手动安装如果混在一起,会造成 skill、command、hook 的重复。这个警告本身就说明,它的安装体验还不够傻瓜化,否则不需要反复强调。

一旦你想用它的全部能力,隐藏成本就浮出来了。

multi-* 系列命令(/multi-plan/multi-execute/multi-backend 等)明确标注「不被基础安装覆盖」,你需要额外装一个 ccg-workflow 运行时。Memory Vault 的 CLI 和 MCP server 需要单独 npm install -g ecc-universal。如果你用私有仓库,ECC Pro 起价每月 19 美元每个席位。2.1 版本新增的 Itô GPU 自托管路径,虽然 ECC 本身不收费,但 GPU 算力要钱,而且 Itô 正好是 ECC 的「首选计算赞助商」。

这些不是坑,作者在 README 里都写得很清楚,甚至专门做了 npx ecc consult 这样的工具帮你选组件。但你得意识到,一个「67 agents + 281 skills」的系统,它的复杂度不可能完全免费。你省下的是写 prompt 的时间,花出去的是理解这套系统配置的时间。

它到底代表了什么

拆完 ECC,我想说一个比这个项目本身更重要的判断。

2024 年大家写 AI Agent,关心的是「模型够不够聪明」「prompt 怎么写更好」。2026 年的 ECC 告诉我们,当模型已经足够聪明,瓶颈转移了,转移到了「怎么让聪明的模型稳定地、重复地、有纪律地工作」。

ECC 的整个架构可以提炼成一个我愿意叫它「Context Tiering」的模式,上下文分层。

把信息按「生命周期」和「确定性」两个维度分成三层。第一层是 rule,永远在场,确定性强,代价是吃上下文,所以要克制。第二层是 skill 和 agent,按需加载,用完释放,灵活但不强制。第三层是 hook,确定性最强,在模型上下文之外执行,但实现成本最高,一旦出错最难调试。

这三层各有利弊,关键在于「把什么东西放在哪一层」。rule 适合放不变的原则(80% 覆盖率、不准硬编码密钥),skill 适合放可复用的工作流(TDD 红绿循环),hook 适合放模型自己靠不住的强制项(改文件前先调查、push 前先跑测试)。判断标准是,如果模型「忘了」这件事代价多大,越大就越往 hook 层放。

这个分层思维不局限于 Claude Code,也不局限于 ECC。你自己写 AGENTS.md、写 .cursorrules、配 GitHub Copilot 的 instructions,底层逻辑都是同一件事,给信息分层。ECC 的价值在于它把这个决策做成了一个完整的、可安装的系统,你不用从零搭,站在它的肩膀上调整就行。

但它 bus factor=1 的现实也在提醒我们,这类「单人大一统」项目最大的风险不是代码质量,而是可持续性。affaan-m 每周跨 7 个 harness 发版,这个节奏能维持多久,取决于商业化能不能把社区贡献者吸引进来。23 万 Star 里哪怕只有千分之一的人愿意提交 PR,bus factor 就不会停在 1。

如果你每天重度使用 Claude Code 或 Codex,ECC 值得一试。我的建议是,别一上来就装 full profile,用 --profile minimal 先把核心工作流跑起来,再按需加 skill。它的 npx ecc consult "你的需求" 能帮你精准定位要装哪些组件。装完之后,先别急着信任它的 hook,在非关键项目上跑几天,观察 GateGuard 这些强制层会不会跟你的工作流打架。hook 是它最强的地方,也是最容易让你抓狂的地方。

评论互动

© 2026 王若风的技术博客 · Powered by Astro