S
STONI
AI
Multi-Agent
AWS Bedrock
Claude
Strands
HTML
개발

AI 멀티 에이전트로 HTML 프로토타입 자동 생성하기 (2편: 직접 만들어보기)

AI 멀티 에이전트로 HTML 프로토타입 자동 생성하기 (2편)

시리즈 개요

  • 1편: 개념과 아키텍처 ←: 프로젝트 개념, 아키텍처, 멀티 에이전트 시스템
  • 2편 (본 글): 직접 만들어보기 - 실제 구현 과정

들어가며

1편에서는 멀티 에이전트 시스템의 개념과 아키텍처를 다뤘습니다. 본 편에서는 실제 구현 과정을 기술적 관점에서 상세히 설명합니다. 아키텍처 설계 결정, 구현 세부사항, 그리고 프로덕션 환경에서 마주한 기술적 과제와 해결 방안을 다룹니다.

프로젝트 구조 설계

아키텍처 설계 원칙

프로젝트 구조 설계 시 다음 원칙을 적용했습니다:

  • 모듈화: 각 에이전트를 독립적인 모듈로 분리하여 유지보수성 향상
  • 확장성: 새로운 에이전트 추가 시 기존 코드 변경 최소화
  • 테스트 가능성: 각 컴포넌트를 독립적으로 테스트할 수 있는 구조

최종 프로젝트 구조:

p2p-prototype-strands/
├── agents/                          # 각 에이전트를 독립적인 모듈로
│   ├── __init__.py                  # 에이전트 export
│   ├── analyzer_agent.py            # 분석 담당
│   ├── enhancer_agent.py            # 확장 담당
│   └── generator_agent.py           # 생성 담당
├── generate_enhanced_prototype_graph.py  # 메인 실행 파일
├── requirements.txt
└── README.md

왜 이렇게 나눴을까요?

설계 결정 사항:

  1. 모듈 분리: 단일 파일 구현은 초기 프로토타입에서 500줄을 초과하면서 유지보수가 어려워짐을 확인했습니다. 각 에이전트를 독립 모듈로 분리하여 코드 가독성과 테스트 용이성을 확보했습니다.
# 모듈화된 임포트 구조
from agents import create_analyzer_agent
from agents import create_enhancer_agent  
from agents import create_generator_agent
  1. 네임스페이스 관리: agents 패키지로 그룹화하여 명확한 네임스페이스를 제공하고, 향후 에이전트 추가 시 일관된 구조를 유지할 수 있도록 설계했습니다.

개발 환경 구성

의존성 격리

Python 가상 환경을 통해 프로젝트별 의존성을 격리했습니다:

python3 -m venv venv
source venv/bin/activate

이는 다른 프로젝트와의 패키지 버전 충돌을 방지하고, 재현 가능한 개발 환경을 보장합니다.

의존성 관리

프로젝트의 복잡도를 최소화하기 위해 핵심 의존성만 선별했습니다:

strands>=0.1.0      # 멀티 에이전트 프레임워크
boto3>=1.34.0       # AWS SDK
anthropic>=0.42.0   # Claude API 클라이언트

의존성 최소화 원칙: 초기 프로토타입에서 다양한 라이브러리를 테스트한 후, 실제 운영에 필요한 세 가지 패키지로 정리했습니다. 이는 배포 크기 감소, 보안 취약점 최소화, 유지보수 부담 경감의 이점을 제공합니다.

첫 번째 에이전트: Analyzer 구현

구현 순서 결정

워크플로우의 진입점인 Analyzer를 먼저 구현했습니다. 이는 전체 파이프라인의 입력 검증과 초기 데이터 구조화를 담당하는 핵심 컴포넌트입니다.

analyzer_agent.py 구현

"""
Analyzer Agent - 사용자 프롬프트를 분석하여 UI/UX 요구사항 추출
"""
from strands import Agent

