åŒã°ããŠããªããšãŒãžã§ã³ããçãåºã â Stop hookã§äœ¿çšçãã°ãåã£ãŠãŸã³ããåã
ååãã¿ãŒããã«ãã¿ã€ã«ç¶ã«èªåé
眮ããè©±ãæžããŸãããä»åã¯ç°å¢ã®äžèº«ã®è©±ã«æ»ããŸã ââ ~/.claude/agents/ ã«ãµããšãŒãžã§ã³ããäœæ¬ãå®çŸ©ããŠããŸããããå®éã«åŒã°ããŠããã®ã¯ãã®ãã¡äœæ¬ããèª°ãæ°ããŠããŸããã§ããããã®èšäºã¯ãStop hookã§åŒã³åºãããã°ã«èœãšãã7d/30dçªã§éèšããŠãå®çŸ©ããã®ã«äžåºŠãåŒã°ããŠããªããšãŒãžã§ã³ãããæ©æ¢°ã§çãåºãä»çµã¿ã®è©±ã§ãã
å°ãããšïŒãšãŒãžã§ã³ãã¯å®çŸ©ããç¬éããèŠããªããªã
~/.claude/agents/*.md ã«ãµããšãŒãžã§ã³ãã远å ããã®ã¯ç°¡åã§ããfrontmatterãæžããŠmarkdownã眮ãã ããåé¡ã¯ãã®åŸã§ãåŒã°ããŠãããã©ããã確èªããææ®µããªãããšã§ãããClaude Codeã®ã»ãã·ã§ã³å
ã§TaskããŒã«ïŒãµããšãŒãžã§ã³ãèµ·åïŒãåŒã°ããŠãããã®èšé²ã¯ã»ãã·ã§ã³ã®transcriptã«åããããŸãŸæ¶ããŠãããŸãã
çµæãarchitect ã planner ã®ãããªããããšäŸ¿å©ããã ããäœã£ããç³»ã®ãšãŒãžã§ã³ãããå®éã«ã¯äžåºŠãèµ·åãããã«agents/ãã£ã¬ã¯ããªã«å±
座ãç¶ããŸããæ°ãå¢ããã»ã©ãã©ããçããŠããŠã©ããæ»ãã§ãããå€å¥ã§ããªããªã ââ ããã¯åã
åæžããèªå·±å¢æ®ããã¹ãã«ãšåãåé¡ã®ããšãŒãžã§ã³ãçã§ãã
èšé²å±€ïŒStop hookã§transcriptããAgentåŒã³åºããæŸã
ã»ãã·ã§ã³çµäºæã«èµ°ãstop_agent_tracker.shãããã®ã»ãã·ã§ã³ã®transcript.jsonlãèªãã§åŒã³åºãã1è¡ãã€JSONLã«èœãšããŸãã
for b in content:
btype = b.get("type")
if btype == "tool_use" and b.get("name") == "Agent":
inp = b.get("input") or {}
if "subagent_type" not in inp:
continue
uid = b.get("id")
uses[uid] = (ts, b.get("name"), inp, b.get("caller"))
elif btype == "tool_result":
rid = b.get("tool_use_id")
results[rid] = (ts, bool(b.get("is_error")))
ããã§éèªæãªã®ããã³ã¡ã³ãã«ãæžããŠããéããClaude Code ã®transcriptã§ã¯ãTaskãããŒã«ã¯ name="Agent" ãšããŠèšé²ãããããšããç¹ã§ããããŒã«åã®è¡šèšãããç¥ããã«ãã£ã«ã¿ãæžããšãäœãæŸããã«ç©ºæ¯ãããŸãã
tool_useãštool_resultãidã§çªãåãããŠæèŠæéãåºããã»ãã·ã§ã³å
ã§æ¢ã«èšé²æžã¿ã®tool_use_idã¯éè€æžã蟌ã¿ããªãèšèšã§ãïŒåäžã»ãã·ã§ã³ã§Stop hookãè€æ°åèµ°ã£ãŠãäºéèšé²ããªãïŒã
rec = {
"ts": use_ts, "session_id": sid, "cwd": cwd,
"tool_use_id": uid, "subagent_type": subagent_type,
"description": description, "duration_ms": duration_ms,
"status": status, "caller": caller,
}
out.write(json.dumps(rec, ensure_ascii=False) + "\n")
åºåå
ã¯~/.claude/logs/agent-invocations.jsonlãä»å®æž¬ãããš665è¡ãæå€ã®ã¬ã³ãŒãã¯2026-05-28ãŸã§é¡ããŸãã
éèšå±€ïŒ7d/30dçªã§Top10ãš0åäžèЧãåºã
agent-usage-summary.shããã®ãã°ãèªã¿ãæå®ããçªïŒããã©ã«ã7dïŒã§Top10ãšãå®çŸ©ãããŠããã®ã«0åãã®ãšãŒãžã§ã³ãäžèЧãåºããŸãã0åå€å®ã®æ¯éå£ã¯~/.claude/agents/*.mdã®ãã¡ã€ã«åã§ãã
known_agents = set()
for fp in glob.glob(os.path.join(agents_dir, "*.md")):
known_agents.add(os.path.splitext(os.path.basename(fp))[0])
for w in windows:
cutoff = now - td
recent = [r for r in records if r["_dt"] >= cutoff]
counts = Counter(r.get("subagent_type", "") for r in recent if r.get("subagent_type"))
used = set(counts.keys())
unused = sorted(known_agents - used)
å®éã«launchdã®æ¥æ¬¡ãžã§ããåããææ°ã¬ããŒãïŒ2026-08-08 10:15å®è¡åïŒãããã§ãã
=== Agent usage (last 7d) ===
total invocations: 16 unique types: 3
Explore 12 0
general-purpose 3 0
code-reviewer 1 0
0-call agents (defined locally but not used in 7d): 7
- INDEX / architect / database-reviewer / planner
- python-reviewer / security-reviewer / typescript-reviewer
=== Agent usage (last 30d) ===
total invocations: 200 unique types: 7
general-purpose 117
Explore 74
reviewer 3
Content Creator 2
fork 2
security-reviewer 1
code-reviewer 1
0-call agents (defined locally but not used in 30d): 6
- INDEX / architect / database-reviewer / planner
- python-reviewer / typescript-reviewer
30æ¥çªã§èŠããšã
~/.claude/agents/ã«å®çŸ©ãããå®è³ª7æ¬ã®ãšãŒãžã§ã³ãïŒINDEXã¯ãã¡ã€ã«ã§ãã£ãŠãšãŒãžã§ã³ãã§ã¯ãªããåŸè¿°ïŒã®ãã¡5æ¬ã0åã§ãããgeneral-purposeãšExploreã ãã§å šåŒã³åºãã®95%ãå ããarchitectã»database-reviewerã»plannerã»python-reviewerã»typescript-reviewerã¯å®çŸ©ãããŠããã ãã§äžåºŠãéžã°ããŠããŸããã
玢åŒã®èªååçæïŒagents-index.sh
éèšãšå¯Ÿã«ãªã£ãŠããã®ãagents-index.shã§ãããã¡ãã¯åŒã³åºãå®çžŸã§ã¯ãªãã~/.claude/agents/*.mdã®frontmatterãéçŽããŠINDEX.mdãæ©æ¢°çæããŸãã
def load_frontmatter(path: pathlib.Path):
text = path.read_text(encoding="utf-8", errors="replace")
m = re.match(r"^---\n(.*?)\n---\n", text, flags=re.DOTALL)
if not m:
return None, "missing frontmatter"
...
for p in sorted(pathlib.Path(agents_dir).glob("*.md")):
if p.name == "INDEX.md":
continue
fm, err = load_frontmatter(p)
if not fm.get("name"):
warnings.append(f"{p.name}: missing 'name'")
nameãdescriptionãæ¬ ããŠãããšãŒãžã§ã³ãå®çŸ©ã¯## â ïž Validation warningsãšããŠINDEX.mdã®æ«å°Ÿã«åºãŸããPyYAMLäŸåãé¿ããŠ1éå±€ã®key: valueã ããæŸãç°¡æããŒãµã«ããŠããã®ã§ãè€éãªfrontmatterã¯æžããŸãããããã®åäŸåãèŠããå£ãã«ããã§ãã
èŠã€ããçãåºãïŒéèšã¹ã¯ãªããèªèº«ããŸã³ãã1æ¬äœã£ãŠãã
2ã€ã®ã¹ã¯ãªãããèªã¿æ¯ã¹ãŠããŠæ°ã¥ããã®ããagents-index.shã¯if p.name == "INDEX.md": continueãšæç€ºçã«èªåã®çæç©ãé€å€ããŠããã®ã«ãagent-usage-summary.shã®known_agentsåéã«ã¯ãã®é€å€ããªãããšã§ãã
# agent-usage-summary.sh åŽïŒé€å€ãªãïŒ
for fp in glob.glob(os.path.join(agents_dir, "*.md")):
known_agents.add(os.path.splitext(os.path.basename(fp))[0])
çµæãagents-index.shãçæããINDEX.mdèªäœããå®çŸ©ãããŠããã®ã«0ååŒã°ããŠããªããšãŒãžã§ã³ãããšããŠæ¯åã¬ããŒãã«æ··å
¥ããŸããå®å®³ã¯ã¬ããŒãã®æ«å°Ÿã«ç¡æå³ãª1è¡ãå¢ããã ãã§ããã2ã€ã®éèšããžãã¯ãåã*.mdã°ããã«äŸåããªãããçæ¹ã ãèªåã®çæç©ãé€å€ãå¿ãããšããããã®æã®ãã¢éçšã«ãããã¡ãªäžæŽåã®å®äŸã§ãã
launchdã§ã®æ¥æ¬¡é ä¿¡
é
ä¿¡ã¯com.shun.agent-usage-dailyãæ
åœããŸãã
<key>ProgramArguments</key>
<array>
<string>/bin/zsh</string>
<string>-c</string>
<string>~/.claude/scripts/agent-usage-summary.sh 7d 30d > ~/.claude/logs/agent-usage-latest.md 2>&1</string>
</array>
<key>StartCalendarInterval</key>
<dict>
<key>Hour</key><integer>10</integer>
<key>Minute</key><integer>15</integer>
</dict>
æ¯æ10:15ã«7dãš30dãäž¡æ¹åããŠagent-usage-latest.mdã«äžæžããLowPriorityIOãšNice 10ãä»ããŠãä»ã®äœæ¥ãéªéããªãããã¯ã°ã©ãŠã³ãæ±ãã«ããŠããŸããéèšèªäœã¯ãã°ãPythonã§ã¡ã¢ãªã«èŒããŠåãã ãã®è»œãåŠçãªã®ã§ãåªå
床ãäžããŠãåŸ
ããããããšã¯ãããŸããã
éçšããŠåãã£ãããš
- äžäœ2æ¬ïŒ
general-purposeã»ExploreïŒã§30æ¥éã®åŒã³åºãã®95.5%ïŒ191/200ïŒãå ããã ãã³ã°ããŒã«ã¯reviewer3åã»Content Creator2åã»fork2åã»security-reviewer1åã»code-reviewer1åãšã1æ¡ã®å®çžŸãããããŸããã - å°éç¹åãšãŒãžã§ã³ãã»ã©åŒã°ããªãã
python-reviewerãtypescript-reviewerã®ãããªèšèªç¹ååãarchitectã»plannerã®ãããªèšèšç¹ååãè»äžŠã¿0åã§ãããçšéãçµã£ããšãŒãžã§ã³ããäœããšãã®èŠç©ãããçãã£ãããšãããããèšèªç³»ã¿ã¹ã¯ãæ¯ãå°ç·èªäœãä»ã®äœæ¥å 容ã«ååšããªããã宿 ã«è¿ãããã°ãèŠããŸã§ã¯æ°ã¥ããŸããã§ããã - ãå®çŸ©ããã ãã§æºè¶³ããããæ°åã§åŠå®ã§ããã 䞻芳ã§ã¯ã䜿ã£ãŠãã€ãããã§ãã宿ž¬ã¯5/7ã0åãCLAUDE.mdã®
implementation-model-routingã«ãŒã«ã§Codexåªå ãæèšããåŸãSonnetãµããšãŒãžã§ã³ããžã®å§è²èªäœãæžã£ãŠããã®ãäžå ãšèããããŸãã
èžãã èœãšã穎
- TaskããŒã«ã¯transcriptäžã§
name="Agent"ã çŽ çŽã«name == "Task"ã§ãã£ã«ã¿ãããšäœãæŸããªã - éè€èšé²é²æ¢ã¯ã»ãã·ã§ã³åäœã®
tool_use_idæ¯èŒã ã°ããŒãã«ã«dedupeãããšåãã»ãã·ã§ã³ã®åå®è¡ã匟ãæãã known_agentsã®ã°ãããèªåã®çæç©ïŒINDEX.mdïŒãé€å€ãå¿ããã éèšããžãã¯ã2ç®æã«åãããŠãããšãçæ¹ã ãé€å€æ¡ä»¶ãæŒãã- 0åãªã¹ãã¯ãäžèŠãã®èšŒæã«ã¯ãªããªãã
security-reviewerã¯7dçªã§ã¯0åã ã30dçªã§ã¯1åãçªã®åãæ¹æ¬¡ç¬¬ã§çµè«ãå€ããã®ã§ãåé€å€æã¯å¿ ãé·ãçªïŒ30dïŒãèŠã
ãŸãšã
- Stop hookã§transcriptãã
AgentåŒã³åºããæŸããJSONLã«1è¡ãã€èšé²ãã agent-usage-summary.shã7d/30dçªã§Top10ãšãå®çŸ©ãããŠããã®ã«0åããæ©æ¢°çã«åºãagents-index.shã®frontmatteréçŽãšãã¢ã§éçšãããšãå®çŸ©ãšå®çžŸã®äž¡æ¹ãå¯èŠåããã- launchdã§æ¯æ10:15ã«èªåé
ä¿¡ã人éã¯
agent-usage-latest.mdãèŠãã ãã§ãã - 宿ž¬ã§ã¯å®çŸ©ãã7æ¬äž5æ¬ã30æ¥é0åãåé€å€æã¯ãã®æ°åãæ ¹æ ã«ã§ãã
次åã¯ããã®0åãªã¹ããããšã«å®éã«ãšãŒãžã§ã³ããåã£ãåŸãCodexåªå ã«ãŒã«å°å ¥ååŸã§ãµããšãŒãžã§ã³ãå§è²ãã®ãã®ãã©ãã ãæžã£ãããæ°åã§èŠãåã«ããŸãã
LilyïŒ@bokuwalilyïŒâ å人éçºè ãClaude Code ã§èªåååºç€ãçµã¿ãªãããiOSã¢ããªãWebãµãŒãã¹ãéç£ããŠããŸã
- AIã§ãå¯ãŠãŠãåãä»çµã¿ããäœã£ãŠæ120äžã«ãã話㯠noteã®ææèšäº ã«ð°
- OSS: github.com/bokuwalily ð
- ææ°æ å ±ã»ãåãåãã㯠X @bokuwalily ãžð
çããã® â€ïž ãã·ã§ã¢ãå±ã¿ã«ãªããŸãïŒ