시스템 레이어
Input
Galaxy Buds
음성 입력
↓
STT
발화 → 텍스트
→
Router
Intent Router
맥락 분석
에이전트 선택
에이전트 선택
→
Sub-agents
Guardian
배터리 수호자
Archivist
아이디어 포착
Handover
기기 연결
Advisor
InsideOut 토론
→
Skills (도구)
📅 Calendar API
🗺️ Maps API
🔋 Battery API
💾 Notes DB
📡 BT Scanner
🤖 Gemma LLM
🧠 Memory DB
→
Output
ElevenLabs TTS
속삭임으로
Galaxy Buds에
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줄