def create_analyzer_agent():
    """Analyzer 에이전트 생성"""
    
    system_prompt = """
You are a UI/UX requirements analyzer.

Your task is to analyze user prompts and extract:
1. Screen type (login, dashboard, form, etc.)
2. Key features needed
3. Required interactions
4. Necessary shadcn UI components

Output must be in JSON format:
{
    "screen_type": "...",
    "features": [...],
    "interactions": [...],
    "required_components": [...]
}

Be specific and comprehensive.
"""
    
    return Agent(
        model="us.anthropic.claude-sonnet-4-5-20250929-v1:0",
        system_prompt=system_prompt,
        provider="bedrock"
    )

프롬프트 설계 전략: JSON 형식의 구조화된 출력을 요구하여 다음 에이전트가 파싱 가능한 일관된 데이터를 보장합니다.

인프라 구성 검증

초기 실행 시 AWS 인증 오류가 발생했습니다:

Error: Unable to authenticate with AWS Bedrock

원인 분석: AWS CLI 자격 증명 미구성

aws configure
# Access Key와 Secret Key 입력
# Region: us-east-1

자격 증명 구성 후 두 번째 오류가 발생했습니다:

Error: You don't have access to the model

원인 분석: Bedrock 모델 접근 권한 미활성화

해결 방법: AWS 콘솔 → Bedrock → Model access → Manage model access에서 Claude 4.5 Sonnet 활성화

핵심 인사이트: 인프라 설정을 개발 전에 체크리스트로 검증하는 것이 효율적입니다.

구현 검증

인프라 구성 완료 후 Analyzer 에이전트의 정상 작동을 검증했습니다:

analyzer = create_analyzer_agent()
result = analyzer("login screen")
print(result)

출력:

{
    "screen_type": "login",
    "features": ["email input", "password input", "submit button"],
    "interactions": ["form submission", "validation"],
    "required_components": ["input", "button", "card"]
}

검증 결과: JSON 형식의 구조화된 응답을 성공적으로 생성하며, 다음 에이전트로의 데이터 파이프라인이 정상 작동함을 확인했습니다.

두 번째 에이전트: Enhancer 구현

에이전트 간 데이터 파이프라인

Enhancer는 Analyzer의 JSON 출력을 입력으로 받아야 합니다.

Strands 프레임워크의 Graph 패턴은 노드 간 자동 데이터 전달 메커니즘을 제공합니다. 이전 노드의 출력이 다음 노드의 컨텍스트로 자동 주입되어, 명시적인 데이터 전달 로직 없이도 워크플로우가 구성됩니다.

enhancer_agent.py 구현

"""
Enhancer Agent - 분석 결과를 상세한 UI/UX 명세로 확장
"""
from strands import Agent

def create_enhancer_agent():
    """Enhancer 에이전트 생성"""
    
    system_prompt = """
You are a UI/UX specification writer.

You receive analysis results and must create detailed 300-500 word specifications.

Include:
1. Complete feature descriptions
2. UI/UX requirements (layout, spacing, typography, colors)
3. Form validation rules and error messages
4. State management (loading, error, success states)
5. Accessibility requirements (ARIA labels, keyboard navigation)
6. Responsive design considerations
7. Shadcn UI component styling patterns

Write in clear, implementable language.
"""
    
    return Agent(
        model="us.anthropic.claude-sonnet-4-5-20250929-v1:0",
        system_prompt=system_prompt,
        provider="bedrock"
    )

프롬프트 엔지니어링 과제

시스템 프롬프트 최적화는 반복적인 실험을 통해 이루어졌습니다. 초기 버전은 지나치게 간결하여 출력 품질이 낮았고, 과도하게 상세한 버전은 AI가 핵심 요구사항을 누락하는 문제가 발생했습니다.

여러 차례의 A/B 테스트를 통해 최적화된 프롬프트 구조:

  • 명확한 역할 정의: "You are a UI/UX specification writer"로 에이전트의 전문성 범위를 명시
  • 구조화된 요구사항: 7가지 포함 사항을 체크리스트 형태로 제시
  • 정량적 출력 제약: "300-500 word specifications"로 응답 길이 제어

