一键导入
self-replicating-agent-tdd
TDD-PDCA plan for building a self-replicating branching agent in {{AGENT_NAME}}. 단일 에이전트가 스스로 서브에이전트를 분기하고, 결과를 수렴시키는 구조.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
TDD-PDCA plan for building a self-replicating branching agent in {{AGENT_NAME}}. 단일 에이전트가 스스로 서브에이전트를 분기하고, 결과를 수렴시키는 구조.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
{{AGENT_NAME}} brain signal architecture — event bus, signal processor, awareness reporter, brain monitor
Integrate {{AGENT_NAME}} with ACP (Agent Client Protocol) agents. Reverse-engineered from goose's Rust ACP provider implementation.
Maintain .{{AGENT_NAME_LOWER}} as an Obsidian vault — graph connectivity overhaul (P-layer mesh, skill clusters, SEO article web), broken link detection, backlink density verification via Obsidian CLI, filename deduplication, bidirectional linking, auto-generated orphan management, cron output graph bloat prevention, and Obsidian compatibility.
AI Trend Collection & Filtering — collect GitHub trending repos, score via 5-axis philosophy filter, evaluate, apply, and retire.
RSS 피드 모니터링 → SEO 기사 수집·분석·트렌드 리포트
Authoring and using agent profiles — pre-defined subagent roles that set model, provider, toolsets, and instructions in one task() call. Covers profile format, the 14 standard roles, pipeline patterns, cost-tiered model assignment, and the ESCALATE mechanism for capability routing.
| name | self-replicating-agent-tdd |
| description | TDD-PDCA plan for building a self-replicating branching agent in {{AGENT_NAME}}. 단일 에이전트가 스스로 서브에이전트를 분기하고, 결과를 수렴시키는 구조. |
| triggers | ["자가 증식 에이전트","branching agent","self-replicating","subagent autonomous branching"] |
| space | outcome |
| type | document |
| tags | ["architecture","branching","self-replicating","tdd","pdca"] |
| links | ["[[@action/skills/agent-architecture/DESCRIPTION]]","[[@action/skills/SKILL-INDEX]]"] |
| created | "2026-05-10T00:00:00.000Z" |
{{AGENT_NAME}} (단일 에이전트)이 복잡한 문제를 감지 → 스스로 서브에이전트를 분기 (branch) → 병렬 추론 → 결과를 부모가 수렴 → 최종 응답 형성.
Phase 1 (COMPLETE): SelfBranchDecider class with 17 passing tests. Phase 2 (COMPLETE): Integrated into run_agent.py loop. Phase 3 (COMPLETE): Structural bugs fixed + integration tests written. 23 tests passing.
| Phase | Goal | Status |
|---|---|---|
| Phase 1 | score_complexity + should_branch + plan_branches + integrate_results | COMPLETE |
| Phase 2 | Hook into run_agent.py _execute_tool_calls_concurrent at api_call_count==1 | COMPLETE |
| Phase 3 | Fix structural bugs (tool_name, _already_branching, decider caching) + integration tests | COMPLETE |
| Phase 4 | End-to-end test + CLI indicator + child agent propagation | COMPLETE |
| # | Bug | Location | Fix |
|---|---|---|---|
| 1 | tool_name missing from tool result messages (sequential) | run_agent.py:7719 | Added tool_name to tool_msg dict |
| 2 | tool_name missing from concurrent path interrupt skip | run_agent.py:7003 | Added tool_name to interrupt skip_msg |
| 3 | _already_branching check-only (never set) | run_agent.py:7289 | Added self._already_branching = True before execute |
| 4 | SelfBranchDecider recreated every call | run_agent.py:7839 | Cached as self._branch_decider |
| 5 | original_user_message not passed in concurrent path | run_agent.py:6877 | Added to _execute_tool_calls() signature and all call sites |
| # | Item | Location |
|---|---|---|
| A | CLI visual indicator on branching | run_agent.py:7291-7293 — ⚡ Self-branch triggered message |
| B | _already_branching propagates to child agents | delegate_tool.py:322 — child._already_branching = getattr(parent_agent, '_already_branching', False) |
Integration Tests (9 in TestSelfBranchIntegration):
test_execute_tool_calls_sets_tool_name_in_result_messages — sequential path tool_msg includes tool_nametest_should_self_branch_false_on_no_conjunction — conjunction gate blocks simple messagestest_should_self_branch_false_on_simple_message — no conjunction → no branchtest_should_self_branch_true_with_conjunction_and_complex_messages — passes when both conditions mettest_should_self_branch_false_when_already_branching — _already_branching flag blocks re-entrytest_should_self_branch_false_on_child_agent — _delegate_depth > 0 blocks branching in childrentest_execute_self_branch_calls_decider_execute_branching — cached decider receives correct argstest_decider_cached_on_agent_instance — conjunction pass → cache settest_branch_response_returned_with_branched_flag — branching result string returnedTest Results: 236 passed, 7 failed (pre-existing, all Azure/max_tokens related)
_execute_tool_calls_concurrent() signature: added original_user_message="" parameterif api_call_count == 1 and self._should_self_branch(messages, original_user_message)_should_self_branch(), _execute_self_branch()Conjunction Gate: Only branch when goal contains natural conjunction (" and ", " and also ", " + ", "그리고", " 또한 ", "且", "並且", "同时"). Prevents branching on every complex single task.
Complexity Score Components (0.0 to 1.0):
| Component | Weight | Notes |
|---|---|---|
| tool_diversity | 0.30 | unique tools / total calls |
| tool_call_count | 0.30 | calls / 15 |
| turn_count | 0.20 | assistant turns / 8 |
| reasoning_ratio | 0.10 | thinking blocks present |
| context_compression | 0.10 | bonus if > 30 messages |
Threshold: 0.30
Tool Name Extraction — CRITICAL FIX: Must extract from BOTH assistant.tool_calls[].function.name (OpenAI format) AND tool role messages with tool_name field ({{AGENT_NAME}} format).
Trigger: api_call_count == 1 — after FIRST tool-call turn completes.
{"role": "tool", "tool_name": "..."})agent/self_brancher.py — SelfBranchDecider classtests/agent/test_self_brancher.py — 17 testsrun_agent.py — integration hooks + new methodsdelegate_task (tools/delegate_tool.py) — 병렬 서브에이전트 spawn (MAX_CONCURRENT=3, MAX_DEPTH=2)_active_children interrupt 전파 (run_agent.py)MemoryManager.on_delegation() — 자식 완료 후 메모리 동기화 hookSessionDB parent_session_id 체인 추적ContextCompressor — iterative summarization_budget_caution_threshold=0.7, _budget_warning_threshold=0.9 — pressure injectionsmart_model_routing — cheap/strong model routingcredential_pool — same-provider credential sharingskip_memory=True, 고립된 메모리, 결과는 summary 문자열만 반환왜 이것부터? Branching decision이 없으면 뒤의 모든 단계가 무의미.
| Step | 내용 |
|---|---|
| T (Test) | "복잡한 문제"를 정량화 — iteration count, tool diversity score, reasoning token ratio, message depth |
| T (Test) | Branching trigger 조건 정의 — threshold 조합 테스트 |
| D (Driver) | AIAgent에 complexity scorer組み込み — _should_branch() method |
| D (Driver) | Branching decision을 autonomous하게 내리는 시스템 — 모델 요청이 아니라 에이전트 자체 판단 |
| C (Check) | 실제 복잡한 문제에서 branching이 트리거되는지 검증 |
왜 이것부터? Branch 결과를 공유하지 못하면 병렬 분기의 가치가 떨어짐.
| Step | 내용 |
|---|---|
| D (Driver) | Wiki-based shared brain 활용 — 자식들이 중간 결과를 wiki에 write, 부모가 read |
| D (Driver) | Branch별 결과 aggregation 메서드 — parent가 wiki에서 branch 결과 수집 |
| C (Check) | 자식 완료 후 wiki에 기록되는 결과의 정확성 검증 |
| A (Adjust) | Wiki write batching 빈도 조정, aggregation 로직 튜닝 |
Bug Fixes:
tool_name missing from run_agent.py tool result messages (line ~7249)
{"role": "tool", "tool_name": "..."} messagesrole, content, tool_call_id — not tool_name"tool_name": name to the tool result message dict_already_branching flag never set (line ~7284)
self._already_branching = True before calling _execute_self_branch()`SelfBranchDecider recreated each call (lines ~7817–7829)
_should_self_branch() created fresh SelfBranchDecider() on every call_branching_happened = False each time → double-branch guard brokenself._branch_decider, reuse across callsIntegration Tests Added (tests/agent/test_self_brancher.py — TestSelfBranchIntegration):
Key Behavioral Insights (from tests):
should_branch() does NOT set _branching_happened — only execute_branching() doesshould_branch() calls without execute_branching() keep returning True_already_branching flag, (2) _delegate_depth > 0SelfBranchDecider.should_branch() is agnostic to _already_branching — that check lives in AIAgent layer above itPhase 4 — TODO:
_already_branching should propagate to child agents via delegate_task context# complexity_score 계산 요소
- tool_call_count: 10회 이상 → +1
- unique_tool_types: 4가지 이상 → +1
- reasoning_tokens / total_tokens: 0.3 이상 → +1
- message_turn_count: 8회 이상 → +1
- nested_delegate (subagent 호출): +2
- context compression 발생: +1
threshold: score >= 3 → branching 고려
파일: agent/self_brancher.py (신규)
class SelfBranchDecider:
"""Parent agent가 autonomous하게 branch를 결정하게 하는 모듈."""
def __init__(self, agent):
self.agent = agent
def score_complexity(self, messages) -> float:
"""0.0~1.0 complexity score."""
def should_branch(self, messages) -> bool:
"""score > threshold AND not already branching."""
def plan_branches(self, goal: str, context: str) -> list[BranchTask]:
"""goal을 branch로 분할."""
def integrate_results(self, branch_results: list) -> str:
"""branch 결과들을 통합."""
# 테스트 시나리오
# 1. 복잡한 디버깅 문제 → branch 발생 확인
# 2. 단순한 질문 → branch 없음 확인
# 3. branch 후 wiki에 결과 기록 확인
# 4. parent가 결과를 수렴해서 최종 응답 형성 확인
현재: 모델이 delegate_task tool을 명시적으로 호출해야 함
→ 원하는: iteration pressure, complexity score 등 내부 신호로 에이전트가 스스로 분기
구현 옵션:
_should_branch() hook을 agent loop에組み込み — 매 turn마다 complexity checkdelegate_task 호출하도록 유도하는 system prompt 전략옵션 A: Wiki (Obsidian) — 기존 infrastructure 활용
brain_record tool로 wiki에 writebrain_query로 wiki에서 branch 결과 read
-优点: 이미 구현되어 있음, persistent옵션 B: In-memory shared state (새로 구현)
delegate_task의 현재 limitation: 자식이 완료될 때까지 부모 block
개선 방향:
tool_progress_callback 활용 — 자식이 중간 결과를 parent에게 pushPhase 1 (T+D) ← 가장 먼저: branching decision 없으면 의미 없음
↓
Phase 2 (D+C) ← Phase 1 완료 후: branch 결과를 공유해야 수렴 가능
↓
Phase 3 (C+A) ← 마지막: 실시간 streaming + autonomous refinement