@startuml
!theme mono

title AI Service 내부 시퀀스 - 맥락기반용어설명

participant "ExplanationController" as Controller
participant "TermExplanationService" as Service
participant "RAGService" as RAG
participant "VectorService" as Vector
participant "LLMClient" as LLM
participant "ExplanationRepository" as Repo
database "Azure OpenAI<<E>>" as OpenAI
database "Vector DB<<E>>" as VectorDB
database "Document Store<<E>>" as DocStore
database "PostgreSQL<<E>>" as DB

== 용어 설명 요청 수신 ==

note over Controller
  요청 경로:
  1. 용어 감지 후 자동 트리거 (비동기)
  2. 사용자 클릭 시 API 요청

  API: GET /api/ai/terms/{term}/explain
  Query: meetingId, context
end note

Controller -> Service: explainTerm(term, meetingId, context)
activate Service

== 용어 정보 조회 ==

Service -> Repo: getTermInfo(term)
activate Repo

Repo -> DB: 용어 정보 조회\n(용어사전에서 정의 및 카테고리)
activate DB

DB --> Repo: 기본 용어 정의
deactivate DB

Repo --> Service: basicDefinition, category
deactivate Repo

== 벡터 임베딩 생성 ==

Service -> Service: 검색 쿼리 구성
note right
  검색 쿼리:
  - 용어명
  - 현재 회의 맥락
  - 카테고리

  예: "{term} {context} {category}"
end note

Service -> Vector: generateQueryEmbedding(queryText)
activate Vector

Vector -> OpenAI: POST /embeddings
activate OpenAI
note right
  model: text-embedding-3-large
  input: 검색 쿼리 텍스트
end note

OpenAI --> Vector: 쿼리 임베딩 벡터
deactivate OpenAI

Vector --> Service: queryEmbedding
deactivate Vector

== RAG 검색 수행 (병렬) ==

Service -> RAG: searchRelatedDocuments(queryEmbedding, term)
activate RAG

par "과거 회의록 검색"
    RAG -> VectorDB: 벡터 유사도 검색 (회의록)
    activate VectorDB
    note right
      검색 조건:
      - 컬렉션: meeting_transcripts
      - 필터: term 포함
      - 유사도 threshold: 0.7
      - 결과: top 3
    end note

    VectorDB --> RAG: 관련 회의록 (top 3)
    deactivate VectorDB

else
    RAG -> VectorDB: 벡터 유사도 검색 (문서)
    activate VectorDB
    note right
      검색 조건:
      - 컬렉션: company_documents
      - 문서 유형: 위키, 매뉴얼, 보고서
      - 유사도 threshold: 0.7
      - 결과: top 2
    end note

    VectorDB --> RAG: 관련 사내 문서 (top 2)
    deactivate VectorDB

else
    RAG -> DocStore: 전체 텍스트 검색
    activate DocStore
    note right
      검색 조건:
      - 문서 유형: 프로젝트, 이메일
      - 키워드: {term}
      - 날짜: 최근 1년
      - 결과: top 2
    end note

    DocStore --> RAG: 관련 업무 이력 (top 2)
    deactivate DocStore
end

RAG -> RAG: 검색 결과 통합 및 정렬
note right
  통합 결과:
  - 과거 회의록 3개
  - 사내 문서 2개
  - 업무 이력 2개

  관련도 점수순 정렬
end note

RAG --> Service: relatedDocuments (총 최대 7개)
deactivate RAG

alt 관련 문서를 찾지 못한 경우
    Service -> Service: 기본 정의만 반환 준비
    note right
      응답:
      - 용어 정의 (사전)
      - "관련 정보를 찾을 수 없습니다"
      - 전문가 요청 버튼
    end note

    Service --> Controller: 기본 정의 응답
    deactivate Service

else 관련 문서 발견

== 맥락 기반 설명 생성 ==

