# Phase 10: 킬러 피처 — Speakly를 넘어서 > Speakly가 제공하지 않는 D3RO-VOICE 고유 기능. > 완전 로컬이라는 강점을 극대화하여 차별화된 사용자 경험을 제공한다. --- ## 10.1 실시간 자막 모드 (Live Caption) ### 목표 핫키 없이 마이크를 계속 듣고, 화면 하단에 실시간 자막을 오버레이로 표시한다. 회의/강의/영상 시청 시 자동 자막 + 회의록 자동 생성. ### 구현 방안 - **Streaming Transcription**: Whisper의 VAD(Voice Activity Detection) 기반 세그먼트 분할 - 오디오를 5~10초 청크로 분할, 이전 컨텍스트를 initialPrompt로 전달 - 침묵 감지(500ms 이상) 시 세그먼트 확정 → 다음 세그먼트 시작 - **오버레이 윈도우**: 항상 최상위(alwaysOnTop), 반투명 배경, 화면 하단 고정 - Vanilla JS 팝업 (React 번들 불필요, 빠른 렌더링) - 최근 3줄 표시, 오래된 줄은 페이드아웃 - 위치/크기 드래그로 조정 가능 - **회의록 저장**: 모든 세그먼트를 타임스탬프와 함께 히스토리에 자동 저장 - 세션 종료 시 전체 텍스트를 마크다운으로 내보내기 가능 - 화자 분리(speaker diarization)는 Phase 10+ (Whisper 자체 미지원, 추후 pyannote 등 연동) ### 필요 서비스 - `LiveCaptionService` (신규): 스트리밍 전사 오케스트레이션 - `AudioCaptureService`: 지속 캡처 모드 추가 (기존 세션 모드와 별도) - `LocalSTTService`: 스트리밍 전사 API 추가 (청크 단위 transcribe) - `WindowManager`: LiveCaptionWindow 프리로딩 + 관리 ### IPC 채널 | 채널 | 방향 | 설명 | |------|------|------| | `caption:start` | handle | 실시간 자막 시작 | | `caption:stop` | handle | 실시간 자막 종료 | | `caption:getState` | handle | 자막 상태 조회 (active/inactive) | | `caption:setPosition` | handle | 오버레이 위치 설정 | | `caption:segment` | send | 확정된 자막 세그먼트 (main→renderer) | | `caption:delta` | send | 중간 전사 결과 (main→renderer) | | `caption:sessionSaved` | send | 회의록 저장 완료 | ### UI 컴포넌트 - **LiveCaptionWindow** (Vanilla JS 팝업): 오버레이 자막 표시 - **CaptionControlBar**: 트레이 메뉴 또는 Dashboard에 시작/정지 토글 - **CaptionHistoryView**: 저장된 회의록 열람 (HistoryPage 확장) ### 우선순위: **1순위** (가장 차별화되는 기능) --- ## 10.2 스크린 컨텍스트 (Screen Context) ### 목표 활성 앱 이름 + 선택된 텍스트를 LLM 프롬프트에 함께 전달하여 컨텍스트 인식 처리. 예: VS Code에서 코드 선택 후 "이거 설명해줘" → 코드+음성 합쳐서 LLM 처리. ### 구현 방안 - **활성 윈도우 감지**: Windows UI Automation API 또는 `@electron/windows-utils` - 활성 앱 프로세스명, 윈도우 타이틀 가져오기 - `GetForegroundWindow()` + `GetWindowText()` + `GetModuleFileName()` - **선택 텍스트 가져오기**: 두 가지 전략 1. **클립보드 방식** (안전): Ctrl+C 시뮬레이션 → 클립보드에서 읽기 → 원본 복원 2. **UI Automation** (고급): IUIAutomation의 TextPattern으로 직접 읽기 - 초기에는 클립보드 방식, 추후 UI Automation으로 고도화 - **LLM 프롬프트 주입**: VoiceModeService에서 컨텍스트를 시스템 프롬프트에 삽입 ``` [컨텍스트] 활성 앱: Visual Studio Code 활성 파일: src/main/services/VoiceModeService.ts 선택된 텍스트: ```typescript private tryFlushAll(): void { ... } ``` [사용자 음성] 이 함수가 뭐하는 건지 설명해줘 ``` - **앱별 프롬프트 커스텀**: 앱 이름에 따라 다른 시스템 프롬프트 적용 - VS Code → "코드 관련 질문입니다" - Chrome → "웹 페이지 내용 관련 질문입니다" - 일반 → "텍스트 관련 질문입니다" ### 필요 서비스 - `ContextService` (신규): 활성 윈도우 + 선택 텍스트 캡처 - `LocalLLMService`: 컨텍스트 주입 시스템 프롬프트 확장 - `VoiceModeService`: 녹음 시작 시 자동 컨텍스트 캡처 - `ConfigService`: 앱별 컨텍스트 설정 저장 ### IPC 채널 | 채널 | 방향 | 설명 | |------|------|------| | `context:getActiveApp` | handle | 활성 앱 정보 조회 | | `context:getSelectedText` | handle | 선택된 텍스트 가져오기 | | `context:setAppConfig` | handle | 앱별 컨텍스트 설정 | | `context:getAppConfigs` | handle | 앱별 설정 목록 | ### UI 컴포넌트 - **ContextIndicator**: StatusBar에 현재 활성 앱 + 컨텍스트 상태 표시 - **ContextSettingsTab**: Settings에 앱별 프롬프트 커스텀 UI - **RecordingTip 확장**: 컨텍스트 캡처 상태 아이콘 표시 ### 우선순위: **2순위** (실용성 높음, 코드 작업 시 매우 유용) --- ## 10.3 음성 메모장 (Voice Memo) ### 목표 전사 결과를 카테고리별로 자동 정리하는 전용 메모 시스템. 태그, 마크다운 내보내기, 검색, 필터 지원. ### 구현 방안 - **태그 시스템**: `#회의`, `#아이디어`, `#할일`, `#메모` 등 해시태그 자동 감지 - 전사 텍스트에서 `#단어` 패턴 추출 - LLM 자동 태그 제안 (선택적): 텍스트 내용 분석 → 태그 추천 - 수동 태그 추가/편집 - **카테고리 자동 분류**: LLM 기반 또는 키워드 기반 - "할 일", "해야 할 것" → `#할일` 자동 태그 - "아이디어", "생각" → `#아이디어` 자동 태그 - **마크다운 내보내기**: 태그별/날짜별 그룹핑된 마크다운 파일 생성 ```markdown # 음성 메모 — 2026-04-05 ## #회의 - 10:30 AM: 프로젝트 킥오프 미팅에서 논의한 내용... - 02:15 PM: 디자인 리뷰 피드백... ## #할일 - 11:00 AM: Phase 10 설계서 작성할 것 ``` - **DB 확장**: memo 테이블 또는 history 테이블에 태그 컬럼 추가 ```sql CREATE TABLE memo_tags ( id TEXT PRIMARY KEY, history_id TEXT NOT NULL REFERENCES history(id), tag TEXT NOT NULL, created_at INTEGER NOT NULL ); CREATE INDEX idx_memo_tags_tag ON memo_tags(tag); ``` ### 필요 서비스 - `MemoService` (신규): 메모 CRUD + 태그 관리 + 내보내기 - `HistoryService`: 태그 연동 확장 - `LocalLLMService`: 자동 태그 제안 (선택적) ### IPC 채널 | 채널 | 방향 | 설명 | |------|------|------| | `memo:getTags` | handle | 전체 태그 목록 | | `memo:setTags` | handle | 히스토리 항목에 태그 설정 | | `memo:getByTag` | handle | 태그별 메모 조회 | | `memo:export` | handle | 마크다운 내보내기 | | `memo:suggestTags` | handle | LLM 기반 태그 자동 제안 | ### UI 컴포넌트 - **MemoPage**: 사이드바에 MEMO 탭 추가, 태그 클라우드 + 메모 목록 - **TagEditor**: 태그 추가/삭제 인라인 편집 (Chip 기반) - **MemoExportDialog**: 내보내기 범위/포맷 선택 ### 우선순위: **3순위** (히스토리 확장, 비교적 단순) --- ## 10.4 멀티 LLM 체인 (Multi-LLM Chain) ### 목표 여러 LLM 명령어를 순차 실행하는 파이프라인 기능. 예: 전사 → 번역 → 요약을 한번의 핫키로 실행. ### 구현 방안 - **파이프라인 정의**: CustomInstruction에 chain 기능 추가 ```typescript interface InstructionChain { id: string; name: string; steps: ChainStep[]; hotkey?: HotkeyBinding; } interface ChainStep { instructionId: string; // 기존 CustomInstruction ID 참조 inputSource: 'previous' | 'original'; // 이전 단계 결과 or 원본 options?: { targetLanguage?: string; temperature?: number; }; } ``` - **실행 엔진**: VoiceModeService에서 체인 실행 1. 전사 완료 → 첫 번째 명령어 실행 2. 결과 → 두 번째 명령어의 입력으로 전달 3. ... → 최종 결과를 텍스트 삽입 - 각 단계 진행 상황을 RecordingTip에 표시 - 중간 취소 가능 (현재 단계 완료 후 중단) - **파이프라인 에디터**: 드래그 앤 드롭으로 단계 구성 - 기존 명령어 목록에서 드래그하여 체인에 추가 - 화살표로 단계 간 연결 시각화 - 테스트 실행: 샘플 텍스트로 체인 전체 실행 결과 미리보기 ### 필요 서비스 - `ChainExecutionService` (신규): 체인 실행 엔진 - `CustomInstructionService`: chain 저장/관리 확장 - `LocalLLMService`: 순차 호출 + 이전 결과 컨텍스트 전달 - `VoiceModeService`: 체인 모드 추가 ### IPC 채널 | 채널 | 방향 | 설명 | |------|------|------| | `chain:getAll` | handle | 체인 목록 조회 | | `chain:create` | handle | 체인 생성 | | `chain:update` | handle | 체인 수정 | | `chain:delete` | handle | 체인 삭제 | | `chain:execute` | handle | 체인 수동 실행 (텍스트 입력) | | `chain:progress` | send | 체인 실행 진행 상황 (현재 단계/총 단계) | ### UI 컴포넌트 - **ChainEditorPage**: 파이프라인 에디터 (CommandsPage 확장 또는 별도 탭) - **ChainStepCard**: 각 단계 카드 (명령어 이름 + 설정) - **ChainPreview**: 체인 실행 결과 미리보기 ### 우선순위: **4순위** (고급 기능, 파워 유저 대상) --- ## 10.5 음성 단축키 (Voice Command) ### 목표 녹음 시작 후 "번역해줘", "요약해줘" 같은 음성 키워드로 명령어를 자동 선택. 핫키 없이 음성만으로 명령어 전환 가능. ### 구현 방안 - **키워드 매칭**: Whisper 전사 결과에서 첫 N초(3초) 또는 첫 문장에서 키워드 탐색 ```typescript interface VoiceCommand { id: string; keywords: string[]; // ["번역해줘", "번역", "translate"] instructionId: string; // 연결된 CustomInstruction triggerPosition: 'start' | 'end' | 'any'; // 키워드 위치 } // 매칭 로직 function matchVoiceCommand(text: string, commands: VoiceCommand[]): VoiceCommand | null { for (const cmd of commands) { for (const keyword of cmd.keywords) { if (text.startsWith(keyword) || text.includes(keyword)) { return cmd; } } } return null; } ``` - **키워드 제거**: 매칭된 키워드를 전사 텍스트에서 제거 후 LLM에 전달 - "이 코드 설명해줘" → 키워드 "설명해줘" 제거 → "이 코드"를 LLM에 전달 - 키워드가 문장 시작/끝에 있을 때만 제거 (중간은 유지) - **프리셋 키워드**: 기본 명령어에 기본 키워드 매핑 - 번역: "번역해줘", "번역", "translate", "영어로" - 요약: "요약해줘", "요약", "summarize" - 다듬기: "다듬어줘", "다듬기", "polish" - 설명: "설명해줘", "explain" - **커스텀 키워드 등록**: Settings에서 명령어별 키워드 편집 ### 필요 서비스 - `VoiceCommandService` (신규): 키워드 매칭 + 명령어 라우팅 - `VoiceModeService`: 전사 완료 후 키워드 매칭 → 명령어 자동 선택 - `CustomInstructionService`: 명령어별 키워드 저장 - `ConfigService`: 음성 단축키 on/off 설정 ### IPC 채널 | 채널 | 방향 | 설명 | |------|------|------| | `voiceCommand:getAll` | handle | 음성 명령어 목록 | | `voiceCommand:setKeywords` | handle | 명령어별 키워드 설정 | | `voiceCommand:setEnabled` | handle | 음성 단축키 활성화/비활성화 | | `voiceCommand:matched` | send | 키워드 매칭 알림 (어떤 명령어가 선택됐는지) | ### UI 컴포넌트 - **VoiceCommandSettings**: Settings에 음성 단축키 탭 또는 섹션 - **KeywordEditor**: 명령어별 키워드 목록 편집 (Chip 입력) - **RecordingTip 확장**: 키워드 감지 시 선택된 명령어 아이콘 표시 ### 우선순위: **5순위** (UX 개선, 키워드 정확도 검증 필요) --- ## 구현 우선순위 요약 | 순위 | 피처 | 난이도 | 임팩트 | 의존성 | |------|------|--------|--------|--------| | 1 | 실시간 자막 | 높음 | 매우 높음 | STT 스트리밍 | | 2 | 스크린 컨텍스트 | 중간 | 높음 | Windows API | | 3 | 음성 메모장 | 낮음 | 중간 | DB 확장 | | 4 | 멀티 LLM 체인 | 중간 | 중간 | CustomInstruction 확장 | | 5 | 음성 단축키 | 낮음 | 중간 | STT 결과 후처리 | ### 권장 구현 순서 1. **10.3 음성 메모장** — 가장 단순, 기존 인프라 활용도 높음 2. **10.5 음성 단축키** — 키워드 매칭만 추가, VoiceModeService 확장 3. **10.2 스크린 컨텍스트** — Windows API 연동 필요하지만 기존 패턴 재사용 4. **10.4 멀티 LLM 체인** — 파이프라인 에디터 UI가 복잡 5. **10.1 실시간 자막** — 스트리밍 전사 + 오버레이 윈도우 = 가장 큰 작업량 --- ## Speakly 대비 차별점 | 기능 | Speakly | D3RO-VOICE | |------|---------|-----------| | 실시간 자막 | X | Phase 10.1 | | 스크린 컨텍스트 | 부분 (활성 앱명만) | Phase 10.2 (선택 텍스트 포함) | | 음성 메모장 | X | Phase 10.3 | | 멀티 LLM 체인 | X | Phase 10.4 | | 음성 단축키 | X | Phase 10.5 | | 완전 로컬 | X (클라우드 의존) | O (Ollama + Whisper) | | 커서 히스토리 팝업 | X | Phase 3.5 (이미 완료) | | Ctrl+Shift+C 커맨드 팝업 | X | Phase 9 (이미 완료) |