# 에이전트 루프 아키텍처 — 워크플로우 비교 분석 > **대상**: 기술 임원 · 개발 리더 > **초점**: 에이전트 코딩 서비스의 핵심 워크플로우 구조와 품질 보증 전략 > **작성일**: 2026-03-31 --- ## 1. 에이전트 루프란? AI 코딩/문서 생성 서비스의 핵심 엔진은 **에이전트 루프**입니다. ``` 사용자 요청 → [LLM 판단] → [도구 실행] → [결과 관찰] → [LLM 재판단] → ... → 최종 응답 ``` 이 반복(iteration)을 **얼마나 지능적으로, 얼마나 품질 있게 수행하느냐**가 서비스 경쟁력을 결정합니다. --- ## 2. 업계 주요 서비스 워크플로우 비교 ### 2-1. OpenHands (오픈소스, ICLR 2025) OpenHands는 CodeAct 논문 기반의 에이전트 프레임워크입니다. ``` ┌─────────────────────────────────────────────────┐ │ AgentController │ │ │ │ while budget > 0: │ │ action = agent.step(state) ← 1 LLM 호출 │ │ observation = runtime.run(action) ← 도구 실행│ │ state.update(action, observation) │ │ if action == AgentFinishAction: │ │ break ← LLM이 "끝"이라 판단하면 종료 │ │ │ │ ⚠ 검증/검수 단계: 없음 │ │ ⚠ 계획 생성: 없음 (LLM 자율 판단) │ └─────────────────────────────────────────────────┘ ``` **핵심 특징**: - **1 반복 = 1 LLM 호출 + 1 도구 실행** (고정) - 계획(Plan) 없음 — LLM의 chain-of-thought에 의존 - 검증(Review) 없음 — LLM이 알아서 다음 반복에서 확인할지 결정 - 종료는 `AgentFinishAction` 반환으로 결정 (LLM 자율) - **SecurityAnalyzer**: 실행 전 위험도 평가 (LOW/MEDIUM/HIGH) — 품질 검증이 아닌 **안전 게이트** **장점**: 단순, 빠름, 모델 무관 **약점**: 문서 생성 후 검수 보장 없음, LLM이 "충분하다"고 판단하면 미완성 상태로 종료 ### 2-2. Claude Code (Anthropic) ``` ┌─────────────────────────────────────────────────┐ │ Claude Code Agent Loop │ │ │ │ while true: │ │ response = llm.call(messages) ← 1 LLM 호출 │ │ if no tool_calls: │ │ break ← 텍스트만 반환하면 종료 │ │ for tool in tool_calls: │ │ result = execute(tool) │ │ messages.append(result) │ │ │ │ ⚠ 검증 단계: 없음 (시스템 프롬프트 권고만) │ │ ⚠ 계획: SKILL.md 프롬프트로 유도 │ └─────────────────────────────────────────────────┘ ``` **핵심 특징**: - OpenHands와 동일한 구조 (1 반복 = 1 LLM 호출) - 종료: 도구 호출이 없으면 종료 (OpenHands의 AgentFinishAction과 유사) - 검증: 시스템 프롬프트에 "확인하라"고 작성 가능하나, **LLM이 무시할 수 있음** - 차별점: SKILL.md 표준으로 도메인별 프롬프트 커스터마이징 ### 2-3. Cursor / Windsurf / GitHub Copilot 모두 동일한 **단일 LLM 호출 루프** 패턴: - Cursor: Tab → Apply 기반, 에이전트 모드에서도 1호출/반복 - Windsurf (Cascade): Flow 기반이지만 루프 구조는 동일 - GitHub Copilot: 코드 완성 특화, 에이전트 모드는 Claude Code와 유사 **공통 약점**: **문서/코드 생성 후 "읽어서 확인"하는 아키텍처가 없음** --- ## 3. 왜 검증 단계가 없을까? ### 3-1. AgentFinishAction 문제 OpenHands는 LLM이 `AgentFinishAction`을 반환하면 루프가 종료됩니다. ```python # OpenHands의 종료 판단 if isinstance(action, AgentFinishAction): return # LLM이 "끝"이라고 하면 끝 ``` **문제**: LLM이 "파일을 생성했으니 끝"이라고 판단하면, **내용이 불완전해도 종료**됩니다. 우리는 왜 AgentFinishAction을 사용하지 않는가? | 항목 | AgentFinishAction (OpenHands) | 도구 호출 없음 종료 (AX Copilot) | |------|------------------------------|--------------------------------| | 종료 판단 | LLM이 명시적으로 "finish" 액션 반환 | LLM이 텍스트만 반환 (도구 미호출) | | 장점 | 명시적, 종료 이유 포함 가능 | 별도 액션 정의 불필요, 자연스러운 대화 흐름 | | 단점 | finish 호출을 잊거나 잘못 호출 가능 | LLM이 도구를 부르지 않으면 의도치 않게 종료 | | 검증 타이밍 | finish 전에 검증 삽입 가능 (미구현) | 도구 실행 후 즉시 검증 삽입 (구현 완료) | **핵심**: 둘 다 "LLM이 알아서 끝내라"는 구조이므로, **검증을 LLM에게 맡기면 생략될 수밖에 없습니다.** ### 3-2. 시스템 프롬프트만으로는 부족 ``` 시스템 프롬프트: "문서 작성 후 반드시 file_read로 결과물을 검토하세요" ``` 이 지시를 LLM이 따를 확률: - GPT-4/Claude: **~60-70%** (복잡한 작업에서 무시 경향) - Gemini Flash: **~40-50%** (무료 모델에서 더 자주 생략) - 로컬 모델 (Ollama): **~30%** (컨텍스트 길어지면 초기 지시 희석) → **아키텍처 수준에서 강제해야 신뢰성 확보 가능** --- ## 4. 검증 강제 아키텍처 (AX Copilot 구현) ### 4-1. 기존 구조 (v1.7.0) ``` 반복 1: LLM 호출 → "file_read로 현재 파일 확인하겠습니다" 도구 실행: file_read → 파일 내용 반환 반복 2: LLM 호출 → "html_create로 보고서를 생성하겠습니다" 도구 실행: html_create → "보고서.html 생성 완료" 반복 3: LLM 호출 → "보고서가 완성되었습니다." (텍스트만 = 루프 종료) ⚠ 생성된 파일을 읽어서 확인하지 않음! ``` ### 4-2. 개선 구조 (v1.7.1 — 검증 강제) ``` 반복 1: LLM 호출 → "file_read로 현재 파일 확인하겠습니다" 도구 실행: file_read → 파일 내용 반환 반복 2: LLM 호출 → "html_create로 보고서를 생성하겠습니다" 도구 실행: html_create → "보고서.html 생성 완료" ┌──────────────────────────────────────────────┐ │ ★ 검증 강제 (자동 삽입) │ │ │ │ 시스템: "생성된 파일을 file_read로 읽고 │ │ 내용 완전성, 구조, 맞춤법을 확인하세요" │ │ │ │ LLM 호출 (검증 전용) │ │ → file_read 실행 → 내용 확인 │ │ → 문제 있으면 수정 도구 호출 │ │ → 문제 없으면 "검증 완료" 보고 │ └──────────────────────────────────────────────┘ 반복 3: LLM 호출 → "보고서가 완성되었습니다." (검증 통과 후 종료) ``` ### 4-3. 코드 흐름 (의사코드) ```csharp while (iteration < maxIterations) { var blocks = await llm.SendWithToolsAsync(messages, tools); foreach (var call in toolCalls) { var result = await tool.ExecuteAsync(call); messages.Add(CreateToolResult(result)); // ★ 검증 강제: 문서 생성 도구 실행 후 자동 삽입 if (settings.EnablePostToolVerification && IsDocumentCreationTool(call.ToolName) && result.Success) { // 검증 전용 LLM 호출 (file_read 유도) await RunPostToolVerificationAsync(messages, call, result); iteration++; // 검증도 반복 횟수에 포함 } } if (no tool calls) break; // 텍스트만 = 종료 } ``` --- ## 5. 부족한 부분과 향후 개발 방향 ### 5-1. 현재 부족한 영역 | 영역 | 현재 상태 | OpenHands 비교 | 개선 필요성 | |------|----------|---------------|-----------| | **Multi-Agent 위임** | ❌ 미구현 | ✅ AgentDelegateAction | 높음 — 복잡한 작업을 하위 에이전트에 분할 | | **Event-Sourced State** | 부분 구현 (Events 컬렉션) | ✅ 불변 이벤트 스트림 | 중간 — 재실행/디버깅에 유용 | | **SecurityAnalyzer** | Ask 모드 권한 확인 | ✅ 위험도 자동 분류 | 낮음 — 사내 환경에서 우선순위 낮음 | | **CodeAct 통합 액션** | 도구별 분리 | ✅ bash+Python 통합 | 낮음 — 현재 도구 체계로 충분 | | **검증 깊이** | 단일 검증 호출 | 해당 없음 | 중간 — 복수 기준별 검증 가능 | | **검증 대상 확대** | 문서 생성 도구만 | 해당 없음 | 중간 — 코드 생성 후에도 검증 필요 | ### 5-2. 향후 개발 계획 #### Phase A: 검증 고도화 (단기) | 기능 | 설명 | 예상 공수 | |------|------|----------| | 검증 기준 커스터마이징 | 설정에서 검증 체크리스트를 사용자가 편집 | 낮음 | | 코드 검증 확대 | `script_create`, `file_edit` 후에도 검증 (구문 오류 검사) | 낮음 | | 검증 결과 UI 표시 | 워크플로우 타임라인에 "✅ 검증 통과" / "⚠ 수정 발생" 배지 | 낮음 | | 검증 통계 | 검증에서 문제 발견/수정된 비율 추적 | 낮음 | #### Phase B: 멀티에이전트 위임 (중기) OpenHands의 `AgentDelegateAction` 패턴을 참고하되, 사내 환경에 맞게: ``` [메인 에이전트] ├── [리서치 에이전트] ← file_read, grep, folder_map 전담 ├── [문서 에이전트] ← html_create, docx_create 전담 └── [검증 에이전트] ← file_read + 품질 평가 전담 ← 검증 분리! ``` | 기능 | 설명 | 예상 공수 | |------|------|----------| | AgentDelegateAction | 하위 에이전트 위임 액션 정의 | 중간 | | 에이전트별 도구 제한 | 리서치=읽기만, 문서=쓰기만 등 | 낮음 | | 검증 에이전트 분리 | 생성과 검증을 다른 에이전트로 | 중간 | #### Phase C: Reflexion 패턴 (장기) Reflexion 논문(Shinn et al., 2023)의 자기 반성 패턴 강화: ``` 실행 → 결과 → 자기 평가 → 반성 메모리 저장 → 다음 시도에 반영 ``` 현재 Self-Reflection은 **오류 발생 시에만** 동작. 이를 **성공 시에도** 적용: - "이 문서는 사용자 요구를 80% 충족. 미흡 점: 표가 누락됨" - 반성 결과를 AgentMemory에 저장 → 같은 유형 작업 시 참고 --- ## 6. 정리 ### 핵심 메시지 ``` ┌─────────────────────────────────────────────────────┐ │ │ │ 업계 모든 에이전트 루프는 "1반복 = 1 LLM 호출" │ │ 검증(Review)을 강제하는 아키텍처는 어디에도 없었음 │ │ │ │ AX Copilot은 "검증 강제"를 아키텍처 수준에서 구현 │ │ → 문서 품질 보증의 차별화 포인트 │ │ │ └─────────────────────────────────────────────────────┘ ``` ### 비교 요약 | 항목 | OpenHands | Claude Code | AX Copilot | |------|-----------|-------------|------------| | 반복당 LLM 호출 | 1회 | 1회 | 1회 + 검증 1회 | | 계획 생성 | ❌ | ❌ | ✅ PlanMode | | 검증 강제 | ❌ | ❌ | ✅ PostToolVerification | | 자기 반성 | ❌ | ❌ | ✅ Self-Reflection | | 컨텍스트 압축 | ❌ | ❌ | ✅ ContextCondenser | | 사용자 승인 | SecurityAnalyzer | 권한 프롬프트 | UserDecisionCallback | | 진행률 추적 | ❌ | ❌ | ✅ TaskDecomposer | | 피드백 학습 | ❌ | ❌ | ✅ FeedbackContext | ### 워크플로우 전체 비교도 ``` OpenHands: 요청 → [LLM] → [도구] → [LLM] → [도구] → [LLM: "끝"] → 응답 ↑ 검증 없음 Claude Code: 요청 → [LLM] → [도구] → [LLM] → [도구] → [LLM: 텍스트만] → 응답 ↑ 검증 없음 AX Copilot (v1.7.1): 요청 → [계획 LLM] → 승인 → [LLM] → [도구] → [★검증 LLM★] → [LLM] → 응답 ↑ PlanMode ↑ 실행 ↑ 생성 ↑ 강제 확인 ↑ 완료 ``` --- *작성: AX Copilot 개발팀 · 2026-03-31*