mcpField
E
engineering-council

engineering-council

github.com/belsrc开发075 次安装5 周前更新
代码仓库

关于 engineering-council

engineering-council 面向评估工程决策的团队,通过确定性路由选择工程角色,让隔离的子 Agent 独立分析,并归纳共识与分歧,不强求一致。

主要功能

  1. 01确定性的主题与角色路由
  2. 02双人组与三人组模式
  3. 03隔离的代码库发现子 Agent
  4. 04角色独立作答
  5. 05可选的反驳轮次
  6. 06保留分歧的综合归纳

适用场景

  1. 01比较工程选择中的对立观点
  2. 02结合代码库背景讨论决策
  3. 03探讨涉及多个领域的决策

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/belsrc/skills --skill engineering-council

安装后在 Claude Code 中输入/engineering-council确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

README.md
references/
council.md
references/personas/
abramov.md
allspaw.md
beck.md
carmack.md
chase.md
chollet.md
dhh.md
dijkstra.md
fowler.md
green.md
hejlsberg.md
hickey.md
husain.md
kaminsky.md
karpathy.md
kay.md
khattab.md
knuth.md
lamport.md
lecun.md
majors.md
marlinspike.md
martin.md
muratori.md
ng.md
ousterhout.md
pearl.md
pike.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。

  1. 明确指定成员(routedBy: "explicit")。用户点名了特定成员(“请征询 Knuth 和 Beck 的意见”“针对这个问题,让 Carmack 和 Muratori 对辩”)。严格使用这些成员。完全跳过分类。完全确定。
  2. 明确指定主题(routedBy: "explicit")。用户点名了主题键(“运行优化决策委员会”)。在 references/routing.md 中查找。完全确定。
  3. 关键词路由(routedBy: "keyword")。扫描请求,查找 references/routing.md 中每个主题列出的锚点词。按锚点词命中数为每个主题评分。选择得分最高的主题。若平分,则按 routing.md 底部的优先级顺序选择(更具体的主题优先)。这是预期的常见路径,且稳定可靠。
  4. 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. 根据请求和主题推导 1 到 n 个范围明确的问题。对于聚焦的请求,默认只提一个问题。仅当请求包含彼此独立的方面时才拆分问题(例如“工具是否已经会持久化输出?”和“其他地方是否已有输出标志?”是两个问题)。最多 4 个问题。像主题用于选择成员那样,使用 references/routing.md 中的主题发现提示来确定要查找的内容。
  2. 针对每个问题并行、隔离地启动一个发现子 Agent。每个子 Agent 在自己的上下文中读取数量有限的文件(每个最多几个文件),并返回一个 DiscoveryFinding。原始文件内容只留在子 Agent 内部;只返回发现结果。
  3. 将发现结果合并成一份精简的 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 提供以下内容,不得提供其他内容:

  1. 要求其阅读 references/personas/<member>.md 并采用该角色的指示,
  2. 用户的原始请求,
  3. 共享的 RepoBrief,
  4. 要求其仅返回一个 PersonaResponse JSON 对象(架构见下文),不得附加说明文字。

如果简报的 rooted 为真,角色应根据证据而不只是请求文本应用自己的视角,并在 groundedIn 中列出其判断所依据的具体仓库事实。如果 rooted 不为真,角色应根据请求进行推理,并省略 groundedIn。

不要让某个子 Agent 看到其他成员的回复。隔离机制能够避免各方观点相互影响。每个角色收到的简报都相同,因此彼此唯一的差异就是视角。

默认情况下,辩论处于开启状态,此时这是第一轮,接下来执行步骤 6。若用户选择退出辩论,则直接进入综合阶段。

第 6 步:辩论轮次(可选)

默认运行。仅在两种情况下跳过:用户在第 1 步选择退出,或第一轮结果一致且没有争议轴,因为所有人都已达成一致时,就没有可供反驳的内容。如果结果一致,注明这一点,然后直接进入综合。否则,这一步只会在第一轮的基础上增加一轮反驳,因此委员会最多运行两轮。

第一轮结束后,在同一轮次中并行重新启动每位成员。给每个反驳子 Agent:

  1. 指示其阅读 references/personas/<member>.md 并采用其中定义的角色,与第一轮相同,
  2. 提供请求和共享的 RepoBrief,与第一轮相同,
  3. 提供其自己的第一轮 PersonaResponse,
  4. 提供其他成员第一轮的立场(立场、裁决和要点),
  5. 指示其仅返回 PersonaRebuttal JSON 对象(架构见下文),而非角色文件中描述的 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 预算取决于评议会规模,而非完整名单。

防护措施

每个人设都体现了一位真实人物有据可查的公开工程理念。请将其观点表述为该理念在当前请求中的应用,而不要声称这是其个人私下的看法,也不要编造引言。以有据可查的立场为依据,也能让人设更加鲜明,因此这既是质量保障,也是表达敬意的方式。

评论

支持 Markdown