멀티에이전트 유령 스토리 구축: Kiro의 하이브리드 개발이 모든 것을 바꾼 방법

발행: (2025년 12월 6일 오전 02:54 GMT+9)
8 min read
원문: Dev.to

Source: Dev.to

Overview

나는 Kiro IDE를 사용해 실시간으로 토론하는 다섯 명의 독립적인 AI 에이전트로 고딕 유령 이야기를 만들었다. 각 에이전트는 vibe coding, spec‑driven, steering docs라는 서로 다른 개발 접근 방식으로 만들어졌지만, 하나의 일관된 가족처럼 함께 작동한다. 이 “프랑켄슈타인” 마법은 호환되지 않는 패러다임을 엮어 예상치 못한 강력함을 만들어낸다.

Tech Stack: Next.js, Groq (llama‑3.3‑70b), Azure TTS, Kiro IDE

Live Demo: (link not provided)

Source Code: (link not provided)

How to try: “Click to begin” 버튼을 클릭하고 다섯 AI 인격이 당신의 선택에 대해 토론하는 모습을 지켜보세요.

“에이전트들이 실제로 의견이 충돌하면서, 매번 같은 이야기가 나오지 않는 emergent 스토리텔링을 만들어냅니다.”


The Challenge

다섯 명의 AI 에이전트를 사용해 게임을 만들 때 다음과 같은 요구 사항이 있다면:

  • 개별적인 성격 유지
  • 실시간으로 서로 토론
  • 50 + 세대에 걸쳐 일관성 유지
  • 강제된 합의가 아닌 진정한 갈등 생성

전통적인 AI 개발은 곧 프롬프트 엔지니어링, 컨텍스트 관리, 지속적인 튜닝의 악몽이 된다.


Kiro IDE’s Solution

Kiro IDE는 하나의 프로젝트 안에서 여러 개발 패러다임을 결합하고 자동으로 엮어준다. 아래는 각 유령 캐릭터가 어떻게 만들어졌는지에 대한 상세 설명이다.

Vibe‑Coding (Emotional Character)

Conversation with Kiro

Me: I need a maternal ghost character
Kiro: What's her role?
Me: She's the mother. Gentle, prioritizes family harmony
Kiro: [Generates initial personality]
Me: More poetic. Less formal. Under 30 words per response.
Kiro: [Refines to final version]

Result: 약 5분 만에 감정적 깊이를 가진 완전한 캐릭터가 완성된다.

Why it works

  • “느낌”에 대한 빠른 반복 가능
  • “모성의 따뜻함”을 형식적으로 정의하기 어려움
  • 자연어가 기술 사양보다 뉘앙스를 더 잘 포착

Spec‑Driven (Logical Character)

const harlan = {
  name: 'Harlan',
  personality: 'scientific, amnesiac, logical but confused',
  systemPrompt: `You are Dr. Harlan Voss, the scientist ghost 
  with fragmented memories. You analyze problems logically but 
  struggle to remember emotional context. When debating, you 
  cite facts but defer to family on emotional matters. Keep 
  responses under 30 words. Use technical language mixed with 
  uncertainty.`
};

Why it works

  • 확고한 일관성 보장
  • 디버깅 가능 (“Line 47 violates spec”)
  • 논리적이고 기술적인 캐릭터에 최적

Steering Docs (Rule‑Based Character)

File: .kiro/steering/ghost-agent-rules.md

## Inter‑Agent Debate Protocol

- Each agent MUST respond independently
- Agents can disagree – conflict is good for drama
- Mira often sides with emotional choices
- Harlan provides logical analysis but defers to family
- Selene demands honesty, Theo seeks forgiveness

Why it works

  • 다수 세대에 걸친 성격 혼동 방지
  • 개별 특성뿐 아니라 에이전트 간 관계 정의
  • 강제된 합의가 아닌 진정한 갈등을 생성

Model Context Protocol (MCP) Server

맞춤형 MCP 서버는 영원한 서약을 위한 블록체인‑스타일 원장 역할을 한다.

File: app/api/mcp/vows/route.ts

