← 목록 W — 음성 AI 에이전트 플랫폼
강의자료 실습자료
아키텍처
시스템 레이어
Input
🎧
Galaxy Buds
음성 입력
↓
🎙️
STT
발화 → 텍스트
→
Router
🧭
Intent Router
맥락 분석
에이전트 선택
→
Sub-agents
🔋
Guardian
배터리 수호자
🗺️
Navigator
일정·경로 안내
📝
Archivist
아이디어 포착
📺
Handover
기기 연결
🧠
Advisor
InsideOut 토론
→
Skills (도구)
📅 Calendar API
🗺️ Maps API
🔋 Battery API
💾 Notes DB
📡 BT Scanner
🤖 Gemma LLM
🧠 Memory DB
→
Output
🎵
ElevenLabs TTS
속삭임으로
Galaxy Buds에

에이전트 카드를 클릭하면 담당 Skills와 트리거 조건을 확인할 수 있어요

라우터가 선택하는 조건

시나리오 시뮬레이터
어떤 상황인지 골라보세요
Router가 어떤 에이전트를 선택하고 어떤 Skills를 호출하는지 흐름을 볼 수 있어요
실행 흐름
코드 구조 구상
// router.js — 의도 파악 + 에이전트 선택
async function route(input, context) {
  const intent = await classifyIntent(input, context);
  // intent: { type, confidence, entities, needsDebate }

  if (intent.confidence < 0.6) {
    return { action: 'ask', question: '무엇을 도와드릴까요?' };
  }

  const agents = selectAgents(intent);
  return executeParallel(agents, intent.entities);
}

function selectAgents(intent) {
  const map = {
    'battery':  ['guardian'],
    'schedule': ['navigator'],
    'capture':  ['archivist'],
    'handover': ['handover'],
    'decision': ['advisor'],   // InsideOut 토론
    'commute':  ['navigator', 'guardian'],
  };
  return map[intent.type] ?? ['advisor'];
}
// agents/navigator.js
export const navigator = {
  name: 'Navigator',
  skills: ['calendar', 'maps', 'tts'],

  async run(entities, skills) {
    const events = await skills.calendar.getToday();
    const next   = events.find(e => e.location);
    if (!next) return null;
    const route  = await skills.maps.getETA(next.location);
    const text   = `${next.title}, ${route.minutes}분 후 출발하세요`;
    return skills.tts.whisper(text);
  }
};

// agents/advisor.js — InsideOut 토론 모드
export const advisor = {
  name: 'Advisor',
  skills: ['llm', 'memory', 'tts'],
  personas: ['elon', 'kahneman', 'zhuge'],

  async run(entities, skills) {
    const opinions = await Promise.all(
      this.personas.map(p => skills.llm.ask(p, entities.query))
    );
    const verdict = await skills.llm.synthesize(opinions);
    return skills.tts.whisper(verdict);
  }
};
// skills/index.js — Skill 레지스트리
export const SKILLS = {
  calendar: { getToday: () => fetchCalendar('today') },
  maps:     { getETA: (dest) => fetchMapsAPI(dest) },
  battery:  { getLevel: () => navigator.getBattery() },
  notes:    { save: (item) => db.insert('notes', item) },
  bluetooth:{ scan: () => bt.getNearbyDevices() },
  llm: {
    ask: (persona, prompt) => callGemma(persona, prompt),
    classify: (text, ctx) =>  callGemma('router', text, ctx),
    synthesize: (opinions) => callGemma('elon', opinions),
  },
  tts: {
    whisper: (text) => elevenLabsTTS(text, VOICE_ID),
  },
  memory: {
    get: (key) => auditoryMemory.recall(key),
    set: (key, val) => auditoryMemory.store(key, val),
  },
};

// 새 Skill 추가 = 한 줄
// SKILLS.weather = { getCurrent: () => fetchWeather() };
// server.js — 전체 실행 흐름
app.post('/api/voice', async (req, res) => {
  const { audioBlob, context } = req.body;

  // 1. STT
  const text = await STT.transcribe(audioBlob);

  // 2. Router → 에이전트 선택 + 실행
  const result = await route(text, {
    battery:  context.battery,
    calendar: await SKILLS.calendar.getToday(),
    time:     new Date(),
    devices:  context.nearbyDevices,
  });

  // 3. TTS 오디오 → Galaxy Buds로
  res.json({ audioBase64: result.audioBase64 });
});

// confidence < 0.6 → "무엇을 도와드릴까요?" 되묻기
// 새 에이전트 추가 = agents/ 파일 1개 + SKILLS 등록 1줄