세 번째 에이전트: Generator 구현

가장 중요한 에이전트

Generator는 실제 HTML을 생성하는 에이전트입니다. 여기서 실수하면 모든 게 무용지물이 되기 때문에 가장 신경 써서 만들었습니다.

generator_agent.py 구현

"""
Generator Agent - 상세 명세를 기반으로 완전한 HTML 생성
"""
from strands import Agent

def create_generator_agent():
    """Generator 에이전트 생성"""
    
    system_prompt = """
You are an expert HTML/CSS generator specializing in shadcn UI patterns.

Generate a complete, production-ready HTML file based on the provided specifications.

CRITICAL REQUIREMENTS:
1. WIDTH: Use max-w-[1440px] mx-auto container
2. TAILWIND CSS: Include CDN link
3. SHADCN STYLING: Follow shadcn UI design patterns with CSS variables
4. STRUCTURE: Use proper HTML5 semantic elements
5. RESPONSIVE: Mobile-first responsive design
6. ACCESSIBILITY: Include ARIA labels and semantic HTML
7. INTERACTIVE: Implement all states (hover, focus, active, disabled)
8. COMPLETE: Return ONLY the complete HTML, no explanations

The HTML must be immediately usable without any modifications.
"""
    
    return Agent(
        model="us.anthropic.claude-sonnet-4-5-20250929-v1:0",
        system_prompt=system_prompt,
        provider="bedrock"
    )

"ONLY HTML" 문제

초기 버전에서는 AI가 HTML 전후로 설명을 덧붙이는 문제가 있었습니다:

Here's the HTML file you requested:

<!DOCTYPE html>
<html>
...
</html>

I've implemented all the features you specified...

이런 식으로 나오면 파일로 저장할 때 문제가 됩니다. 그래서 프롬프트에 "Return ONLY the complete HTML, no explanations"를 명확히 추가했습니다.

코드 블록 제거 로직

그래도 가끔 AI가 html 로 감싸서 보내는 경우가 있어서, 후처리 코드를 추가했습니다:

def clean_html(html_content):
    """HTML 에서 마크다운 코드 블록 제거"""
    html_content = html_content.strip()
    
    # ```html 또는 ``` 제거
    html_content = re.sub(r'^```[a-zA-Z]*\s*\n?', '', html_content)
    html_content = re.sub(r'\n?```\s*$', '', html_content)
    
    # 혹시 모를 추가 ``` 제거
    while html_content.startswith('```'):
        html_content = html_content[3:].strip()
    while html_content.endswith('```'):
        html_content = html_content[:-3].strip()
    
    return html_content

작은 것 같지만, 이런 디테일이 사용자 경험을 크게 좌우합니다.

Strands Graph로 연결하기

워크플로우 통합

세 개의 독립적인 에이전트를 하나의 파이프라인으로 통합합니다. Strands의 Graph 패턴을 활용하여 에이전트 간 의존성을 선언적으로 정의했습니다.

from strands.multiagent import GraphBuilder

def main():
    # 에이전트 생성
    analyzer = create_analyzer_agent()
    enhancer = create_enhancer_agent()
    generator = create_generator_agent()
    
    # Graph 빌더 생성
    builder = GraphBuilder()
    
    # 노드 추가
    builder.add_node(analyzer, "analyzer")
    builder.add_node(enhancer, "enhancer")
    builder.add_node(generator, "generator")
    
    # 엣지(의존성) 추가
    builder.add_edge("analyzer", "enhancer")
    builder.add_edge("enhancer", "generator")
    
    # 시작점 설정
    builder.set_entry_point("analyzer")
    
    # 타임아웃 설정 (10분)
    builder.set_execution_timeout(600)
    
    # 그래프 빌드
    graph = builder.build()
    
    return graph

통합 검증

graph = main()
result = graph("login screen")

Graph 실행 결과:

