【拯救 5.6 Sol(1)】Codex子代理实践 —— Claude code版本

huo0 2026-08-06 11:49 1

基于作者原帖:【拯救 5.6 Sol(1)】开箱即用、快速高效、减少上下文腐烂的Codex子代理实践


丢给ai 写了一套 Claude Code适用版本的sh


目前我也是刚上手体验


#!/usr/bin/env bash
set -euo pipefail

TARGET_HOME="${TARGET_HOME:-$HOME}"
CLAUDE_DIR="$TARGET_HOME/.claude"
TIMESTAMP="$(date +%Y%m%d-%H%M%S)"
BACKUP_DIR="$CLAUDE_DIR/backups/subagent-policy-$TIMESTAMP"
STAGE_DIR="$(mktemp -d "${TMPDIR:-/tmp}/claude-subagent-policy.XXXXXX")"

cleanup() {
rm -rf "$STAGE_DIR"
}
trap cleanup EXIT

mkdir -p "$CLAUDE_DIR/agents" "$BACKUP_DIR"

backup_file() {
local rel="$1"
local src="$CLAUDE_DIR/$rel"
if [[ -f "$src" ]]; then
mkdir -p "$BACKUP_DIR/$(dirname "$rel")"
cp -a "$src" "$BACKUP_DIR/$rel"
printf 'present\t%s\n' "$rel" >> "$BACKUP_DIR/manifest.tsv"
else
printf 'absent\t%s\n' "$rel" >> "$BACKUP_DIR/manifest.tsv"
fi
}

backup_file "settings.json"
backup_file "CLAUDE.md"
backup_file "agents/default.md"
backup_file "subagent-policy.sh"

python3 - "$CLAUDE_DIR/settings.json" "$CLAUDE_DIR/CLAUDE.md" "$STAGE_DIR/settings.json" <<'PY'
from pathlib import Path
import json
import sys

settings_path = Path(sys.argv[1])
claude_md_path = Path(sys.argv[2])
dst = Path(sys.argv[3])

merged = {}

if settings_path.exists():
loaded = json.loads(settings_path.read_text(encoding="utf-8"))
if not isinstance(loaded, dict):
raise SystemExit("settings.json 顶层必须是 JSON 对象")
merged.update(loaded)

# 兼容修正:如果现有 CLAUDE.md 实际是误放的 JSON 配置,则迁移合并到 settings.json。
if claude_md_path.exists():
raw = claude_md_path.read_text(encoding="utf-8").strip()
if raw.startswith("{"):
try:
misplaced = json.loads(raw)
except json.JSONDecodeError:
misplaced = None
if isinstance(misplaced, dict):
def deep_merge(a, b):
for k, v in b.items():
if isinstance(v, dict) and isinstance(a.get(k), dict):
deep_merge(a[k], v)
elif k not in a:
a[k] = v
return a
deep_merge(merged, misplaced)

merged.setdefault("$schema", "https://json.schemastore.org/claude-code-settings.json")

env = merged.setdefault("env", {})
if not isinstance(env, dict):
raise SystemExit("settings.json 的 env 必须是对象")

# Claude Code 的并发值只计算子代理,因此主代理 + 6 个子代理对应 6。
env["CLAUDE_CODE_MAX_CONCURRENT_SUBAGENTS"] = "6"

# 设为 1 表示子代理不能继续派生子代理。
env["CLAUDE_CODE_MAX_SUBAGENT_SPAWN_DEPTH"] = "1"

# 禁用内置 Explore/Plan 代理入口,策略上统一引导使用自定义 default。
env["CLAUDE_CODE_DISABLE_EXPLORE_PLAN_AGENTS"] = "1"

permissions = merged.setdefault("permissions", {})
if not isinstance(permissions, dict):
raise SystemExit("settings.json 的 permissions 必须是对象")

deny = permissions.setdefault("deny", [])
if not isinstance(deny, list):
raise SystemExit("settings.json 的 permissions.deny 必须是数组")

# default 不是 Claude Code 的特殊保留名;这里通过提示词 + 禁用其他代理名来约束派发选择。
for item in [
"Agent(Explore)",
"Agent(Plan)",
"Agent(general-purpose)",
"Agent(claude)",
]:
if item not in deny:
deny.append(item)

dst.write_text(json.dumps(merged, ensure_ascii=False, indent=2) + "\n", encoding="utf-8")
PY

cat > "$STAGE_DIR/CLAUDE.md" <<'EOF'
## 子代理使用

子代理在我们的工作里只用于探索,是主代理的探子。把 `default` 子代理当成用于「宽而重」读取的工具:只有在它能减少主线程上下文污染、提高并行度或者提供独立核验时才使用,但需要比默认行为更积极、更频繁地考虑派发,而不只在任务开头使用。

### 何时直接处理

以下内容由主代理直接读取和处理,不派子代理:

* 已知位置的小文件、少量代码或者单一事实;
* 即将修改的确切代码;
* 派发、等待和复核成本不低于直接读取的任务;
* 奠基性文档,无论多长都由主代理完整阅读,包括架构文档、设计文档、交接备忘录以及其他用于建立全局视角的材料。它们的价值在细节和脉络,不能由子代理转述代替。

### 何时适合派发

适合交给子代理的任务:

* 巨型文件(奠基性文档除外)、跨文件或者跨目录检索;
* 相互独立、可以并行的探索或者核验;
* 长任务中需要重新确认某个模块现状的工作;
* 会产生大量日志、搜索结果或者外围材料的阅读。

多个独立任务应在同一轮并发派发。

### 委派与验证

给子代理的任务必须自包含,明确检索范围、具体问题和期望输出。精度重要时,要求返回 `file:line`、符号名和必要的关键原文。

