Files
2nd/10_Wiki/Topic_Programming/Subsystems/Agent_오케스트레이터_분해.md
T
Antigravity Agent e2c5471046 wiki: Topic_Blog 신규 문서 일괄 추가 + ASTRA 성장 자산 동기화
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-16 09:55:38 +09:00

8.2 KiB

id, title, category, status, verification_status, canonical_id, aliases, duplicate_of, source_trust_level, confidence_score, created_at, updated_at, review_reason, merge_history, tags, raw_sources, applied_in, github_commit
id title category status verification_status canonical_id aliases duplicate_of source_trust_level confidence_score created_at updated_at review_reason merge_history tags raw_sources applied_in github_commit
agent-orchestrator-decomposition Agent 오케스트레이터 분해 AI_and_ML draft applied
agent executor
orchestrator
god class 분해
multi-agent
ChunkedWriter
sequential dispatch
에이전트 파이프라인
A 0.9 2026-06-13 2026-06-13
agent
orchestrator
multi-agent
architecture
ai
astraai
AstraAI/src/agent.ts
AstraAI/src/agents/AgentWorkflowManager.ts
AstraAI/src/agent/multiAgent/workflow.ts
AstraAI/src/features/company/dispatcher.ts
AstraAI

Agent 오케스트레이터 분해

🎯 한 줄 통찰 (One-line insight)

한 턴의 복잡한 처리(컨텍스트 조립→라우팅→스트리밍→후처리→학습)는 거대 orchestrator 하나가 흐름의 골격만 쥐고 세부는 추출된 모듈에 위임하는 구조가 유지보수에 유리하며, 멀티에이전트는 "병렬 persona 줄세우기"보다 자원 제약에 맞춘 순차 실행 + 단일 작성자 다중 역할이 로컬 환경에서 더 견고하다 [S1][S2][S4].

🧠 핵심 개념 (Core concepts)

  1. 얇은 골격 + 추출 위임: agent.ts(orchestrator)는 한 턴의 흐름을 읽을 수 있게 유지하고, 세부는 handlePrompt/, llm/, actions/, sessions/, multiAgent/ 로 추출 [S1].
  2. Action tag 실행: 모델 출력의 <create_file>, <run_command> 등 태그를 액션 실행기로 라우팅해 도구를 수행 [S1][S4].
  3. 단일 작성자 다중 역할(ChunkedWriter): outline → section[N] → polish 를 같은 모델이 번갈아 수행 — hop 마다 컨텍스트 폭증·본문 손실을 피함 [S2].
  4. 순차 디스패치(company): CEO 플래너 → 전문가들 순차 실행(peer-context 전달) → CEO 리포터 합성 [S4].
  5. mission 락: 무거운 LLM 작업은 missionId 단위로 직렬화 [S2][참조: 동시성 제어 Lock Queue Transaction].

🧩 추출된 패턴 (Extracted patterns)

  • God-class 분해: orchestrator 의 import 가 100줄을 넘지만, 이는 "기능을 작은 모듈로 추출하고 흐름에서 다시 끌어모은" 결과 — 흐름은 한 곳, 구현은 분산 [S1].
  • 메시지 프로토콜 UI: webview 와 streamStart/streamChunk/streamEnd/workflowStage 메시지로 통신 — 진행 단계는 본문이 아니라 상단 인디케이터로 [S3].
  • 모든 종료 경로에서 인디케이터 닫기: 성공·취소·에러 어디서든 workflowStage{done:true} 를 보내 "영원히 도는 스피너" 방지 [S3].
  • peer-context 버퍼: 앞 에이전트 출력을 잘라(PEER_OUTPUT_BUDGET 1500) 다음 에이전트 프롬프트에 전달 [S4].
  • raw 출력 → 공용 액션 실행기 재사용: 전문가도 action tag 를 낼 수 있고, 채팅과 같은 실행기를 통과시켜 도구 동작 일관성 유지 [S4].

📖 세부 내용 (Details)

멀티에이전트 설계의 진화 (post-mortem)

초기엔 planner/researcher/reflector/writer/synthesizer 5개 persona 를 줄세웠다. 문제: 각 hop 마다 컨텍스트가 누적되고 원본 본문이 추상화로 손실 돼, 사용자가 본문 분석을 요청해도 "분석 방법론" 만 만들어내는 사고가 났다. → 현재는 단일 ChunkedWriter 가 outline/section/polish 세 역할을 같은 모델에서 번갈아 수행 — 각 호출이 작고 본문은 매 호출에 직접 전달돼 손실이 없다 [S2].

왜 순차 디스패치인가 (company 모드)

