openapi: 3.0.3 info: title: RAG Service API description: | 회의록 작성 서비스를 위한 RAG (Retrieval-Augmented Generation) 서비스 API **주요 기능**: - 용어집 검색 (PostgreSQL + pgvector) - 관련자료 검색 (Azure AI Search) - 회의록 유사도 검색 (Vector DB) **기술 스택**: Python 3.11+, FastAPI, PostgreSQL+pgvector, Azure AI Search, Claude AI, Redis version: 1.0.0 contact: name: AI Specialist (서연), Backend Developer (준호) servers: - url: http://localhost:8000 description: 로컬 개발 서버 - url: https://api-rag.hgzero.com description: 운영 서버 tags: - name: Terms description: 용어집 검색 API - name: Documents description: 관련자료 검색 API - name: Minutes description: 회의록 유사도 검색 API paths: # ============================================================================ # Terms APIs - 용어집 검색 # ============================================================================ /api/rag/terms/search: post: tags: - Terms summary: 용어 검색 (Hybrid) description: | 키워드 검색과 벡터 유사도 검색을 결합한 하이브리드 검색 **검색 방식**: - `keyword`: 키워드 매칭 (PostgreSQL LIKE) - `vector`: 벡터 유사도 (Cosine Similarity) - `hybrid`: 키워드 + 벡터 가중합 (기본값) **성능**: < 500ms (캐시 HIT 시 < 50ms) x-user-story: UFR-RAG-010 x-controller: TermsController requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/TermSearchRequest' examples: hybrid_search: summary: 하이브리드 검색 (기본) value: query: "마이크로서비스 아키텍처" search_type: "hybrid" top_k: 5 confidence_threshold: 0.7 keyword_search: summary: 키워드 검색만 value: query: "Docker" search_type: "keyword" top_k: 3 confidence_threshold: 0.6 responses: '200': description: 검색 결과 content: application/json: schema: type: array items: $ref: '#/components/schemas/TermSearchResult' '400': $ref: '#/components/responses/BadRequest' '500': $ref: '#/components/responses/InternalError' /api/rag/terms/{termId}: get: tags: - Terms summary: 용어 상세 조회 description: 용어 ID로 용어 정보 조회 x-user-story: UFR-RAG-010 x-controller: TermsController parameters: - name: termId in: path required: true schema: type: string description: 용어 ID responses: '200': description: 용어 정보 content: application/json: schema: $ref: '#/components/schemas/Term' '404': $ref: '#/components/responses/NotFound' '500': $ref: '#/components/responses/InternalError' /api/rag/terms/{termId}/explain: post: tags: - Terms summary: 맥락 기반 용어 설명 생성 description: | Claude AI를 활용한 맥락 기반 용어 설명 생성 **생성 과정**: 1. 현재 회의 맥락 분석 2. RAG 검색 (관련 회의록, 문서, 업무 이력) 3. Claude AI 호출 (프롬프트 엔지니어링) 4. 결과 생성 및 캐싱 **성능**: < 3초 (Claude API 호출 포함) x-user-story: UFR-RAG-020 x-controller: TermsController parameters: - name: termId in: path required: true schema: type: string description: 용어 ID requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/TermExplainRequest' responses: '200': description: 용어 설명 content: application/json: schema: $ref: '#/components/schemas/TermExplanation' '404': $ref: '#/components/responses/NotFound' '500': $ref: '#/components/responses/InternalError' # ============================================================================ # Documents APIs - 관련자료 검색 # ============================================================================ /api/rag/documents/search: post: tags: - Documents summary: 관련 문서 검색 description: | Azure AI Search 기반 하이브리드 검색 + Semantic Ranking **검색 기능**: - 전체 텍스트 검색 - 벡터 유사도 검색 - Semantic Ranking (Azure AI Search) - 필터링 (폴더, 문서 유형) x-user-story: UFR-RAG-030 x-controller: DocumentsController requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/DocumentSearchRequest' responses: '200': description: 검색 결과 content: application/json: schema: type: array items: $ref: '#/components/schemas/DocumentSearchResult' '400': $ref: '#/components/responses/BadRequest' '500': $ref: '#/components/responses/InternalError' /api/rag/documents/stats: get: tags: - Documents summary: 문서 통계 조회 description: 전체 문서 통계 정보 조회 x-controller: DocumentsController responses: '200': description: 문서 통계 content: application/json: schema: $ref: '#/components/schemas/DocumentStats' '500': $ref: '#/components/responses/InternalError' # ============================================================================ # Minutes APIs - 회의록 유사도 검색 # ============================================================================ /api/rag/minutes/search: post: tags: - Minutes summary: 회의록 벡터 검색 description: | 회의록 내용 기반 벡터 유사도 검색 **검색 방식**: Cosine Similarity (임계값 70% 이상) **성능**: < 1초 (캐시 HIT 시 < 100ms) x-user-story: UFR-RAG-030 x-controller: MinutesController requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/MinutesSearchRequest' responses: '200': description: 검색 결과 content: application/json: schema: type: array items: $ref: '#/components/schemas/MinutesSearchResult' '400': $ref: '#/components/responses/BadRequest' '500': $ref: '#/components/responses/InternalError' /api/rag/minutes/{minutesId}: get: tags: - Minutes summary: 회의록 상세 조회 description: 회의록 ID로 상세 정보 조회 x-user-story: UFR-RAG-030 x-controller: MinutesController parameters: - name: minutesId in: path required: true schema: type: string description: 회의록 ID responses: '200': description: 회의록 정보 content: application/json: schema: $ref: '#/components/schemas/RagMinutes' '404': $ref: '#/components/responses/NotFound' '500': $ref: '#/components/responses/InternalError' /api/rag/minutes/related: post: tags: - Minutes summary: 연관 회의록 조회 description: | 벡터 유사도 기반 연관 회의록 조회 (Redis 캐싱) **처리 과정**: 1. Redis 캐시 조회 2. 캐시 MISS 시 DB 조회 3. 회의록 내용을 벡터 임베딩으로 변환 4. 벡터 유사도 검색 (자기 자신 제외) 5. 결과 Redis 캐싱 (TTL: 1시간) **성능**: < 1초 (캐시 HIT 시 < 100ms) x-user-story: UFR-RAG-030 x-controller: MinutesController requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/RelatedMinutesRequest' responses: '200': description: 연관 회의록 목록 content: application/json: schema: type: array items: $ref: '#/components/schemas/RelatedMinutesResponse' '404': $ref: '#/components/responses/NotFound' '500': $ref: '#/components/responses/InternalError' /api/rag/minutes/stats: get: tags: - Minutes summary: 회의록 통계 조회 description: 전체 회의록 통계 정보 조회 x-controller: MinutesController responses: '200': description: 회의록 통계 content: application/json: schema: $ref: '#/components/schemas/MinutesStats' '500': $ref: '#/components/responses/InternalError' # ============================================================================ # Components # ============================================================================ components: schemas: # Terms Schemas TermSearchRequest: type: object required: - query properties: query: type: string description: 검색 쿼리 example: "마이크로서비스 아키텍처" search_type: type: string enum: [keyword, vector, hybrid] default: hybrid description: 검색 방식 top_k: type: integer default: 5 minimum: 1 maximum: 20 description: 반환할 최대 결과 수 confidence_threshold: type: number format: float default: 0.7 minimum: 0.0 maximum: 1.0 description: 최소 신뢰도 임계값 Term: type: object properties: term_id: type: string description: 용어 ID term_name: type: string description: 용어명 definition: type: string description: 용어 정의 context: type: string description: 사용 맥락 category: type: string description: 카테고리 created_at: type: string format: date-time description: 생성 일시 updated_at: type: string format: date-time description: 수정 일시 TermSearchResult: type: object properties: term: $ref: '#/components/schemas/Term' relevance_score: type: number format: float description: 관련도 점수 (0.0 ~ 1.0) match_type: type: string enum: [keyword, vector, hybrid] description: 매칭 방식 TermExplainRequest: type: object required: - meeting_context properties: meeting_context: type: string description: 현재 회의 맥락 (회의 주제, 안건 등) example: "마이크로서비스 아키텍처 도입 검토 회의" TermExplanation: type: object properties: term: $ref: '#/components/schemas/Term' explanation: type: string description: 맥락 기반 설명 (Claude AI 생성) context_documents: type: array items: type: string description: 참조 문서 목록 generated_by: type: string default: Claude 3.5 Sonnet description: 생성 모델 cached: type: boolean description: 캐시 여부 # Documents Schemas DocumentSearchRequest: type: object required: - query properties: query: type: string description: 검색 쿼리 top_k: type: integer default: 5 minimum: 1 maximum: 20 folder: type: string description: 폴더 필터 document_type: type: string description: 문서 유형 필터 semantic_ranking: type: boolean default: true description: Semantic Ranking 사용 여부 relevance_threshold: type: number format: float default: 0.6 description: 최소 관련도 임계값 DocumentSearchResult: type: object properties: document_id: type: string title: type: string content: type: string description: 문서 내용 (요약) folder: type: string document_type: type: string relevance_score: type: number format: float created_at: type: string format: date-time DocumentStats: type: object properties: total_documents: type: integer by_type: type: object additionalProperties: type: integer total_chunks: type: integer # Minutes Schemas MinutesSearchRequest: type: object required: - query properties: query: type: string description: 검색 쿼리 (회의 내용) top_k: type: integer default: 5 minimum: 1 maximum: 20 similarity_threshold: type: number format: float default: 0.7 minimum: 0.0 maximum: 1.0 RagMinutes: type: object properties: minutes_id: type: string title: type: string full_content: type: string description: 전체 회의록 내용 meeting_date: type: string format: date-time participants: type: array items: type: string created_at: type: string format: date-time MinutesSearchResult: type: object properties: minutes: $ref: '#/components/schemas/RagMinutes' similarity_score: type: number format: float description: 유사도 점수 (0.0 ~ 1.0) RelatedMinutesRequest: type: object required: - minute_id properties: minute_id: type: string description: 기준 회의록 ID top_k: type: integer default: 3 minimum: 1 maximum: 10 similarity_threshold: type: number format: float default: 0.7 RelatedMinutesResponse: type: object properties: minutes: $ref: '#/components/schemas/RagMinutes' similarity_score: type: number format: float MinutesStats: type: object properties: total_minutes: type: integer indexed_count: type: integer average_similarity: type: number format: float # Error Schemas ErrorResponse: type: object properties: status: type: string enum: [error] code: type: string message: type: string details: type: object responses: BadRequest: description: 잘못된 요청 content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' example: status: error code: BAD_REQUEST message: 검색 쿼리가 비어 있습니다 NotFound: description: 리소스를 찾을 수 없음 content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' example: status: error code: NOT_FOUND message: 용어를 찾을 수 없습니다 InternalError: description: 서버 내부 오류 content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' example: status: error code: INTERNAL_ERROR message: 서버 오류가 발생했습니다