子代理结果只是线索,可能遗漏或者出错。复核时顺着它提供的 `file:line` 和关键原文抽查必要的小范围内容,不重新通读它已经处理的全部材料。只有两类内容需要主代理完整阅读:即将修改的确切代码,以及奠基性文档。子代理对这两类内容最多负责定位。

子代理默认只做探索、检索和核验。代码修改、方案取舍和最终验证由主代理负责。

### Claude Code 派发规则

* 是否派发以及派发数量由主代理自主决定;较重探索应拆成多个独立轻任务并发处理。
* 最多并行派发 6 个子代理。
* 只使用名为 `default` 的自定义子代理,不使用 `Explore`、`Plan`、`general-purpose`、`claude` 或其他角色。
* 使用命名子代理,不使用 `/subtask` 或其他 conversation fork(对话分叉)。命名子代理天然使用新的独立上下文,不继承主对话历史;因此每个任务都必须自包含。
* 派发多个子代理后,主代理停止其他读取、检索、命令执行和文件修改,等待全部结果返回后再继续。
* 每个子代理只使用一次,不恢复、不追派。需要进一步拆分时,由主代理重新创建新的自包含任务。
* 子代理运行超过 10 分钟仍未完成时视为异常。主代理应检查代理面板或已有结果,采用可用的部分输出并停止该子代理,再决定是否拆分成更小任务重新派发。
EOF

cat > "$STAGE_DIR/agents-default.md" <<'EOF'
---
name: default
description: 通用只读探索子代理。用于巨型文件、跨文件或跨目录检索、并行探索、独立核验以及高输出量材料整理。主代理应主动使用;不要用于即将修改的确切代码或奠基性文档。
tools: Read, Grep, Glob
disallowedTools: Write, Edit, Bash, PowerShell, Agent, Skill, mcp__*
model: haiku
effort: low
permissionMode: plan
maxTurns: 30
---

你是通用只读探索子代理,是主代理派出的探子。你只做探索、检索和核验:不改动任何东西,不做方案取舍或者最终判断,这些由主代理负责。

不要派生、调用或者请求新的子代理。任务需要继续拆分时,把拆分建议返回给主代理。

交付要求:

- 产出直接提供给主代理作为行动依据。内容密集,不寒暄,不复述过程,不写客套结论。
- 给证据,不做包装。关键处附上 `file:line`、符号名和必要的逐字原文,出处必须准确并足以复核。
- 明确区分「看到的事实」和「你的推断」,存疑内容必须标注,不把猜测写成事实。
- 压缩体量,但保留确切名称、签名、取值和路径,不在转述中改变精确信息。

工作方式:

- 每次调用只有一轮,任务必须自包含。不要反问,用这一轮尽量覆盖完整范围。
- 无法答全时,明确说明查到了什么、没有覆盖什么、哪里存疑或者存在矛盾。宁可写明「没查到」或「没覆盖」,不要含糊省略。
EOF

python3 - "$STAGE_DIR/settings.json" "$STAGE_DIR/CLAUDE.md" "$STAGE_DIR/agents-default.md" <<'PY'
from pathlib import Path
import json
import re
import sys

settings_path, claude_md_path, agent_path = map(Path, sys.argv[1:])
settings = json.loads(settings_path.read_text(encoding="utf-8"))
env = settings["env"]
assert env["CLAUDE_CODE_MAX_CONCURRENT_SUBAGENTS"] == "6"
assert env["CLAUDE_CODE_MAX_SUBAGENT_SPAWN_DEPTH"] == "1"
assert env["CLAUDE_CODE_DISABLE_EXPLORE_PLAN_AGENTS"] == "1"
for item in ["Agent(Explore)", "Agent(Plan)", "Agent(general-purpose)", "Agent(claude)"]:
assert item in settings["permissions"]["deny"]

claude_md = claude_md_path.read_text(encoding="utf-8")
assert claude_md.count("## 子代理使用") == 1
assert "只使用名为 `default`" in claude_md

agent = agent_path.read_text(encoding="utf-8")
assert agent.startswith("---\n")
assert re.search(r"(?m)^name: default$", agent)
assert re.search(r"(?m)^tools: Read, Grep, Glob$", agent)
assert re.search(r"(?m)^disallowedTools: .*Agent", agent)
assert re.search(r"(?m)^model: haiku$", agent)
assert re.search(r"(?m)^effort: low$", agent)
assert re.search(r"(?m)^permissionMode: plan$", agent)
PY

install -m 600 "$STAGE_DIR/settings.json" "$CLAUDE_DIR/settings.json"
install -m 644 "$STAGE_DIR/CLAUDE.md" "$CLAUDE_DIR/CLAUDE.md"
install -m 644 "$STAGE_DIR/agents-default.md" "$CLAUDE_DIR/agents/default.md"

python3 -m json.tool "$CLAUDE_DIR/settings.json" >/dev/null

printf 'Claude Code 用户级子代理策略已写入。\n'
printf '备份目录:%s\n' "$BACKUP_DIR"
printf '已更新:%s\n' "$CLAUDE_DIR/settings.json"
printf '已更新:%s\n' "$CLAUDE_DIR/CLAUDE.md"
printf '已更新:%s\n' "$CLAUDE_DIR/agents/default.md"
printf '已保存脚本:%s\n' "$CLAUDE_DIR/subagent-policy.sh"
printf '新建或修改 agents 目录后,已运行的 Claude Code 会话需要重启一次。\n'
最新回复 (2)
  • cuican 08-19 09:56
    1

    好用吗,佬,我也想试试,有没有后续优化

  • huo0 楼主 08-19 11:23
    2

    有没有后续优化



    我这个一直在用,配合他那个tool mcp更爽,一定要配上

* 帖子来源Linux.do
返回