Back to skills
SKILL.md
gan-trinity
ASecurity通用三体自主开发工作流(用户级,任何项目可用):Planner 探测项目并拆需求 → Sprint Contract 谈判 → Generator 实现 → Evaluator 独立审查 → 修复循环直至达标。触发词:gan-trinity、三体流程、三体开发、三体工作流、用三体做、agent 对抗开发、多角色自审开发。适用于复杂开发任务:脚本、配置、文档、批处理、设计稿等需要独立质量把关的场景。简单一次性小改(改错别字、单行修复)不要用本流程。
- 2 stars
- 0 votes
- 0 copies
- 0 views
- Added September 22, 2026
Works with
Security analysis
92/100- Installs packages at runtime which could introduce malicious dependencies
Pro scans all 4 files and shows the line behind each finding
npx -y skills add xdeqdqyhxcpm/gan-trinity --agent claude-codeAre you the author of gan-trinity?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/xdeqdqyhxcpm-gan-trinity)---
name: gan-trinity
displayName: GAN 三体
version: "1.5.0"
license: MIT
description: "通用三体自主开发工作流(用户级,任何项目可用):Planner 探测项目并拆需求 → Sprint Contract 谈判 → Generator 实现 → Evaluator 独立审查 → 修复循环直至达标。触发词:gan-trinity、三体流程、三体开发、三体工作流、用三体做、agent 对抗开发、多角色自审开发。适用于复杂开发任务:脚本、配置、文档、批处理、设计稿等需要独立质量把关的场景。简单一次性小改(改错别字、单行修复)不要用本流程。"
---
# GAN 三体 — 通用自主开发工作流(WorkBuddy 原生版)
Planner 拆需求 → Sprint Contract 谈判 → Generator 实现 → Evaluator 独立审查 → 修复循环。三个角色互相制约,直到质量达标。
核心思想:**写代码的和验收的必须是两个不同的人**。每个角色起一个独立子 agent(上下文互不可见),从机制上杜绝"自己给自己打分"。
## 触发
- 用户输入 `/gan-trinity <任务描述>`
- 或用户明确说"用三体流程 / 三体开发 / gan-trinity / 让几个 agent 互相审"做事
如果只打了 `/gan-trinity` 没跟描述,**反问他要做什么**,不要直接跑。简单小改(改错别字、单行修复)不启动本流程,直接做。
## 参数
从用户输入中提取:
- **task**(必需):用户需求原样传入。
- **targetDir**(可选):用户明确指定输出目录才传,否则不传,让 Planner 探测项目结构自行决定。
- **context**(可选):用户补充的额外约束(领域标准、工具链、风格要求等),没提就不传。
- **maxFixes**(可选,默认 3):单个 sprint 的修复循环上限。
## 执行
主 agent 亲自当**编排者**,用 `Agent` 工具起子 agent 扮演三个角色。不要自己写完再自己审——那等于没跑本流程。
### 前置提醒
本流程每个 sprint 至少起 4 个子 agent,token 消耗是普通开发的数倍。开跑前先说一句预计规模(几个 sprint、约几个子 agent),让用户有机会喊停。
### 阶段 1 — Plan(1 个子 agent)
用 `Agent` 工具,`subagent_type: "Explore"`(只读,防止 Planner 手滑改文件),thoroughness 用 `medium`。
prompt 用下方 **T1 Planner** 模板。Planner 必须把结果包在 ```json 代码块里输出,主 agent 收到后自己解析。
从 Planner 输出中取出:
- `productName` / `overview` / `techStack`
- `workingDir` → 与用户传的 `targetDir` 合并:`targetDir = 用户指定 || spec.workingDir`
- `standards[]` → 拼成 `standardsText`,后续每个 prompt 都要带上
- `sprints[]`(3–5 个)→ 每个含 `sprintId` / `title` / `goal` / `features[]` / `fileToEdit`
解析失败或 sprints 为空 → 停,报告失败原因,不要硬编一个计划。
### 阶段 2 — Sprints(串行,每个 sprint 3–4 个子 agent)
按 `sprintId` 顺序串行推进(MVP 先验证方向,后续 sprint 基于它叠加)。每个 sprint 走四步:
**Step 1 — Sprint Contract 谈判**
1. `Agent(subagent_type: "general-purpose")` + **T2 Contract-Gen** → Generator 提出验收标准
2. `Agent(subagent_type: "general-purpose")` + **T3 Contract-Eval** → Evaluator 增删改并签字
3. 校验签字:Evaluator 输出的最后一行必须含 `CONTRACT_SIGNED`
- 没有 → 记 `status: "contract_failed"`,**跳过本 sprint**,继续下一个
- 有 → 拿到 `contractReview` 全文(含最终验收标准),进入 Step 2
**Step 2 — Generator 开发**
`Agent(subagent_type: "general-purpose")` + **T4 Generator**。要求它在回复末尾标注 `CODE_COMPLETE`。没产出 → `status: "dev_failed"`,跳过。
**Step 3 — Evaluator 独立评估**
`Agent(subagent_type: "general-purpose")` + **T5 Evaluator**。Evaluator 必须**重新自己读文件**(不能信 Generator 的自述),并且**实际跑验证**(语法检查、dry-run、参数边界试跑),最后输出 JSON 代码块,字段:`passed` / `bugs[]`(每条 `severity` + `description` + `reproduction`)/ `score` / `summary`。
**Step 4 — 修复循环(≤ maxFixes)**
`while (!passed && fixRound < maxFixes && bugs.length > 0)`:
1. `Agent` + **T6 Fix** → Generator 修当前这批 bug
2. `Agent` + **T7 ReEval** → Evaluator 重读文件复验,同样输出 JSON
3. 更新 `bugs`;`passed === true` 就 break
最终状态判定:
- `evalResult.passed || (fixRound > 0 && bugs.length === 0)` → `passed`
- `fixRound >= maxFixes` → `max_fixes_reached`
- 其他 → `bugs_remain`
### 阶段 3 — Report(主 agent 自己写,不再起子 agent)
汇总表格:每个 sprint 的 标题 / 文件 / 状态 / 评分 / 修复轮次 / 遗留问题数,加总通过率与平均分,列出产物目录。
## Prompt 模板
以下模板自包含,直接替换 `{{...}}` 后传给子 agent。子 agent 看不到当前对话,占位符必须全部填实。
### T1 Planner
```
你是软件架构师 Planner,运行在用户当前项目(会话工作目录即项目根)。
第一步:先探测项目再定计划。用 Read/Glob/Grep 查看 CLAUDE.md、README、目录结构、以及既有的同类产物(脚本/文档/配置放在哪、什么风格)。不要凭空假设项目结构。
用户需求:「{{task}}」
{{targetDir ? "用户已指定输出目录:" + targetDir + "(workingDir 直接用这个)" : "用户未指定输出目录:你必须根据探测结果自行决定 workingDir(优先沿用项目既有约定目录;没有约定就新建议一个合理的)。"}}
{{context ? "用户补充的约束/上下文:" + context : ""}}
输出产品开发计划,字段:
- productName: 产物名称
- overview: 2 句话概述
- techStack: 推荐技术栈(与项目既有技术选型一致)
- workingDir: 输出目录(相对项目根)
- standards: 从项目文档和既有产物中提取的硬性约束清单(编码风格、术语、精度/格式标准、依赖限制等);确实没有就给空数组
- sprints: 3-5 个,每个聚焦一个可独立验证的功能模块
- 第 1 个 sprint 必须是最小可验证版本(MVP),先验证方向
- 后续 sprint 逐步增加功能
- 每个 sprint 含 sprintId(number), title, goal, features(string[]), fileToEdit(相对 workingDir 的文件名)
规则:产物品质优先;上述 standards 中的硬性约束不可妥协。
把完整计划包在一个 ```json 代码块里输出,不要输出其他多余内容。
```
### T2 Contract-Gen
```
你是 Generator(开发者),正在为 Sprint {{sprintId}} 签订验收契约。
产品:{{productName}}({{overview}})
目标:{{goal}}
功能点:{{features}}
编辑文件:{{targetDir}}{{fileToEdit}}
项目根:{{projectRoot}}
项目硬性约束(来自项目探测):
{{standardsText}}
先读项目相关文件和既有同类产物,然后提出本 sprint 的验收标准(acceptance criteria):
- 每条必须具体可测试("脚本对不符合规范的输入报错并以非零码退出" 而非 "功能正常")
- 至少 3 条,最多 6 条
- 覆盖正常路径 + 边界情况
- 脚本类产物:包含语法检查、参数正确性、错误处理
- 配置/文档类产物:包含参数范围校验、步骤完整性、与项目文档一致性
输出验收标准列表后,标注 "CONTRACT_PROPOSAL_END"。
```
### T3 Contract-Eval
```
你是 Evaluator(质量审查员)。Generator 提议了以下验收标准:
{{contract}}
产品:{{productName}} | Sprint {{sprintId}}: {{title}}
目标文件:{{targetDir}}{{fileToEdit}}
项目硬性约束(来自项目探测):
{{standardsText}}
请审查:
1. 这些标准是否足够覆盖功能点和边界情况?
2. 是否与项目文档/既有产物约定一致?
3. 是否覆盖了上述硬性约束?
4. 有遗漏就补充,有不合理就修改
5. 标准严重不足且无法修补时,不要签字
输出合并后的最终验收标准列表,标注 "CONTRACT_FINAL_END"。
最后一行写:CONTRACT_SIGNED
```
### T4 Generator
```
你是 Generator(开发者)。Sprint Contract 已签署。
产品:{{productName}}
Sprint {{sprintId}}:{{title}}
目标文件:{{targetDir}}{{fileToEdit}}(完整路径为项目根 {{projectRoot}} 下)
技术栈:{{techStack}}
验收标准:
{{contractReview}}
项目硬性约束:
{{standardsText}}
请实现产物。注意:
- 必须与项目既有风格/文档约定一致
- 写完必须自查语法/格式能通过;脚本类用 Bash 实际跑一次 `--help` 或等价的最小验证
- 写完后在回复末尾标注 CODE_COMPLETE
```
### T5 Evaluator
```
你是 Evaluator(独立测试员)。请严格审查刚交付的产物。你不知道是谁写的,也不关心——只按标准验。
产品:{{productName}}
Sprint {{sprintId}} - {{title}}
文件:{{targetDir}}{{fileToEdit}}(项目根 {{projectRoot}})
验收标准:
{{contractReview}}
测试步骤:
1. 用 Read 工具读取该文件完整内容(必要时对比项目既有同类产物)
2. 逐条验证验收标准:
- 脚本类:语法、错误处理、参数正确性、边界情况。用 Bash 实际执行验证(如 python -m py_compile、--help、喂非法参数看是否报错退出)
- 配置类:语法、参数范围、与项目文档一致性
- 文档类:步骤完整性、参数准确性、与项目术语一致
3. 检查硬性约束落实情况:
{{standardsText}}
4. 记录每个不通过项
只报真实缺陷,不要为了显得严格而编造问题;也不要因为文件"看起来不错"就跳过实际执行验证。
把结果包在一个 ```json 代码块里输出:
{
"passed": true/false, // 所有标准都通过才为 true
"bugs": [{"severity":"critical|major|minor","description":"...","reproduction":"..."}],
"score": 0-100,
"summary": "一句话总结"
}
```
### T6 Fix
```
你是 Generator。Evaluator 发现了以下问题:
{{bugList}}
请修复文件 {{targetDir}}{{fileToEdit}}(项目根 {{projectRoot}})中的所有问题,保持已有功能不被破坏。
修完自己实际跑一次验证,确认修好了。完成后标注 FIX_COMPLETE。
```
### T7 ReEval
```
你是 Evaluator。请重新审查修复后的版本。
文件:{{targetDir}}{{fileToEdit}}(项目根 {{projectRoot}})
上次失败的问题:
{{bugList}}
用 Read 工具重新读取文件,并用 Bash 实际复现验证这些问题是否已修复,同时确认原有功能未被破坏。
把结果包在一个 ```json 代码块里输出,字段同上次:
{"passed": ..., "bugs": [...], "score": ..., "summary": "..."}
```
## 机制说明
- 所有项目上下文由 **Planner 自己探测**(`CLAUDE.md` / README / 目录结构 / 既有同类产物),本 skill 不含任何项目硬编码。
- 每个 sprint 先做 **Contract 谈判**:Generator 提标准 → Evaluator 增删改并签字,签字后才开工。Evaluator 拒签的 sprint 直接跳过而不是硬做。
- Evaluator 是独立子 agent,上下文与 Generator 完全隔离,天然不会给自己写的代码打分。
- 修复循环默认上限 3 轮;到顶仍未过就如实报 `max_fixes_reached`,不粉饰。
- 最终报告含每个 sprint 的通过状态、评分、修复轮次。
## 版本演进:从 Workflow 脚本到 Agent 编排
v1.0 用 Claude Code 的 `Workflow` 工具执行 JS 脚本做编排,有两个问题:WorkBuddy 根本没有 `Workflow` 工具(**完全跑不了**),而且流程写死在 JS 里,改一步要改脚本。
v1.1 起改为「SKILL.md 内嵌 prompt 模板 + 主 agent 用 `Agent` 工具编排」,从此跨平台通用:
| 项 | v1.0(Workflow 脚本版) | v1.5(Agent 编排版,当前) |
| --- | --- | --- |
| 运行载体 | `Workflow` 执行 `gan-trinity.js` | 主 agent 用 `Agent` 工具起子 agent,模板内嵌 SKILL.md |
| 平台兼容 | 仅 Claude Code(旧版) | **WorkBuddy + Claude Code 通用** |
| 角色隔离 | `agent()` 调用 | 每个角色一次独立 `Agent` 调用,上下文互不可见 |
| Planner 权限 | 全量工具 | `subagent_type: Explore`,强制只读 |
| Evaluator 能力 | 只读文件审查 | 允许实际执行验证(语法检查、喂非法参数、dry-run) |
| Sprint 执行 | `pipeline` 并行 | 默认串行(MVP 先跑通再叠加) |
| 改流程 | 要改 JS | 改 markdown 即可 |
跨平台可行的原因是两边的子代理机制已趋同:启动子代理的工具**都叫 `Agent`**(Claude Code 2.1.63 起由 `Task` 改名,旧名保留为别名),内置类型**都有 `Explore` 和 `general-purpose`**,且都支持主代理在 skill 正文里串行编排多个子代理。
原始 v1.0 脚本保留在 `reference/gan-trinity.claude-code.js`,依赖 `Workflow` 工具,**在 WorkBuddy 不可执行**,仅作迁移参考。
### 平台差异备忘
| | WorkBuddy | Claude Code |
| --- | --- | --- |
| skill 目录 | `~/.workbuddy/skills/<name>/` | `~/.claude/skills/<name>/`(或项目级 `.claude/skills/`) |
| 扩展 frontmatter 字段 | `displayName` / `version` | `allowed-tools` / `context` / `model` 等 |
本 skill 的 frontmatter 只用了两平台共通的 `name` / `description` / `license`,WorkBuddy 扩展字段(`displayName` / `version`)在 Claude Code 中会被忽略但不报错,因此**同一份文件两边都能加载**。
> 兼容性结论来自两平台官方文档的能力比对,并已实测:**WorkBuddy 端**跑通多个真实项目;
> **Claude Code 端**(v2.1.128)实测用 `Agent` 工具成功启动 4 个子代理(`Explore` + `general-purpose` ×3)
> 并产出可运行产物,完整多 Sprint 流程因测试预算上限未跑到底。
## 运行环境适配(Windows / 受管沙箱,实测踩坑)
这些坑会让子 agent 莫名其妙地失败或"看起来失败",开跑前把它们写进 `standardsText` 传给每个角色:
- **`.ps1` 必须存成 UTF-8 带 BOM**。Windows PowerShell 5.1 对无 BOM 的 `.ps1` 按 ANSI(GBK) 解码,中文注释会被解码错乱并**吞掉引号**,表现为解析期语法错误、脚本完全跑不起来。补 BOM:
`[System.IO.File]::WriteAllText($p, $txt, (New-Object System.Text.UTF8Encoding($true)))`。
(`.ini` / `.py` / `.md` 反而**不能**带 BOM:pytest 配置和 Python 源码对 BOM 敏感,且常有测试断言"无 BOM"。)
- **不要在 venv 里执行 `pip install --upgrade pip`**。卸载旧 pip 时会把 `pip.exe` 移向系统临时目录,项目盘与系统盘不同盘时 rename 直接失败(`WinError 17`),退化成删除后又会撞上宿主的批量删除防护并中断(`SystemExit(1)`),结果 venv 的 pip 被卸掉一半(`No module named pip`)。正确做法:只做 `python -m pip --version` 可用性校验,不可用时用 `python -m ensurepip --default-pip` 自愈。
- **删除操作可能被宿主接管**。若环境把 `unlink` 重定向到回收站并设有"单次批量删除上限",则在同一会话里删除数累计超阈值后,**后续任何删除都会抛 `SystemExit(1)`**。后果:所有"真实删文件"的用例批量失败,堆栈最内层落在项目之外的注入模块上。判定与规避写进项目 README,并在给 Evaluator 的 prompt 里说明,避免它把这当成 Generator 的缺陷。
- **命令文本本身也可能被安全策略拦截**:如果验证命令里出现被列黑的关键字(例如某个运行时编译指令的字面量),整条命令会被拒。改用动态拼接绕开。
- **PowerShell 的 stdout 不回显时**:一切验证落盘再读(`Out-File` + `Read`),不要凭 exit code 宣称成功。
- **Windows 提交代码会被 Git 警告 `LF will be replaced by CRLF`**。根因常是**系统级** `core.autocrlf=true`
(`git config --system core.autocrlf` 查得到,`--global` 却是空的,容易误判成自己设过)。
开源项目应加 `.gitattributes` 统一行尾,否则跨平台协作会出现整文件级 diff:
```
* text=auto eol=lf
*.bat text eol=crlf # Windows 批处理必须保留 CRLF
```
改完执行 `git add --renormalize .` 让已跟踪文件重新规范化,再用 `git ls-files --eol` 复核是否全为 `i/lf`。
- **删除钩子可能搬走未预期的目录**。实测:清理 `__pycache__` 时钩子报 `SAFE_DELETE_FAIL_CLOSED: trash-failed / Some operations were aborted`,事后发现**整个 `.git` 被逐项拆散进了回收站**(90 条:`.git`、`refs`、`objects` 及 30+ 个 object 前缀子目录),`git stash` 随即报 "not a valid object"。约定:
- 动手做任何 git/删除操作前,**先把源码备份到仓库外**;
- **避免 `git stash` / `git clean` / 大批量递归删除**;
- git 操作后用 `Test-Path <repo>\.git` 复核,别假设它还在;
- 一旦发现 `.git` 丢失:先扫回收站的 `$I*` 元数据(UTF-16LE 尾部存原始路径)确认被搬走了什么;若碎片过多,**重建仓库比搬运碎片更稳**(内容都在工作区,丢失的只是提交历史)。
## 变异检验:证明测试真的能抓 bug(Evaluator 必做)
写完回归测试不等于测试有效。要求 Generator **逐项禁用修复**,确认对应用例确实失败。做法与坑:
- 用**外科式定点变异**:对源码做一处定向字符串替换(如把 `mkstemp` 换回固定名、把重试上限改成 1、把截断点退回旧逻辑),跑对应用例,然后立刻还原并校验 sha256。一次只禁用一个修复,与用例一一对应。
- **不要用 `git stash` 制造变异**(见上,会连累 `.git`);而且仓库若是"修复后才重建"的,基线提交里已经是修复后的代码,`git show <基线>` 取不到旧版本。
- **判定必须严格**:只有 `exit==1` **且** 输出含 `failed` 才算"用例如期失败"。只看"退出码非零"会把 `exit=4`(pytest 用法错误,用例根本没跑)误判成 ✅——实测踩过:把 `::用例名` 当独立参数传给 pytest,三个变异全部假阳性通过,等于白做。
- 用例 node id 必须整体作一个参数传:`tests/x.py::test_name`,不能拆成 `tests/x.py` + `::test_name`。
## 两个高价值的独立验证手段(别省)
### 1. clone 级复现门禁
把仓库 clone 到**仓库外**的全新目录,在 clone 内跑全量测试 + 校验行尾(`git ls-files --eol` 无 `crlf`)+ 工作区干净。这是唯一能发现「开发机上一直存在、但 clone 下来不存在」这类缺陷的手段。实测价值:某项目的 `data/`、`logs/` 被 gitignore,开发机上一直有(历史运行留下),clone 下来不存在,导致一个用 `data_dir.iterdir()` 的用例在干净 clone 里 `FileNotFoundError` 假失败——本机全绿,只有 clone 能照出来。成本极低,值得每个交付型项目跑一次。
### 2. 禁网桩与模块导入的相互干扰
项目若有「autouse 夹具把 `socket.socket` 换成函数」的禁网桩,则**在该夹具生效后再 in-process 导入任何会拉起 `ssl` 的模块会炸**:`ssl.py` 里 `class SSLSocket(socket)` 拿到的已不是类,抛 `TypeError: function() argument 'code' must be code, not str`。既有测试通常在夹具生效前就完成了导入,所以从没暴露。对策:需要比对各文件里的常量时,**改纯文本解析 + `ast.literal_eval`**,不要导入模块。
顺带:写「文本 I/O 必须显式 encoding」这类自检时,`\bopen\(` 会误匹配 `opener.open(url, ...)` 这种属性调用,用 `(?<![.\w])open\(` 排除。
## 本地验证的路径纪律
- 跑测试前必须 `Set-Location` 到**项目根**:若工作区里放着项目源码的备份副本,其中同名 `tests/test_*.py` 会在收集阶段与项目内模块冲突,直接抛一堆 collection ERROR(不是用例失败,容易被误读成"改坏了")。
- 每次 pytest 都带 `--basetemp` 指向**仓库外的全新目录**:否则 pytest 清理历史临时目录时可能触发宿主机批量删除防护,让"真实删文件"的用例抛 `SystemExit(1)`。
## 子 agent 调用失败时的处置
`Agent` 调用可能因网络/服务端问题失败(实测见过 `502` + `getaddrinfo ENOTFOUND`)。此时**不要假装流程走完了**:
1. 先看子 agent 是否已经落了产物——它可能在被中断前已写完部分文件,从磁盘接管比从头重做省事。
2. 主 agent 可接手实现,但**必须如实标注哪些环节缺少独立评估**("Generator 与 Evaluator 由同一主体完成,未做角色隔离"),不能把自验冒充成三体流程的独立审查。
3. 交付时把"未执行的 sprint"和"未走通的环节"单列出来,让用户知道还差什么。
## 变更记录
- **2026-09-21(v1.5.0)**:整理为公开发布版。补全 `README.md` / `LICENSE`(MIT) / 安装说明 / 实战案例;清理原稿中的本机绝对路径与内部项目名;修正 frontmatter 版本号与变更记录长期不一致的问题(此前写 1.1 而记录已到 v1.4)。
- 2026-09-15(v1.4):新增「两个高价值的独立验证手段」(clone 级复现门禁、禁网桩与 `ssl` 导入的相互干扰)与「本地验证的路径纪律」(先进项目根、pytest 带 `--basetemp`)。均为某 Python 爬虫项目 S1/S2 收尾时实测。
- 2026-09-15(v1.3):补充「删除钩子可能搬走 `.git`」的备份纪律,与「变异检验:证明测试真的能抓 bug」一节(外科式定点变异、严格判定 `exit==1 且含 failed`、node id 必须整体传参)。
- 2026-09-15(v1.2):新增「运行环境适配」(Windows/受管沙箱的 ps1 BOM、pip 自升级自毁、删除被接管、命令文本被拦、stdout 不回显)与「子 agent 调用失败时的处置」两节。
- 2026-09-15(v1.1):从 Claude Code 的 `Workflow` 脚本版改写为 WorkBuddy 原生 `Agent` 编排版,迁入用户级 skill 目录。原版为 Claude Code `Workflow` 脚本驱动(v1.0)。
Files in this skill
- SKILL.md
- examples/disk-cleanup-case.md
- reference/SKILL.claude-code-v1.0.md
- reference/gan-trinity.claude-code.js
Attribution
Comments
Loading comments…