Service -> Service: LLM 프롬프트 구성
note right
  시스템 프롬프트:
  - 역할: 용어 설명 전문가
  - 지시사항:
    * 기본 정의 제공
    * 현재 회의 맥락에서의 의미
    * 관련 프로젝트/이슈 연결
    * 과거 사용 사례 요약
    * 참조 출처 링크

  사용자 프롬프트:
  - 용어: {term}
  - 기본 정의: {basicDefinition}
  - 현재 회의 맥락: {context}
  - 관련 문서: {relatedDocuments}

  출력 형식:
  {
    "basicDefinition": "간단한 정의",
    "contextualMeaning": "맥락 기반 설명",
    "useCases": [사용 사례],
    "relatedProjects": [프로젝트],
    "pastDiscussions": [과거 논의],
    "references": [출처 링크]
  }
end note

Service -> LLM: generateContextualExplanation(prompt)
activate LLM

LLM -> OpenAI: POST /chat/completions
activate OpenAI
note right
  요청 파라미터:
  - model: gpt-4o
  - temperature: 0.3
  - max_tokens: 1500
  - response_format: json_object
end note

OpenAI -> OpenAI: 맥락 기반 설명 생성
note right
  처리 단계:
  1. 검색된 문서 분석
  2. 용어 사용 맥락 파악
  3. 실제 사용 사례 추출
  4. 프로젝트/이슈 연결
  5. 과거 논의 요약
     - 언제 논의되었는지
     - 누가 사용했는지
     - 어떻게 사용되었는지
  6. 참조 출처 정리
end note

OpenAI --> LLM: 맥락 기반 설명 (JSON)
deactivate OpenAI

LLM --> Service: explanation
deactivate LLM

== 설명 저장 ==

Service -> Repo: saveExplanation(term, meetingId, explanation)
activate Repo

Repo -> DB: INSERT INTO term_explanations
activate DB
note right
  저장 데이터:
  - term
  - meeting_id
  - basic_definition
  - contextual_meaning
  - use_cases (JSON)
  - related_projects (JSON)
  - past_discussions (JSON)
  - references (JSON)
  - created_at
end note

DB --> Repo: explanationId
deactivate DB

Repo --> Service: explanationId
deactivate Repo

== 응답 데이터 구성 ==

Service -> Service: 최종 응답 구성
note right
  응답 구조:
  {
    "term": "용어명",
    "basicDefinition": "간단한 정의 (1-2문장)",
    "contextualMeaning": "이 회의에서의 의미",
    "useCases": [
      "실제 사용 사례 1",
      "실제 사용 사례 2"
    ],
    "relatedProjects": [
      {
        "name": "프로젝트명",
        "relevance": "연관성 설명"
      }
    ],
    "pastDiscussions": [
      {
        "date": "2024-12-15",
        "participants": ["참석자1", "참석자2"],
        "summary": "논의 요약",
        "link": "회의록 링크"
      }
    ],
    "references": [
      {
        "title": "문서 제목",
        "type": "위키|매뉴얼|회의록",
        "link": "URL"
      }
    ]
  }
end note

Service --> Controller: 맥락 기반 설명 응답
deactivate Service

Controller --> Controller: 200 OK 응답 반환
note right
  프론트엔드 표시:
  - 툴팁 또는 사이드 패널
  - 접을 수 있는 섹션별 표시
  - 참조 링크 클릭 가능
end note

end

note over Controller, DB
처리 시간:
- 용어 정보 조회: 50-100ms
- 벡터 임베딩: 500ms-1초
- RAG 병렬 검색: 1-2초
- LLM 설명 생성: 3-5초
- 저장 처리: 100-200ms
총 처리 시간: 약 5-8초

차별화 포인트:
- 단순 용어 설명이 아닌
  조직 내 실제 사용 맥락과 이력 제공
- 업무 지식이 없어도
  실질적인 도움 제공
end note

@enduml
