# AgentEngine Architecture Document > **Version:** v2.61.0 | **Last Updated:** 2026-05-04 | **Author:** ConnectAI Lab --- ## 1. Overview (설계 개요) `AgentEngine`은 ConnectAI(Astra) 확장의 핵심 실행 엔진으로, **Producer-Consumer 패턴** 기반의 멀티 에이전트 오케스트레이션을 담당합니다. Planner → Researcher → Writer의 3단계 파이프라인을 통해 사용자의 자연어 요청을 전략 수립, 정보 수집, 최종 보고서 작성이라는 전문화된 단계로 분할 처리합니다. ### 핵심 설계 원칙 | 원칙 | 구현 | |---|---| | **의존성 주입 (DI)** | `IAgent` 인터페이스를 통해 에이전트를 런타임에 교체 가능 | | **명시적 동시성 제어** | `LockManager`(Mutex) + `ActionQueueManager`(Concurrency Limit) | | **복원력 우선 (Resilience-First)** | `ErrorRecoveryMatrix`를 통한 오류 자동 분류 및 복구 | | **투명한 상태 관리** | `MissionState`를 통한 감사 이력(Audit Trail) 자동 기록 | --- ## 2. Architecture Diagram (아키텍처 다이어그램) ``` ┌──────────────────────────────────────────────────────────────┐ │ AgentWorkflowManager │ │ (Public Entry Point) │ └──────────────────────────┬───────────────────────────────────┘ │ ▼ ┌──────────────────────────────────────────────────────────────┐ │ AgentEngine │ │ ┌─────────────────────────────────────────────────────────┐ │ │ │ 1. LockManager.acquire() ← Mutex (동일 미션 중복 방지) │ │ │ │ 2. ActionQueue.enqueue() ← Concurrency Limit (≤3) │ │ │ │ 3. resilientExecute() ← Error Recovery Matrix │ │ │ └─────────────────────────────────────────────────────────┘ │ │ │ │ ┌──────────┐ ┌──────────────┐ ┌────────────┐ │ │ │ Planner │──▶│ Researcher │──▶│ Writer │ │ │ │ (IAgent) │ │ (IAgent) │ │ (IAgent) │ │ │ └──────────┘ └──────┬───────┘ └────────────┘ │ │ │ │ │ ┌──────┴───────┐ │ │ │ WriterPrep │ ← Promise.all() 병렬 실행 │ │ │ (Parallel) │ │ │ └──────────────┘ │ │ │ │ ┌─────────────────────────────────────────────────────────┐ │ │ │ MissionState (Audit Trail) │ │ │ │ idle → planner → researcher → writer → completed │ │ │ │ [toStructuredLog()] → JSON 출력 → 모니터링 대시보드 │ │ │ └─────────────────────────────────────────────────────────┘ │ └──────────────────────────────────────────────────────────────┘ ``` --- ## 3. Lock Management (락 관리) ### 3.1 LockManager (Mutex) **파일:** `src/core/lock.ts` **설계 의도:** 동일한 `missionId`에 대한 중복 실행을 방지합니다. 예를 들어, 사용자가 동일한 질문을 빠르게 두 번 전송한 경우, 두 번째 요청은 첫 번째 요청이 완료될 때까지 대기합니다. **동작 원리:** ``` Mission A (id: "abc") 시작 → Lock 획득 ✅ Mission B (id: "abc") 시작 → Lock 대기 ⏳ (Mission A 완료까지) Mission A 완료 → Lock 해제 → Mission B Lock 획득 ✅ ``` **핵심 보장:** - 동일 미션 ID의 순차 실행 보장 (Race Condition 방지) - `finally` 블록에서 반드시 `release()` 호출 → 데드락 불가 ### 3.2 ActionQueueManager (동시성 제어) **파일:** `src/core/queue.ts` **설계 의도:** 시스템 전체에서 동시에 실행되는 에이전트 작업 수를 제한하여 리소스 고갈을 방지합니다. **핵심 파라미터:** | 파라미터 | 기본값 | 설명 | |---|---|---| | `concurrencyLimit` | 3 | 동시 실행 가능한 최대 작업 수 | | `activeCount` | - | 현재 실행 중인 작업 수 (동적) | | micro-delay | 10ms | 작업 간 시스템 호흡 시간 | **Mutex vs Queue의 역할 분리:** | 구분 | LockManager | ActionQueueManager | |---|---|---| | 범위 | 미션 단위 (단일 ID) | 시스템 전체 | | 목적 | 중복 실행 방지 | 리소스 포화 방지 | | 방식 | 독점 잠금 (Exclusive) | 동시성 제한 (Bounded) | --- ## 4. Error Recovery Matrix (오류 복구 매트릭스) ### 4.1 오류 분류 체계 `ErrorClassifier`는 에러 객체의 `name`과 `message`를 정규식 패턴 매칭하여 세 범주로 자동 분류합니다. ``` ┌──────────────┬──────────┬──────────────┬─────────────────────────────────┐ │ Error Type │ Retries │ Backoff │ Action │ ├──────────────┼──────────┼──────────────┼─────────────────────────────────┤ │ TRANSIENT │ 3 │ Exponential │ 자동 재시도 (1s → 2s → 4s) │ │ │ │ (1000ms) │ │ ├──────────────┼──────────┼──────────────┼─────────────────────────────────┤ │ PERMANENT │ 0 │ N/A │ 즉시 중단 + 사용자 안내 메시지 │ ├──────────────┼──────────┼──────────────┼─────────────────────────────────┤ │ ABORT │ 0 │ N/A │ Graceful Exit (조용한 종료) │ └──────────────┴──────────┴──────────────┴─────────────────────────────────┘ ``` ### 4.2 분류 패턴 목록 **Transient (재시도 가능):** - `ECONNREFUSED`, `ECONNRESET`, `ETIMEDOUT`, `ENOTFOUND` - `timeout`, `network`, `fetch failed`, `Failed to fetch` - HTTP `502`, `503`, `429` - `socket hang up` **Permanent (즉시 중단):** - HTTP `401`, `403`, `404` - `유효한 응답을 받지 못했습니다` (내부 검증 실패) - `Ollama URL이 설정되지 않았습니다` (설정 누락) - `invalid model`, `model not found` (모델 문제) **분류 불가 → Permanent (보수적 처리):** - 알려지지 않은 오류는 안전하게 Permanent로 분류하여 무한 재시도를 방지 ### 4.3 resilientExecute 실행 흐름 ``` resilientExecute(agent, ...) │ ├─ attempt 0: agent.execute() │ ├─ 성공 → return result │ └─ 실패 → ErrorClassifier.classify(error) │ ├─ ABORT → throw (즉시 전파) │ ├─ PERMANENT → throw (사용자 메시지 첨부) │ └─ TRANSIENT → continue │ ├─ attempt 1: wait 1000ms → agent.execute() │ └─ (동일 분기) │ ├─ attempt 2: wait 2000ms → agent.execute() │ └─ (동일 분기) │ └─ attempt 3: wait 4000ms → agent.execute() └─ 실패 시 → "재시도 소진" 에러 throw ``` --- ## 5. MissionState & Monitoring (상태 관리 및 모니터링) ### 5.1 MissionState 설계 의도 엔진 내부의 상태(`this.stage`)를 독립 객체로 분리하여: 1. **감사 이력(Audit Trail)** 자동 기록: 모든 상태 전환이 타임스탬프, 소요 시간과 함께 기록됨 2. **외부 노출**: `getMissionState()`를 통해 외부 모니터링 시스템이 실시간 상태를 읽을 수 있음 3. **디버깅 지원**: 에러 발생 시 `summarizeAudit()`로 전체 전환 이력을 한 줄로 덤프 ### 5.2 toStructuredLog() 출력 포맷 ```json { "missionId": "mission_1714832400000", "status": "completed", "startTime": "2026-05-04T02:40:00.000Z", "totalElapsedMs": 12450, "transitionCount": 4, "transitions": [ { "from": "idle", "to": "planner", "durationMs": 0, "message": "전략 수립 중...", "ts": "2026-05-04T02:40:00.000Z" }, { "from": "planner", "to": "researcher", "durationMs": 3200, "message": "핵심 정보 수집 및 분석 중...", "ts": "2026-05-04T02:40:03.200Z" } ] } ``` 이 포맷은 ELK Stack, Loki, Datadog 등의 외부 시스템에 파싱 없이 직접 인제스트할 수 있습니다. ### 5.3 Mission Control Dashboard **파일:** `assets/mission_control.html` `toStructuredLog()`의 JSON 출력을 브라우저에서 시각화하는 독립형 대시보드입니다. - 에이전트 타임라인 시각화 - 단계별 지연 시간(Latency) 표시 - 미션 상태 및 효율성 분석 지표 제공 --- ## 6. IAgent Interface (에이전트 인터페이스) ### 6.1 기본 시그니처 ```typescript interface IAgent { execute( input: string, context?: string, signal?: AbortSignal, options?: AgentExecuteOptions ): Promise; } ``` ### 6.2 AgentExecuteOptions (확장 옵션) | 필드 | 타입 | 용도 | |---|---|---| | `context` | `string` | 추가 컨텍스트 | | `signal` | `AbortSignal` | 중단 시그널 | | `config` | `Record` | 에이전트별 커스텀 설정 (temperature, maxTokens 등) | | `priorResults` | `Record` | 이전 단계 중간 결과물 (병렬 파이프라인용) | **확장 전략:** 새로운 에이전트가 추가될 때 `options.config`에 자유롭게 설정을 넣을 수 있으므로, `IAgent` 시그니처를 변경할 필요가 없습니다. --- ## 7. Test & Benchmark Coverage (테스트 커버리지) **파일:** `tests/agentEngine.test.ts` | **총 41개 테스트** | Suite | Tests | Description | |---|---|---| | ErrorClassifier | 20 | Transient(10), Permanent(7), Abort(2), Unknown(1) 분류 정확성 | | Recovery Matrix | 3 | 매트릭스 규칙 정합성 | | MissionState | 4 | 상태 전환, Audit Trail, JSON 포맷 | | Engine Integration | 6 | 정상/재시도/즉시중단/취소/재시도소진/상태정리 | | Performance | 3 | 정상 Latency, 재시도 오버헤드, 즉시 중단 시간 | | Concurrency & Stress | 4 | 병렬 실행, 혼합 오류, 큐 포화, Race Condition | ### 벤치마크 기준치 | Metric | Measured | Threshold | |---|---|---| | Normal Mission Avg Latency | 165ms | < 1,000ms | | Retry Overhead (2 retries) | 3,012ms | 2,500–10,000ms | | Permanent Fail Time | 11ms | < 500ms | | 5 Concurrent Missions | 23ms | < 30,000ms | | Queue Saturation (10 tasks) | 44ms | all complete | ### 배포 게이트 ```json "vscode:prepublish": "npm run test && npm run compile" ``` 모든 41개 테스트가 통과해야만 `.vsix` 패키징이 진행됩니다. --- ## 8. File Map (파일 맵) ``` src/ ├── lib/ │ └── engine.ts ← AgentEngine, MissionState, ErrorClassifier, │ ErrorRecoveryMatrix, IAgent, AgentExecuteOptions ├── core/ │ ├── queue.ts ← ActionQueueManager (Concurrency Limit) │ └── lock.ts ← LockManager (Mutex) ├── agents/ │ ├── factory.ts ← PlannerAgent, ResearcherAgent, WriterAgent (BaseAgent) │ └── AgentWorkflowManager.ts ← Public API (runStrictWorkflow) └── utils.ts ← logInfo, logError, logWarn (→ VS Code Output Channel "Astra") tests/ └── agentEngine.test.ts ← 41 integration tests + benchmarks assets/ └── mission_control.html ← Mission Control Dashboard (standalone) ``` --- ## 9. Maintenance Notes (유지보수 참고) ### 새 에이전트 추가 시 1. `IAgent`를 구현하는 새 클래스를 `factory.ts`에 추가 2. `AgentEngine` 생성자에 주입 (DI) 3. `PipelineStage` 타입에 새 단계 추가 4. `AgentWorkflowManager.mapStageToUI()`에 UI 매핑 추가 ### 새 오류 패턴 추가 시 1. `ErrorClassifier.TRANSIENT_PATTERNS` 또는 `PERMANENT_PATTERNS`에 정규식 추가 2. `tests/agentEngine.test.ts`의 해당 describe 블록에 테스트 케이스 추가 3. `npm run test:engine`으로 검증 ### 동시성 제한 변경 시 `src/core/queue.ts`의 `new ActionQueueManager(N)` 생성자 인자를 조정합니다. 기본값은 3이며, 리소스 여유에 따라 조정 가능합니다.