사용자는 단일 GPU/제한된 RAM 에서 Astra 를 돌린다. 병렬 에이전트는 여러 모델을 동시에 메모리에 상주시켜야 한다. 순차 실행은 "정확히 한 번에 하나의 모델만 상주" 를 보장하고, LM Studio lifecycle 매니저가 이전 모델을 unload 하고 다음을 load 한다 [S4]. → 이 위키의 sub-agent 제약(병렬 fanout 금지)과도 같은 원리.

왜 handlePrompt 를 재사용하지 않는가

handlePrompt대화형 경로용이라 대화 이력·스트리밍 UI·에이전트 모드 주입 등 12가지를 떠안는다. company 턴은 "system 1개 + user 1개 → 문자열 1개" 의 깨끗한 primitive 가 필요하므로 AIService.chat() 을 쓴다 — 책임이 다른 경로는 다른 primitive [S4].

⚖️ 비교 및 선택 기준 (Comparison & decision criteria)

멀티에이전트 방식 장점 단점 언제
병렬 persona N개 빠름(자원 충분 시) 모델 다중 상주, 컨텍스트 누적/본문 손실 RAM/GPU 넉넉한 서버
단일 작성자 다중 역할 컨텍스트 작고 본문 보존 한 모델 품질에 의존 로컬 단일 모델
순차 디스패치 한 번에 한 모델, 자원 안전 총 시간 김 단일 GPU/제한 RAM

⚖️ 모순 및 업데이트 (Contradictions & updates)

  • orchestrator 크기: 분해했어도 agent.ts 가 크다 — "흐름 가독성" 을 위해 의도적으로 골격을 남긴 트레이드오프(완전 분해 시 흐름 추적이 파일 사이를 떠돈다).
  • 순차의 비용: 응답이 느리다. 사용자 경험을 위해 진행 단계를 webview 인디케이터로 보여 체감 지연을 완화한다.

🛠️ 적용 사례 (Applied in summary)

  • AstraAI/src/agent.ts — orchestrator 골격 + 추출 모듈 import [S1].
  • AstraAI/src/agents/AgentWorkflowManager.ts — ChunkedWriter 단일 작성자 다중 역할 [S2].
  • AstraAI/src/agent/multiAgent/workflow.ts — webview 메시지 프로토콜, 모든 경로 인디케이터 닫기 [S3].
  • AstraAI/src/features/company/dispatcher.ts — 순차 디스패치, peer-context, 설계 근거 주석 [S4].

💻 코드 패턴 (Code patterns)

// 1) 단일 작성자 다중 역할 — 스테이지를 UI 라벨로 (src/agents/AgentWorkflowManager.ts)
const writer = new ChunkedWriter(modelName, overrides);  // outline → section → polish
const engine = new AgentEngine(writer);
return await engine.runMission(missionId, prompt, brainContext, signal,
    (stage, msg) => onProgress(this.mapStageToUI(stage), msg));  // ① 구조 → ② 본문 → ③ 다듬기

// 2) 모든 종료 경로에서 인디케이터 닫기 (src/agent/multiAgent/workflow.ts)
} catch (error: any) {
    deps.getWebview()?.postMessage({ type: 'workflowStage', value: { step: '완료', done: true } });
    if (error.name === 'AbortError') { /* 취소 */ return; }
    // ... 에러 카드
} finally { deps.options.onStreamLifecycle?.end(); }

// 3) 순차 디스패치 + peer-context 버퍼 (src/features/company/dispatcher.ts, 개념)
let peerContext = '';
for (const task of plan.tasks) {
    const prompt = buildSpecialistPrompt(task, peerContext);   // 앞 에이전트 맥락 포함
    const out = await aiService.chat({ system, user: prompt }); // 한 번에 한 모델만 상주
    writeAgentOutput(sessionDir, task, out.content);
    peerContext += '\n' + out.content.slice(0, PEER_OUTPUT_BUDGET);  // 다음 에이전트에 전달
}

검증 상태 및 신뢰도

  • 상태: draft
  • 검증 단계: applied
  • 출처 신뢰도: A
  • 신뢰 점수: 0.90
  • 중복 검사 결과: 신규 생성 (New discovery)

🔗 지식 그래프 (Knowledge Graph)

📚 출처 (Sources)

  • [S1] AstraAI/src/agent.ts — orchestrator 골격, 추출 모듈 import 구조
  • [S2] AstraAI/src/agents/AgentWorkflowManager.ts — ChunkedWriter, 멀티에이전트 진화 post-mortem
  • [S3] AstraAI/src/agent/multiAgent/workflow.ts — 메시지 프로토콜, 인디케이터 닫기
  • [S4] AstraAI/src/features/company/dispatcher.ts — 순차 디스패치 근거, peer-context, primitive 분리

📝 변경 이력 (Change history)

  • 2026-06-13: AstraAI 코드 분석 기반 초안 생성.