内容
军团
> "我就是军团,因为我们是许多人。"
生的 [MCP](https://protocol.io) 模型委员会。军团语言模型(LLM)作为独立工具,并将它们编排成辩论、评审团、盲审小组、私人精炼竞技场、工作坊和自定义多模型商议。
每个模型都通过 OpenAI **响应 API** 接口格式访问。使用 OpenAI 或 Azure 直接访问,或通过兼容的网关(例如 [LiteLLM](https://docs.lit.ai) 代理其他提供商,并通过配置文件配置整个委员会。
## 目录
- [工作原理)
- [设计决策决策)
- [需求)
- [设置)
- [配置)
- [日志记录](#日志记录)
- [运行)
- [试用](#试用)
- VS Code 中使用](#在-vs-code-中使用)
部署](#部署)
##
```mermaid
flowchart LR
AI AI] -->|克劳德 / GPT / | 军 军团响应 API| GPT[OpenAI / Azure — 直接 军团 -->|| GW[网 LiteLLM]
劳德 & 杰米尼 & LLaMA
```
- **每个模型一个工具**,以模型名称的 slug 形式命名(例如 `克劳德` → `克劳德`)。每个工具接受一个 `提示`,以及可选的 `上下文`、`角色`、`系统`、`温度` 和 `最大令牌数`。
- **一个 `仲裁` 工具一个提示分发模型 — 带有轮讨论、可见性综合 — 并单独答案。有关编排选项,请参见 [预设](#预设--configpresetsjson)。
- **预设命名预设的、预先配置的委员会(辩论、评审团、等),每个预设一个工具公开。
- 身份和遥测 `结构化内容` 中,而不是答案文本中。日志记录到 **标准错误流**(安全用于标准输入/输出)。
## 设计决策
- **没有提供商。** 没有特定于提供商的代码,也没有内置列表。军团接口格式;不支持该模型通过网关访问新模型无需在此- **模型是配置,而不是代码。** 添加添加一个 JSON 文件。该目录在每次请求时重新无需重建或重启。
- **每个模型一个工具。** 每个模型对调用 AI 来说都表现为一个具有自己描述的工具,而不是一个带有模型参数的工具。`仲裁` 工具涵盖了临时多模型场景,`config/presets/` 中的每个预设都作为一个强制的、预先配置的委员会工具公开。
- **无状态。** 每个调用都是一次性的,`store: false`。没有任何内容被持久化数据库,也没有会话状态。
- **小。** 几百行 TypeScript 代码,一个捆绑的输出文件,六个依赖项。
## 需求
- Node.js 24+
- 至少一个与 OpenAI-Responses 兼容的端点(直接提供商 API,或桥接的模型的 LiteLLM 等网关) 设置
```pwnpm install
copy .env.example .env # 然后编辑 .env
```
所有配置都位于 目录中。捆绑的默认值**层**;目录中的 `config夹**覆盖在它们文件**:
- **目录资源** (`models/`/`、`presets/`、`tools/`):本地文件覆盖捆绑的同;本地文件添加捆绑文件都保留不变。因此,放入一个 `config/presets/refine.json` 只覆盖该预设 — 其他捆绑预设保留不变。
- **单文件文本** (`prompts.json`、`errors.json`、`schema.json`):按**键**合并 — 默认值 < 捆绑 < 本地。部分本地文件只覆盖它。
- **``**:如果文件,则完全覆盖,否则使用捆绑可以**覆盖或添加**,但捆绑条目。要关闭不想要的捆绑预设,请使用ABLE_PRESETS`下文)。
> **从 npm 安装?提供自己的模型文件。** 捆绑配置不含密钥的example.json` ,这些文件被扫描器故意忽略 — 因此捆**零**实际没有实际模型文件,服务器**快速启动失败**在 ... 中未文件`)。在运行服务器的目录中添加config/models/<name>.(参见下文 其余部分回捆绑默认值布局无论哪种方式都相同,并且每个请求都会。
### 模型 — `config/models/*.json需要一个模型文件 — 服务器在没有模型文件的快速启动失败**。每个 JSON 文件成为一个工具转换为 slug 的名称命名(`config/models/f` → 工具 `fable`):
```{
"modelclaude-fable",
"description":劳德童 快速、富有创造力、通用。",
"": "https://.com",
" "sk-模型密钥"
}
```
model`(必需)— 部署的模型端点路由到。
- `description` —调用 AI 选择正确的- `system`选的基础系统指令,内置于每次调用此模型 `baseUrl`apiKey` —;省略的值回 `DEFAULT_BASE_URL` / `DEFAULT_API_KEY`。
- `omitParams` — 可选的请求参数列表,用于删除此模型的参数,例如 `["temperature"]`。服务器保持提供商无关:不假设哪些模型拒绝哪些参数 — 您在此模型的特性。有助于推理模型和一些部署拒绝 `temperature`。
**热加载:** 目录在每次请求时重新扫描 — 添加或编辑模型文件,并在下一次调用时生效,无需重启。
**机密和 git:** 模型文件可以包含 API 密钥,因此 `config/models/*.json` 被 git 忽略。复制一个 `*.example.json`(跟踪,无密钥,忽略)以开始:
```pwsh
copy config\models\gpt.example.json config\models\gpt.json # 然后添加您的密钥
```
### 角色 — `config/`
可选的指令文件。每个` 文件成为一个命名角色(从文件名转换为 slug一个文件,在下时生效。本仓库skeptic.md`.md`、`jud` 和 `short(一种简洁回答,无需商议”的角色,有助于限制输出)作为现成的启动器 — 可以自由编辑或删除它们(它们不包含机密)。
工具中可用的选择器变为 `roleName`,例如传递 `role: "skeptic"` 或在 `quorum 中使用 `"modelptic"`。
### — `config//*.json`
可选加载 **委员会配方**,每个预设一个(以文件名转换为 slug 的名称命名,如模型每个预设成为其自己的工具** — 添加 `config/presets/code_review.json`,在下一次请求时出现一个 `code_review` 工具。每个预设都有一个 `description`,一个 `roles` 列表,以及可选的权威 `mode` / `synthesizer` 默认值。每个角色在其 **内联** 中定义行为 — 角色的 `description` *即是* 其指令(行为合约);没有 `description` 的角色回退到匹配的 `config/roles/<role>.md` 文件:
```json
{
"description": [
竞争:让几个参赛者相互竞争,然后加冕获胜者。",
"",
"用任意数量的模型配备 `contestant`;一个 `judge` 做出决定。"
],
"mode": "parallel",
"synthesizer": "judge",
"roles": { "role": "contestant", "description": "论证为什么你的答案比其他人好。min": 2, "max": null },
"role": "", "description": "加冕单个获胜者并证明其合理性。", "min": 1, "max": 1 }
]
}
```
调用 AI 直接调用预设工具(例如 `code_review`),并仍然编写 `models` 选择器,将任何模型分配给任何预设角色。预设是 **强制性的**选择使用预设每个角色必须在其基数内配备,否则结果是一个错误,说明需要修复的内容。
键:
description`** (— 字符串或字符串预设工具的自己的。
- **`roles`** — 每个都带有可选的 `description`,以及 `min` / `max` 说话者(默认为恰好一个;`max: null` = 无限制,`min: 0` = 可选)。
- **`mode`、`synthesizer`、`synthesizeEvery`、`framer`、`reframeEvery`、`closingStatements`、`elimin`、`elimin`、`enterEveryvote`、`voteEvery`、`voteVisibility`、`defaultRounds`** — 可选的编排默认值。`framer` 是 `synthesizer` 的镜像:一个中立的声音,开启讨论(并在每 `reframeEvery` 轮重新调整)而不是关闭它。大部分可以按调用覆盖;`eliminateEvery`(幸存者模式:综合者每 N 轮删除一个说话者 — 删除的说话者永远退出并且不再被提示)、`eliminationsOptional`(让综合者保留给定轮中的所有人)和 `enterEvery`(分阶段进入:使用 `@team` 标签的选择器,一个战斗人员一个队伍开始,一个队伍每 N 轮进入一个)是仅预设的。`vote` 开启 **匿名同行投票**:每个活跃的说话者都进行隐秘的自由式投票,只有匿名计票到达转录记录(咨询 — 综合者/裁判决定是否采纳它);`voteEvery` / `voteVisibility` 调整它。查看已发货的预设和 `quorum` 工具的描述,了解每个功能的作用。
该仓库提供了这些预设 — 可以自由编辑或删除:
<dl>
<dt><code>code_review</code></dt>
<dd>结构化的多模型代码审查。</dd>
<dt><code>debate</code></dt>
<dd>双方辩论一个问题以得出综合结果。</dd>
<dt><code>brainstorm</code></dt>
<dd>跨模型的分散创意生成。</dd>
<dt><code>quick_take</code></dt>
<dd>来自多个模型的快速一次性反应。</dd>
<dt><code>tiebreak</code></dt>
<dd>一个决定性的第三方声音解决了僵局。</dd>
<dt><code>battle_royale</code></dt>
<dd>自由竞争;一个监管者加冕获胜者。</dd>
<dt><code>jury</code></dt>
<dd>独立裁决加上一个秘密的陪审团投票,由法官称重。</dd>
<dt><code>election</code></dt>
<dd>候选人竞选,然后由秘密投票决定 —结果是裁决,而不是法官的裁决。可选的 <code>incumbent</code捍卫记录的无声 <electorate</code每一轮并投票而不竞选。</<dt><code>double_blind</code>
<dd>独立审小组 — 没有其他人。</dd>
<dt><code>let</code></dt>
<dd>私人自我,跨越。</dd>
<dt>refine</code></dt>
<dd>物的中继润色。</dd>
<dt>workshop</code></dt>
<dd化创意团队。</<dt><code></code></dt>
<dd>主持的小彼此的意见。</dd>
<dt><code_girl</code></dt>
<dd>幸每轮减少一个,直到一个幸存。</<dt><code>war_games</code></dt>
<dd>分阶段团队擂台<code>@team</code> 标签的一个接一个进入中立的裁判犯规并命名获胜团队,可选>booker</设置比赛。</dd>
</dl>
空/缺失的文件夹 →设工具。
> **角色文本提示输出限制** —maxTokens` 进行,并为推理模型轮仲裁预留。
### AI 指南 — `config/description.md`
客户端的可选降序 Markdown 作为 MCP `instructions` — 描述模型和 AI 何时应使用每个模型。查看此仓库的副本以获取模板。
### 工具、字段和消息文本 — `config/*.json` 和 `config/tools/*.md`
所有面向用户的文本都位于配置中,而不是代码中,并且每次请求都热加载。每个文件都覆盖内置默认值,按键合并,因此只需覆盖您想要的内容;打开已发货的副本以查看完整的键集和 `{token}` 占位符:
- `config/tools/<tool>.md 工具的描述 `quorum.md`)。删除以回退到内置字符串。
- `config/schema.json` — 输入字段描述(`prompt` = 共享字段,`quorum` = 仅仲裁;`quorum` 键在名称冲突时获胜)。
- `config/prompts.json` — 模型读取的提示塑形模板:角色合约、上下文块、转录头、轮次横幅。在此处调整角色绑定强度和轮次框架。
- `config/errors.json` — 显示给调用 AI 的运行时错误消息。
(启动/配置验证错误保留在代码中 — 报告损坏配置文件无法在其中生存的错误消息。)
### 环境变量
| 变量 | 必需 | 描述 |
| --- | --- | --- |
| `DEFAULT_BASE_URL` | 否* | 模型的 API 根目录,无 `baseUrl` — SDK 追加 `/responses`。例如 `https://api.openai.com/v1`,`https://<res>.openai.azure.com/openai/v1`;LiteLLM 代理在其普通根目录下工作。 |
| `DEFAULT_API_KEY` | 否* | 模型的 API 密钥,无 `apiKey`。保留在服务器端。 |
| `HOST` | 否 | HTTP 绑定地址(默认为 `127.0.0.1`)。设置 `0.0.0` 以公开 — 然后设置 `ALLOWED_HOSTS`。 |
| `ALLOWED_HOSTS` | 否 | 非 localhost 绑定的重新绑定保护的以逗号分隔的主机。 |
| `PORT` | 否 | HTTP 端口(默认为 ``;忽略)。 |
|_ROUNDS` | `仲裁` 工具接受的最大讨论轮数(默认为 `5`)。 |
| `TOKEN_BUDGET` | 否 | `仲裁` 运行的默认**软**累积令牌预算(未设置 = 无限制;按调用覆盖 `tokenBudget`)。 |
|YNAMIC_ROLES` | 否 | 允许调用 AI 在内联定义临时 `仲裁` 角色(默认为 `true`)。 |
| `DISABLE_PRESETS` | 否 |号分隔的预设 slug 列表不** 注册为工具(例如 `battle_royale,jury`捆绑和本地预设;未知名称被忽略。未设置 = 所有预设注册。 |
| `LOG_LEVEL` | 否 | `debug` \| `info` \| `warn` \|`(默认为 `info`)。 |
\*模型必须从或默认值中解析baseUrl` 和 `apiKey` — 在启动时验证。
缺少/空模型无效模型文件、无法解析的端点或密钥、两个文件名转换为时**快速**。
###
每个工具调用无状态的一次性响应 API模型的端点原生支持响应AI、Azure Open Foundry一个 `baseUrl` 直接调用;其余的回退到 通常是与 Lite 等原生 API 桥接的 Open兼容网关。
## 日志记录
- `info`(蓝色):服务器启动和每个模型调用的一行元数据 — 模型、延迟、令牌使用、角色、上下文存在。无提示/响应内容。
- `debug灰色):另外记录完整的提示和响应(上下文被提及,不会打印 `warn`(橙色)/`(红色):回退和失败。
不是 TTY颜色自动禁用 运行
一个,将传输作为参数 `stdio`开发(绿色,无需构建步骤,通过 `):
```pwnpm run dev io 传输
dev:http # :$PORT/mcp 上的可流式 HTTP 传输
```
生产(编译为 `bin/server.js`):
```pwsh
npm run build
npm start # node bin/server.js (stdio)
npm run start:http # node bin/server.js http
```
## 试用
使用 MCP 检查器列出工具:
```pwnpx @modelcontextprotocol npx tsx ts/server```
## 在 VS Code 中使用
添加到您的 `mcp.json`:
```json
{
"servers": {
"legion": {
"command": "node",
" ["bin/server.js"],
" "legion 的路径",
"env": {
"DEFAULT_BASE_URLhttps://your-gateway.example.com "DEFAULT_API_KEY": "sk"
}
}
}
对于 HTTP 传输,客户端指向://>:<PORT>/` 健康状况
- /health` — **活动**确认进程已启动并加载配置 `{ status: "ok", name, models }`(计数)。不进行外部调用。此容器 `HE` 和 Kubernetes 活跃/就绪探测应访问此内容。
- `health?deep` — 可选 **连接性** 检查:向每个模型发送一个小提示,并报告每个模型的可用性(如果任何模型失败,则返回 `503`)。对每个模型进行实际的付费调用,因此请手动