[SUCCESS] Graph execution completed
[INFO] Executed 3/3 nodes
[INFO] Execution time: 52430ms

검증 결과: 모든 에이전트가 순차적으로 실행되어 완전한 HTML 파일을 생성했습니다. Analyzer의 분석 → Enhancer의 명세 확장 → Generator의 HTML 생성 파이프라인이 정상 작동함을 확인했습니다.

생성된 HTML 파일을 브라우저에서 검증한 결과, 로그인 화면이 의도한 대로 렌더링되며 기능적 요구사항을 충족함을 확인했습니다.

파일 저장 로직 구현

시맨틱 파일명 생성 전략

출력 파일의 추적성과 관리 효율성을 위해 컨텍스트 기반 파일명 생성 로직을 구현했습니다.

import json
from datetime import datetime

def save_html(result, output_dir="output"):
    """HTML을 의미 있는 파일명으로 저장"""
    
    # output 디렉토리 생성
    os.makedirs(output_dir, exist_ok=True)
    
    # Analyzer 결과에서 screen_type 추출
    analyzer_result = result.results.get("analyzer")
    screen_type = "prototype"  # 기본값
    
    if analyzer_result:
        try:
            analyzer_text = str(analyzer_result.result.message.content[0].text)
            analyzer_data = json.loads(analyzer_text)
            screen_type = analyzer_data.get("screen_type", "prototype")
            screen_type = screen_type.lower().replace(" ", "_")
        except:
            pass  # 파싱 실패시 기본값 사용
    
    # 타임스탬프 생성
    timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
    
    # 파일명 조합
    filename = f"{screen_type}_{timestamp}.html"
    filepath = os.path.join(output_dir, filename)
    
    # HTML 추출 및 정리
    generator_result = result.results.get("generator")
    html_content = str(generator_result.result.message.content[0].text)
    html_content = clean_html(html_content)
    
    # 파일 저장
    with open(filepath, "w", encoding="utf-8") as f:
        f.write(html_content)
    
    return filepath

생성 예시: login_20250130_123045.html - 화면 타입과 타임스탬프를 조합하여 파일의 목적과 생성 시점을 명확히 식별할 수 있습니다.

중간 산출물 보존 전략

디버깅과 품질 개선을 위해 Enhancer의 출력(상세 명세)을 별도 파일로 보존하는 로직을 추가했습니다:

def save_enhanced_prompt(result, filepath):
    """Enhanced prompt를 텍스트 파일로 저장"""
    enhancer_result = result.results.get("enhancer")
    if enhancer_result:
        enhanced_prompt = str(enhancer_result.result.message.content[0].text)
        
        # HTML 파일명에서 .html을 _prompt.txt로 변경
        prompt_filepath = filepath.replace(".html", "_prompt.txt")
        
        with open(prompt_filepath, "w", encoding="utf-8") as f:
            f.write(enhanced_prompt)
        
        return prompt_filepath
    return None

사용자 인터페이스 개선

진행 상황 피드백 구현

초기 버전에서는 워크플로우 실행 중 사용자에게 아무런 피드백이 제공되지 않았습니다. 이는 사용자 경험 측면에서 다음과 같은 문제를 야기했습니다:

  • 현재 진행 상태에 대한 정보 부재
  • 예상 소요 시간에 대한 불확실성
  • 프로세스 중단 여부 판단 불가

진행 상황 피드백 로직을 구현하여 사용자 가시성을 확보했습니다:

def main():
    print("=" * 60)
    print("Enhanced HTML Prototype Generator (Graph Pattern)")
    print("=" * 60)
    print("\nThis tool uses Strands Graph pattern for workflow execution:")
    print("1. Analyze prompt - Extract screen type and features")
    print("2. Enhance prompt - Add detailed specifications")
    print("3. Generate HTML - Create final prototype")
    print("\n" + "=" * 60)
    
    # 사용자 입력
    print("\nEnter your prompt (e.g., 'login screen', 'dashboard'):")
    user_prompt = input("> ").strip()
    
    if not user_prompt:
        print("[ERROR] Please provide a prompt")
        return
    
    print(f"\n{'=' * 60}")
    print(f"Processing: '{user_prompt}'")
    print("=" * 60)
    
    print("\n[INFO] Building workflow graph...")
    graph = build_graph()
    
    print("[INFO] Executing graph workflow...")
    print("[INFO] This may take 30-60 seconds...\n")
    
    result = graph(user_prompt)
    
    # 결과 처리...

