ai-battle 0.1.0 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +86 -86
- package/ai-battle.sh +29 -6
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,37 +1,50 @@
|
|
|
1
|
-
|
|
1
|
+
<h1 align="center">⚔️ ai-battle</h1>
|
|
2
2
|
|
|
3
|
-
>
|
|
3
|
+
<p align="center">
|
|
4
|
+
<strong>让多个 AI Agent 对同一问题进行结构化圆桌讨论</strong>
|
|
5
|
+
</p>
|
|
4
6
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
7
|
+
<p align="center">
|
|
8
|
+
自动管理轮次 · 检测共识 · 保存全部记录
|
|
9
|
+
</p>
|
|
8
10
|
|
|
9
|
-
|
|
11
|
+
<p align="center">
|
|
12
|
+
<a href="https://www.npmjs.com/package/ai-battle"><img src="https://img.shields.io/npm/v/ai-battle?style=flat-square&logo=npm&logoColor=white&color=CB3837" alt="npm version" /></a>
|
|
13
|
+
<img src="https://img.shields.io/badge/Bash-4%2B-4EAA25?style=flat-square&logo=gnubash&logoColor=white" alt="Bash 4+" />
|
|
14
|
+
<img src="https://img.shields.io/badge/Dep-jq-blue?style=flat-square" alt="jq" />
|
|
15
|
+
<a href="LICENSE"><img src="https://img.shields.io/badge/License-MIT-yellow?style=flat-square" alt="MIT License" /></a>
|
|
16
|
+
</p>
|
|
10
17
|
|
|
11
|
-
|
|
12
|
-
- 🔁 **同类自辩** — 同一 Agent 可参加多席位(如 `gemini,gemini`)
|
|
13
|
-
- 🔨 **裁判模式** — 独立裁判每轮总结差异、自动检测共识、生成最终报告
|
|
14
|
-
- 👁️ **上帝视角** — 每轮结束后可人工注入补充信息引导讨论方向
|
|
15
|
-
- 💾 **Session 录制** — 保存 Agent CLI 原始输出(stream-json/json/raw)
|
|
16
|
-
- 🔄 **断点续讨** — 中断后自动恢复到上次轮次继续讨论
|
|
17
|
-
- 🔌 **可扩展** — 实现 3 个函数 + 注册即可接入新 Agent
|
|
18
|
+
---
|
|
18
19
|
|
|
19
|
-
##
|
|
20
|
+
## ✨ Features
|
|
21
|
+
|
|
22
|
+
| Feature | Description |
|
|
23
|
+
| :--- | :--- |
|
|
24
|
+
| 🤖 **多 Agent 圆桌** | 支持 Claude / Codex / Gemini 自由组合 |
|
|
25
|
+
| 🔁 **同类自辩** | 同一 Agent 可参加多席位(如 `gemini,gemini`) |
|
|
26
|
+
| 🔨 **裁判模式** | 独立裁判每轮总结差异、自动检测共识、生成最终报告 |
|
|
27
|
+
| 👁️ **上帝视角** | 每轮结束后人工注入补充信息引导讨论方向 |
|
|
28
|
+
| 💾 **Session 录制** | 保存 Agent CLI 原始输出(stream-json / json / raw) |
|
|
29
|
+
| 🔄 **断点续讨** | 中断后自动恢复到上次轮次继续讨论 |
|
|
30
|
+
| 🔌 **可扩展** | 实现 3 个函数 + 注册即可接入新 Agent |
|
|
31
|
+
|
|
32
|
+
## 🚀 Quick Start
|
|
20
33
|
|
|
21
34
|
```bash
|
|
22
|
-
#
|
|
35
|
+
# 创建讨论目录
|
|
23
36
|
mkdir my-topic && cd my-topic
|
|
24
37
|
|
|
25
|
-
#
|
|
38
|
+
# 写入问题
|
|
26
39
|
echo "微服务 vs 单体架构的优缺点?" > problem.md
|
|
27
40
|
|
|
28
|
-
#
|
|
41
|
+
# 启动讨论(自动拉取最新版)
|
|
29
42
|
npx ai-battle --agents claude,gemini --rounds 8
|
|
30
43
|
```
|
|
31
44
|
|
|
32
|
-
## 📦
|
|
45
|
+
## 📦 Installation
|
|
33
46
|
|
|
34
|
-
|
|
47
|
+
**推荐:无需安装,直接使用 npx**
|
|
35
48
|
|
|
36
49
|
```bash
|
|
37
50
|
npx ai-battle --agents claude,gemini --rounds 5
|
|
@@ -45,21 +58,27 @@ npx ai-battle --agents claude,gemini --rounds 5
|
|
|
45
58
|
npm install -g ai-battle
|
|
46
59
|
```
|
|
47
60
|
|
|
48
|
-
|
|
61
|
+
### 前置依赖
|
|
49
62
|
|
|
50
|
-
|
|
63
|
+
- `bash` 4+
|
|
64
|
+
- [`jq`](https://jqlang.github.io/jq/)
|
|
65
|
+
- Agent CLI 工具(至少安装 2 个):`claude` / `codex` / `gemini`
|
|
66
|
+
|
|
67
|
+
## 📖 Usage
|
|
68
|
+
|
|
69
|
+
```
|
|
51
70
|
ai-battle [options]
|
|
52
71
|
ai-battle help
|
|
53
72
|
```
|
|
54
73
|
|
|
55
|
-
| 参数 | 说明 |
|
|
56
|
-
|
|
57
|
-
| `--agents, -a <a1,a2>` | 选择参与的 Agent
|
|
58
|
-
| `--rounds, -r <N>` |
|
|
59
|
-
| `--god, -g` |
|
|
60
|
-
| `--referee [agent]` |
|
|
74
|
+
| 参数 | 说明 | 默认值 |
|
|
75
|
+
| :--- | :--- | :--- |
|
|
76
|
+
| `--agents, -a <a1,a2>` | 选择参与的 Agent,支持同类 | `claude,codex` |
|
|
77
|
+
| `--rounds, -r <N>` | 最大讨论轮次 | `10` |
|
|
78
|
+
| `--god, -g` | 开启上帝视角(每轮可注入补充信息) | — |
|
|
79
|
+
| `--referee [agent]` | 开启裁判模式(每轮总结 + 生成 SUMMARY.md) | — |
|
|
61
80
|
|
|
62
|
-
|
|
81
|
+
### 💡 Examples
|
|
63
82
|
|
|
64
83
|
```bash
|
|
65
84
|
# 同类 Agent 自我辩论
|
|
@@ -68,7 +87,7 @@ ai-battle --agents gemini,gemini
|
|
|
68
87
|
# 三方圆桌讨论
|
|
69
88
|
ai-battle --agents claude,codex,gemini --rounds 5
|
|
70
89
|
|
|
71
|
-
#
|
|
90
|
+
# 裁判模式
|
|
72
91
|
ai-battle --agents claude,codex,gemini --referee --rounds 5
|
|
73
92
|
|
|
74
93
|
# 指定 claude 做裁判
|
|
@@ -78,7 +97,7 @@ ai-battle --agents codex,gemini --referee claude --rounds 5
|
|
|
78
97
|
ai-battle --agents claude,codex --referee --god
|
|
79
98
|
```
|
|
80
99
|
|
|
81
|
-
## 🔄
|
|
100
|
+
## 🔄 How It Works
|
|
82
101
|
|
|
83
102
|
```mermaid
|
|
84
103
|
sequenceDiagram
|
|
@@ -95,7 +114,6 @@ sequenceDiagram
|
|
|
95
114
|
S->>S: 加载 .env / 检查 problem.md
|
|
96
115
|
S->>A: check_A() 可用性检查
|
|
97
116
|
S->>B: check_B() 可用性检查
|
|
98
|
-
S->>S: 生成指令文件 / 初始化配置
|
|
99
117
|
end
|
|
100
118
|
|
|
101
119
|
rect rgb(30, 50, 40)
|
|
@@ -107,7 +125,6 @@ sequenceDiagram
|
|
|
107
125
|
S->>B: call_B(problem)
|
|
108
126
|
B-->>S: 回复 B
|
|
109
127
|
end
|
|
110
|
-
S->>S: 保存至 rounds/ 和 .sessions/
|
|
111
128
|
end
|
|
112
129
|
|
|
113
130
|
rect rgb(40, 40, 60)
|
|
@@ -139,83 +156,68 @@ sequenceDiagram
|
|
|
139
156
|
S->>U: 🎉 达成共识!
|
|
140
157
|
else 未达成
|
|
141
158
|
S->>U: 是否追加轮次?
|
|
142
|
-
alt 追加
|
|
143
|
-
U-->>S: 追加 N 轮
|
|
144
|
-
Note over S: 继续 Round 循环
|
|
145
|
-
else 结束
|
|
146
|
-
opt 裁判模式
|
|
147
|
-
S->>R: generate_final_summary()
|
|
148
|
-
R-->>S: SUMMARY.md
|
|
149
|
-
end
|
|
150
|
-
S->>U: 讨论结束
|
|
151
|
-
end
|
|
152
159
|
end
|
|
153
160
|
```
|
|
154
161
|
|
|
155
|
-
## 🤖
|
|
162
|
+
## 🤖 Built-in Agents
|
|
156
163
|
|
|
157
|
-
| Agent |
|
|
158
|
-
|
|
159
|
-
|
|
|
160
|
-
|
|
|
161
|
-
|
|
|
164
|
+
| Agent | Backend | Check Command |
|
|
165
|
+
| :--- | :--- | :--- |
|
|
166
|
+
| `claude` | Claude CLI | `claude -p "hello"` |
|
|
167
|
+
| `codex` | Codex CLI | `codex exec "hello"` |
|
|
168
|
+
| `gemini` | Gemini CLI | `gemini -p "hello"` |
|
|
162
169
|
|
|
163
|
-
## 📁
|
|
170
|
+
## 📁 Output Structure
|
|
164
171
|
|
|
165
172
|
```text
|
|
166
|
-
|
|
167
|
-
├── problem.md
|
|
168
|
-
├──
|
|
173
|
+
my-topic/
|
|
174
|
+
├── problem.md # 讨论问题(用户创建)
|
|
175
|
+
├── referee.md # 裁判自定义提示词(可选)
|
|
176
|
+
├── rounds/ # 讨论轮次记录
|
|
169
177
|
│ ├── round_1_claude.md
|
|
170
178
|
│ ├── round_1_gemini.md
|
|
171
|
-
│ ├── referee_round_2.md
|
|
172
|
-
│
|
|
173
|
-
|
|
174
|
-
├── .
|
|
175
|
-
├──
|
|
176
|
-
├──
|
|
177
|
-
|
|
178
|
-
└── .debate.log # 运行日志(tail -f 实时查看)
|
|
179
|
+
│ ├── referee_round_2.md # 裁判总结(--referee)
|
|
180
|
+
│ └── god_round_1.md # 上帝注入(--god)
|
|
181
|
+
├── .sessions/ # Agent CLI 原始输出
|
|
182
|
+
├── consensus.md # 共识结论(如达成)
|
|
183
|
+
├── SUMMARY.md # 最终总结(裁判自动生成)
|
|
184
|
+
├── .debate.json # 状态配置
|
|
185
|
+
└── .debate.log # 运行日志(tail -f 实时查看)
|
|
179
186
|
```
|
|
180
187
|
|
|
181
|
-
##
|
|
182
|
-
|
|
183
|
-
| 文件 | 说明 |
|
|
184
|
-
|------|------|
|
|
185
|
-
| `.env` | 自动加载环境变量(启动时) |
|
|
186
|
-
| `referee.md` | 裁判自定义提示词(开启 `--referee` 时) |
|
|
188
|
+
## 🔌 Extend Agent
|
|
187
189
|
|
|
188
|
-
|
|
190
|
+
只需实现 3 个函数并注册:
|
|
189
191
|
|
|
190
192
|
```bash
|
|
191
|
-
# 1.
|
|
193
|
+
# 1. 实现函数
|
|
192
194
|
check_myagent() { ... } # 可用性检查,返回 0/1
|
|
193
|
-
call_myagent() { ... } # 调用 Agent
|
|
194
|
-
generate_myagent_md() { ... } #
|
|
195
|
+
call_myagent() { ... } # 调用 Agent: $1=system_prompt $2=user_msg $3=session_tag
|
|
196
|
+
generate_myagent_md() { ... } # 生成指令文件: $1=max_rounds $2=problem
|
|
195
197
|
|
|
196
198
|
# 2. 注册
|
|
197
199
|
register_agent "myagent"
|
|
198
200
|
```
|
|
199
201
|
|
|
200
|
-
## 🔑
|
|
202
|
+
## 🔑 Environment Variables
|
|
201
203
|
|
|
202
204
|
<details>
|
|
203
205
|
<summary><b>Claude</b></summary>
|
|
204
206
|
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
207
|
+
| Variable | Description |
|
|
208
|
+
| :--- | :--- |
|
|
209
|
+
| `ANTHROPIC_BASE_URL` | API 地址 |
|
|
210
|
+
| `ANTHROPIC_AUTH_TOKEN` | 认证 Token |
|
|
211
|
+
| `ANTHROPIC_DEFAULT_SONNET_MODEL` | 模型名称 |
|
|
212
|
+
| `API_TIMEOUT_MS` | 超时时间(毫秒) |
|
|
211
213
|
|
|
212
214
|
</details>
|
|
213
215
|
|
|
214
216
|
<details>
|
|
215
217
|
<summary><b>Codex</b></summary>
|
|
216
218
|
|
|
217
|
-
|
|
|
218
|
-
|
|
219
|
+
| Variable | Description | Default |
|
|
220
|
+
| :--- | :--- | :--- |
|
|
219
221
|
| `CODEX_MODEL` | Codex 模型 | `gpt-5.3-codex` |
|
|
220
222
|
|
|
221
223
|
</details>
|
|
@@ -223,18 +225,16 @@ export API_TIMEOUT_MS=600000
|
|
|
223
225
|
<details>
|
|
224
226
|
<summary><b>Gemini</b></summary>
|
|
225
227
|
|
|
226
|
-
|
|
|
227
|
-
|
|
228
|
+
| Variable | Description |
|
|
229
|
+
| :--- | :--- |
|
|
228
230
|
| `GEMINI_API_KEY` | API Key(如需自定义) |
|
|
229
231
|
|
|
230
232
|
</details>
|
|
231
233
|
|
|
232
|
-
##
|
|
234
|
+
## 🤝 Contributing
|
|
233
235
|
|
|
234
|
-
-
|
|
235
|
-
- `jq`
|
|
236
|
-
- Agent CLI 工具:`claude` / `codex` / `gemini`(至少安装 2 个)
|
|
236
|
+
欢迎提交 [Issue](https://github.com/Alfonsxh/ai-battle/issues) 和 [Pull Request](https://github.com/Alfonsxh/ai-battle/pulls)!
|
|
237
237
|
|
|
238
238
|
## 📄 License
|
|
239
239
|
|
|
240
|
-
[MIT](LICENSE)
|
|
240
|
+
[MIT](LICENSE) © [Alfons](https://github.com/Alfonsxh)
|
package/ai-battle.sh
CHANGED
|
@@ -254,8 +254,20 @@ $user_msg
|
|
|
254
254
|
|
|
255
255
|
local text=""
|
|
256
256
|
|
|
257
|
-
#
|
|
258
|
-
|
|
257
|
+
# 从输出中提取有效内容
|
|
258
|
+
# 1. 先截取 codex 标记行之后的内容(跳过 prompt 回显和 thinking 块)
|
|
259
|
+
# 2. 再过滤掉元数据行和 token 统计
|
|
260
|
+
if grep -qn '^codex$' "$tmpout" 2>/dev/null; then
|
|
261
|
+
# 找到最后一个 "codex" 标记行,取其后所有内容(即真正回复)
|
|
262
|
+
local codex_line
|
|
263
|
+
codex_line=$(grep -n '^codex$' "$tmpout" | tail -1 | cut -d':' -f1)
|
|
264
|
+
text=$(tail -n "+$((codex_line + 1))" "$tmpout" \
|
|
265
|
+
| grep -v '^\(tokens used\|Exit code:\|[0-9,]*$\)' \
|
|
266
|
+
| sed '/^$/d')
|
|
267
|
+
else
|
|
268
|
+
# 兜底: 无 codex 标记时沿用原始过滤
|
|
269
|
+
text=$(grep -v '^\(thinking\|exec\|mcp startup\|OpenAI Codex\|--------\|workdir:\|model:\|provider:\|approval:\|sandbox:\|reasoning\|session id:\|user$\|tokens used\|Exit code:\|^$\)' "$tmpout" 2>/dev/null | sed '/^$/d')
|
|
270
|
+
fi
|
|
259
271
|
|
|
260
272
|
rm -f "$tmpout"
|
|
261
273
|
|
|
@@ -489,15 +501,26 @@ log_and_print() {
|
|
|
489
501
|
echo -e "$1" | sed 's/\x1b\[[0-9;]*m//g' >> "$LOG_FILE"
|
|
490
502
|
}
|
|
491
503
|
|
|
492
|
-
# 检查 AGREED
|
|
504
|
+
# 检查 AGREED 关键字(要求行首匹配,避免误触发)
|
|
493
505
|
has_agreed() {
|
|
494
|
-
|
|
506
|
+
# 要求 AGREED: 出现在行首(允许 ** 加粗),避免匹配标题或 prompt 模板中的 AGREED
|
|
507
|
+
echo "$1" | grep -qE '^\*{0,2}AGREED:[[:space:]]'
|
|
495
508
|
}
|
|
496
509
|
|
|
497
510
|
# 提取 AGREED 后的结论
|
|
498
511
|
extract_agreed() {
|
|
499
|
-
|
|
500
|
-
|
|
512
|
+
# 提取行首 AGREED: 后面的结论文本
|
|
513
|
+
local raw
|
|
514
|
+
raw=$(echo "$1" | grep -oE '^\*{0,2}AGREED:[[:space:]]*.*' | head -1 \
|
|
515
|
+
| sed 's/^\*\{0,2\}AGREED:[[:space:]]*//' | sed 's/[[:space:]]*$//' | sed 's/\*\{1,2\}$//')
|
|
516
|
+
|
|
517
|
+
# 校验: 拒绝占位符结论(如 <共识结论>, <xxx> 等)
|
|
518
|
+
if echo "$raw" | grep -qE '^<[^>]+>$'; then
|
|
519
|
+
echo ""
|
|
520
|
+
return
|
|
521
|
+
fi
|
|
522
|
+
|
|
523
|
+
echo "$raw"
|
|
501
524
|
}
|
|
502
525
|
|
|
503
526
|
# Agent 颜色映射(自动提取基础类型)
|