1实现原理 · 为什么它能做到
机制核心不是『调用多个模型』而是『Claude 亲自下场』:SKILL.md 要求 Claude 在给出对手模型结论的同时给出自己的独立 critique 与综合裁决,并明确让用户知道这一点。
**Important: Claude is an active participant in this debate, not just an orchestrator.** You (Claude) will provide your own critiques, challenge opponent models, and contribute substantive improvements alongside the external models.
真实执行层是一个自带 Python CLI(debate.py + 5 个模块),skill 通过固定命令行把文档经 stdin 喂给脚本;脚本用 litellm 并行调用各家 provider 并解析 `[AGREE]` / `[SPEC]` 标记。
python3 "$(find ~/.claude -name debate.py -path '*adversarial-spec*' 2>/dev/null | head -1)" critique --models MODEL_LIST --doc-type TYPE <<'SPEC_EOF'
调用通道分两类:API key 走的模型经 litellm 统一出口;订阅制模型(ChatGPT/Google 账号)走本机 CLI 子进程,把文档拼进 argv/stdin 交给 codex / gemini。
cmd = [ "codex", "exec", "--json", "--full-auto", "--skip-git-repo-check", "--model", actual_model, "-c", f'model_reasoning_effort="{reasoning_effort}"', ]
收敛判定靠模型输出里的字面标记,而非语义判断:任何模型没出现 [AGREE] 就继续下一轮;对『前两轮就同意』强制加一轮 --press 反懒惰盘问。
**Handling Early Agreement (Anti-Laziness Check):** If any model says `[AGREE]` within the first 2 rounds, be skeptical.
长辩论可中断可回滚:会话状态、每轮 checkpoint、常用配置各自落盘,session 与 profile 分离存放。
SESSIONS_DIR = Path.home() / ".config" / "adversarial-spec" / "sessions" CHECKPOINTS_DIR = Path.cwd() / ".adversarial-spec-checkpoints"
可选的人工在环通道是 Telegram 机器人:每轮把摘要推给用户,轮询 60 秒内回复并把答复并入下一轮;无需回复则自动继续。
TELEGRAM_API: str = "https://api.telegram.org/bot{token}/{method}"
企业级替代通道:可切到 AWS Bedrock 让所有模型调用统一走 Bedrock 前缀(用于合规/网关场景),配置写回家目录的 config.json。
**When Bedrock mode is enabled, ALL model calls route through Bedrock** - no direct API calls are made.
成品交付由 Claude(宿主)完成而非脚本:skill 要求把最终文档打印并写入当前目录的 spec-output.md(PRD 续做则为 tech-spec-output.md),脚本本身不产出该文件。
1. Print the complete, polished document to terminal 2. Write it to `spec-output.md` in current directory
2核心能力
3外部依赖
| 类型 | 依赖 |
|---|---|
| package | litellm |
| api | 多家 LLM 供应商 API(经 litellm 统一出口) |
| cli | codex(OpenAI Codex CLI,走 ChatGPT 订阅) |
| cli | gemini(Google Gemini CLI,走 Google 账号) |
| api | AWS Bedrock(可选企业通道,全部调用可改走 bedrock/ 前缀) |
| network | Telegram Bot API(可选人工在环) |
| package | 开发依赖(pytest/pytest-cov/ruff/mypy/pre-commit) |
4风险提醒 风险提醒:橙色 · 评估后使用
- 文档出域不可控(主要在功能固有) — 每次 critique 都会把 spec 全文送给所选模型;--context 还会读取并外发任意本地文件(schema.sql、合规文档等)。产品规格常含未公开信息,使用前必须确认文档可否发给对应供应商;企业场景应切 Bedrock 或仅用自托管模型。
- 外部模型输出即第二指令源 — 脚本按字面标记解析 [AGREE]/[SPEC],模型返回文本既进入下一轮输入也进入 Claude 的综合素材;若某模型(或其被注入的上下文,如 --context 里的恶意文档)输出指令性内容,可能影响最终文档与『是否收敛』的判定。
- 凭证面宽 — 读取多达 9 个 API key 环境变量 + AWS 凭证 + Telegram token;list_providers 会暴露『哪些钥匙存在』这一信息;telegram 通道把文档摘要外发到第三方平台(Telegram)。
- 子进程与 --full-auto — codex exec --full-auto 授权该 CLI 自行执行动作(在其自身沙箱内),gemini -y 亦为自动批准模式;两个 CLI 均为远程安装的第三方包,行为受其自身版本与账号策略影响,本 skill 不做审计。
- 无强制轮数护栏 + 成本不可预知 — 'Maximum 10 rounds' 仅是提示词纪律(代码无上限),多模型多轮会产生真实费用;难度高的 spec 可能长时间迭代并把成本推到用户预期之外(虽有成本摘要,但是事后可见)。
- 文档质量依赖模型与提示词,无客观验证 — 所谓『收敛』等于所选模型都输出了 [AGREE],不构成对规格正确性的验证;SKILL.md 也自述要按 document 类型清单人工核对(Step 5 的 completeness/consistency/clarity/actionability 四项自检)。
5第二遍独立确认
- [ok] 多模型调用确实存在(非纯提示词) — models.py import litellm + from litellm import completion,标准路径 'response = completion(**completion_kwargs)';providers.py CODEX_AVAILABLE/GEMINI_CLI_AVAILABLE 用 shutil.which 探测。
- [ok] 订阅制模型走 CLI 子进程 — call_codex_model 构造 ['codex','exec','--json','--full-auto','--skip-git-repo-check','--model',…] 并 subprocess.run;call_gemini_cli_model 构造 ['gemini','-m',model,'-y'] 并把 prompt 经 input= 传入。
- [ok] Telegram 端点与轮询 — telegram_bot.py 'TELEGRAM_API: str = "https://api.telegram.org/bot{token}/{method}"' + 'with urlopen(req, timeout=30)'(urllib,非 requests);poll_for_reply(timeout=60 默认) 与 cmd_notify 均存在。
- [ok] Bedrock 模式确实可全量接管调用 — is_bedrock_enabled()/get_bedrock_config() 读 GLOBAL_CONFIG_PATH;models.py 在 bedrock 分支设置 AWS_REGION 并给 model 加 'bedrock/' 前缀;handle_bedrock_command 支持 status/enable/disable/add-model/remove-model/alias。
- [discrepancy] 『Maximum 10 rounds』是否由代码强制 — SKILL.md 写 'Maximum 10 rounds per cycle (ask user to continue if reached)',但对 debate.py 全文检索无任何轮数上限常量/参数(--round 只是当前轮号,--rounds 只用于 send-final 汇报)。结论:轮数上限是提示词纪律,代码不设护栏,已在 how_it_works 第 4 条与 risks 中如实标注。
- [discrepancy] 『Write it to spec-output.md』的归属 — 第一遍曾按『脚本写文件』记录;第二遍在 scripts/ 全目录检索 'spec-output' 零命中,确认该写入由宿主 Write 工具完成(SKILL.md allowed-tools: Bash, Read, Write, AskUserQuestion)。已改写为『成品交付由 Claude 完成』并据此调整 file_writes。
- [discrepancy] Python 版本要求一致性 — SKILL.md Requirements 写 'Python 3.10+ with `litellm` package installed',而 pyproject.toml 写 requires-python = ">=3.9" 且 ruff target-version = "py39"、mypy python_version = "3.10"。属文档与打包元数据的轻微不一致(不影响功能判定)。
- [ok] 成本追踪是否真有实现(非仅文档) — providers.py MODEL_COSTS 价目表 + DEFAULT_COST;debate.py 'Cost: ${cost_tracker.total_cost:.4f}' 与 JSON 输出 'cost': {total, input_tokens, output_tokens, by_model}。
6结论
89a0a6e57cca0f6a…f90cf0c36c