UX 개선 효과: 워크플로우 단계별 진행 상황을 실시간으로 제공하여 사용자의 대기 시간에 대한 불확실성을 해소했습니다.

예외 처리 전략

프로덕션 환경에서 다양한 예외 상황이 발생할 수 있습니다:

try:
    result = graph(user_prompt)
    
    if result.status.value != "COMPLETED":
        print(f"[ERROR] Graph execution failed with status: {result.status}")
        return
    
    # 성공 처리...
    
except KeyboardInterrupt:
    print("\n\n[CANCELLED] Operation cancelled by user")
except Exception as e:
    print(f"\n\n[ERROR] {e}")
    import traceback
    traceback.print_exc()

예외 처리 설계:

  • KeyboardInterrupt: 사용자의 명시적 중단 요청 처리
  • 일반 Exception: 예상치 못한 오류에 대한 상세 진단 정보 제공

실제 테스트와 개선

통합 테스트 수행

개발 완료 후 다양한 시나리오에서 시스템 동작을 검증했습니다:

테스트 1: "login screen"

  • 결과: ✅ 성공
  • HTML이 깔끔하게 생성됨

테스트 2: "dashboard with charts"

  • 결과: ⚠️ 부분 성공
  • 차트가 플레이스홀더로만 나옴 (실제 차트 라이브러리는 안 쓰고)
  • → 이건 의도한 대로. 프로토타입이니까

테스트 3: "signup form"

  • 결과: ✅ 성공
  • validation 로직도 잘 들어감

테스트 4: "asdfasdf" (무의미한 입력)

  • 결과: ❌ 실패
  • Analyzer가 혼란스러워함
  • → 입력 검증 필요

입력 검증 구현

테스트 결과를 바탕으로 입력 검증 로직을 추가했습니다:

def validate_prompt(prompt):
    """프롬프트가 유효한지 검증"""
    if len(prompt) < 3:
        return False, "Prompt too short. Please be more specific."
    
    if len(prompt) > 200:
        return False, "Prompt too long. Please be more concise."
    
    # 일부 의미 있는 단어가 있는지 확인
    meaningful_words = ["screen", "page", "form", "dashboard", "login", "signup", "profile"]
    if not any(word in prompt.lower() for word in meaningful_words):
        print("[WARNING] Your prompt might be too vague. Consider being more specific.")
    
    return True, None

# main에서 사용
is_valid, error_message = validate_prompt(user_prompt)
if not is_valid:
    print(f"[ERROR] {error_message}")
    return

검증 전략: 길이 제약과 키워드 기반 휴리스틱을 조합하여 기본적인 입력 품질을 보장합니다. 더 정교한 검증을 위해서는 LLM 기반 의미 분석이 필요할 수 있습니다.

성능 최적화

타임아웃 최적화

초기 타임아웃 설정(180초)은 복잡한 프롬프트 처리 시 제한적이었습니다.

builder.set_execution_timeout(600)  # 10분으로 증가

타임아웃 전략: 네트워크 지연, LLM 응답 시간 변동성, 프롬프트 복잡도를 고려하여 600초로 설정했습니다. 이는 99 퍼센타일 응답 시간을 수용할 수 있는 값입니다.

비용 효율성 분석

AWS Bedrock의 토큰 기반 과금 모델에 따른 비용 분석을 수행했습니다.

에이전트별 토큰 소비량:

  • Analyzer: 1,000-1,500 토큰
  • Enhancer: 3,000-4,000 토큰
  • Generator: 5,000-7,000 토큰
  • 총합: 9,000-12,000 토큰

