`check-divisions.sh` 失败:四个地方要同步改

2026-08-09

给 agency-agents 加一个自己的 division,是这个仓库里最容易被低估的一件事。它看上去只是「新建一个文件夹,把几个 agent markdown 丢进去」,但仓库里有一个专门的脚本 scripts/check-divisions.sh 盯着这件事,只要你少改了一个地方,它就会让构建失败。

这篇只处理这一个失败面。按排查文章的老规矩走五步:现象长什么样、怎么确认失败真的来自 division 列表漂移、源码语义给出的处置是什么、改完怎么验证、以及——最后这步别跳过——什么情况说明根本不是这个原因。

先交代口径:以下全部来自对仓库源码与文档的阅读。我们没有安装过其中任何 agent,没有运行过这些脚本中的任何一个,所以文中不会出现任何「跑起来打了几行」的描述。

一、现象

典型触发路径有三种,共同点都是「division 的集合变了」:

  • 你新建了一个顶层目录,往里面放了自己的 agent;
  • 你把某个已有 division 目录改了名,或者拆成了两个;
  • 你只在 divisions.json 里加了条目,磁盘上还没建目录(或者反过来)。

然后 scripts/check-divisions.sh 不通过,构建失败。这个脚本存在的意义就是拦住这种「配置漂移」:仓库把漂移当成明确的敌人,divisions.json_note 字段和几个 check-* 脚本共同构成一套自检。

要理解它为什么这么严格,得先知道 division 这个概念在仓库里被引用了多少次。当前这套花名册是 255 个带 frontmatter 的 agent markdown,分布在 17 个 division(核对日 2026-08-09)。division 不只是一个展示分组:它同时决定了 convert.sh 要遍历哪些目录去渲染产物、lint-agents.sh 默认扫描哪些目录、CI 在哪些路径变更时触发校验。任何一处漏改,结果都不是报错,而是静默地少做事——你的新 agent 不会被转换、不会被校验、改了 CI 也不跑。check-divisions.sh 就是把这种静默失败提前变成显式失败。

二、怎么确认是这个问题

check-divisions.sh 守的东西,源码层面是一句话:division 列表必须与磁盘目录、convert.shlint-agents.sh 里的 AGENT_DIRS 数组、lint-agents.yml 的路径过滤器一致,不一致就让构建失败。

所以真相源只有一个(divisions.json),下游有四个。把这四处逐个对一遍,就能判定是不是它:

序号要对齐的地方对齐动作
1磁盘上的顶层目录列出仓库根目录,看你的新 division 目录名与 divisions.json 里的键是否逐字符一致
2scripts/convert.shAGENT_DIRSgrep -n "AGENT_DIRS" scripts/convert.sh
3scripts/lint-agents.shAGENT_DIRSgrep -n "AGENT_DIRS" scripts/lint-agents.sh
4lint-agents.yml 的路径过滤器打开这个 CI 工作流文件,看 path 过滤列表里有没有你的目录

(表里第 2、3 行那两条 grep 是我们给的通用排查动作,不是仓库文档里的官方命令;第 1、4 行靠肉眼比对。)

还有一条前置判定,很多人卡在这里:**一个目录要成为 division,必须至少包含一个带 frontmatter 的 agent 文件。**如果你的新目录里只有 README、只有草稿、或者 agent 文件的 frontmatter 根本没被识别出来,那它在脚本眼里就不是 division,你在 divisions.json 里加的条目自然对不上。

这条在 Windows 上尤其值得多看一眼。仓库标准行尾是 LF(见 .gitattributes),lint-agents.sh 的第 0 道检查就是直接拒绝 CRLF,级别是 ERROR。源码注释解释了理由:行尾多一个 \r 会让后面的 frontmatter 检查报出令人困惑的「missing frontmatter ---」——明明文件开头写的就是 ---。所以如果你是在 Windows 编辑器里新建的 agent 文件,先确认行尾,再去怀疑 division 配置。顺带一提,install.sh 注释里写明的平台支持是 Linux、macOS(bash 3.2+)与 Windows 的 Git Bash / WSL,这些脚本本来就不是给 PowerShell 直接跑的。

三、源码语义给出的处置

divisions.json_note 原文写了新增 division 的正确顺序,照抄执行即可:

  1. 建目录——并且确保里面至少有一个带 frontmatter 的 agent markdown(namedescriptioncolor 三项必填,缺任意一项 lint 报 ERROR)。
  2. divisions.json 里加条目——这是唯一的真相源,其它地方都是它的投影。
  3. scripts/check-divisions.sh
  4. 按它的报错去更新它指向的地方

第 4 步是这套设计的精髓:脚本本身就会告诉你还差哪一处,你不需要凭记忆去数「四个地方」。反过来说,别绕过第 3 步直接凭印象改四个文件——万一仓库上游又多接了一个消费方,你手里这份「四处清单」就过期了,脚本不会过期。

至于那四处各自为什么必须改,理解了就不容易漏:

  • convert.shAGENT_DIRS:这是转换流水线的输入范围。整条链路是「源 agent markdown → convert.sh 渲染成各工具格式 → integrations/install.sh 拷贝到目标目录」,目前 tools.json 覆盖 16 种工具。漏改这里,你的新 division 就不会出现在任何一种工具的产物里。
  • lint-agents.shAGENT_DIRS:这是校验的默认扫描范围。这个脚本不给文件参数时就扫所有 agent 目录,漏改意味着你的新 agent 从来没被质量门碰过。
  • lint-agents.yml 的路径过滤器:这是 CI 的触发条件。漏改的表现最隐蔽——本地手动跑能过,PR 里改了新目录却压根不触发校验。
  • 磁盘目录:名字差一个连字符、差一个大小写,前三处改得再对也白搭。

