关于 engineering-council
engineering-council 面向评估工程决策的团队,通过确定性路由选择工程角色,让隔离的子 Agent 独立分析,并归纳共识与分歧,不强求一致。
主要功能
- 01确定性的主题与角色路由
- 02双人组与三人组模式
- 03隔离的代码库发现子 Agent
- 04角色独立作答
- 05可选的反驳轮次
- 06保留分歧的综合归纳
适用场景
- 01比较工程选择中的对立观点
- 02结合代码库背景讨论决策
- 03探讨涉及多个领域的决策
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ belsrc/ skills --skill engineering-council安装后在 Claude Code 中输入/engineering-council确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
README.mdreferences/council.mdreferences/personas/abramov.mdallspaw.mdbeck.mdcarmack.mdchase.mdchollet.mddhh.mddijkstra.mdfowler.mdgreen.mdhejlsberg.mdhickey.mdhusain.mdkaminsky.mdkarpathy.mdkay.mdkhattab.mdknuth.mdlamport.mdlecun.mdmajors.mdmarlinspike.mdmartin.mdmuratori.mdng.mdousterhout.mdpearl.mdpike.md详细介绍
工程委员会
召集一个由少数工程角色组成的委员会,分别听取每个角色的独立看法,然后综合各方共识和仍存的分歧。其价值在于相互对立但都合理的观点之间的张力,因此目标绝不是强行达成共识,而是清晰呈现决策空间。
工作原理
路由是确定性的,且仅处理文本。发现和委员会是两个基于隔离子 Agent 的 map-reduce 阶段。
request
│
▼
[route] Layer 1 classify ──► topic ──► Layer 2 lookup ──► members deterministic
│
▼
[discover] map: 1..n discovery subagents read files in their own context
reduce: merge findings into one lean RepoBrief grounds the council
│
▼
[echo] selection + brief + files read audit gate
│
▼
[council] map: one persona subagent per member, given the RepoBrief round one, uncorrelated
│
▼
[debate] optional: re-spawn each member with the others' round-one round two, opt-in
positions; one rebuttal pass, capped at two rounds
│
▼
[synthesize] positions, agreements, splits, and movement if debated
路由分为两层,以便审计。第 2 层是在 references/routing.md 中进行字面查找:给定主题和模式,总是会得到相同的成员集合。第 1 层负责选择主题,优先匹配关键词,以确保常见路径具有可复现性;只有在没有匹配锚点词时,才由模型仅在封闭的主题枚举中进行推理。
两个扇出阶段都刻意使用隔离子 Agent。在发现阶段,原始文件内容只在发现子 Agent 内部存在,因此只有提炼后的发现结果会传递给编排器,委员会也不会接触文件转储。在委员会阶段,每个角色都基于干净的上下文进行推理,内容锚定于自身定义、请求和共享简报;这样产生的看法彼此独立,而不是先阅读其他角色的意见后趋于一致。辩论轮默认开启,并增加一轮反驳,成本约为委员会阶段的两倍;如需单轮评估,可选择关闭;如果第一轮已达成一致,则会自动跳过。
第 1 步:确定模式
默认模式为 duo(一对极性相反的视角,以辩证方式呈现)。当用户提出要求、点名三位成员,或请求明确涵盖多个领域时,使用 triad(三位成员,多视角)。
duo 不只是“两个成员”,而是沿着请求核心张力轴线两端选出的极性配对。triad 则是选择三位成员,分别覆盖不同的相关领域。因此,模式会改变哪些成员入选,而不仅仅是成员数量。
还要检测用户是否选择关闭了辩论轮。辩论是一个正交标志,而非模式:它适用于 duo 和 triad,并且默认开启,因为反驳环节是委员会形成审慎立场的核心部分,而不是简单并列各方的第一反应。只有当用户提出要求时才关闭(“不要辩论”“单轮”“只要各方看法”“跳过反驳”)。它控制第 6 步。
第 2 步:选择成员
按以下优先级顺序解析选择。第一个匹配项生效。记录触发的分支为 routedBy。
- 明确指定成员(
routedBy: "explicit")。用户点名了特定成员(“请征询 Knuth 和 Beck 的意见”“针对这个问题,让 Carmack 和 Muratori 对辩”)。严格使用这些成员。完全跳过分类。完全确定。 - 明确指定主题(
routedBy: "explicit")。用户点名了主题键(“运行优化决策委员会”)。在references/routing.md中查找。完全确定。 - 关键词路由(
routedBy: "keyword")。扫描请求,查找references/routing.md中每个主题列出的锚点词。按锚点词命中数为每个主题评分。选择得分最高的主题。若平分,则按routing.md底部的优先级顺序选择(更具体的主题优先)。这是预期的常见路径,且稳定可靠。 - LLM 兜底(
routedBy: "llm")。仅当没有匹配到任何锚点词时使用。从routing.md中的封闭枚举里选择最匹配的主题。不得臆造枚举之外的主题。
确定主题后,根据模式从表格中读取成员集合:duo 模式使用 defaultDuo,triad 模式使用 defaultTriad。对于少数 duo 标记为 flex 的主题,从 references/council.md 中选择轴线最符合请求的极性配对,并在备注中说明。
步骤 3:发现仓库上下文(集中式简报)
发现过程让评审团立足于实际代码库,而不只是请求文本。默认启用。当以下两项同时成立时运行:技能在仓库内运行,且请求涉及具体产物(具名文件、命令或模块,或“这个 CLI 工具”“我们的身份验证模块”等所属关系表述)。对于答案不会因仓库状态而改变的抽象问题(“一般来说,应该尽早优化还是晚些优化”),自动跳过;如果没有仓库,则降级为纯文本模式。
触发条件和覆盖方式:
- 默认启用。 满足上述条件时,将
rooted: true设为简报字段。 - 选择退出。 如果用户要求跳过上下文 grounding(“不要发现”“只谈原则”“跳过仓库”),则将
rooted: false设为简报字段,仅根据请求进行推理。 - 强制启用。 如果用户要求基于仓库进行分析,即使请求处于抽象与具体的边界,也要运行发现过程。
- 没有仓库,或未找到相关内容。 没有仓库时,将
rooted: false设为简报字段;如果找到了仓库但没有相关内容,则将rooted: true设为简报字段,并在摘要中说明未找到与问题相关的内容,以便各角色知道自己是基于文本进行推理。
发现过程以 map-reduce 方式运行:
- 根据请求和主题推导 1 到 n 个范围明确的问题。对于聚焦的请求,默认只提一个问题。仅当请求包含彼此独立的方面时才拆分问题(例如“工具是否已经会持久化输出?”和“其他地方是否已有输出标志?”是两个问题)。最多 4 个问题。像主题用于选择成员那样,使用
references/routing.md中的主题发现提示来确定要查找的内容。 - 针对每个问题并行、隔离地启动一个发现子 Agent。每个子 Agent 在自己的上下文中读取数量有限的文件(每个最多几个文件),并返回一个
DiscoveryFinding。原始文件内容只留在子 Agent 内部;只返回发现结果。 - 将发现结果合并成一份精简的
RepoBrief。合并filesRead,汇总conventions,并综合facts形成summary。不要将原始文件内容粘贴到简报中。简报供评审团据此行动,而不是用来复刻目录树。
控制发现范围。若简报不断膨胀,就会导致上下文失控;只有每个子 Agent 返回发现结果而非文件转储,才能通过并行分工避免这种情况。
假设仓库可信。若仓库中包含不可信内容,将文件内容提供给子 Agent 会形成提示注入攻击面;对于 v1,这一假设会明确说明,但不会加以防护。
步骤 4:启动前回显选择结果
这是审计关卡。打印已解析的选择结果和发现简报,让用户能够查看并覆盖评审团的选取方式及其依据,然后继续,无需等待,除非用户在此前一轮中提出异议。
Council: <topic> · <mode>
Members: <member list>
Routed by: <explicit | keyword | llm>
Why: <one line>
Grounded: <rooted ? "yes" : "no">
Files read: <files, or "none (reasoning from the request)">
Brief: <one to three line summary, or "n/a">
Debate: <on | off>
routedBy 字段让路由过程可供检查;文件读取行让上下文依据可供检查,因此发现范围不当时会显而易见,而不会悄然发生。两者都不得省略。
步骤 5:启动评审团(第一轮)
针对每位选定成员启动一个子 Agent,并在同一轮中启动,使它们并行、隔离地运行。只向每个子 Agent 提供以下内容,不得提供其他内容:
- 要求其阅读
references/personas/<member>.md并采用该角色的指示, - 用户的原始请求,
- 共享的
RepoBrief, - 要求其仅返回一个
PersonaResponseJSON 对象(架构见下文),不得附加说明文字。
如果简报的 rooted 为真,角色应根据证据而不只是请求文本应用自己的视角,并在 groundedIn 中列出其判断所依据的具体仓库事实。如果 rooted 不为真,角色应根据请求进行推理,并省略 groundedIn。
不要让某个子 Agent 看到其他成员的回复。隔离机制能够避免各方观点相互影响。每个角色收到的简报都相同,因此彼此唯一的差异就是视角。
默认情况下,辩论处于开启状态,此时这是第一轮,接下来执行步骤 6。若用户选择退出辩论,则直接进入综合阶段。
第 6 步:辩论轮次(可选)
默认运行。仅在两种情况下跳过:用户在第 1 步选择退出,或第一轮结果一致且没有争议轴,因为所有人都已达成一致时,就没有可供反驳的内容。如果结果一致,注明这一点,然后直接进入综合。否则,这一步只会在第一轮的基础上增加一轮反驳,因此委员会最多运行两轮。
第一轮结束后,在同一轮次中并行重新启动每位成员。给每个反驳子 Agent:
- 指示其阅读
references/personas/<member>.md并采用其中定义的角色,与第一轮相同, - 提供请求和共享的
RepoBrief,与第一轮相同, - 提供其自己的第一轮
PersonaResponse, - 提供其他成员第一轮的立场(立场、裁决和要点),
- 指示其仅返回
PersonaRebuttalJSON 对象(架构见下文),而非角色文件中描述的PersonaResponse,不要在对象前后添加任何文字。
要求每个角色直接回应其他成员:承认有力的观点,强化其他人重视不足的分歧,或以更有力的论据坚持己见。只有当修订后的裁决或立场核心确实发生变化时,才将 moved 设为 true,不要因为表面上的改动就设为 true。
保持本轮内的隔离。每个反驳子 Agent 都能看到其他成员第一轮的输出,但看不到他们实时进行的第二轮推理,因为所有子 Agent 都基于相同的第一轮上下文并行运行。这能让第二轮保持非相关性,也正是隔离运行子 Agent 让第一轮有价值的原因。
到此为止。两轮是上限。不要运行第三轮,因为边际变化不值得再进行 N 次调用。
第 7 步:综合并保留不同意见
辩论未启用时,基于第一轮的 PersonaResponse 对象进行综合。辩论已运行时,则基于最终状态进行综合:每位成员的立场即其 PersonaRebuttal(revisedVerdict、修订后的 stance、更新后的 recommendation),同时仍参考第一轮的 tradeoffsRaised,以全面了解各个维度。呈现分歧,不要通过投票将其抹去。比较各成员的裁决和权衡取舍,机械地找出存在争议的维度,而不是猜测他们在哪些方面意见不一。成员提供 groundedIn 时,指出立场所依据的仓库事实;如果分歧取决于仓库事实,而非纯粹的原则,也要明确说明,因为这类分歧最值得读者关注。
使用以下确切结构:
## <topic> council · <mode>
### Positions
- **<Member>** (<verdict>): <one to two line condensation of stance + recommendation> [grounded | from principle]
- ... one bullet per member
### Where they agree
<the shared ground, if any. omit the section if there is none>
### Where they split
<the contested axes. for each, name the tradeoff and which member sits on which side. flag any split that turns on a repo fact. this is the heart of the output>
### How positions moved
<debate only. for each member whose moved is true, name what shifted and the specific argument that moved them; note who held firm. omit this section entirely when debate was off>
### Reading
<either a synthesized recommendation when the evidence points one way, or an explicit handoff: "the call hinges on <axis>; if you weight <X> over <Y>, go with <member>'s read.">
只有当问题确实是二元选择时,才给出单一的裁决统计,而且即便如此也要展示分歧。仅当运行了调研时,才将各个立场标记为有依据或仅基于原则;如果没有简报,则省略标签。仅当运行了辩论时,才包含变动部分;角色让步或坚持的关键点,往往是整个输出中最有信息量的一行。
合同
每个角色子 Agent 都返回以下结构。固定架构可让综合过程通过机械方式完成,而不必解析散文。
type CouncilVerdict = "for" | "against" | "depends";
type PersonaResponse = {
readonly member: string; // canonical id, e.g. "knuth"
readonly stance: string; // the member's lens applied to the request
readonly verdict: CouncilVerdict;
readonly keyConcerns: readonly string[];
readonly tradeoffsRaised: readonly string[];
readonly recommendation: string;
readonly groundedIn?: readonly string[]; // repo facts the verdict leans on; absent when not rooted
};
辩论运行时(第 6 步),每位成员在第二轮返回此结构,而非 PersonaResponse。它包含与立场变化相关的差异以及最终建议,因此综合时可以直接使用辩论后的立场,无需重新推导;第一轮的 tradeoffsRaised 仍可提供更全面的维度信息。
type PersonaRebuttal = {
readonly member: string;
readonly respondsTo: readonly string[]; // members whose points this answers
readonly revisedVerdict: CouncilVerdict; // may match round one or move
readonly stance: string; // refined position after seeing the others
readonly recommendation: string; // final recommendation, which can change when moved
readonly moved: boolean; // whether this persona changed its position
};
当 routedBy 为 explicit 或 keyword 时,选择遵循以下结构,且结果是确定的:
type Mode = "duo" | "triad";
type Selection = {
readonly topic: string; // closed enum member from routing.md
readonly mode: Mode;
readonly members: readonly string[]; // from the static topic table
readonly routedBy: "explicit" | "keyword" | "llm";
readonly note: string; // why this topic, for the echo
};
每个调研子 Agent 都会返回一项发现,因此将发现合并到简报中的过程是机械的:
type DiscoveryFinding = {
readonly question: string; // the scoped question this agent investigated
readonly filesRead: readonly string[];
readonly facts: readonly string[]; // concrete observations, each tied to a file
readonly relevant: boolean; // false when nothing bearing on the question was found
};
协调器会将这些发现整合为一份精简简报,供每个角色子 Agent 使用。原始的 DiscoveryFinding[] 留在协调器处用于回显;角色只会收到以下内容:
type RepoBrief = {
readonly rooted: boolean; // false when no repo, or discovery was skipped
readonly filesRead: readonly string[]; // union across findings, echoed for audit
readonly conventions: readonly string[]; // language, build tooling, existing patterns
readonly summary: string; // synthesis of the findings, not raw file dumps
};
参考文件
references/council.md是成员名单和极性配对表。它很轻量,用于确定路由并解决 flex 二人组的问题。请先阅读。references/routing.md是统一的话题表:锚定词、defaultDuo、defaultTriad、平局时的优先级列表,以及每个话题对应的发现提示,用来告诉发现流程要查找什么。这是第 2 层。references/personas/<member>.md是内容较重的人设提示词。人设文件只会在分配给相应成员的子 Agent 中加载,因此 Token 预算取决于评议会规模,而非完整名单。
防护措施
每个人设都体现了一位真实人物有据可查的公开工程理念。请将其观点表述为该理念在当前请求中的应用,而不要声称这是其个人私下的看法,也不要编造引言。以有据可查的立场为依据,也能让人设更加鲜明,因此这既是质量保障,也是表达敬意的方式。