비용 분석: Claude 4.5 Sonnet의 가격 정책 기준, 프로토타입당 약 $0.05-0.10의 비용이 발생합니다. 이는 프로토타입 생성 도구로서 합리적인 수준의 운영 비용입니다.

프로젝트 마무리

문서화 전략

프로젝트 문서화는 장기 유지보수성의 핵심입니다. README에 다음 정보를 체계적으로 구성했습니다:

  1. 프로젝트 개요: 목적, 핵심 기능, 사용 사례
  2. 설치 방법: 환경 구성, 의존성 설치, 인프라 설정
  3. 사용 방법: CLI 인터페이스, 파라미터 설명, 예제 실행
  4. 아키텍처 설명: 시스템 구조, 에이전트 역할, 데이터 흐름
  5. 트러블슈팅: 일반적인 문제와 해결 방법

문서화 원칙: 신규 개발자가 6개월 후에도 프로젝트를 이해하고 수정할 수 있도록 기술적 맥락과 설계 의도를 상세히 기록했습니다.

requirements.txt 정리

개발 중에 테스트로 설치한 패키지들을 정리하고, 실제로 필요한 것만 남겼습니다:

pip freeze > requirements_full.txt  # 전체 목록 백업
# 필요한 것만 선별
cat > requirements.txt << EOF
strands>=0.1.0
boto3>=1.34.0
anthropic>=0.42.0
EOF

핵심 교훈

1. 점진적 개발 방법론의 중요성

프로젝트 초기 단계에서 완벽한 설계를 추구하기보다, 핵심 컴포넌트(Analyzer)부터 구현을 시작하는 것이 효과적이었습니다. 이는 다음과 같은 이점을 제공했습니다:

  • 실제 구현을 통한 요구사항 검증
  • 조기 피드백을 통한 설계 개선
  • 프로젝트 진행 동력 확보

2. 단위별 검증의 효율성

모놀리식 개발 대신 컴포넌트별 독립 테스트 전략을 채택했습니다:

  • 각 에이전트 구현 직후 즉시 검증
  • 문제 발생 시 범위 격리를 통한 신속한 디버깅
  • 점진적 통합을 통한 리스크 최소화

3. 프롬프트 엔지니어링의 반복적 특성

시스템 프롬프트 최적화는 본질적으로 반복적인 프로세스입니다:

  • 초기 버전은 불완전할 수밖에 없음
  • 10-20회의 반복을 통한 점진적 개선
  • A/B 테스트를 통한 객관적 품질 측정

4. 사용자 중심 에러 처리

기술적으로 정확한 에러 메시지와 사용자 친화적인 에러 메시지는 다릅니다:

  • 개발자: 스택 트레이스, 디버그 정보 필요
  • 사용자: 문제의 원인과 해결 방법 필요
  • 두 가지 레벨의 에러 정보 제공이 이상적

5. 동시 문서화의 필요성

사후 문서화는 실패 확률이 높습니다:

  • 개발 중 실시간 문서 작성이 효율적
  • 설계 의도와 기술적 맥락이 신선한 시점에 기록
  • 미래의 유지보수 비용 대폭 절감

6. 멀티 에이전트 아키텍처의 이점

각 에이전트의 전문화된 역할 분담은 다음을 가능하게 합니다:

  • 명확한 책임 분리 (Separation of Concerns)
  • 독립적인 컴포넌트 개선
  • 시스템 전체의 일관된 품질 유지
  • 팀 협업 패턴과 유사한 구조

7. 클라우드 서비스 초기 구성의 중요성

AWS Bedrock과 같은 클라우드 서비스는 강력한 기능을 제공하지만:

  • IAM 정책, 모델 접근 권한 등 초기 설정이 복잡
  • 체크리스트 기반 구성 검증으로 시행착오 최소화
  • 철저한 문서 검토가 개발 시간 단축의 핵심

프로덕션 환경 문제 해결