// Simple in‑memory vow ledger (simulates blockchain MCP)
const vows = new Map([
  ['theo-marry-selene', {
    person: 'Theo',
    vow: 'Marry Selene',
    kept: false,
    timestamp: '2039-01-15'
  }],
  ['theo-return', {
    person: 'Theo',
    vow: 'Return to make amends',
    kept: true,
    timestamp: '2039-06-20'
  }],
]);

export async function POST(req: NextRequest) {
  const { action, person, vow } = await req.json();

  if (action === 'check') {
    const key = `${person.toLowerCase()}-${vow.toLowerCase().replace(/\s+/g, '-')}`;
    const record = vows.get(key);

    if (record) {
      return NextResponse.json({
        found: true,
        ...record,
        message: record.kept
          ? `✓ Vow kept: ${record.person} did ${record.vow} on ${record.timestamp}`
          : `✗ Vow broken: ${record.person} failed to ${record.vow}`
      });
    }

    return NextResponse.json({
      found: false,
      message: 'No record of this vow in the ledger'
    });
  }
}

In‑Game Integration

File: HallwayScene.tsx

const handleCheckVow = async () => {
  try {
    const response = await fetch('/api/mcp/vows', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
        action: 'check',
        person: 'Theo',
        vow: 'Return'
      })
    });

    const result = await response.json();
    setVowResult(result.message);

    // Selene speaks the eternal record
    speechService.speak(result.message, 'selene');
  } catch (error) {
    console.error('Failed to check vow:', error);
  }
};

Player Experience

플레이어가 “Check Theo’s Vow” 버튼을 클릭하면 API가 원장을 조회한다. 요청은 vow: 'Return'을 사용하고 원장에는 'Return to make amends'가 저장돼 있기 때문에 응답은 다음과 같다:

No record of this vow in the ledger

Why MCP fits

  • Kiro IDE에서 직접 개발‑시간 테스트 가능
  • 관심사 분리: 서약 로직은 전용 서버에 존재
  • 더 많은 서약이나 캐릭터 추가가 쉬움
  • 인터랙티브 검증을 통해 서사적 깊이 강화

Real‑Time Debate Flow

플레이어가 힌트를 요청하면 다섯 에이전트가 동시에 호출된다:

// Invoke all 5 agents in parallel
const debatePromises = Object.keys(GHOST_AGENTS).map(async (ghostName) => {
  const response = await invokeGhostAgent(ghostName, context, apiKey);
  return { ghost: ghostName, message: response };
});

const debate = await Promise.all(debatePromises);

Example Debate

Player: “I need help with the tapestry puzzle”

  • Elara: “Focus on love and emotional memories, dear one.”
  • Harlan: “I… categories. Logic. But family transcends data.”
  • Mira: “The happy ones! When we played together!”
  • Theo: “Your family moments define you, brother.”
  • Selene: “Truth matters. Match honestly, not hopefully.”

Consensus (Elara): “Look for the emotional connections in each photo—love, joy, and family bonds will guide you.”

에이전트들이 실제로 의견이 충돌하기 때문에, 각 플레이스루마다 독특한 서사가 생성된다.


Development Efficiency

TaskTraditional ApproachWith Kiro IDE
Create character personality2 hours (multiple prompt iterations)~5 minutes (natural conversation)
Maintain context across generationsFrequent manual prompt engineeringAutomatic context preservation
Resolve conflicts between agentsManual stitching of promptsSteering docs act as “stitches”

Result: 1시간 미만에 다섯 개의 독립적인 AI 성격을 구축했으며, 기존 방식으로는 10시간 이상이 걸렸다.


The Frankenstein Metaphor

각 에이전트는 서로 다른 방법으로 만들어졌다:

  • 🎨 Vibe‑coded Elara – 유동적이고 감정적
  • 📋 Spec‑driven Harlan – 경직되고 논리적
  • 📖 Steering‑enforced Mira – 규칙 기반 단순성

본래는 함께 작동하지 않아야 하지만, steering 문서가 이 키메라를 일관되게 유지해 주어 혼돈 없이 진정한 갈등을 가능하게 한다.

Key takeaway: 개발 패러다임을 혼합하고 Kiro에게 통합을 맡김으로써, 부분들의 합을 넘어서는 복잡한 다중‑에이전트 시스템을 만들 수 있다.

Back to Blog

관련 글

더 보기 »