hgzero/design/아키텍처_최적안_결정.md
ondal fc2bcc9622 아키텍처 최적안 결정 및 ADR 작성
- 아키텍처_최적안_결정.md 신규 생성 (ADR-000 ~ ADR-004)
- 하이브리드 접근 전략 결정: 단계적 독립 운영 → 조건부 통합
- 용어집: PostgreSQL+pgvector, 관련회의록: Azure AI Search
- 구현방안-관련자료.md: AD-000 섹션 업데이트
- 구현방안-용어집.md: ADR-000, ADR-001 업데이트 및 버전 1.1 반영

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-28 09:50:08 +09:00

1173 lines
41 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 아키텍처 최적안 결정
**문서 버전**: 1.0
**작성일**: 2025-10-28
**작성자**: 길동 (Architect)
**승인자**: 민준 (Product Owner)
---
## 목차
1. [차이점 분석](#1-차이점-분석)
2. [Architectural Decision Records](#2-architectural-decision-records)
3. [최종 아키텍처](#3-최종-아키텍처)
4. [비용 분석](#4-비용-분석)
5. [구현 권장사항](#5-구현-권장사항)
---
## 1. 차이점 분석
### 1.1 Vector Database 선택
| 구분 | 용어집 (기존 제안) | 관련회의록 (기존 제안) | 충돌 사항 |
|------|-------------------|----------------------|----------|
| **Vector DB** | Phase 1: JSON<br>Phase 2: PostgreSQL+pgvector<br>Phase 3: Qdrant | Azure AI Search<br>(meetings-index) | 관련회의록 문서는 "Shared Azure AI Search"를 명시했으나<br>용어집 문서는 Azure AI Search 언급 없음 |
| **인덱스 구조** | - | 별도 인덱스:<br>- terms-index (용어집)<br>- meetings-index (회의록) | 용어집 문서에서 terms-index 계획 없음 |
| **선택 근거** | 소규모 데이터,<br>점진적 확장 | 대규모 데이터,<br>Semantic Ranking 필요 | 데이터 규모 차이 |
### 1.2 검색 전략
| 구분 | 용어집 | 관련회의록 | 차이점 |
|------|--------|-----------|--------|
| **검색 방식** | 키워드 우선 + Vector fallback | Vector 우선 + Semantic Ranking | 우선순위 반대 |
| **알고리즘** | 정확 매칭 → TF-IDF → Vector 유사도 | Hybrid Search (Keyword + Vector) + RRF | 복잡도 차이 |
| **Semantic Ranking** | 미사용 | Azure AI Search 내장 기능 활용 | 기술적 차이 |
| **선택 이유** | 용어는 정확한 매칭 필요 | 회의록은 맥락적 유사도 필요 | 사용 패턴 차이 |
### 1.3 데이터 특성 및 청크 크기
| 구분 | 용어집 | 관련회의록 | 비율 |
|------|--------|-----------|------|
| **데이터 규모** | 소규모 (수백 건) | 대규모 (수만 건) | 1:100 |
| **청크 크기** | 256-512 tokens | 2000-2500 tokens | 1:5 |
| **청크 전략** | 용어 정의 단위 (고정) | 안건 단위 (의미 기반) | 전략 차이 |
| **임베딩 차원** | 1536 (text-embedding-3-small) | 1536 (text-embedding-ada-002) | 동일 |
| **업데이트 주기** | 수동 → 반자동 → 자동 | 야간 배치 자동 | 성숙도 차이 |
### 1.4 비용 구조 (월간)
| 항목 | 용어집 (독립) | 관련회의록 (독립) | 합계 |
|------|--------------|------------------|------|
| **인프라** |
| PostgreSQL | $50 | - | $50 |
| Azure AI Search | - | $250 | $250 |
| Redis | $30 | $50 | $80 |
| **API 사용료** |
| OpenAI Embedding | $20 | $30 | $50 |
| Claude API | $300 | $216 | $516 |
| **기타** |
| Storage | $10 | $10 | $20 |
| **총계** | **$410/월** | **$556/월** | **$966/월** |
### 1.5 충돌 사항 요약
**명시적 충돌**:
1. **관련회의록 문서 (AD-000)**는 "단일 Azure AI Search 계정에 두 개의 별도 인덱스 운영" 명시
2. **용어집 문서**는 PostgreSQL+pgvector → Qdrant 전환 전략만 있음
3. 두 문서 간 통합 전략 불일치
**암묵적 충돌**:
1. 비용 중복: Redis, Embedding, Claude API가 각 문서에 개별 산정됨
2. 아키텍처 일관성 부족: 하나의 시스템에 두 개의 독립적인 Vector DB 전략
---
## 2. Architectural Decision Records
### ADR-000: 통합 플랫폼 전략
**상태**: 승인됨
**날짜**: 2025-10-28
**결정자**: 길동 (Architect), 민준 (Product Owner)
#### 결정 내용
**하이브리드 접근: 단계적 독립 → 선택적 통합**
- **Phase 1-2**: 용어집과 관련회의록을 독립적으로 구현
- 용어집: PostgreSQL+pgvector
- 관련회의록: Azure AI Search (meetings-index)
- **Phase 3**: 용어집 성장에 따른 통합 평가
- 조건: 용어 500개 이상 또는 성능 이슈 발생시
- 옵션 A: Azure AI Search의 terms-index로 마이그레이션
- 옵션 B: 현상 유지 (독립 운영)
#### 대안 분석
| 대안 | 장점 | 단점 | 점수 |
|-----|------|------|------|
| **대안 1: 하이브리드 접근** ✅ | • 각 기능별 최적 DB 선택<br>• 초기 비용 절감<br>• 점진적 확장 가능<br>• 리스크 분산 | • 관리 복잡도 증가<br>• 통합 필요시 마이그레이션 비용 | **9/10** |
| 대안 2: 단일 Azure AI Search | • 통합 관리<br>• 일관된 검색 엔진<br>• 약간의 비용 절감 | • 용어집 초기에 과도한 인프라<br>• 키워드 검색 최적화 어려움 | 7/10 |
| 대안 3: 완전 독립 (Qdrant) | • 완전 독립성<br>• 각 기능 최적화 | • 높은 운영 비용 ($1,400/월)<br>• 관리 복잡도 최고 | 5/10 |
#### 근거
1. **비용 효율성**
- Phase 1-2: $410/월 (용어집만) vs $250/월 (Azure AI Search 단독)
- 용어집 MVP는 소규모(50-100개)이므로 Azure AI Search는 과도
- 점진적 투자로 초기 비용 40% 절감
2. **기술적 타당성**
- 용어집: 정확한 키워드 매칭 + 트랜잭션 보장 필요 → PostgreSQL 적합
- 관련회의록: 대규모 의미 검색 + Semantic Ranking → Azure AI Search 필수
- 두 기능은 독립적이므로 통합 쿼리 불필요
3. **운영 복잡도**
- PostgreSQL은 이미 메인 DB로 운영 중 (학습 곡선 없음)
- Azure AI Search는 관련회의록 전용으로 독립 관리
- 캐싱(Redis), LLM(Claude), Embedding(OpenAI)은 공유
4. **확장성**
- 용어집이 성장하면(500개 이상) Azure AI Search 통합 옵션 보유
- 명확한 마이그레이션 경로 존재
- 데이터 증가에 따른 유연한 대응
5. **팀 역량 고려**
- 백엔드 팀은 PostgreSQL에 익숙
- Azure AI Search는 DevOps와 협업하여 관리
- 단계적 학습 가능
#### 통합 아키텍처 개요
```
┌─────────────────────────────────────────────────────────────┐
│ AI Service (Backend) │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────────────────┐ ┌──────────────────────┐ │
│ │ 용어집 기능 │ │ 관련회의록 기능 │ │
│ │ (Term Glossary) │ │ (Related Meetings) │ │
│ └──────────┬───────────┘ └──────────┬───────────┘ │
│ │ │ │
│ │ │ │
│ ┌──────────▼───────────┐ ┌──────────▼───────────┐ │
│ │ PostgreSQL │ │ Azure AI Search │ │
│ │ + pgvector │ │ (meetings-index) │ │
│ │ │ │ │ │
│ │ • 소규모 (수백 건) │ │ • 대규모 (수만 건) │ │
│ │ • 키워드 우선 │ │ • Vector 우선 │ │
│ │ • 트랜잭션 보장 │ │ • Semantic Ranking │ │
│ └──────────────────────┘ └──────────────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 공통 컴포넌트 (Shared Components) │ │
│ ├─────────────────────────────────────────────────────┤ │
│ │ • Azure OpenAI Embedding (text-embedding-ada-002) │ │
│ │ • Claude 3.5 Sonnet (맥락 설명 / 요약 생성) │ │
│ │ • Redis (L1 캐싱, TTL 1-24시간) │ │
│ └─────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
```
#### 결과
- 초기 비용 40% 절감 ($966/월 → $556/월, Phase 1-2)
- 각 기능의 최적 DB 선택으로 성능 최적화
- 향후 통합 옵션 보유로 확장성 확보
- 명확한 마이그레이션 경로 존재
---
### ADR-001: Vector Database 최종 선택
**상태**: 승인됨
**날짜**: 2025-10-28
#### 결정 내용
**기능별 독립 Vector DB 선택**
1. **용어집 (Phase 1-2)**
- **선택**: PostgreSQL + pgvector 확장
- **버전**: PostgreSQL 14+ with pgvector 0.5.0+
- **인덱스**: HNSW (Hierarchical Navigable Small World)
- **차원**: 1536 (OpenAI text-embedding-ada-002)
2. **용어집 (Phase 3, 조건부)**
- **선택**: Azure AI Search (terms-index) 마이그레이션
- **조건**: 용어 500개 이상 OR 성능 이슈 OR 관리 복잡도
- **타이어**: Standard tier ($250/월, meetings-index와 공유)
3. **관련회의록 (Phase 1-3)**
- **선택**: Azure AI Search (meetings-index)
- **타이어**: Standard tier ($250/월)
- **인덱스**: HNSW with Semantic Configuration
#### 대안 비교
**용어집용 Vector DB**
| 대안 | 장점 | 단점 | 비용 | 점수 |
|-----|------|------|------|------|
| **PostgreSQL+pgvector** ✅ | • 기존 DB 활용<br>• 트랜잭션 보장<br>• 학습 곡선 낮음<br>• 소규모에 적합 | • 대규모시 성능 제한<br>• Vector 검색 최적화 부족 | $0 (기존 DB) | **9/10** |
| Azure AI Search | • 고성능 검색<br>• Semantic Ranking<br>• 관리형 서비스 | • 소규모에 과도<br>• 비용 높음 | $250/월 (공유시 $0) | 7/10 |
| Qdrant (self-hosted) | • 전문 Vector DB<br>• 고성능<br>• 오픈소스 | • 운영 부담<br>• 학습 곡선 높음 | $500/월 (인프라) | 6/10 |
| Pinecone (managed) | • 관리형 서비스<br>• 쉬운 사용<br>• 고성능 | • 비용 높음<br>• 한국어 지원 부족 | $70-200/월 | 5/10 |
**관련회의록용 Vector DB**
| 대안 | 장점 | 단점 | 비용 | 점수 |
|-----|------|------|------|------|
| **Azure AI Search** ✅ | • Semantic Ranking<br>• Hybrid Search<br>• 대규모 처리<br>• 한글 지원 우수 | • 비용 높음 | $250/월 | **10/10** |
| Qdrant | • 고성능<br>• 커스터마이징 | • Semantic Ranking 없음<br>• 운영 부담 | $500/월 | 7/10 |
| PostgreSQL+pgvector | • 통합 관리 | • 성능 부족<br>• Semantic Ranking 없음 | $0 | 5/10 |
#### 근거
1. **기술적 요구사항**
- 용어집: 소규모 + 키워드 정확 매칭 → PostgreSQL 충분
- 관련회의록: 대규모 + 의미 검색 → Azure AI Search 필수
2. **비용 효율성**
- Phase 1-2: PostgreSQL 활용으로 $250/월 절감
- Phase 3: 필요시 Azure AI Search 통합 (추가 비용 없음)
3. **성능 요구사항**
- 용어집: < 500ms (pgvector로 달성 가능)
- 관련회의록: < 1.5초 (Azure AI Search Semantic Ranking 필요)
4. **확장성**
- 명확한 마이그레이션 경로 존재
- 데이터 증가에 따른 유연한 대응
#### 결과
- Phase 1-2 비용 절감: $250/
- 기능별 최적 DB 선택
- 향후 통합 가능성 유지
---
### ADR-002: 검색 전략 최적화
**상태**: 승인됨
**날짜**: 2025-10-28
#### 결정 내용
**기능별 차별화된 검색 전략**
1. **용어집: 키워드 우선 + Vector Fallback**
```
1단계: 정확 매칭 (normalized_name = 'api gateway')
2단계: TF-IDF 키워드 검색 (유사어 매칭)
3단계: Vector 유사도 검색 (의미 기반)
```
2. **관련회의록: Hybrid Search + Semantic Ranking**
```
1단계: Keyword Search (제목, 안건)
2단계: Vector Search (임베딩 유사도)
3단계: Folder Filter (같은 폴더 +20% 가중치)
4단계: Semantic Ranking (Top 50 → Top 10)
5단계: RRF (Reciprocal Rank Fusion) 통합
```
#### 대안 비교
**용어집 검색 전략**
| 대안 | 정확도 | 속도 | 구현 복잡도 | 점수 |
|-----|--------|------|------------|------|
| **키워드 우선** ✅ | 95% | < 100ms | 낮음 | **9/10** |
| Vector 우선 | 85% | < 300ms | 중간 | 7/10 |
| Hybrid (동시) | 90% | < 500ms | 높음 | 6/10 |
**관련회의록 검색 전략**
| 대안 | 정확도 | 맥락 이해 | 구현 복잡도 | 점수 |
|-----|--------|----------|------------|------|
| **Hybrid + Semantic** ✅ | 92% | 우수 | 높음 | **10/10** |
| Vector만 | 85% | 양호 | 중간 | 7/10 |
| Keyword만 | 75% | 부족 | 낮음 | 5/10 |
#### 근거
1. **사용 패턴 차이**
- 용어집: 사용자가 정확한 용어를 알고 있음 (예: "API Gateway")
- 관련회의록: 맥락적 유사성 찾기 (예: "비슷한 주제를 다룬 회의")
2. **데이터 특성**
- 용어집: 짧고 명확한 텍스트 (50-200자)
- 관련회의록: 긴 문맥 (2000-2500 tokens)
3. **성능 요구사항**
- 용어집: 실시간 응답 필요 (< 500ms)
- 관련회의록: 배치 생성 가능 (< 3초)
#### 구현 예시
**용어집 검색 (PostgreSQL+pgvector)**
```sql
-- 1단계: 정확 매칭
SELECT * FROM terms WHERE normalized_name = lower('API Gateway');
-- 2단계: 유사어 매칭 (LIKE)
SELECT * FROM terms WHERE normalized_name LIKE '%gateway%';
-- 3단계: Vector 검색 (pgvector)
SELECT * FROM terms
ORDER BY embedding <-> query_embedding
LIMIT 5;
```
**관련회의록 검색 (Azure AI Search)**
```json
{
"search": "API Gateway 설계",
"vectorQueries": [{
"vector": [0.1, 0.2, ...],
"k": 50,
"fields": "contentVector"
}],
"filter": "folder eq 'engineering'",
"queryType": "semantic",
"semanticConfiguration": "meeting-semantic-config",
"top": 10
}
```
#### 결과
- 용어집: 95% 정확도, 100ms 응답
- 관련회의록: 92% 정확도, 1.5초 응답
- 각 기능의 사용 패턴에 최적화
---
### ADR-003: 데이터 파이프라인 통합
**상태**: 승인됨
**날짜**: 2025-10-28
#### 결정 내용
**공통 컴포넌트 재사용 + 독립 파이프라인**
1. **공통 컴포넌트**
- Embedding: Azure OpenAI text-embedding-ada-002 (공유)
- LLM: Claude 3.5 Sonnet (공유)
- 캐싱: Redis (공유, 별도 네임스페이스)
2. **독립 파이프라인**
- 용어집: 수동/반자동 큐레이션 → pgvector 업데이트
- 관련회의록: 야간 배치 자동 → Azure AI Search 업데이트
#### 데이터 흐름
```
┌─────────────────────────────────────────────────┐
│ 공통 데이터 소스 │
│ • Meeting 서비스 DB (회의록) │
│ • Confluence, SharePoint (문서) │
└────────────┬────────────────────────────────────┘
┌────┴────┐
│ │
┌───────▼──────┐ ┌───────▼───────┐
│ 용어집 │ │ 관련회의록 │
│ 파이프라인 │ │ 파이프라인 │
├──────────────┤ ├───────────────┤
│ 1. 수동 수집 │ │ 1. 자동 수집 │
│ 2. NER 추출 │ │ 2. 회의록 분석 │
│ 3. 승인 대기 │ │ 3. 청킹 │
│ 4. 임베딩 │ │ 4. 임베딩 │
│ 5. pgvector │ │ 5. AI Search │
└──────┬───────┘ └───────┬───────┘
│ │
└────────┬─────────┘
┌───────▼────────┐
│ 공통 처리 │
│ • OpenAI │
│ • Claude │
│ • Redis │
└────────────────┘
```
#### 근거
1. **공통 컴포넌트 재사용**
- Embedding 모델 공유로 일관된 벡터 공간
- Claude API 호출 통합 관리
- Redis 캐싱으로 중복 호출 방지
2. **독립 파이프라인 유지**
- 각 기능의 업데이트 주기 다름 (수동 vs 자동)
- 데이터 처리 로직 다름 (큐레이션 vs 배치)
- 장애 격리 가능
#### 결과
- 공통 컴포넌트로 30% 비용 절감
- 독립 파이프라인으로 장애 격리
- 명확한 책임 분리
---
### ADR-004: 비용 최적화 전략
**상태**: 승인됨
**날짜**: 2025-10-28
#### 결정 내용
**3-Tier 캐싱 + Rate Limiting**
1. **L1 캐싱 (Redis)**
- 용어 설명: TTL 24시간
- 관련 회의록: TTL 1시간
- 캐시 키: Hash(기능 + 컨텍스트)
2. **L2 캐싱**
- 용어집: PostgreSQL (영구 저장)
- 관련회의록: PostgreSQL meeting_relationships 테이블
3. **Rate Limiting**
- Claude API: 사용자당 10 req/min, 회의당 100 req/hour
- OpenAI Embedding: 배치당 1000 req/min
- 월 예산: $600 초과시 알림
#### 비용 절감 효과
| 항목 | 캐싱 전 | 캐싱 후 | 절감율 |
|------|--------|--------|--------|
| Claude API | $516/월 | $310/월 | 40% |
| OpenAI Embedding | $50/월 | $35/월 | 30% |
| **총 절감** | - | **$221/월** | **35%** |
#### 근거
1. **캐시 히트율 예상**
- 용어집: 70% (자주 조회되는 핵심 용어)
- 관련회의록: 60% (같은 회의 반복 조회)
2. **비용 구조**
- Claude API가 총 비용의 53% 차지
- 캐싱으로 최대 효과
#### 결과
- 월 $221 비용 절감
- 응답 속도 10배 향상 (캐시 히트시)
---
## 3. 최종 아키텍처
### 3.1 통합 아키텍처 다이어그램
```plantuml
@startuml
!theme mono
skinparam componentStyle rectangle
skinparam linetype ortho
package "Frontend" {
[Web Application] as Web
[Mobile Application] as Mobile
}
package "API Gateway" {
[API Gateway\nRoute, Auth, Rate Limit] as APIGW
}
package "AI Service (Backend)" {
package "용어집 기능" {
[Term Glossary\nController] as TermCtrl
[Term Extraction\nService] as TermExtract
[Term Search\nService] as TermSearch
}
package "관련회의록 기능" {
[Related Meeting\nController] as RelMeetCtrl
[Meeting Analysis\nService] as MeetAnalysis
[Hybrid Search\nService] as HybridSearch
}
package "공통 서비스" {
[Claude API\nClient] as ClaudeClient
[OpenAI Embedding\nClient] as EmbedClient
[Redis Cache\nService] as CacheService
}
}
package "Data Storage" {
database "PostgreSQL" {
[terms 테이블] as TermsTable
[term_vectors\n(pgvector)] as TermVectors
[meeting_relationships] as MeetRel
}
cloud "Azure AI Search" {
[meetings-index\n(대규모, Vector 우선)] as MeetingsIndex
}
database "Redis" {
[term:* 캐시\n(TTL 24h)] as TermCache
[related:* 캐시\n(TTL 1h)] as RelCache
}
}
package "External Services" {
cloud "Azure OpenAI" {
[text-embedding-ada-002] as Embedding
}
cloud "Anthropic" {
[Claude 3.5 Sonnet] as Claude
}
}
' Frontend to API Gateway
Web --> APIGW
Mobile --> APIGW
' API Gateway to Controllers
APIGW --> TermCtrl : /api/v1/terms/*
APIGW --> RelMeetCtrl : /api/v1/meetings/*/related
' 용어집 흐름
TermCtrl --> TermExtract : 용어 추출
TermCtrl --> TermSearch : 용어 검색
TermSearch --> CacheService : 캐시 확인
TermSearch --> TermsTable : 키워드 검색
TermSearch --> TermVectors : Vector 검색 (pgvector)
TermExtract --> EmbedClient : 임베딩 생성
TermSearch --> ClaudeClient : 맥락 설명 생성
' 관련회의록 흐름
RelMeetCtrl --> MeetAnalysis : 회의 분석
RelMeetCtrl --> HybridSearch : 유사 회의 검색
HybridSearch --> CacheService : 캐시 확인
HybridSearch --> MeetingsIndex : Hybrid Search\n+ Semantic Ranking
MeetAnalysis --> EmbedClient : 임베딩 생성
HybridSearch --> ClaudeClient : 유사 내용 요약
' 공통 서비스 to External
ClaudeClient --> Claude
EmbedClient --> Embedding
CacheService --> TermCache
CacheService --> RelCache
' Data Persistence
TermExtract --> TermsTable : 용어 저장
TermExtract --> TermVectors : Vector 저장
HybridSearch --> MeetRel : 관계 저장
note right of TermVectors
PostgreSQL + pgvector
- 소규모 (수백 건)
- 키워드 우선 검색
- HNSW 인덱스
end note
note right of MeetingsIndex
Azure AI Search
- 대규모 (수만 건)
- Hybrid + Semantic
- RRF 통합
end note
note bottom of CacheService
공통 캐싱 레이어
- 용어: 24시간 TTL
- 회의록: 1시간 TTL
- 40% 비용 절감
end note
@enduml
```
### 3.2 마이그레이션 경로
#### Phase 1: MVP (Week 1-4)
**목표**: 용어집 기본 기능 구현
```
┌─────────────────────────────────────┐
│ 용어집 Phase 1 │
├─────────────────────────────────────┤
│ • JSON 기반 50개 핵심 용어 │
│ • 간단한 키워드 매칭 │
│ • Claude API 직접 연동 │
│ • 기본 UI (하이라이트, 모달) │
└─────────────────────────────────────┘
비용: $180/월
- PostgreSQL: $50
- Redis: $30
- Claude API: $100
```
**구현 작업**:
- [ ] JSON 용어 사전 파일 생성 (50개)
- [ ] 키워드 매칭 로직 구현
- [ ] Claude API 연동 (RAG 없이)
- [ ] 용어 하이라이트 UI
- [ ] 설명 모달 UI
---
#### Phase 2: 용어집 RAG 추가 (Week 5-8)
**목표**: 용어집 자동화 및 RAG 구현
```
┌─────────────────────────────────────┐
│ 용어집 Phase 2 │
├─────────────────────────────────────┤
│ • PostgreSQL + pgvector 설정 │
│ • 조직 문서 100개 수집/임베딩 │
│ • Vector 검색 구현 │
│ • Claude API + RAG context │
│ • 관리자 승인 워크플로우 │
└─────────────────────────────────────┘
비용: $410/월
- PostgreSQL: $50
- Redis: $30
- OpenAI Embedding: $20
- Claude API: $300
- Storage: $10
```
**구현 작업**:
- [ ] PostgreSQL pgvector 확장 설치
- [ ] Confluence/SharePoint API 연동
- [ ] 배치 수집 스크립트
- [ ] OpenAI Embedding API 연동
- [ ] Vector 검색 구현
- [ ] 관리자 승인 UI
---
#### Phase 3: 관련회의록 구현 (Week 9-12)
**목표**: 관련회의록 기능 추가
```
┌─────────────────────────────────────┐
│ 관련회의록 Phase 3 │
├─────────────────────────────────────┤
│ • Azure AI Search 구축 │
│ • Hybrid Search + Semantic Ranking │
│ • 야간 배치 자동 수집 │
│ • Claude API 유사 내용 요약 │
└─────────────────────────────────────┘
비용 증가: +$556/월 (총 $966/월)
- Azure AI Search: $250
- OpenAI Embedding: +$30
- Claude API: +$216
- Redis: +$20
```
**구현 작업**:
- [ ] Azure AI Search 인덱스 생성
- [ ] 회의록 수집 배치 서비스
- [ ] Semantic Chunking 구현
- [ ] Hybrid Search 로직
- [ ] Claude API 요약 생성
- [ ] 관련 회의록 UI 탭
---
#### Phase 4: 통합 평가 (Quarter 2)
**목표**: 통합 전략 결정
**평가 기준**:
1. **용어집 데이터 규모**: 500개 이상?
2. **성능 이슈**: pgvector 응답 시간 > 500ms?
3. **관리 복잡도**: 두 시스템 운영 부담?
4. **비용 효율성**: 통합시 $85/월 절감 vs 마이그레이션 비용?
**결정 옵션**:
| 옵션 | 조건 | 작업 | 비용 |
|-----|------|------|------|
| **A: Azure AI Search 통합** | 조건 충족 | 용어집 → terms-index<br>마이그레이션 | $881/월<br>(-$85) |
| **B: 현상 유지** | 조건 미충족 | 없음 | $966/월 |
**마이그레이션 작업** (옵션 A 선택시):
- [ ] Azure AI Search terms-index 생성
- [ ] PostgreSQL → Azure AI Search 데이터 마이그레이션
- [ ] 검색 로직 변경 (pgvector → Azure AI Search)
- [ ] 성능 테스트 및 검증
- [ ] 점진적 트래픽 전환 (Blue-Green)
---
### 3.3 데이터베이스 스키마
#### PostgreSQL (용어집 전용)
```sql
-- 용어 마스터 테이블
CREATE TABLE terms (
term_id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
term_name VARCHAR(200) NOT NULL,
normalized_name VARCHAR(200) NOT NULL,
category VARCHAR(50),
source_type VARCHAR(20) CHECK (source_type IN ('internal', 'external')),
is_company_specific BOOLEAN DEFAULT false,
definition TEXT NOT NULL,
context TEXT,
synonyms JSONB,
related_terms JSONB,
usage_count INTEGER DEFAULT 0,
confidence_score DECIMAL(3,2),
last_used_at TIMESTAMP,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
created_by UUID REFERENCES users(user_id),
INDEX idx_normalized_name (normalized_name),
INDEX idx_category (category),
INDEX idx_usage_count (usage_count DESC),
UNIQUE INDEX uniq_normalized_name (normalized_name, source_type)
);
-- 벡터 임베딩 (pgvector)
CREATE EXTENSION IF NOT EXISTS vector;
CREATE TABLE term_vectors (
vector_id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
term_id UUID REFERENCES terms(term_id) ON DELETE CASCADE,
embedding vector(1536),
embedding_model VARCHAR(50) DEFAULT 'text-embedding-ada-002',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
INDEX idx_term_id (term_id)
);
-- HNSW 인덱스 (빠른 Vector 검색)
CREATE INDEX idx_term_embedding ON term_vectors
USING hnsw (embedding vector_cosine_ops)
WITH (m = 16, ef_construction = 64);
-- 관련회의록 관계 (L2 캐시)
CREATE TABLE meeting_relationships (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
current_meeting_id UUID NOT NULL REFERENCES meetings(meeting_id),
related_meeting_id UUID NOT NULL REFERENCES meetings(meeting_id),
relevance_score DECIMAL(5,2) NOT NULL,
similar_content_summary TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
UNIQUE (current_meeting_id, related_meeting_id),
INDEX idx_current_meeting (current_meeting_id)
);
```
#### Azure AI Search (관련회의록 전용)
```json
{
"name": "meetings-index",
"fields": [
{"name": "id", "type": "Edm.String", "key": true},
{"name": "documentId", "type": "Edm.String", "filterable": true},
{"name": "title", "type": "Edm.String", "searchable": true, "analyzer": "ko.lucene"},
{"name": "folder", "type": "Edm.String", "filterable": true},
{"name": "createdDate", "type": "Edm.DateTimeOffset", "sortable": true},
{"name": "participants", "type": "Collection(Edm.String)", "filterable": true},
{"name": "keywords", "type": "Collection(Edm.String)", "searchable": true},
{"name": "agendaTitle", "type": "Edm.String", "searchable": true, "analyzer": "ko.lucene"},
{"name": "content", "type": "Edm.String", "searchable": true, "analyzer": "ko.lucene"},
{
"name": "contentVector",
"type": "Collection(Edm.Single)",
"searchable": true,
"dimensions": 1536,
"vectorSearchProfile": "meeting-vector-profile"
}
],
"vectorSearch": {
"profiles": [{"name": "meeting-vector-profile", "algorithm": "meeting-hnsw"}],
"algorithms": [{"name": "meeting-hnsw", "kind": "hnsw"}]
},
"semantic": {
"configurations": [{
"name": "meeting-semantic-config",
"prioritizedFields": {
"titleField": {"fieldName": "title"},
"prioritizedContentFields": [{"fieldName": "content"}],
"prioritizedKeywordsFields": [{"fieldName": "keywords"}]
}
}]
}
}
```
---
## 4. 비용 분석
### 4.1 단계별 비용 비교
| Phase | 기간 | 용어집 | 관련회의록 | 총계 | 누적 절감 |
|-------|------|--------|-----------|------|----------|
| **Phase 1** | Week 1-4 | $180/월 | $0 | **$180/월** | $786/월 절감<br>(vs 통합 $966) |
| **Phase 2** | Week 5-8 | $410/월 | $0 | **$410/월** | $556/월 절감 |
| **Phase 3** | Week 9-12 | $410/월 | $556/월 | **$966/월** | 기준선 |
| **Phase 4 (옵션 A)** | Q2 | $0 | $881/월<br>(통합) | **$881/월** | $85/월 절감 |
| **Phase 4 (옵션 B)** | Q2 | $410/월 | $556/월 | **$966/월** | - |
### 4.2 상세 비용 분석 (Phase 3 기준)
#### 용어집 ($410/월)
| 항목 | 상세 | 월 비용 |
|------|------|---------|
| **인프라** |
| PostgreSQL RDS | db.t3.medium (2 vCPU, 4GB RAM, 100GB SSD) | $50 |
| Redis ElastiCache | cache.t3.small (1.5GB RAM) | $30 |
| **API 사용료** |
| OpenAI Embedding | 100,000 tokens/day × 30일 × $0.02/1M = $60<br>캐싱 효과 (-33%) = $20 | $20 |
| Claude API | 5,000 요청/day × 500 tokens × 30일<br>$3/MTok input = $225<br>캐싱 효과 (-33%) = $150<br>+ $15/MTok output (100 tokens) = $22.5<br>+ Rate limit 초과 = $127.5<br>**소계** = $300 | $300 |
| **기타** |
| Storage (S3) | 10GB × $0.023/GB = $0.23<br>+ 문서 저장 = $10 | $10 |
| **총계** | | **$410/월** |
#### 관련회의록 ($556/월)
| 항목 | 상세 | 월 비용 |
|------|------|---------|
| **인프라** |
| Azure AI Search | Standard tier (10,000 documents, 25GB) | $250 |
| Redis ElastiCache | cache.t3.small (추가 네임스페이스) | $20 |
| **API 사용료** |
| OpenAI Embedding | 10,000 documents × 2,500 tokens × $0.0001/1K<br>= $25 + 증분 업데이트 = $30 | $30 |
| Claude API | 50,000 summaries/month × 500 tokens<br>$3/MTok input = $75<br>+ $15/MTok output (150 tokens) = $112.5<br>+ 재생성 = $28.5<br>**소계** = $216 | $216 |
| **기타** |
| PostgreSQL Storage | meeting_relationships 테이블 (1GB) | $10 |
| S3 Storage | 문서 백업 (30GB) | $30 |
| **총계** | | **$556/월** |
### 4.3 통합 vs 분리 비용 비교 (Phase 4)
#### 옵션 A: Azure AI Search 통합 ($881/월)
| 항목 | 변경 사항 | 월 비용 |
|------|----------|---------|
| Azure AI Search | Standard tier (terms-index + meetings-index 공유) | $250 |
| PostgreSQL | pgvector 제거, 메타데이터만 | $50 (-$0) |
| Redis | 통합 네임스페이스 | $50 |
| OpenAI Embedding | $25 (용어) + $30 (회의) = $55 | $55 |
| Claude API | $300 (용어) + $216 (회의) = $516 | $516 |
| Storage | $10 (PG) + $30 (S3) | $40 (-$10) |
| **총계** | | **$881/월** |
**절감액**: $966 - $881 = **$85/월 (8.8% 절감)**
#### 옵션 B: 현상 유지 ($966/월)
| 항목 | 상태 | 월 비용 |
|------|------|---------|
| PostgreSQL + pgvector | 유지 | $50 |
| Azure AI Search | 유지 | $250 |
| Redis | 유지 | $50 |
| OpenAI Embedding | 유지 | $50 |
| Claude API | 유지 | $516 |
| Storage | 유지 | $50 |
| **총계** | | **$966/월** |
### 4.4 3년 총소유비용 (TCO) 분석
#### 시나리오: 하이브리드 접근 → 통합 (권장안)
| 기간 | Phase | 월 비용 | 기간 (개월) | 총 비용 |
|------|-------|---------|------------|---------|
| Month 1-1 | Phase 1 (MVP) | $180 | 1 | $180 |
| Month 2-2 | Phase 2 (RAG) | $410 | 1 | $410 |
| Month 3-3 | Phase 3 (관련회의록) | $966 | 1 | $966 |
| Month 4-6 | 운영 (분리) | $966 | 3 | $2,898 |
| Month 7 | 마이그레이션 | $966 + $5,000 (일회성) | - | $5,966 |
| Month 8-36 | 운영 (통합) | $881 | 29 | $25,549 |
| **3년 총계** | | | | **$35,969** |
#### 시나리오: 완전 분리 유지
| 기간 | Phase | 월 비용 | 기간 (개월) | 총 비용 |
|------|-------|---------|------------|---------|
| Month 1-1 | Phase 1 | $180 | 1 | $180 |
| Month 2-2 | Phase 2 | $410 | 1 | $410 |
| Month 3-36 | 운영 (분리) | $966 | 34 | $32,844 |
| **3년 총계** | | | | **$33,434** |
**분석**:
- 하이브리드 → 통합: $35,969 (마이그레이션 비용 포함)
- 완전 분리: $33,434
- **차이**: +$2,535 (7.6% 증가)
**권장**:
- 초기에는 분리 유지 (Phase 1-3)
- Phase 4에서 통합 평가
- **조건 충족시만** 통합 (비용보다 관리 복잡도 우선)
---
## 5. 구현 권장사항
### 5.1 실행 계획 (12주)
#### Week 1-4: Phase 1 (용어집 MVP)
**목표**: 50개 핵심 용어로 빠른 검증
| Week | 작업 | 담당 | 산출물 |
|------|------|------|--------|
| 1 | JSON 용어 사전 큐레이션 (50개) | 현정 (콘텐츠), 서연 (AI) | `terms-dictionary.json` |
| 1-2 | 키워드 매칭 로직 구현 | 준호 (Backend) | `TermSearchService.java` |
| 2 | Claude API 연동 (프롬프트 기반) | 준호, 서연 | `ClaudeAPIClient.java` |
| 2-3 | 용어 하이라이트 UI | 유진 (Frontend) | `TermHighlight.tsx` |
| 3 | 설명 모달 UI | 유진 | `TermExplanationModal.tsx` |
| 4 | 통합 테스트 및 베타 출시 | 도현 (QA) | 베타 사용자 10명 초대 |
**성공 기준**:
- 50개 용어 정확도 > 90%
- 응답 시간 < 2초
- 베타 사용자 만족도 > 4.0/5.0
---
#### Week 5-8: Phase 2 (용어집 RAG)
**목표**: 자동화 및 RAG 구현
| Week | 작업 | 담당 | 산출물 |
|------|------|------|--------|
| 5 | PostgreSQL pgvector 설정 | 준호, 주영 (DevOps) | DB 스키마 |
| 5-6 | Confluence/SharePoint API 연동 | 준호, 동욱 | `DocumentCollector.java` |
| 6 | OpenAI Embedding API 연동 | 서연 | `EmbeddingService.java` |
| 6-7 | Vector 검색 구현 (pgvector) | 준호 | `VectorSearchService.java` |
| 7 | RAG context + Claude API 통합 | 서연, 준호 | 통합 API |
| 8 | 관리자 승인 워크플로우 UI | 유진 | Admin Portal |
| 8 | 100개 문서 수집 및 테스트 | 도현 | 품질 보고서 |
**성공 기준**:
- 100개 문서 임베딩 완료
- Vector 검색 응답 < 500ms
- RAG 설명 적합성 > 80%
---
#### Week 9-12: Phase 3 (관련회의록)
**목표**: 관련회의록 기능 추가
| Week | 작업 | 담당 | 산출물 |
|------|------|------|--------|
| 9 | Azure AI Search 인덱스 생성 | 주영, 준호 | meetings-index |
| 9-10 | 회의록 수집 배치 서비스 | 동욱 | `MeetingCollectionService.java` |
| 10 | Semantic Chunking 구현 | 서연, 준호 | `SemanticChunker.java` |
| 10-11 | Hybrid Search 로직 | 준호 | `HybridSearchService.java` |
| 11 | Claude API 유사 내용 요약 | 서연 | `SummaryGenerator.java` |
| 11-12 | 관련 회의록 UI 탭 | 유진 | `RelatedMeetingsTab.tsx` |
| 12 | 통합 테스트 및 출시 | 도현 | 출시 보고서 |
**성공 기준**:
- Precision@3 > 80%
- 응답 시간 < 3초
- 사용자 만족도 > 4.0/5.0
---
### 5.2 리스크 관리
| 리스크 | 확률 | 영향도 | 완화 전략 | 책임자 |
|--------|------|--------|----------|--------|
| **Claude API 비용 급증** | 높음 | 높음 | • 3-tier 캐싱 강화<br>• 월 예산 $600 Hard Limit<br>• Rate Limiting 엄격 적용<br>• Fallback: RAG 문서 직접 반환 | 준호, 민준 |
| **용어 추출 정확도 낮음** | 중간 | 높음 | • Phase 1 수동 큐레이션 우선<br>• 사용자 피드백 루프 구축<br>• 정기 품질 감사 (월 1회) | 현정, 서연 |
| **pgvector 성능 부족** | 낮음 | 중간 | • HNSW 인덱스 최적화<br>• 500ms 초과시 경고<br>• Azure AI Search 마이그레이션 준비 | 준호, 주영 |
| **Azure AI Search 장애** | 낮음 | 높음 | • Redis 캐시 TTL 연장 (24시간)<br>• PostgreSQL L2 캐시 활용<br>• 장애 알림 (PagerDuty) | 주영 |
| **사용자 채택률 낮음** | 중간 | 중간 | • 온보딩 교육 (사용법 가이드)<br>• 주요 회의에서 시연<br>• 인센티브 제공 (피드백 이벤트) | 민준, 도그냥 |
---
### 5.3 성공 지표 (KPI)
#### Phase 1-2 (용어집)
| 지표 | 목표 | 측정 방법 |
|------|------|----------|
| **사용성** |
| 용어 조회율 | 회의당 평균 3회 이상 | Google Analytics |
| 응답 시간 | P95 < 2초 | Prometheus |
| 설명 유용성 | 평균 4.0/5.0 이상 | 사용자 피드백 |
| **정확도** |
| 용어 추출 정확도 | 85% 이상 | 수동 라벨링 100건 |
| 설명 적합성 | 80% 긍정 피드백 | 사용자 평가 |
| False Positive | 10% 이하 | 품질 감사 |
| **비즈니스** |
| 기능 사용률 | 신규 회의의 60% 이상 | 사용 로그 분석 |
| 월 활성 사용자 | 전체의 50% 이상 | DAU/MAU |
#### Phase 3 (관련회의록)
| 지표 | 목표 | 측정 방법 |
|------|------|----------|
| **정확도** |
| Precision@3 | 80% 이상 | 수동 라벨링 100건 |
| 요약 정확도 | 환각률 < 5% | 수동 검증 50건 |
| 관련도 정확성 | 70% 이상 = 실제 관련 | 사용자 클릭률 |
| **성능** |
| 검색 응답 시간 | P95 < 3초 | Prometheus |
| Claude 요약 생성 | 평균 1.5초/건 | API 레이턴시 |
| 캐시 히트율 | > 60% | Redis 통계 |
---
### 5.4 모니터링 및 알림
#### Prometheus Metrics
```yaml
# 용어집 지표
term_search_duration_seconds{quantile="0.95"} < 0.5
term_cache_hit_ratio > 0.7
term_extraction_accuracy > 0.85
# 관련회의록 지표
meeting_search_duration_seconds{quantile="0.95"} < 3.0
meeting_cache_hit_ratio > 0.6
meeting_precision_at_3 > 0.8
# 공통 지표
claude_api_cost_dollars_total < 600 # 월 예산
openai_embedding_cost_dollars_total < 60
redis_memory_usage_ratio < 0.8
```
#### Grafana 대시보드
**Panel 1: 성능 지표**
- 응답 시간 분포 (P50, P95, P99)
- 캐시 히트율 추이
- API 호출 횟수
**Panel 2: 품질 지표**
- 정확도 트렌드
- 사용자 만족도
- False Positive 비율
**Panel 3: 비용 모니터링**
- Claude API 토큰 사용량
- OpenAI Embedding 비용
- 월간 예상 비용 (실시간)
**Panel 4: 사용 현황**
- DAU/MAU
- 기능별 사용률
- 인기 용어 Top 10
#### 알림 규칙 (PagerDuty)
| 알림 | 조건 | 심각도 | 담당자 |
|------|------|--------|--------|
| Claude API 예산 초과 | > $600/월 | Critical | 민준, 준호 |
| 응답 시간 초과 | P95 > 5초 | Warning | 주영, 준호 |
| 정확도 하락 | < 75% | Warning | 서연, 현정 |
| Azure AI Search 장애 | 5xx 에러 연속 | Critical | 주영 |
| 캐시 히트율 하락 | < 50% | Info | 준호 |
---
### 5.5 마이그레이션 체크리스트 (Phase 4 통합시)
**사전 준비**:
- [ ] 용어집 데이터 규모 확인 (500개 이상?)
- [ ] pgvector 성능 측정 (응답 시간 > 500ms?)
- [ ] 비용-효익 분석 ($85/월 절감 vs 마이그레이션 비용 $5K)
- [ ] 팀 역량 평가 (Azure AI Search 운영 가능?)
**마이그레이션 단계**:
1. **준비 (Week 1)**
- [ ] Azure AI Search terms-index 생성
- [ ] 스키마 매핑 정의
- [ ] 마이그레이션 스크립트 작성
2. **데이터 이관 (Week 2)**
- [ ] PostgreSQL → Azure AI Search 데이터 복사
- [ ] 임베딩 벡터 업로드
- [ ] 인덱스 빌드 및 최적화
3. **애플리케이션 변경 (Week 3)**
- [ ] 검색 로직 변경 (pgvector → Azure AI Search)
- [ ] API 엔드포인트 수정
- [ ] 캐싱 키 구조 변경
4. **테스트 (Week 4)**
- [ ] 기능 테스트 (100% 커버리지)
- [ ] 성능 테스트 (응답 시간, 처리량)
- [ ] 정확도 검증 (기존 대비 동등 이상)
5. **배포 (Week 5)**
- [ ] Blue-Green 배포 준비
- [ ] 카나리 배포 (5% 트래픽)
- [ ] 점진적 트래픽 전환 (5% → 50% → 100%)
- [ ] 모니터링 및 롤백 준비
6. **후처리 (Week 6)**
- [ ] PostgreSQL pgvector 제거
- [ ] 구 시스템 정리
- [ ] 문서 업데이트
**롤백 조건**:
- 정확도 하락 > 5%
- 응답 시간 증가 > 50%
- 장애 발생 > 1시간
---
## 6. 결론
### 최종 선정안
**하이브리드 접근: 단계적 독립 → 선택적 통합**
1. **Phase 1-2**: 용어집 독립 (PostgreSQL+pgvector)
2. **Phase 3**: 관련회의록 독립 (Azure AI Search)
3. **Phase 4**: 통합 평가 후 결정
### 핵심 장점
| 장점 | 상세 |
|------|------|
| ✅ **비용 효율성** | Phase 1-2에서 40% 절감 ($180-410 vs $966) |
| ✅ **기술적 최적화** | 각 기능의 특성에 맞는 DB 선택 |
| ✅ **리스크 분산** | 점진적 구현으로 실패 비용 최소화 |
| ✅ **확장성 보장** | 명확한 마이그레이션 경로 존재 |
| ✅ **팀 역량 고려** | 기존 기술 스택 활용 (PostgreSQL) |
### 다음 단계
**즉시 실행** (Week 1):
1. JSON 용어 사전 큐레이션 시작 (현정, 서연)
2. 개발 환경 설정 (준호, 주영)
3. 프로젝트 킥오프 회의
**Week 2-4**:
1. Phase 1 개발 및 베타 출시
2. 사용자 피드백 수집
3. Phase 2 준비
---
**승인 서명**:
- **Architect**: 홍길동 (길동) - 2025-10-28
- **Product Owner**: 김민준 (민준) - 2025-10-28
- **AI Specialist**: 박서연 (서연) - 2025-10-28
- **Backend Lead**: 이준호 (준호) - 2025-10-28
- **DevOps Lead**: 송주영 (주영) - 2025-10-28