문제 1: HTML 렌더링 오류

증상: 생성된 HTML의 레이아웃 깨짐 또는 스타일 미적용

원인 분석: Generator 프롬프트의 모호성으로 인해 AI가 필수 의존성(Tailwind CDN) 누락 또는 CSS 변수 오용

해결 방안:

# 시스템 프롬프트를 더 구체적으로
"""
CRITICAL REQUIREMENTS:
1. Always include Tailwind CSS CDN
2. Use proper CSS variables for shadcn themes
3. Include all necessary <meta> tags
...
"""

적용 전략: 프롬프트에 "CRITICAL" 키워드를 사용하여 필수 요구사항의 우선순위를 명시적으로 표현했습니다.

문제 2: 실행 타임아웃

증상: 복잡한 프롬프트 처리 시 execution timeout 오류 발생

원인 분석: 기본 타임아웃(180초)이 복잡한 시나리오에 불충분

해결 방안:

builder.set_execution_timeout(600)  # 10분으로 증가

설정 근거: 네트워크 지연, 프롬프트 복잡도, LLM 응답 시간 변동성을 고려하여 충분한 여유를 확보했습니다.

문제 3: 비의미적 파일명

증상: 모든 출력 파일이 output_TIMESTAMP.html 형식으로 저장됨

원인 분석: Analyzer 출력의 screen_type 파싱 실패

해결 방안:

try:
    analyzer_data = json.loads(analyzer_text)
    screen_type = analyzer_data.get("screen_type", "prototype")
    screen_type = screen_type.lower().replace(" ", "_")
except Exception as e:
    print(f"[WARNING] Could not parse screen type: {e}")
    screen_type = "prototype"  # 안전한 기본값

개선 효과: 강건한 예외 처리와 명확한 기본값 정의로 파일 추적성을 확보했습니다.

문제 4: AWS 인증 실패

증상: Unable to authenticate with AWS Bedrock 오류

진단 체크리스트:

  1. ✅ AWS CLI 설치 확인 (aws --version)
  2. ✅ AWS 자격 증명 구성 (aws configure)
  3. ✅ Region 설정 (us-east-1)
  4. ✅ Bedrock 모델 접근 권한 활성화 확인
  5. ✅ IAM 권한 검증 (bedrock:InvokeModel)

해결 프로토콜: 체크리스트를 순차적으로 검증하여 인증 문제의 근본 원인을 식별합니다.

문제 5: 응답 시간 지연

원인 분석: 과도하게 상세한 시스템 프롬프트와 중간 출력

최적화 전략:

  1. 시스템 프롬프트 리팩토링 (핵심 요구사항 중심)
  2. Enhancer 출력 길이 제약 (300-500 단어)
  3. 불필요한 중간 로깅 제거

성능 개선 결과: 평균 응답 시간 45초 → 30초 (33% 개선)

아키텍처 대안 분석

프로젝트 설계 과정에서 단일 에이전트 대 멀티 에이전트 아키텍처를 비교 검토했습니다.

단일 에이전트 아키텍처 (실험)

# 모든 기능을 하나의 프롬프트로 처리
single_agent = Agent(
    model="claude-4.5-sonnet",
    system_prompt="""
    You are an HTML generator.
    Analyze the user's request, create detailed specs, and generate HTML.
    Include all the features...
    """
)

평가 결과:

  • ❌ 워크플로우 단계 누락 (분석 생략 → 직접 HTML 생성)
  • ❌ 일관성 없는 출력 품질
  • ❌ 디버깅 복잡도 증가 (단계별 검증 불가)

멀티 에이전트 아키텍처 (채택)

이점:

  • ✅ 명확한 워크플로우 단계 분리
  • ✅ 중간 산출물 검증 가능
  • ✅ 독립적 컴포넌트 개선
  • ✅ 일관된 품질 보장

결론: 초기 구현 복잡도가 높지만, 장기적 유지보수성과 확장성 측면에서 멀티 에이전트 아키텍처가 우수합니다.

