parallel-subagent-batch-merge
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
Chinese並列サブエージェントのバッチ生成とマルチフォーマットマージ
并行子代理的批量生成与多格式合并
Extracted: 2026-02-11
Context: Claude Code で大量データを並列サブエージェントで生成し、出力を1つのファイルに統合する場面
提取日期: 2026-02-11
场景: 使用Claude Code通过并行子代理生成大量数据,并将输出整合到单个文件的场景
Problem
问题
Claude Code のサブエージェント(Task tool)を大量並列起動すると、以下の問題が発生する:
- 出力フォーマットの不統一 — 同じプロンプトでも、エージェントごとに出力構造が異なる
- 辞書型:
{ "id": { ...data } } - リスト+id:
[{ "id": "...", "data": {...} }] - リスト+別名:
[{ "questionId": "...", "data": {...} }]
- 辞書型:
- 構文エラーの混入 — 、trailing comma 等の JSON 構文エラー
:= - 型の揺れ — が
relatedConceptsのはずがstringで返る等array - コンテンツ重複 — 同じ説明文が複数選択肢にコピーされる
大量并行启动Claude Code子代理(Task工具)时,会出现以下问题:
- 输出格式不一致 — 即使使用相同提示词,不同代理的输出结构也不同
- 字典型:
{ "id": { ...data } } - 列表+id:
[{ "id": "...", "data": {...} }] - 列表+别名:
[{ "questionId": "...", "data": {...} }]
- 字典型:
- 混入语法错误 — 出现、 trailing comma等JSON语法错误
:= - 类型不一致 — 例如应返回
relatedConcepts却返回stringarray - 内容重复 — 相同说明文本被复制到多个选项中
Solution
解决方案
1. バッチ分割: ヘルパースクリプトで入力を標準化
1. 批量分割: 使用辅助脚本标准化输入
python
undefinedpython
undefinedprepare_batches.py: 入力データを N 件ずつのテキストファイルに分割
prepare_batches.py: 将输入数据分割为每份N条的文本文件
→ 各サブエージェントが1ファイルだけ読めばよい
→ 每个子代理只需读取一个文件即可
batches = [items[i:i+BATCH_SIZE] for i in range(0, len(items), BATCH_SIZE)]
- バッチサイズ 20 が実績あり(コンテキスト窓との兼ね合い)
- 最終バッチは端数になるので注意batches = [items[i:i+BATCH_SIZE] for i in range(0, len(items), BATCH_SIZE)]
- 经验证,批量大小设为20效果最佳(平衡上下文窗口限制)
- 注意最后一批可能存在数据量不足的情况2. 並列起動: 全バッチを run_in_background=true
で同時起動
run_in_background=true2. 并行启动: 所有批次通过run_in_background=true
同时启动
run_in_background=trueundefinedundefined21バッチ × Sonnet subagent を同時起動
同时启动21个批次 × Sonnet子代理
for batch in 1..21:
Task(subagent_type="general-purpose", model="sonnet",
run_in_background=true, prompt=f"Read batch_{batch}.txt ...")
- 出力先を `batch_XX_output.json` で分離(書き込み競合の回避)
- 全エージェント完了後にマージfor batch in 1..21:
Task(subagent_type="general-purpose", model="sonnet",
run_in_background=true, prompt=f"Read batch_{batch}.txt ...")
- 输出文件命名为`batch_XX_output.json`以避免写入冲突
- 所有代理执行完成后再进行合并3. 正規化マージ: 3種フォーマットを統一
3. 规范化合并: 统一3种格式
python
def normalize_batch(batch_data):
"""辞書型・リスト型どちらでも { id: data } に正規化"""
if isinstance(batch_data, dict):
return batch_data
elif isinstance(batch_data, list):
result = {}
for item in batch_data:
qid = item.get("id") or item.get("questionId")
data = item.get("enhancedExplanation", item)
result[qid] = data
return resultpython
def normalize_batch(batch_data):
"""将字典型或列表型数据统一格式为 { id: data }"""
if isinstance(batch_data, dict):
return batch_data
elif isinstance(batch_data, list):
result = {}
for item in batch_data:
qid = item.get("id") or item.get("questionId")
data = item.get("enhancedExplanation", item)
result[qid] = data
return result4. 型修正: 期待する型に強制変換
4. 类型修正: 强制转换为预期类型
python
undefinedpython
undefinedrelatedConcepts: String? なのに array で返ってきた場合
当relatedConcepts应返回String却返回array时
if isinstance(val, list):
val = "".join(val) if val else None
undefinedif isinstance(val, list):
val = "".join(val) if val else None
undefined5. 構文エラー修正: JSON parse 前に既知パターンを置換
5. 语法错误修正: JSON解析前替换已知错误模式
python
raw = raw.replace(':="', ': "') # := → : のタイポ修正python
raw = raw.replace(':="', ': "') # 修正:= → :的拼写错误6. 品質検証: 重複検出 + 自動修正
6. 质量验证: 重复检测 + 自动修正
python
undefinedpython
undefinedcontrastTable の point 重複チェック
检查contrastTable的point是否重复
points = [e["point"] for e in contrast_table]
if len(set(points)) < len(points):
# → 手動で固有テキストに差し替え
undefinedpoints = [e["point"] for e in contrast_table]
if len(set(points)) < len(points):
# → 手动替换为唯一文本
undefinedKey Metrics (実績)
关键指标(实际成果)
| 項目 | 数値 |
|---|---|
| 対象データ | 408問 |
| バッチ数 | 21(20問×20 + 8問×1) |
| 並列エージェント | 21(全同時起動) |
| フォーマット種類 | 3種(辞書14 / リスト+id 2 / リスト+questionId 5) |
| 構文エラー | 1件(batch_21: |
| 型の揺れ | 8件(batch_21: relatedConcepts が配列) |
| コンテンツ重複 | 7問(contrastTable point 重複) |
| 最終結果 | 全408問マージ成功、検証 ALL GREEN |
| 项目 | 数值 |
|---|---|
| 目标数据 | 408题 |
| 批次数 | 21(20题×20 + 8题×1) |
| 并行代理数 | 21(全部同时启动) |
| 格式类型 | 3种(字典14 / 列表+id 2 / 列表+questionId 5) |
| 语法错误 | 1处(batch_21: |
| 类型不一致 | 8处(batch_21: relatedConcepts 返回数组) |
| 内容重复 | 7题(contrastTable point重复) |
| 最终结果 | 全部408题合并成功,验证全部通过 |
When to Use
适用场景
- Claude Code で 50件以上 のデータを構造化生成するとき
- 各項目が 独立 しており並列処理可能なとき
- 出力が JSON で、スキーマが明確なとき
- の判断で「Claude Code 直接生成」を選択した後の実行パターン
claude-code-self-generation-over-api.md
- 需要用Claude Code结构化生成50条以上数据时
- 每个项目独立可并行处理时
- 输出为JSON且schema明确时
- 在中选择「Claude Code 直接生成」后的执行模式
claude-code-self-generation-over-api.md
Gotcha: キー名不統一の検出と正規化
注意事项: 键名不一致的检测与规范化
LLMバッチ生成では、同じフィールドに対してバッチごとに異なるキー名が出力される(例: / / )。
choicechoiceLabeloption在LLM批量生成时,同一字段可能在不同批次输出不同的键名(例如: / / )。
choicechoiceLabeloption検出
检测
python
key_sets = set()
for item in data['items']:
for entry in item.get('nested', []):
key_sets.add(tuple(sorted(entry.keys())))
print(f'Unique key patterns: {len(key_sets)}')
for ks in sorted(key_sets):
print(f' {ks}')python
key_sets = set()
for item in data['items']:
for entry in item.get('nested', []):
key_sets.add(tuple(sorted(entry.keys())))
print(f'Unique key patterns: {len(key_sets)}')
for ks in sorted(key_sets):
print(f' {ks}')正規化
规范化
python
for entry in item.get('nested', []):
normalized = {}
normalized['choice'] = entry.get('choice') or entry.get('choiceLabel') or entry.get('option', '')
normalized['point'] = entry.get('point') or entry.get('reason', '')
# ...python
for entry in item.get('nested', []):
normalized = {}
normalized['choice'] = entry.get('choice') or entry.get('choiceLabel') or entry.get('option', '')
normalized['point'] = entry.get('point') or entry.get('reason', '')
# ...検証
验证
python
bad = [(item['id'], set(e.keys()))
for item in data['items']
for e in item.get('nested', [])
if set(e.keys()) != EXPECTED_KEYS]
assert not bad, f'Still inconsistent: {bad}'python
bad = [(item['id'], set(e.keys()))
for item in data['items']
for e in item.get('nested', [])
if set(e.keys()) != EXPECTED_KEYS]
assert not bad, f'Still inconsistent: {bad}'Anti-patterns
反模式
- バッチサイズが大きすぎる(50+)→ エージェントのコンテキスト消費で品質低下
- マージスクリプトが特定フォーマットだけ想定 → 必ず全フォーマットに対応する
- 検証なしでマージ完了とする → スクリプトを必ず実行
validate - 重複エラーを無視する → UIで同じテキストが並ぶと著しく品質低下
- キー名不統一を見逃す → Swift Codable等の厳格なデコーダで即座にクラッシュ
- 批处理尺寸过大(50+)→ 代理上下文消耗导致质量下降
- 合并脚本仅针对特定格式设计 → 必须兼容所有格式
- 未验证就判定合并完成 → 必须执行脚本
validate - 忽略重复错误 → UI中出现重复文本会严重降低质量
- 忽略键名不一致 → 在Swift Codable等严格解码器中会直接崩溃",