# 맥락기반 용어설명 데이터 확보 및 Claude AI 연동 아키텍처 결정 문서 ## 1단계: 각자의 생각 ### 민준 (Product Owner) 비즈니스 관점에서 용어 데이터는 두 가지 소스가 핵심입니다. 1. **조직 문서**: 내부 업무 매뉴얼, 정책, 프로젝트 문서가 차별화의 핵심 2. **외부 기술 문서**: 범용 기술 용어는 보조적으로 활용 데이터 품질이 서비스 차별화의 핵심이므로, 초기에는 작은 규모로 시작해도 정확도가 높아야 합니다. MVP에서는 핵심 조직 문서 100개 정도로 시작하고, 점진적으로 확장하는 전략이 필요합니다. ### 서연 (AI Specialist) **전문용어 처리 파이프라인**을 4단계로 제안합니다: 1. **수집 (Collection)** - 조직문서: SharePoint, Confluence, Google Drive API 연동 - 외부문서: 공개 API 문서, GitHub 기술문서 2. **추출 (Extraction)** - NER(Named Entity Recognition) 기반 기술용어 추출 - TF-IDF + 도메인 사전 기반 조직 특화 용어 추출 - Claude API를 활용한 맥락 기반 용어 추출 3. **정제 (Refinement)** - 중복 제거: Fuzzy matching으로 유사 용어 통합 - 품질 검증: 인간 피드백 루프(HITL) 구축 - 메타데이터 태깅: 카테고리, 출처, 신뢰도 점수 4. **벡터라이징 (Vectorization)** - **임베딩 모델**: OpenAI text-embedding-3-large 또는 Cohere embed-multilingual-v3.0 - **벡터 DB**: Pinecone 또는 Qdrant (관리형 vs 자체 호스팅) - **청크 전략**: - 용어 정의: 단일 청크 (256 토큰) - 문맥 정보: 슬라이딩 윈도우 (512 토큰, 128 오버랩) **Claude API 연동 구조**: ```json { "request": { "model": "claude-sonnet-4-5-20250929", "max_tokens": 1024, "system": "당신은 회의록 작성 보조 AI입니다. 전문용어를 회의 맥락에 맞춰 설명해주세요.", "messages": [ { "role": "user", "content": [ { "type": "text", "text": "회의 내용: {meeting_transcript}\n\n발견된 용어: {term}\n\n관련 문서:\n{rag_context}\n\n위 용어를 회의 맥락에 맞춰 2-3문장으로 설명해주세요." } ] } ] }, "response": { "id": "msg_...", "type": "message", "role": "assistant", "content": [ { "type": "text", "text": "API Gateway는 클라이언트와 백엔드 서비스 사이의 단일 진입점으로..." } ], "model": "claude-sonnet-4-5-20250929", "stop_reason": "end_turn", "usage": { "input_tokens": 450, "output_tokens": 120 } } } ``` ### 준호 (Backend Developer) **데이터 아키텍처 및 API 설계**를 제안합니다: **1. 데이터 소스별 수집 전략** ``` 조직 문서: ├── Confluence API (주간 배치) ├── SharePoint Graph API (주간 배치) ├── Google Drive API (주간 배치) └── 수동 업로드 (관리자 페이지) 외부 문서: ├── GitHub 기술문서 크롤링 (월간 배치) ├── 공개 API 문서 (Swagger/OpenAPI) └── 산업 표준 용어집 (수동 큐레이션) ``` **2. 데이터베이스 스키마** ```sql -- 용어 마스터 테이블 CREATE TABLE terms ( term_id UUID PRIMARY KEY, term_name VARCHAR(200) NOT NULL, normalized_name VARCHAR(200) NOT NULL, category VARCHAR(50), source_type VARCHAR(20), -- 'internal', 'external' definition TEXT, context TEXT, confidence_score DECIMAL(3,2), created_at TIMESTAMP, updated_at TIMESTAMP, INDEX idx_normalized (normalized_name), INDEX idx_category (category) ); -- 용어-문서 매핑 테이블 CREATE TABLE term_documents ( mapping_id UUID PRIMARY KEY, term_id UUID REFERENCES terms(term_id), document_id UUID, relevance_score DECIMAL(3,2), excerpt TEXT, created_at TIMESTAMP ); -- 벡터 인덱스 메타데이터 CREATE TABLE term_vectors ( vector_id UUID PRIMARY KEY, term_id UUID REFERENCES terms(term_id), embedding_model VARCHAR(50), vector_store_key VARCHAR(200), created_at TIMESTAMP ); ``` **3. REST API 엔드포인트** ``` POST /api/v1/terms/extract - 회의 전사 텍스트에서 용어 추출 - Request: { "transcript": "...", "meeting_id": "..." } - Response: { "terms": [...], "extraction_time_ms": 1234 } GET /api/v1/terms/{term_id}/context - 특정 용어의 맥락 정보 조회 - Query params: meeting_context, max_results - Response: { "term": {...}, "related_docs": [...], "ai_explanation": "..." } POST /api/v1/terms/search - 벡터 유사도 검색 - Request: { "query": "...", "filters": {...}, "top_k": 5 } - Response: { "results": [...], "search_time_ms": 234 } ``` **4. 성능 최적화** - Redis 캐싱: 자주 조회되는 용어 (TTL 1시간) - CDN 캐싱: 외부 기술 문서 용어 (TTL 24시간) - 배치 처리: 야간 시간대 벡터 업데이트 ### 동욱 (Backend Developer) **실용적인 구현 전략**을 제안합니다: **Phase 1: MVP (4주)** - JSON 파일 기반 용어 사전 (terms-dictionary.json) - 수동 큐레이션 50개 핵심 용어 - Claude API 직접 호출 (RAG 없이 프롬프트 기반) - 간단한 키워드 매칭 **Phase 2: 기본 RAG (4주)** - PostgreSQL + pgvector 확장 - 조직 문서 100개 수집/임베딩 - 기본 벡터 검색 구현 - Claude API + RAG context 연동 **Phase 3: 고도화 (8주)** - Pinecone 또는 Qdrant 도입 - 자동 수집 파이프라인 구축 - 하이브리드 검색 (키워드 + 벡터) - 피드백 루프 및 품질 개선 **인프라 구성**: ```yaml services: term-extraction: - NLP 서버 (Python FastAPI) - spaCy, transformers 라이브러리 - 배치 작업용 Celery worker vector-search: - Qdrant (self-hosted) 또는 Pinecone (managed) - API Gateway 통합 claude-api-proxy: - Rate limiting (100 req/min) - Response caching (Redis) - Error handling & retry logic ``` ### 유진 (Frontend Developer) **사용자 경험 관점**에서 고려사항: 1. **실시간 용어 감지 UI** - STT 텍스트 스트리밍 중 용어 하이라이트 - 1초 이내 반응 속도 보장 - 로딩 스피너 대신 skeleton UI 2. **용어 설명 모달** - 빠른 프리뷰: 2-3줄 요약 - 상세보기 확장: 관련 문서 링크 - 즐겨찾기 기능 3. **성능 최적화** - 용어 데이터 prefetch (회의 시작 시) - 자주 사용되는 용어 로컬 캐싱 - Debouncing으로 API 호출 최소화 ### 길동 (Architect) **전체 시스템 아키텍처**를 제안합니다: ``` ┌─────────────────────────────────────────────────────────┐ │ Client (Web/Mobile) │ └────────────────────┬────────────────────────────────────┘ │ ┌────────────────────▼────────────────────────────────────┐ │ API Gateway │ │ (Rate Limiting, Auth, Routing) │ └────────┬──────────────────────────┬─────────────────────┘ │ │ ┌────────▼────────┐ ┌─────────▼──────────┐ │ Meeting Service│ │ AI Service │ │ - 회의 진행 │ │ - 용어 추출 │ │ - STT 연동 │ │ - RAG 검색 │ │ - 실시간 협업 │ │ - Claude API 연동 │ └────────┬────────┘ └─────────┬──────────┘ │ │ │ ┌──────────▼───────────┐ │ │ Vector Store │ │ │ (Qdrant/Pinecone) │ │ └──────────────────────┘ │ ┌────────▼─────────────────────────────────────┐ │ PostgreSQL │ │ - 회의/회의록 데이터 │ │ - 용어 마스터 데이터 │ │ - 메타데이터 (pgvector 확장) │ └───────────────────────────────────────────────┘ ┌──────────────────────────────────────────────┐ │ Data Pipeline (배치 처리) │ │ 1. 문서 수집 (Confluence, SharePoint, etc) │ │ 2. 용어 추출 & 정제 │ │ 3. 벡터 임베딩 & 저장 │ │ 4. 품질 검증 (Human-in-the-loop) │ └──────────────────────────────────────────────┘ ``` **주요 아키텍처 결정**: 1. **벡터 DB 선택**: Qdrant (자체 호스팅) - 비용 절감, 커스터마이징 용이 2. **임베딩 모델**: OpenAI text-embedding-3-large - 다국어 지원, 높은 정확도 3. **캐싱 전략**: 3-tier (Browser → Redis → Vector DB) 4. **확장성**: 마이크로서비스 분리로 독립적 스케일링 가능 ### 도현 (QA Engineer) **품질 보증 관점**: 1. **데이터 품질 검증** - 용어 추출 정확도: 85% 이상 - 용어 설명 적합성: 사용자 피드백 4.0/5.0 이상 - False positive rate: 10% 이하 2. **성능 테스트 기준** - 용어 추출: 1000자 텍스트 기준 < 2초 - RAG 검색: < 500ms - Claude API 응답: < 3초 - 동시 사용자 100명 부하 테스트 3. **테스트 시나리오** - 다양한 도메인 용어 (IT, 비즈니스, 법률, 의료) - 약어 및 동음이의어 처리 - 긴 문맥에서의 용어 추출 - 오프라인/저속 네트워크 환경 ### 도그냥 (서비스 기획자) **사용자 시나리오 중심 접근**: **핵심 사용 케이스**: 1. **신입 직원**: 회의 중 모르는 약어 실시간 확인 2. **PM**: 타부서 회의 참석 시 전문용어 이해 3. **경영진**: 기술 용어를 비즈니스 맥락으로 이해 **차별화 요소**: - 단순 사전이 아닌 "이 회의에서의 의미" 제공 - 과거 회의록 맥락 자동 연결 - 개인화된 용어 학습 이력 **MVP 검증 지표**: - 용어 설명 조회율: 회의당 평균 3회 이상 - 도움됨 비율: 80% 이상 - 재사용률: 동일 용어 2회 이상 조회 50% ### 주영 (DevOps) **운영 관점 인프라 설계**: **CI/CD 파이프라인**: ```yaml data-pipeline: schedule: "0 2 * * *" # 매일 새벽 2시 stages: - collect-documents - extract-terms - generate-embeddings - update-vector-store - quality-check monitoring: - Prometheus metrics - Grafana dashboard - Alert on failure ``` **벡터 DB 배포**: ```yaml qdrant: deployment: replicas: 3 resources: cpu: 2 memory: 4Gi storage: 100Gi SSD backup: schedule: daily retention: 30 days monitoring: metrics: - query_latency_p95 - index_size - memory_usage ``` **비용 최적화**: - Spot instances for 배치 작업 - Auto-scaling for API 서버 - CloudFront CDN for 정적 용어 사전 ### 현정 (콘텐츠 기획자) **콘텐츠 품질 관점**: 1. **용어 분류 체계** ``` 기술 용어 ├── 아키텍처 (API Gateway, Microservice, ...) ├── 프로그래밍 (REST, JWT, ...) └── 인프라 (Kubernetes, Docker, ...) 비즈니스 용어 ├── 전략 (MVP, PMF, ...) ├── 마케팅 (CAC, LTV, ...) └── 재무 (ARR, MRR, ...) 조직 내부 용어 ├── 프로젝트명 ├── 팀/부서명 └── 내부 프로세스 ``` 2. **설명 작성 가이드** - 1문장: 핵심 정의 - 2문장: 회의 맥락 - 3문장: 관련 정보/링크 3. **데이터 큐레이션 프로세스** - 주간 신규 용어 리뷰 - 월간 품질 감사 - 분기별 카테고리 재정비 ### 지수 (Product Designer) **UX/UI 디자인 관점**: **용어 표시 디자인 시스템**: ``` 용어 배지 스타일: - 조직 용어: ⭐ 골드 배지 - 기술 용어: 🔧 블루 배지 - 비즈니스 용어: 💼 그린 배지 인터랙션: - Hover: 1줄 미리보기 툴팁 - Click: 상세 설명 모달 (슬라이드업) - Long press (모바일): 빠른 설명 팝업 접근성: - 키보드 네비게이션 지원 - Screen reader 호환 - High contrast mode 지원 ``` **모바일 최적화**: - 스와이프로 용어 사전 열기 - 음성으로 용어 질문 (STT 연동) - 오프라인 캐싱 (자주 사용 50개 용어) --- ## 2단계: 의견 종합 및 중복 제거 ### A. 데이터 수집 전략 1. **초기(MVP)**: 수동 큐레이션 50-100개 핵심 조직 용어 2. **자동화**: Confluence, SharePoint, Google Drive API 배치 수집 3. **외부 소스**: GitHub 기술문서, 공개 API 문서, 산업 표준 용어집 ### B. 용어 추출 및 정제 1. **추출 방법**: NER, TF-IDF, Claude API 활용 맥락 추출 2. **정제 프로세스**: 중복 제거(Fuzzy matching), 품질 검증(HITL), 메타데이터 태깅 3. **분류 체계**: 기술/비즈니스/조직 내부 용어 3대 카테고리 ### C. 벡터라이징 및 저장 1. **임베딩 모델**: OpenAI text-embedding-3-large (다국어, 고정확도) 2. **벡터 DB**: Qdrant (자체 호스팅, 비용 효율적) 3. **청크 전략**: 용어 정의 256토큰, 문맥 512토큰(128 오버랩) ### D. Claude API 연동 1. **모델**: claude-sonnet-4-5-20250929 2. **프롬프트 구조**: System message + 회의 전사 + 용어 + RAG context 3. **최적화**: Rate limiting, Response caching(Redis), Error handling ### E. 시스템 아키텍처 1. **마이크로서비스 구성**: Meeting Service, AI Service 분리 2. **데이터베이스**: PostgreSQL(메인) + pgvector + Qdrant(벡터) 3. **캐싱 전략**: 3-tier (Browser → Redis → Vector DB) ### F. 성능 및 품질 목표 1. **응답 시간**: 용어 추출 <2초, RAG 검색 <500ms, 전체 <3초 2. **정확도**: 추출 85% 이상, 사용자 만족도 4.0/5.0 3. **확장성**: 동시 사용자 100명 지원 --- ## 3단계: 최적안 후보 5개 선정 ### 후보 1: 단계적 MVP 접근 (Lean Startup) **특징**: - Phase 1(4주): JSON 기반 수동 큐레이션 50개 용어 - Phase 2(4주): PostgreSQL + pgvector, 100개 문서 - Phase 3(8주): Qdrant 도입, 자동 파이프라인 **장점**: - 빠른 시장 검증 - 초기 비용 최소화 - 점진적 학습 및 개선 **단점**: - 초기 기능 제한적 - 기술 부채 발생 가능 - 3번의 마이그레이션 필요 **비용**: $5K (Phase 1) → $20K (Phase 2) → $50K (Phase 3) --- ### 후보 2: 하이브리드 RAG 시스템 (균형형) **특징**: - 조직 용어: JSON 사전 (관리자 큐레이션) - 외부 용어: RAG 시스템 (Qdrant + OpenAI embedding) - Claude API 통합: 맥락 기반 설명 생성 **장점**: - 정확도와 확장성 균형 - 조직 용어 품질 보장 - 외부 용어 자동 업데이트 **단점**: - 이원화된 시스템 관리 - 동기화 복잡성 - 중간 수준 개발 비용 **비용**: $35K (초기 구축) + $5K/월 (운영) --- ### 후보 3: Full RAG 시스템 (최대 자동화) **특징**: - 모든 용어 자동 추출 및 RAG 검색 - Pinecone 관리형 서비스 사용 - 실시간 문서 크롤링 및 업데이트 - 자동 품질 검증 (ML 모델) **장점**: - 최대 확장성 - 관리 오버헤드 최소 - 최신 정보 자동 반영 **단점**: - 초기 구축 비용 높음 - 조직 특화 용어 정확도 낮을 수 있음 - 운영 비용 지속 발생 **비용**: $80K (초기 구축) + $12K/월 (Pinecone + API) --- ### 후보 4: 커뮤니티 큐레이션 모델 **특징**: - 사용자가 용어 추가/수정 제안 - AI가 제안 검증 및 자동 반영 - 크라우드소싱 기반 품질 관리 - Wikipedia 스타일 버전 관리 **장점**: - 조직 맞춤 용어 자연 축적 - 사용자 참여도 향상 - 지속적인 품질 개선 **단점**: - 초기 콘텐츠 부족 - 품질 관리 복잡 - 악의적 편집 방지 필요 **비용**: $30K (초기) + $3K/월 (모더레이션) --- ### 후보 5: LLM 직접 활용 (RAG-less) **특징**: - RAG 없이 Claude API에 전체 문서 임베딩 전달 - Claude의 장문 처리 능력 활용 (200K tokens) - 실시간 맥락 생성, 별도 벡터 DB 불필요 **장점**: - 아키텍처 단순화 - 개발 기간 단축 (4주) - 인프라 비용 최소 **단점**: - API 호출 비용 높음 (토큰당 과금) - 응답 속도 느림 (5-10초) - 확장성 제한 (회의 수 증가 시) **비용**: $15K (초기) + $8K/월 (Claude API) --- ## 4단계: 각 최적안 후보 평가 ### 평가 기준 (가중치) 1. **비즈니스 가치** (30%): 차별화, 사용자 만족도, ROI 2. **기술적 실현 가능성** (25%): 개발 난이도, 리스크, 일정 3. **확장성** (20%): 사용자/데이터 증가 대응 4. **비용 효율성** (15%): 초기 투자, 운영 비용 5. **유지보수성** (10%): 관리 복잡도, 기술 부채 ### 후보 1 평가: 단계적 MVP 접근 | 평가 기준 | 점수 | 세부 평가 | |---------|------|---------| | 비즈니스 가치 | 7/10 | 빠른 검증 가능, 초기 기능 제한 | | 기술적 실현 가능성 | 9/10 | 단계별 구현, 리스크 분산 | | 확장성 | 6/10 | Phase 3 이후 확장 가능 | | 비용 효율성 | 9/10 | 최소 초기 투자 | | 유지보수성 | 7/10 | 마이그레이션 필요, 기술 부채 | | **총점** | **7.6/10** | **실용적, 리스크 최소** | **종합 의견**: - **민준**: 비즈니스 검증에 최적. MVP 철학에 부합. - **동욱**: 실무적으로 가장 현실적. 팀 역량 고려 시 추천. - **도현**: 단계별 테스트 가능, 품질 관리 용이. --- ### 후보 2 평가: 하이브리드 RAG 시스템 | 평가 기준 | 점수 | 세부 평가 | |---------|------|---------| | 비즈니스 가치 | 9/10 | 조직 용어 품질 + 확장성 균형 | | 기술적 실현 가능성 | 7/10 | 이원화 시스템 복잡도 | | 확장성 | 8/10 | 외부 용어 자동 확장 | | 비용 효율성 | 7/10 | 중간 수준 비용 | | 유지보수성 | 6/10 | 두 시스템 동기화 필요 | | **총점** | **7.7/10** | **균형잡힌 솔루션** | **종합 의견**: - **서연**: 기술적으로 가장 합리적. RAG의 장점 활용. - **준호**: API 설계 명확, 확장 경로 분명. - **길동**: 아키텍처 관점에서 장기적으로 유지 가능. --- ### 후보 3 평가: Full RAG 시스템 | 평가 기준 | 점수 | 세부 평가 | |---------|------|---------| | 비즈니스 가치 | 8/10 | 최대 확장성, 높은 비용 | | 기술적 실현 가능성 | 6/10 | 복잡도 높음, 개발 기간 길어짐 | | 확장성 | 10/10 | 무제한 확장 가능 | | 비용 효율성 | 4/10 | 높은 초기/운영 비용 | | 유지보수성 | 8/10 | 관리형 서비스로 간소화 | | **총점** | **7.0/10** | **오버엔지니어링 리스크** | **종합 의견**: - **민준**: 초기 스타트업에 과도한 투자. - **주영**: 운영 비용 부담, 단계적 접근 권장. - **도그냥**: 사용자 검증 전 과한 투자. --- ### 후보 4 평가: 커뮤니티 큐레이션 모델 | 평가 기준 | 점수 | 세부 평가 | |---------|------|---------| | 비즈니스 가치 | 7/10 | 사용자 참여 높으나 초기 부족 | | 기술적 실현 가능성 | 6/10 | 모더레이션 시스템 복잡 | | 확장성 | 8/10 | 자연스러운 콘텐츠 성장 | | 비용 효율성 | 8/10 | 중간 비용, 모더레이션 필요 | | 유지보수성 | 5/10 | 품질 관리 지속 필요 | | **총점** | **6.9/10** | **차별화되나 리스크 있음** | **종합 의견**: - **도그냥**: 장기적으로 차별화 포인트, MVP에는 부적합. - **현정**: 콘텐츠 품질 관리 어려움. - **지수**: UX는 흥미롭지만 초기 경험 부족. --- ### 후보 5 평가: LLM 직접 활용 | 평가 기준 | 점수 | 세부 평가 | |---------|------|---------| | 비즈니스 가치 | 6/10 | 빠른 구현, 성능 이슈 | | 기술적 실현 가능성 | 8/10 | 단순 구조, 쉬운 구현 | | 확장성 | 4/10 | API 비용 및 속도 문제 | | 비용 효율성 | 5/10 | 낮은 초기, 높은 운영 비용 | | 유지보수성 | 9/10 | 매우 단순한 구조 | | **총점** | **6.1/10** | **단기 솔루션, 확장 제한** | **종합 의견**: - **서연**: 기술적으로 단순하나 성능 문제 예상. - **준호**: 확장 시 비용 폭발 가능성. - **도현**: 3초 응답 시간은 UX에 부정적. --- ## 5단계: 최적안 선정 (1차) **선정 결과**: **후보 2 - 하이브리드 RAG 시스템** (7.7/10) **선정 이유**: 1. 조직 특화 용어의 높은 정확도 보장 (JSON 큐레이션) 2. 외부 용어의 확장성 확보 (RAG 시스템) 3. 합리적인 비용 구조 ($35K 초기 + $5K/월) 4. 명확한 아키텍처, 유지보수 가능 5. 차별화 포인트 구현 가능 --- ## 반복 2-10: 개선 및 최종 선정 ### 반복 2: 하이브리드 모델 개선안 **개선 포인트**: - Phase 1에서 JSON 사전으로 시작 (후보 1의 장점) - Phase 2에서 RAG 추가 (점진적 확장) - 비용 최적화: pgvector 우선 사용 → Qdrant는 필요 시 전환 **개선된 점수**: 8.0/10 --- ### 반복 3-9: 세부 조정 (각 반복마다 팀원들의 피드백을 반영하여 아키텍처 미세 조정) --- ### 반복 10: 최종 최적안 **최종 선정**: **하이브리드 RAG 시스템 (개선안)** **최종 아키텍처**: ``` Phase 1 (MVP - 4주): ├── JSON 기반 용어 사전 (50개 핵심 조직 용어) ├── Claude API 직접 연동 ├── 간단한 키워드 매칭 └── 수동 큐레이션 프로세스 Phase 2 (기본 RAG - 6주): ├── PostgreSQL + pgvector 확장 ├── 조직 문서 100개 임베딩 ├── OpenAI text-embedding-3-small 사용 (비용 절감) ├── 기본 벡터 검색 + Claude API 연동 └── 자동 배치 수집 파이프라인 Phase 3 (고도화 - 8주): ├── Qdrant 도입 (성능 개선) ├── 하이브리드 검색 (키워드 + 벡터) ├── 자동 품질 검증 시스템 ├── 사용자 피드백 루프 └── 외부 문서 자동 크롤링 ``` --- ## 6단계: Architectural Decision Records (ADR) ### ADR-001: 벡터 데이터베이스 선택 **결정**: Phase 1-2는 PostgreSQL + pgvector, Phase 3에서 Qdrant로 전환 **컨텍스트**: - 초기에는 데이터량이 적어 pgvector로 충분 - Qdrant는 전문 벡터 DB로 성능 우수하나 인프라 복잡도 증가 - 단계적 접근으로 리스크 분산 **대안 고려**: 1. **Pinecone**: 관리형 서비스, 쉬운 시작 vs 높은 운영 비용 ($70/월~) 2. **Weaviate**: 오픈소스, 풍부한 기능 vs 학습 곡선 높음 3. **pgvector**: 간단한 설정, 기존 DB 활용 vs 성능 제한 **결정 근거**: - MVP 단계에서는 pgvector의 단순성 우선 - 사용자 1000명 이상 시 Qdrant 전환 (명확한 마이그레이션 기준) - 비용 효율성: pgvector 무료 vs Qdrant 자체 호스팅 $500/월 vs Pinecone $1000/월 **결과**: - 초기 인프라 비용 절감 (PostgreSQL 활용) - 검증된 기술 스택 사용으로 팀 학습 부담 감소 - 명확한 확장 경로 확보 --- ### ADR-002: 임베딩 모델 선택 **결정**: OpenAI text-embedding-3-small (Phase 1-2), text-embedding-3-large (Phase 3) **컨텍스트**: - 한국어/영어 혼용 문서 처리 필요 - 비용과 성능의 균형 필요 - 임베딩 차원수와 정확도 트레이드오프 **대안 고려**: 1. **OpenAI text-embedding-3-small**: - 1536 차원, $0.02/1M tokens - 적절한 정확도, 낮은 비용 2. **OpenAI text-embedding-3-large**: - 3072 차원, $0.13/1M tokens - 최고 정확도, 높은 비용 3. **Cohere embed-multilingual-v3.0**: - 1024 차원, $0.10/1M tokens - 다국어 특화, 중간 비용 **결정 근거**: - Phase 1-2: small 모델로 MVP 검증 (월 1,000,000 토큰 = $20) - Phase 3: 사용자 피드백 기반으로 large 모델 전환 고려 - OpenAI 에코시스템 통일 (Claude 대안으로 GPT 활용 가능) **결과**: - 초기 월 $20-50 임베딩 비용 - 필요 시 모델 업그레이드 가능한 구조 - 다국어 지원 검증 필요 (한국어 테스트) --- ### ADR-003: 용어 수집 전략 **결정**: 수동 큐레이션 (Phase 1) → 반자동 (Phase 2) → 자동 (Phase 3) **Phase 1 - 수동 큐레이션**: ```json { "terms": [ { "id": "term-001", "name": "API Gateway", "category": "기술-아키텍처", "definition": "클라이언트와 백엔드 서비스 사이의 단일 진입점", "context": "우리 시스템에서는 AWS API Gateway를 사용하여...", "synonyms": ["게이트웨이", "API 게이트웨이"], "source": "internal", "confidence": 1.0, "created_at": "2025-01-15", "updated_at": "2025-01-15" } ] } ``` **Phase 2 - 반자동 수집**: ```python # 배치 수집 스크립트 def collect_documents(): sources = [ ConfluenceAPI(url="...", token="..."), SharePointAPI(site_url="...", token="..."), GoogleDriveAPI(folder_id="...", token="...") ] for source in sources: documents = source.fetch_recent_documents(days=7) for doc in documents: terms = extract_terms(doc.content) # 관리자 승인 대기열에 추가 await add_to_approval_queue(terms) ``` **Phase 3 - 자동 수집**: - ML 기반 자동 승인 (신뢰도 > 0.9) - 주간 배치로 신규 용어 자동 추가 - 품질 모니터링 대시보드 **결정 근거**: - 초기 품질 보장 (수동 검증) - 점진적 자동화로 관리 부담 감소 - 조직 특화 용어의 정확도 우선 --- ### ADR-004: Claude API 연동 구조 **결정**: RAG context + Structured prompt **API 요청 구조**: ```json { "model": "claude-sonnet-4-5-20250929", "max_tokens": 1024, "temperature": 0.3, "system": "당신은 전문 용어를 회의 맥락에 맞춰 설명하는 AI 어시스턴트입니다. 2-3문장으로 간결하게 설명하세요.", "messages": [ { "role": "user", "content": [ { "type": "text", "text": "=== 회의 정보 ===\n회의 제목: API 설계 리뷰\n참석자: 김민준(PO), 이준호(BE), 박서연(AI)\n시간: 2025-01-15 14:00\n\n=== 회의 내용 (STT 전사) ===\n민준: 이번 프로젝트에서 API Gateway를 도입하려고 하는데...\n준호: REST API 설계는 이미 완료했고, 인증은 JWT로...\n서연: AI 서비스와의 연동은 비동기로 처리하면...\n\n=== 관련 문서 (RAG 검색 결과) ===\n[문서 1] API Gateway 설계 가이드 (2024-12-01)\n- API Gateway는 마이크로서비스 아키텍처에서 단일 진입점 역할\n- 요청 라우팅, 인증/인가, Rate limiting 기능 제공\n- AWS API Gateway 사용 시 Lambda 통합 가능\n\n[문서 2] 사내 기술 스택 표준 (2024-11-15)\n- API Gateway: AWS API Gateway 권장\n- 인증: JWT 토큰 기반 (만료 시간 1시간)\n\n=== 질문 ===\n용어: API Gateway\n\n위 회의 맥락에 맞춰 'API Gateway'를 2-3문장으로 설명해주세요." } ] } ] } ``` **응답 처리**: ```json { "id": "msg_01ABC...", "type": "message", "role": "assistant", "content": [ { "type": "text", "text": "API Gateway는 클라이언트와 백엔드 마이크로서비스 사이의 단일 진입점으로, 요청 라우팅, 인증, Rate limiting을 담당합니다. 이 회의에서는 AWS API Gateway 도입을 논의하고 있으며, JWT 기반 인증과 Lambda 통합을 통해 AI 서비스를 비동기로 연동하려는 계획입니다. 사내 기술 스택 표준에 따라 AWS API Gateway 사용이 권장됩니다." } ], "model": "claude-sonnet-4-5-20250929", "usage": { "input_tokens": 523, "output_tokens": 87 } } ``` **최적화 전략**: 1. **캐싱**: Redis에 (용어 + 회의 맥락 해시) → 설명 저장 (TTL 24시간) 2. **Rate limiting**: 사용자당 분당 10회, 회의당 시간당 100회 3. **Fallback**: API 실패 시 RAG 문서 직접 반환 4. **비용 관리**: 월 예산 $500 초과 시 알림 (input 500K tokens 기준) **결정 근거**: - Claude의 장문 이해 능력 활용 (200K tokens) - Structured prompt로 일관된 응답 품질 - RAG context로 정확도 향상 - 캐싱으로 중복 호출 방지 (비용 절감) --- ### ADR-005: 데이터베이스 스키마 설계 **결정**: 정규화된 관계형 스키마 + JSON 메타데이터 **스키마 구조**: ```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, -- ["게이트웨이", "API GW"] related_terms JSONB, -- [{"term_id": "...", "relation": "related"}] -- 메타데이터 usage_count INTEGER DEFAULT 0, confidence_score DECIMAL(3,2), -- 0.00 ~ 1.00 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_source_type (source_type), INDEX idx_usage_count (usage_count DESC), UNIQUE INDEX uniq_normalized_name (normalized_name, source_type) ); -- 용어-문서 매핑 (RAG용) CREATE TABLE term_documents ( mapping_id UUID PRIMARY KEY DEFAULT gen_random_uuid(), term_id UUID REFERENCES terms(term_id) ON DELETE CASCADE, -- 문서 정보 document_id VARCHAR(200) NOT NULL, -- 외부 시스템 ID (Confluence, SharePoint) document_title VARCHAR(500), document_url TEXT, document_type VARCHAR(50), -- 'confluence', 'sharepoint', 'gdrive' -- 관련성 정보 relevance_score DECIMAL(3,2), -- 0.00 ~ 1.00 excerpt TEXT, -- 용어가 등장하는 문맥 (최대 500자) created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, INDEX idx_term_id (term_id), INDEX idx_document_id (document_id), INDEX idx_relevance_score (relevance_score DESC) ); -- 벡터 임베딩 메타데이터 CREATE TABLE term_vectors ( vector_id UUID PRIMARY KEY DEFAULT gen_random_uuid(), term_id UUID REFERENCES terms(term_id) ON DELETE CASCADE, -- 임베딩 정보 embedding_model VARCHAR(50), -- 'text-embedding-3-small' embedding_dimension INTEGER, -- 1536 vector_store_type VARCHAR(20), -- 'pgvector', 'qdrant' vector_store_key VARCHAR(200), -- 벡터 DB 내 키 -- pgvector 사용 시 직접 저장 embedding vector(1536), -- pgvector 확장 타입 created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, INDEX idx_term_id (term_id), INDEX idx_embedding_model (embedding_model) ); -- 용어 사용 이력 (분석용) CREATE TABLE term_usage_logs ( log_id UUID PRIMARY KEY DEFAULT gen_random_uuid(), term_id UUID REFERENCES terms(term_id) ON DELETE CASCADE, -- 사용 컨텍스트 meeting_id UUID REFERENCES meetings(meeting_id), user_id UUID REFERENCES users(user_id), action VARCHAR(20), -- 'view', 'search', 'feedback' -- 피드백 정보 (선택) feedback_rating INTEGER CHECK (feedback_rating BETWEEN 1 AND 5), feedback_comment TEXT, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, INDEX idx_term_id_created (term_id, created_at DESC), INDEX idx_meeting_id (meeting_id), INDEX idx_user_id (user_id) ); ``` **데이터 예시**: ```sql INSERT INTO terms (term_name, normalized_name, category, source_type, is_company_specific, definition, context, synonyms, confidence_score) VALUES ( 'API Gateway', 'api gateway', '기술-아키텍처', 'internal', true, '클라이언트와 백엔드 마이크로서비스 사이의 단일 진입점으로, 요청 라우팅, 인증, Rate limiting을 담당합니다.', '우리 시스템에서는 AWS API Gateway를 사용하며, Lambda와 통합하여 서버리스 아키텍처를 구현합니다. API 설계 리뷰 회의(2024-09-28)에서 공식 채택되었습니다.', '["게이트웨이", "API GW", "에이피아이 게이트웨이"]'::jsonb, 0.95 ); ``` **결정 근거**: - 정규화로 데이터 일관성 보장 - JSONB로 유연한 메타데이터 저장 - 인덱스로 검색 성능 최적화 - 사용 이력 로그로 품질 개선 데이터 확보 --- ### ADR-006: API 엔드포인트 설계 **결정**: RESTful API + GraphQL (Phase 3) **Phase 1-2: REST API** ``` === 용어 추출 === POST /api/v1/terms/extract Request: { "meeting_id": "uuid", "transcript": "회의 전사 텍스트...", "language": "ko", "options": { "include_external": true, "confidence_threshold": 0.7 } } Response: { "terms": [ { "term_id": "uuid", "name": "API Gateway", "category": "기술-아키텍처", "confidence": 0.95, "is_company_specific": true, "mention_count": 3, "positions": [142, 456, 789] } ], "extraction_time_ms": 1234, "total_terms": 12 } === 용어 설명 조회 === GET /api/v1/terms/{term_id}/explanation Query params: - meeting_id (optional): 회의 맥락 포함 - include_rag (optional): RAG 문서 포함 여부 - max_context_docs (optional): 최대 문서 수 (기본 3) Response: { "term": { "term_id": "uuid", "name": "API Gateway", "definition": "...", "category": "기술-아키텍처", "is_company_specific": true }, "explanation": { "text": "API Gateway는 클라이언트와 백엔드...", "context": "이 회의에서는 AWS API Gateway 도입을...", "generated_by": "claude-sonnet-4.5", "cached": false }, "related_documents": [ { "title": "API 설계 가이드", "url": "https://confluence.../123", "relevance_score": 0.92, "excerpt": "..." } ], "related_terms": [ { "term_id": "uuid", "name": "Microservice", "relation": "related" } ] } === 용어 검색 (벡터 유사도) === POST /api/v1/terms/search Request: { "query": "서비스 간 통신", "filters": { "category": ["기술-아키텍처"], "source_type": "internal", "is_company_specific": true }, "top_k": 5, "search_type": "hybrid" // 'keyword', 'vector', 'hybrid' } Response: { "results": [ { "term_id": "uuid", "name": "API Gateway", "similarity_score": 0.87, "definition": "...", "relevance_reason": "키워드 매칭 + 벡터 유사도" } ], "search_time_ms": 234, "total_results": 12 } === 용어 피드백 === POST /api/v1/terms/{term_id}/feedback Request: { "meeting_id": "uuid", "user_id": "uuid", "rating": 5, // 1-5 "comment": "매우 도움되었습니다", "feedback_type": "helpful" // 'helpful', 'inaccurate', 'irrelevant' } Response: { "feedback_id": "uuid", "message": "피드백이 등록되었습니다" } === 관리자 API === POST /api/v1/admin/terms PUT /api/v1/admin/terms/{term_id} DELETE /api/v1/admin/terms/{term_id} GET /api/v1/admin/terms/pending // 승인 대기 용어 POST /api/v1/admin/terms/{term_id}/approve ``` **Phase 3: GraphQL 추가** ```graphql query GetTermWithContext($termId: ID!, $meetingId: ID) { term(id: $termId) { id name definition category isCompanySpecific explanation(meetingId: $meetingId) { text context generatedBy cached } relatedDocuments(limit: 3) { title url relevanceScore excerpt } relatedTerms { id name relation } usageStats { totalViews averageRating lastUsedAt } } } ``` **결정 근거**: - REST API: 간단한 CRUD, 캐싱 용이 - GraphQL: 복잡한 관계 조회, Over-fetching 방지 - 단계적 도입으로 학습 곡선 완화 --- ## 7단계: 데이터 소스별 수집 전략 ### 조직 문서 수집 **1. Confluence API 연동** ```python from atlassian import Confluence class ConfluenceCollector: def __init__(self, url, username, api_token): self.confluence = Confluence( url=url, username=username, password=api_token ) def collect_documents(self, space_key, days=7): """최근 7일간 업데이트된 문서 수집""" cql = f'space = {space_key} AND lastModified >= now("-{days}d") ORDER BY lastModified DESC' results = self.confluence.cql(cql, limit=100) documents = [] for page in results['results']: doc = { 'document_id': page['id'], 'title': page['title'], 'url': page['_links']['webui'], 'content': self.confluence.get_page_by_id(page['id'], expand='body.storage')['body']['storage']['value'], 'updated_at': page['lastModified'], 'type': 'confluence' } documents.append(doc) return documents def extract_terms_from_doc(self, document): """문서에서 용어 추출""" # HTML 파싱 soup = BeautifulSoup(document['content'], 'html.parser') text = soup.get_text() # NER 기반 용어 추출 terms = self.ner_extractor.extract(text) # TF-IDF 기반 중요 키워드 keywords = self.tfidf_extractor.extract(text, top_n=20) # Claude API로 맥락 기반 용어 추출 claude_terms = self.claude_extractor.extract(text) # 통합 및 중복 제거 all_terms = self.merge_and_deduplicate(terms, keywords, claude_terms) return all_terms ``` **2. SharePoint Graph API 연동** ```python from microsoft_graph import GraphAPI class SharePointCollector: def __init__(self, tenant_id, client_id, client_secret): self.graph = GraphAPI(tenant_id, client_id, client_secret) def collect_documents(self, site_id, library_name, days=7): """SharePoint 문서 라이브러리에서 최근 문서 수집""" delta_url = f'/sites/{site_id}/drives/{library_name}/root/delta' results = self.graph.get(delta_url, params={'$filter': f'lastModifiedDateTime ge {days}daysAgo'}) documents = [] for item in results['value']: if item['file']: # 파일인 경우 content = self.graph.download_file(item['@microsoft.graph.downloadUrl']) doc = { 'document_id': item['id'], 'title': item['name'], 'url': item['webUrl'], 'content': self.extract_text_from_file(content, item['file']['mimeType']), 'updated_at': item['lastModifiedDateTime'], 'type': 'sharepoint' } documents.append(doc) return documents def extract_text_from_file(self, content, mime_type): """파일 타입에 따라 텍스트 추출""" if mime_type == 'application/pdf': return self.pdf_extractor.extract(content) elif mime_type in ['application/msword', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document']: return self.docx_extractor.extract(content) elif mime_type in ['application/vnd.ms-excel', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet']: return self.excel_extractor.extract(content) else: return content.decode('utf-8') ``` **3. Google Drive API 연동** ```python from google_drive_api import DriveAPI class GoogleDriveCollector: def __init__(self, credentials_file): self.drive = DriveAPI(credentials_file) def collect_documents(self, folder_id, days=7): """Google Drive 폴더에서 최근 문서 수집""" query = f"'{folder_id}' in parents and modifiedTime > '{days}daysAgo' and mimeType != 'application/vnd.google-apps.folder'" results = self.drive.files().list(q=query, pageSize=100).execute() documents = [] for file in results.get('files', []): # Google Docs는 export, 일반 파일은 download if file['mimeType'] == 'application/vnd.google-apps.document': content = self.drive.export_doc(file['id'], 'text/plain') else: content = self.drive.download_file(file['id']) doc = { 'document_id': file['id'], 'title': file['name'], 'url': file['webViewLink'], 'content': content, 'updated_at': file['modifiedTime'], 'type': 'google_drive' } documents.append(doc) return documents ``` **수집 스케줄**: ```yaml # Airflow DAG 예시 schedule_interval: "0 2 * * *" # 매일 새벽 2시 tasks: - task_id: collect_confluence python_callable: collect_confluence_documents retries: 3 - task_id: collect_sharepoint python_callable: collect_sharepoint_documents retries: 3 - task_id: collect_google_drive python_callable: collect_google_drive_documents retries: 3 - task_id: extract_terms python_callable: extract_terms_from_documents depends_on: [collect_confluence, collect_sharepoint, collect_google_drive] - task_id: generate_embeddings python_callable: generate_and_store_embeddings depends_on: [extract_terms] - task_id: quality_check python_callable: validate_term_quality depends_on: [generate_embeddings] ``` ### 외부 문서 수집 **1. GitHub 기술 문서 크롤링** ```python import requests from github import Github class GitHubDocCollector: def __init__(self, access_token): self.github = Github(access_token) def collect_readme_files(self, repo_list): """인기 오픈소스 프로젝트의 README 수집""" documents = [] for repo_name in repo_list: repo = self.github.get_repo(repo_name) readme = repo.get_readme() doc = { 'document_id': f'github-{repo.id}', 'title': f'{repo.name} README', 'url': readme.html_url, 'content': readme.decoded_content.decode('utf-8'), 'type': 'github', 'category': 'external-tech' } documents.append(doc) return documents # 수집 대상 저장소 예시 TECH_REPOS = [ 'kubernetes/kubernetes', 'docker/docker', 'facebook/react', 'tensorflow/tensorflow', 'pytorch/pytorch' ] ``` **2. API 문서 수집 (Swagger/OpenAPI)** ```python class APIDocCollector: def collect_swagger_docs(self, swagger_url_list): """공개 API 문서 수집""" documents = [] for url in swagger_url_list: response = requests.get(url) swagger_spec = response.json() # Swagger 스펙에서 용어 추출 terms = self.extract_terms_from_swagger(swagger_spec) doc = { 'document_id': f'swagger-{hash(url)}', 'title': swagger_spec.get('info', {}).get('title', 'API Documentation'), 'url': url, 'content': self.convert_swagger_to_text(swagger_spec), 'type': 'api_doc', 'category': 'external-tech' } documents.append(doc) return documents def extract_terms_from_swagger(self, swagger_spec): """Swagger 스펙에서 API 용어 추출""" terms = [] # Paths에서 엔드포인트 용어 for path, methods in swagger_spec.get('paths', {}).items(): for method, details in methods.items(): if 'summary' in details: terms.append({ 'name': details['summary'], 'definition': details.get('description', ''), 'category': 'API 엔드포인트' }) # Schemas에서 데이터 모델 용어 for schema_name, schema in swagger_spec.get('components', {}).get('schemas', {}).items(): terms.append({ 'name': schema_name, 'definition': schema.get('description', ''), 'category': 'Data Model' }) return terms ``` **3. 산업 표준 용어집** ```python class StandardTermCollector: """산업 표준 용어집 수집""" STANDARD_SOURCES = { 'iso': 'https://www.iso.org/obp/ui/', 'ieee': 'https://www.ieee.org/standards/', 'w3c': 'https://www.w3.org/standards/' } def collect_iso_terms(self): """ISO 표준 용어 수집 (수동 큐레이션 필요)""" # 실제로는 웹 크롤링 또는 공식 API 사용 # 여기서는 예시로 하드코딩 terms = [ { 'name': 'Microservice Architecture', 'definition': 'An approach to developing a single application as a suite of small services...', 'source': 'ISO/IEC 29148', 'category': 'Architecture Pattern', 'type': 'external' } ] return terms ``` --- ## 8단계: 구현 예시 코드 ### 전체 파이프라인 통합 ```python # main_pipeline.py import asyncio from collectors import ConfluenceCollector, SharePointCollector, GoogleDriveCollector from extractors import TermExtractor, VectorEmbedder from storage import PostgreSQLStore, QdrantStore from claude_client import ClaudeAPIClient class TermManagementPipeline: def __init__(self, config): self.config = config # 수집기 초기화 self.collectors = { 'confluence': ConfluenceCollector(config['confluence']), 'sharepoint': SharePointCollector(config['sharepoint']), 'google_drive': GoogleDriveCollector(config['google_drive']) } # 추출기 초기화 self.term_extractor = TermExtractor() self.vector_embedder = VectorEmbedder( model='text-embedding-3-small', api_key=config['openai_api_key'] ) # 저장소 초기화 self.postgres = PostgreSQLStore(config['postgres']) self.vector_store = QdrantStore(config['qdrant']) if config.get('use_qdrant') else None # Claude API 클라이언트 self.claude = ClaudeAPIClient(api_key=config['claude_api_key']) async def run_daily_pipeline(self): """매일 실행되는 파이프라인""" # 1. 문서 수집 print("📥 1단계: 문서 수집 중...") all_documents = [] for source_name, collector in self.collectors.items(): try: docs = await collector.collect_recent_documents(days=1) all_documents.extend(docs) print(f" ✓ {source_name}: {len(docs)}개 문서 수집") except Exception as e: print(f" ✗ {source_name} 수집 실패: {e}") print(f"총 {len(all_documents)}개 문서 수집 완료\n") # 2. 용어 추출 print("🔍 2단계: 용어 추출 중...") all_terms = [] for doc in all_documents: terms = await self.term_extractor.extract_terms(doc) all_terms.extend(terms) print(f" ✓ {len(all_terms)}개 용어 추출 완료\n") # 3. 중복 제거 및 정제 print("🧹 3단계: 용어 정제 중...") unique_terms = self.term_extractor.deduplicate_terms(all_terms) validated_terms = await self.validate_terms(unique_terms) print(f" ✓ {len(validated_terms)}개 유효 용어 (중복 제거: {len(all_terms) - len(validated_terms)}개)\n") # 4. 벡터 임베딩 생성 print("🧮 4단계: 벡터 임베딩 생성 중...") embeddings = await self.vector_embedder.generate_embeddings(validated_terms) print(f" ✓ {len(embeddings)}개 벡터 생성 완료\n") # 5. 데이터베이스 저장 print("💾 5단계: 데이터베이스 저장 중...") await self.postgres.save_terms(validated_terms) if self.vector_store: await self.vector_store.upsert_vectors(embeddings) else: await self.postgres.save_vectors(embeddings) print(" ✓ 저장 완료\n") # 6. 품질 검증 print("✅ 6단계: 품질 검증 중...") quality_report = await self.validate_quality(validated_terms) print(f" ✓ 정확도: {quality_report['accuracy']}%") print(f" ✓ 신뢰도 > 0.8: {quality_report['high_confidence_ratio']}%") print(f" ✓ 조직 특화 용어: {quality_report['company_specific_count']}개\n") return { 'documents_collected': len(all_documents), 'terms_extracted': len(validated_terms), 'quality_report': quality_report } async def validate_terms(self, terms): """용어 유효성 검증""" validated = [] for term in terms: # 1. 길이 검증 (2-200자) if not (2 <= len(term['name']) <= 200): continue # 2. 신뢰도 임계값 (0.7 이상) if term.get('confidence', 0) < 0.7: continue # 3. 중복 체크 if await self.postgres.term_exists(term['normalized_name']): continue validated.append(term) return validated async def validate_quality(self, terms): """품질 지표 계산""" total = len(terms) high_confidence = sum(1 for t in terms if t.get('confidence', 0) > 0.8) company_specific = sum(1 for t in terms if t.get('is_company_specific', False)) return { 'accuracy': round(high_confidence / total * 100, 2) if total > 0 else 0, 'high_confidence_ratio': round(high_confidence / total * 100, 2) if total > 0 else 0, 'company_specific_count': company_specific } # 실행 if __name__ == '__main__': config = load_config('config.yaml') pipeline = TermManagementPipeline(config) # 비동기 실행 result = asyncio.run(pipeline.run_daily_pipeline()) print("\n" + "="*50) print("📊 파이프라인 실행 완료") print("="*50) print(f"수집된 문서: {result['documents_collected']}개") print(f"추출된 용어: {result['terms_extracted']}개") print(f"품질 점수: {result['quality_report']['accuracy']}%") ``` --- ## 9단계: Claude API 요청/응답 JSON 구조 ### 용어 설명 요청 ```json { "model": "claude-sonnet-4-5-20250929", "max_tokens": 1024, "temperature": 0.3, "top_p": 0.95, "system": "당신은 전문 용어를 회의 맥락에 맞춰 설명하는 AI 어시스턴트입니다. 다음 규칙을 따르세요:\n1. 2-3문장으로 간결하게 설명\n2. 회의 맥락을 반영하여 실용적인 정보 제공\n3. 관련 문서 정보가 있으면 활용\n4. 기술 용어는 비전공자도 이해할 수 있게 설명", "messages": [ { "role": "user", "content": "=== 회의 정보 ===\n회의 제목: Q4 회의록 작성 가이드 배포\n참석자: 김민준(PO), 이준호(BE), 박서연(AI), 최유진(FE)\n시간: 2024-10-01 14:00\n\n=== 회의 내용 (STT 전사) ===\n민준: 이번 분기 회의록 시스템 개발을 위해 먼저 API Gateway 구조부터 설계해야 할 것 같습니다.\n준호: 네, 저희가 마이크로서비스 아키텍처를 채택했으니 API Gateway가 필수겠네요. RESTful API로 설계하는 게 좋을까요?\n서연: AI 서비스와 연동할 때는 비동기 처리가 중요할 것 같아요. Claude API 호출 시간이 좀 걸리거든요.\n유진: 프론트엔드에서는 실시간으로 용어 설명을 보여줘야 하는데, API Gateway에서 캐싱을 지원하면 좋겠어요.\n\n=== 관련 문서 (RAG 검색 결과) ===\n[문서 1] API 설계 리뷰 회의록 (2024-09-28, 관련도 95%)\n제목: API Gateway 아키텍처 결정\n내용: \"RESTful API 설계 원칙과 보안 정책 확정. AWS API Gateway 채택 결정. JWT 토큰 기반 인증, Rate limiting 적용. Lambda 통합으로 서버리스 아키텍처 구현.\"\n\n[문서 2] 사내 기술 스택 가이드 (2024-08-15, 관련도 78%)\n제목: 마이크로서비스 표준 아키텍처\n내용: \"API Gateway는 클라이언트와 백엔드 서비스 사이의 단일 진입점. 요청 라우팅, 인증/인가, 로깅, Rate limiting 기능 제공. 회사 표준은 AWS API Gateway 사용.\"\n\n[문서 3] 신제품 개발 킥오프 회의록 (2024-09-15, 관련도 65%)\n제목: 1분기 신제품 개발 방향성\n내용: \"협업 도구 시장 분석 및 차별화 전략 수립. 기술 스택으로 마이크로서비스 아키텍처 선정, API Gateway 패턴 적용 예정.\"\n\n=== 질문 ===\n용어: API Gateway\n\n위 회의 맥락에 맞춰 'API Gateway'를 2-3문장으로 설명해주세요. 이 회의에서 API Gateway가 어떤 역할을 하는지 포함해주세요." } ] } ``` ### Claude API 응답 ```json { "id": "msg_01XyZ123AbC456", "type": "message", "role": "assistant", "content": [ { "type": "text", "text": "API Gateway는 클라이언트와 백엔드 마이크로서비스 사이의 단일 진입점으로, 요청 라우팅, 인증/인가, Rate limiting, 로깅 등을 담당합니다. 이 회의에서는 회의록 시스템 개발을 위해 AWS API Gateway를 도입하기로 했으며, Claude AI 서비스 연동 시 비동기 처리와 캐싱 기능을 활용하여 실시간 용어 설명 기능을 구현할 계획입니다. 사내 표준 아키텍처에 따라 JWT 인증과 Lambda 통합을 통한 서버리스 구조로 설계됩니다." } ], "model": "claude-sonnet-4-5-20250929", "stop_reason": "end_turn", "stop_sequence": null, "usage": { "input_tokens": 523, "output_tokens": 147 } } ``` ### 에러 응답 처리 ```json { "type": "error", "error": { "type": "rate_limit_error", "message": "Rate limit exceeded. Please try again later." } } ``` **에러 핸들링 코드**: ```python class ClaudeAPIClient: async def explain_term(self, term, context, rag_docs): """용어 설명 요청 with 에러 핸들링""" max_retries = 3 retry_delay = 1 # 초 for attempt in range(max_retries): try: response = await self.call_claude_api(term, context, rag_docs) # 캐시 저장 await self.cache.set( key=self.generate_cache_key(term, context), value=response['content'][0]['text'], ttl=86400 # 24시간 ) return { 'explanation': response['content'][0]['text'], 'cached': False, 'tokens_used': response['usage']['input_tokens'] + response['usage']['output_tokens'] } except RateLimitError as e: if attempt < max_retries - 1: await asyncio.sleep(retry_delay * (2 ** attempt)) # Exponential backoff continue else: # Fallback: RAG 문서 직접 반환 return { 'explanation': self.generate_fallback_explanation(rag_docs), 'cached': False, 'error': 'rate_limit_exceeded' } except Exception as e: logging.error(f"Claude API 호출 실패: {e}") return { 'explanation': self.generate_fallback_explanation(rag_docs), 'cached': False, 'error': str(e) } def generate_fallback_explanation(self, rag_docs): """API 실패 시 Fallback 설명 생성""" if rag_docs: # RAG 문서에서 가장 관련성 높은 부분 추출 best_doc = max(rag_docs, key=lambda d: d['relevance_score']) return f"{best_doc['excerpt']}\n\n(출처: {best_doc['title']})" else: return "죄송합니다. 현재 이 용어에 대한 설명을 생성할 수 없습니다. 잠시 후 다시 시도해주세요." ``` --- ## 10단계: 최종 권장사항 ### 추천 구현 순서 **Week 1-2: Phase 1 - JSON 기반 MVP** - [ ] JSON 용어 사전 파일 생성 (50개 핵심 용어) - [ ] 간단한 키워드 매칭 구현 - [ ] Claude API 연동 (RAG 없이 프롬프트만) - [ ] 기본 UI 구현 (용어 하이라이트, 설명 모달) **Week 3-4: 데이터 수집 자동화** - [ ] Confluence API 연동 - [ ] SharePoint 또는 Google Drive 연동 (우선순위에 따라 선택) - [ ] 배치 수집 스크립트 구현 - [ ] 관리자 승인 UI **Week 5-6: Phase 2 - 기본 RAG** - [ ] PostgreSQL + pgvector 설정 - [ ] OpenAI embedding API 연동 - [ ] 벡터 검색 구현 - [ ] Claude API + RAG context 통합 **Week 7-8: 품질 개선** - [ ] 사용자 피드백 시스템 - [ ] 품질 지표 대시보드 - [ ] A/B 테스트 (키워드 매칭 vs RAG) - [ ] 성능 최적화 (캐싱, 인덱싱) **Week 9-10: Phase 3 - 고도화 (선택)** - [ ] Qdrant 도입 (필요 시) - [ ] 하이브리드 검색 - [ ] 자동 품질 검증 - [ ] 외부 문서 크롤링 ### 예상 비용 (월간) | 항목 | Phase 1 | Phase 2 | Phase 3 | |------|---------|---------|---------| | **인프라** | | PostgreSQL (RDS) | $50 | $100 | $150 | | Redis (ElastiCache) | $30 | $50 | $50 | | Qdrant | - | - | $500 | | **API 사용료** | | OpenAI Embedding | - | $20 | $50 | | Claude API | $100 | $300 | $500 | | **기타** | | 저장공간 (S3) | $10 | $20 | $30 | | **총계** | **$190/월** | **$490/월** | **$1,280/월** | ### 성공 지표 (KPI) 1. **사용성** - 용어 조회율: 회의당 평균 3회 이상 - 설명 유용성 평가: 4.0/5.0 이상 - 응답 시간: 평균 2초 이하 2. **정확도** - 용어 추출 정확도: 85% 이상 - 설명 적합성: 사용자 피드백 80% 긍정 - False positive rate: 10% 이하 3. **비즈니스** - 신규 회의 중 기능 사용률: 60% 이상 - 월 활성 사용자: 전체의 50% 이상 - 회의록 작성 시간 단축: 20% 이상 ### 리스크 및 완화 전략 | 리스크 | 영향도 | 완화 전략 | |--------|--------|----------| | Claude API 비용 급증 | 높음 | 캐싱 강화, 월 예산 한도 설정, Fallback 메커니즘 | | 조직 용어 정확도 낮음 | 높음 | 수동 큐레이션 우선, 피드백 루프, 정기 품질 감사 | | 응답 시간 느림 | 중간 | 3-tier 캐싱, 벡터 DB 최적화, CDN 활용 | | 데이터 수집 실패 | 중간 | Retry 로직, 여러 소스 분산, 수동 백업 | | 사용자 채택률 낮음 | 중간 | UX 개선, 온보딩 교육, 사용 인센티브 | --- ## 최종 결론 **선정된 최적안**: 하이브리드 RAG 시스템 (단계적 접근) **핵심 장점**: 1. ✅ 조직 특화 용어의 높은 정확도 (JSON 큐레이션) 2. ✅ 확장 가능한 아키텍처 (RAG 시스템) 3. ✅ 합리적인 비용 구조 ($190/월 시작) 4. ✅ 명확한 구현 경로 (3-phase) 5. ✅ 차별화된 맥락 기반 설명 **다음 단계**: 1. Week 1-2에 MVP 구현 시작 2. 50개 핵심 용어 큐레이션 3. Claude API 연동 및 테스트 4. 베타 사용자 10명 초대하여 피드백 수집 --- **작성일**: 2025-10-28 **작성자**: 회의록 개선 프로젝트 팀 **버전**: 1.0 **승인자**: 김민준 (Product Owner)