四、处置后怎么验证

按顺序做这三件事,注意每一步各自能证明什么:

第一步,重跑一致性检查。

./scripts/check-divisions.sh

它通过,只说明四处配置对齐了,不代表你的 agent 内容有效

第二步,单独 lint 新目录里的文件。

lint-agents.sh 的用法是 ./scripts/lint-agents.sh [file ...],不给文件则扫描所有 agent 目录。所以既可以点名验,也可以全量验:

# 只验新加的这几个
./scripts/lint-agents.sh <你的新目>/*.md

# 或者走默认全量扫描,顺便确认新目录确实进了扫描范围
./scripts/lint-agents.sh

(以上为按脚本 USAGE 段的参数语义组合的示例,未逐项运行,以仓库最新脚本与 --help 的实际输出为准。)

看结果时必须分清级别:**frontmatter 缺分隔符、缺必填字段、CRLF 行尾是 ERROR;推荐章节缺失、正文词数不足 50、章节标题没有映射到两个目标文件是 WARN。**WARN 不会让检查失败。这一点很关键——别看到一堆黄字就以为 division 又配错了。

第三条 WARN 值得单独提一句,因为它反直觉:lint-agents.sh 会把每个 ## 级标题分流到两个转换目标。命中 identity、learning + memory、communication、style、critical rule、rules you must follow 这几类关键词的标题去 SOUL.md,其余全部去 AGENTS.md,lint 要求两边至少各有一个标题,否则各报一条 WARN。也就是说,你给章节起的标题不只是排版,它同时是路由——决定了这段内容被转换到哪个产物文件里。新建 division 时如果一整批 agent 都是照同一个模板复制的,这条 WARN 往往会成批出现。

第三步,确认转换产物范围。

install.sh 提供了 --dry-run,作用是只打印计划、不写任何东西;还有 --list [tools|teams|agents],列出后退出。在往 ~/.claude/agents/ 这类共享目录写文件之前先用它看一眼计划,是这个仓库对新手最有价值的一个习惯。注意 install.sh 读的是 integrations/已转换的文件,产物缺失或过期时它默认会先调 convert.sh(可用 --no-convert 关掉)——所以如果你想验证「新 division 是否真的进了转换范围」,别用一个陈旧的 integrations/ 目录去下结论。

五、什么情况说明不是这个原因

这一步是本文相对「报错大全」的全部增量。仓库里守着不同东西的脚本有好几个,失败信息指向下面这些方向时,改 division 配置是白费力气:

失败指向归谁管该去改什么
tools.json 条目缺 id / label / kebab / format / installKind / destcheck-tools.sh对齐 tools.jsoninstall.shALL_TOOLSconvert.sh 的转换器集合
runbook 里引用的 slug 解析不到真实 agent 文件check-runbooks.shstrategy/ 下 runbook 里的 slug,或补上缺失的 agent
frontmatter 缺字段、CRLF、正文过短lint-agents.sh改 agent markdown 本身
与已有 agent 相似度超标check-agent-originality.sh重写内容,见下

另外三种「看起来像 division 出了问题、其实不是」的情况:

一、你加的目录本来就不该是 division。divisions.json_note 明确说了并非每个顶层目录都是 division:integrations/convert.sh 写出的产物目录,strategy/ 放 playbook 与 runbook、没有 agent frontmatter,examples/scripts/ 同理。这四个在 check-divisions.sh 里通过 NON_DIVISION_DIRS 排除。你要放的如果是编排方法论或示例,别往 division 里塞。

二、失败其实来自原创性检查。check-agent-originality.sh 把候选 agent 与整个花名册对比,用实体中性化后的 8 词 shingle 重叠率打分——换掉国家名、平台名一类专有名词藏不住换皮。默认 ORIGINALITY_FAIL=40ORIGINALITY_WARN=20(都可用环境变量覆盖)。源码注释给出的库内校准数据是:现有 agent 之间最差相似度约 1.5%、中位数 0%,所以双位数就是强异常。这个脚本依赖 python3,缺了直接退出码 2——如果你的环境里没有 python3,看到的失败跟 division 一点关系都没有。

**三、行尾问题伪装成了 frontmatter 问题。**前面说过,CRLF 会让报错读起来像「文件没有 frontmatter」。看到这句先查行尾,别去翻 divisions.json

最后记一条这个仓库里值得抄走的做法:check-agent-originality.sh 的 division 列表是直接读 divisions.json,而不是在脚本里硬编码一份拷贝。源码注释写明了理由——硬编码的字面量会悄悄跟目录漂移,读文件则不可能。这也正是本文标题里「四个地方」的由来:那四处之所以还需要手工同步,是因为它们各自的形态(bash 数组、CI 路径过滤器、磁盘目录)暂时没法直接读同一个 JSON;而能读的地方,仓库都选择了读。你自己维护脚本集合时,能读文件就别抄常量。

顺带说一句规模背景:这个仓库在 2026-08-09 的快照里有 140729 star。这只说明关注度,不说明它适配你的项目,也不代表这套校验脚本能替你判断提示词写得好不好——lint 检查的是结构与重复度,不评估质量。

延伸阅读


本文依据 agency-agents 官方仓库(github.com/msitarzewski/agency-agents)的 README、tools.jsondivisions.jsonscripts/ 下的安装与校验脚本整理,核对日 2026-08-09。本文内容为仓库源码与文档口径,我们没有安装或运行过其中任何 agent。目录、脚本与安装路径随上游更新而变动,请以仓库最新内容与 ./scripts/install.sh --help 的实际输出为准。

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