- CLAUDE.md: 프로젝트 규칙, 기술 스택, 코딩 규칙, 페이즈 로드맵 - .claude/settings.json: 권한, 강제 훅 (매 프롬프트 설계서 규칙 주입) - .claude/skills/: implement-phase, review-phase, scaffold, test-commit, debug - .claude/agents/: electron-architect, voice-pipeline-expert, ui-specialist - docs/design/00-09: 마스터 아키텍처, 서비스 명세(16개), IPC(113채널), DB스키마, UI컴포넌트, 검증리포트, 외부엔진연동, 갭분석, VoiceMode패턴, 디자인시스템, 히스토리팝업 - docs/phases/1-7+3.5: 전체 구현 페이즈 문서 - docs/re-findings/: Speakly RE 노하우 5개 문서
115 lines
5.6 KiB
Markdown
115 lines
5.6 KiB
Markdown
# Phase 4: Ollama LLM 연동 (텍스트 다듬기, 번역)
|
|
|
|
## 목표
|
|
Ollama REST API를 통해 로컬 LLM과 연동하여, 전사된 텍스트를 다듬기(polishing)하거나 번역(translate)할 수 있는 상태. 스트리밍 응답을 UI에 실시간 표시하고, 커스텀 명령어의 기본 구조를 갖춘다.
|
|
|
|
## 태스크
|
|
|
|
### 4.1 LocalLLMService 구현
|
|
- `src/main/services/LocalLLMService.ts`
|
|
- Ollama REST API 연동 (`/api/generate`, `/api/chat`, `/api/tags`)
|
|
- 싱글톤 + EventEmitter 패턴
|
|
- 상태 머신: `Unavailable → Available → Generating → Available` (서비스 명세 LLMState 참조)
|
|
- Ollama 가용성 폴링 (5초 간격, `OLLAMA_CONFIG.pollIntervalMs`)
|
|
- `availability-changed` 이벤트로 UI에 상태 전파
|
|
- ConfigService에서 `llm.serverUrl`, `llm.defaultModel` 읽기
|
|
|
|
### 4.2 비스트리밍 생성 (`generate`)
|
|
- `POST /api/generate` 호출 (stream: false)
|
|
- GenerateOptions 지원: model, temperature, maxTokens, topP, topK, systemPrompt
|
|
- GenerateResult 반환: text, model, promptTokens, completionTokens, totalDuration
|
|
- 타임아웃 처리 (AbortController, 기본 120초)
|
|
|
|
### 4.3 스트리밍 생성 (`stream`)
|
|
- `POST /api/generate` (stream: true) → NDJSON 파싱
|
|
- fetch + ReadableStream으로 청크 처리
|
|
- `token` 이벤트를 통해 점진적 토큰 전달
|
|
- AbortController로 중간 취소 지원
|
|
- 버퍼 관리: 불완전한 JSON 라인 처리
|
|
|
|
### 4.4 텍스트 다듬기 모드 (Polishing)
|
|
- PostProcessCommand `{ type: 'polish', style?: 'formal' | 'casual' }` 처리
|
|
- 시스템 프롬프트 설계:
|
|
```
|
|
[formal] 다음 음성 전사 텍스트를 자연스럽고 격식 있는 문어체로 다듬어주세요.
|
|
원래 의미를 유지하면서 문법 오류를 수정하고, 불필요한 반복이나 필러를 제거하세요.
|
|
다듬어진 텍스트만 출력하세요. 설명이나 부가 문구를 붙이지 마세요.
|
|
[casual] 다음 음성 전사 텍스트를 자연스러운 구어체로 다듬어주세요.
|
|
원래 의미와 톤을 유지하면서 문법 오류만 수정하세요.
|
|
다듬어진 텍스트만 출력하세요.
|
|
```
|
|
- VoiceModeService의 Processing 상태에서 호출
|
|
|
|
### 4.5 번역 모드 (Translate)
|
|
- PostProcessCommand `{ type: 'translate', targetLanguage: string }` 처리
|
|
- 시스템 프롬프트 설계:
|
|
```
|
|
다음 텍스트를 {targetLanguage}로 번역해주세요.
|
|
자연스럽고 정확한 번역만 출력하세요. 원문이나 설명을 붙이지 마세요.
|
|
```
|
|
- 감지 언어 → 대상 언어 자동 전환 (한국어 감지 시 영어로, 영어 감지 시 한국어로)
|
|
- ConfigService에서 기본 대상 언어 설정 지원
|
|
|
|
### 4.6 커스텀 명령어 기본 구조
|
|
- PostProcessCommand `{ type: 'custom', prompt: string }` 처리
|
|
- 사용자가 직접 시스템 프롬프트를 지정하여 LLM에 전달
|
|
- CustomInstruction 인터페이스 초기 정의:
|
|
```typescript
|
|
interface CustomInstruction {
|
|
id: string;
|
|
name: string;
|
|
prompt: string;
|
|
isBuiltin: boolean;
|
|
createdAt: number;
|
|
}
|
|
```
|
|
- Phase 6에서 완전 구현 (CRUD, 프리셋, 핫키 바인딩)
|
|
|
|
### 4.7 스트리밍 응답 UI 표시
|
|
- RecordingTipWindow에 `processing` 상태 추가
|
|
- Thinking 프로그레스 바 (점근 수렴 패턴: `min(95, (1 - 1/(1+1.5*t)) * 100)%`)
|
|
- 스트리밍 토큰이 도착하면 텍스트 실시간 표시
|
|
- ResultPopupWindow에 스트리밍 텍스트 영역 추가
|
|
- 토큰 도착 시 점진적 텍스트 추가
|
|
- 완료 시 복사 버튼 활성화
|
|
- IPC 채널:
|
|
- `llm:streamToken` (main→renderer, 스트리밍 토큰)
|
|
- `llm:streamComplete` (main→renderer, 생성 완료)
|
|
- `llm:streamError` (main→renderer, 에러)
|
|
|
|
### 4.8 VoiceModeService LLM 통합
|
|
- RecognitionState.Processing 상태에서 LLM 호출
|
|
- 전사 완료 → postProcessCommand에 따라 분기:
|
|
- `none`: 바로 텍스트 삽입
|
|
- `polish` / `translate` / `custom`: LLM 스트리밍 호출 → 완료 후 텍스트 삽입
|
|
- `processing-update` 이벤트를 통해 UI에 진행 상황 전달
|
|
- LLM 미가용 시 postProcess를 `none`으로 폴백 + 사용자 알림
|
|
|
|
### 4.9 에러 처리
|
|
- Ollama 서버 미실행: `LLM_CONNECTION_FAILED` 에러, UI에 "Ollama가 실행 중이 아닙니다" 표시
|
|
- 모델 미설치: `LLM_MODEL_NOT_FOUND` 에러, UI에 모델 설치 안내 표시
|
|
- 생성 실패/타임아웃: `LLM_GENERATION_FAILED`, 원본 텍스트로 폴백 옵션 제공
|
|
- 네트워크 에러: 재시도 없이 즉시 에러 표시 (로컬이므로 재시도 불필요)
|
|
|
|
### 4.10 IPC 채널 추가
|
|
- `llm:getStatus` — LLM 가용 상태 조회
|
|
- `llm:getModels` — 설치된 Ollama 모델 목록
|
|
- `llm:generate` — 비스트리밍 텍스트 생성
|
|
- `llm:stream` — 스트리밍 텍스트 생성 시작
|
|
- `llm:cancelStream` — 스트리밍 취소
|
|
- `llm:checkConnection` — Ollama 연결 테스트
|
|
|
|
## Speakly RE 참조
|
|
- GensparkService: 클라우드 LLM 호출 패턴 (D3RO는 로컬 Ollama로 대체)
|
|
- CustomInstructionService: 명령어 구조, 프롬프트 템플릿
|
|
- VoiceModeService: Processing 상태 전이, 후처리 파이프라인
|
|
- RecordingTip: thinking 상태 프로그레스 바, 점근 수렴 패턴
|
|
|
|
## 완료 조건
|
|
- [ ] Ollama 가용성 자동 감지 및 UI 표시
|
|
- [ ] 전사된 텍스트를 다듬기(polish) 모드로 LLM 처리 가능
|
|
- [ ] 전사된 텍스트를 번역(translate) 모드로 LLM 처리 가능
|
|
- [ ] 커스텀 프롬프트로 자유 LLM 처리 가능
|
|
- [ ] 스트리밍 토큰이 UI에 실시간 표시됨
|
|
- [ ] Ollama 미실행/모델 미설치 시 적절한 에러 메시지 표시
|
|
- [ ] LLM 미가용 시 원본 텍스트 삽입으로 폴백
|