향후 개선 로드맵

현재 시스템은 MVP(Minimum Viable Product) 단계이며, 다음 개선 사항을 계획하고 있습니다:

1. UI 라이브러리 확장

현황: shadcn UI 단독 지원
목표: 다중 UI 라이브러리 지원

  • Material UI
  • Chakra UI
  • Ant Design

구현 전략: 라이브러리별 전문화된 Generator 에이전트 개발

2. 실시간 프리뷰 기능

목표: 생성 즉시 브라우저 자동 실행

import webbrowser

def preview_html(filepath):
    """생성된 HTML을 브라우저로 열기"""
    webbrowser.open(f"file://{os.path.abspath(filepath)}")

3. 버전 관리 시스템

목표: 동일 프롬프트의 다중 버전 생성 및 비교

output/
  login_v1_20250130.html
  login_v2_20250130.html
  login_v3_20250130.html

4. 자동화된 반응형 테스트

목표: 다양한 뷰포트에서 자동 검증

  • Desktop (1920x1080)
  • Tablet (768x1024)
  • Mobile (375x667)

도구: Playwright를 활용한 스크린샷 자동 캡처

5. 품질 보증 에이전트

목표: 생성된 HTML의 자동 품질 검사

  • HTML 표준 준수 검증
  • 접근성 체크 (WCAG)
  • 성능 점수 측정
  • SEO 모범 사례 평가

아키텍처: 독립적인 Validator 에이전트 추가

실제 활용 사례

프로덕션 환경에서의 시스템 활용 사례를 공유합니다:

사례 1: 신속한 프로토타이핑

시나리오: 클라이언트 미팅에서 즉각적인 시각적 피드백 필요

기존 워크플로우: Figma 디자인 → HTML 변환 (1일 소요)

개선된 워크플로우:

> dashboard with sales charts and user table

결과: 30초 만에 인터랙티브 프로토타입 생성 및 즉시 피드백 획득

ROI: 프로토타이핑 시간 96% 단축

사례 2: 디자인 대안 평가

시나리오: A/B 테스팅을 위한 다중 디자인 변형 생성

> modern minimalist login screen
> colorful playful login screen
> professional corporate login screen

결과: 3가지 변형을 2분 내 생성하여 팀 리뷰 진행

이점: 의사결정 속도 향상 및 디자인 다양성 확보

사례 3: 기술 학습 도구

시나리오: 새로운 UI 패턴 습득

> complex dashboard with sidebar navigation and nested cards

학습 효과:

  • shadcn UI 구현 패턴의 실제 예제 획득
  • 코드 리뷰를 통한 베스트 프랙티스 학습
  • 즉각적인 실험 및 반복 학습 가능

결론

본 프로젝트를 통해 멀티 에이전트 시스템의 실무 구현 경험을 축적했습니다.

기술적 성과:

  • Strands Graph 패턴을 활용한 워크플로우 오케스트레이션
  • AWS Bedrock/Claude 모델의 프로덕션 통합
  • 프롬프트 엔지니어링 방법론 확립
  • 에이전트 간 데이터 파이프라인 설계

프로세스 개선:

  • 점진적 개발을 통한 리스크 관리
  • 실사용 피드백 기반 반복 개선
  • 동시 문서화를 통한 지식 보존

핵심 인사이트: AI 기반 자동화 도구의 실용적 구현 가능성을 검증했으며, 멀티 에이전트 아키텍처가 복잡한 생성 작업에 효과적임을 확인했습니다.

이 글이 유사한 시스템 구축을 계획하는 엔지니어들에게 실질적인 참고 자료가 되기를 바랍니다.


참고 자료


시리즈 전체 보기:

  • 1편: 개념과 아키텍처 ← 멀티 에이전트 시스템이 무엇인지 궁금하다면
  • 2편: 직접 만들어보기 (현재 글) ← 구현 과정과 실제 코드가 궁금하다면

Happy coding! 🚀

Clickable cat