@startuml !theme mono title AI Service 내부 시퀀스 - 결정사항제안 participant "SuggestionController" as Controller participant "DecisionSuggestionService" as Service participant "LLMClient" as LLM participant "SuggestionRepository" as Repo participant "TranscriptRepository" as TranscriptRepo database "Azure OpenAI<>" as OpenAI database "PostgreSQL<>" as DB == 실시간 결정사항 제안 요청 == note over Controller TranscriptService로부터 호출 또는 API 직접 호출: POST /api/ai/suggestions/decision Body: { "meetingId": "{meetingId}", "transcriptText": "최근 대화 내용" } end note Controller -> Service: suggestDecisions(meetingId, transcriptText) activate Service == 회의 맥락 및 이전 결정 조회 == Service -> TranscriptRepo: getMeetingContext(meetingId) activate TranscriptRepo TranscriptRepo -> DB: SELECT meeting_info, participants\nFROM meeting_context activate DB DB --> TranscriptRepo: 회의 정보 deactivate DB TranscriptRepo --> Service: meetingContext deactivate TranscriptRepo Service -> Repo: getPreviousDecisions(meetingId) activate Repo Repo -> DB: SELECT content FROM ai_suggestions\nWHERE meeting_id = {meetingId}\nAND suggestion_type = 'DECISION'\nAND status = 'APPLIED' activate DB DB --> Repo: 이미 확정된 결정사항 deactivate DB Repo --> Service: previousDecisions deactivate Repo == LLM 기반 결정사항 패턴 감지 == Service -> Service: 결정사항 감지 프롬프트 생성 note right 시스템 프롬프트: - 역할: 결정사항 추출 전문가 - 목표: 대화에서 결정 패턴 감지 결정 패턴 예시: - "~하기로 했습니다" - "~로 결정했습니다" - "~하는 것으로 합의했습니다" - "~로 진행하겠습니다" - "~은 이렇게 처리하겠습니다" 사용자 프롬프트: - 회의 참석자: {participants} - 이미 확정된 결정: {previousDecisions} - 현재 대화 내용: {transcriptText} 지시사항: - 위 패턴이 포함된 문장 찾기 - 결정 내용 구조화 - 결정자/참여자 식별 - 결정 카테고리 분류 - 신뢰도 점수 계산 응답 형식: { "decisions": [ { "content": "결정 내용", "category": "기술|일정|리소스|정책|기타", "decisionMaker": "결정자 이름", "participants": ["참여자1", "참여자2"], "confidence": 0.0-1.0, "extractedFrom": "원문 발췌", "context": "결정 배경" } ] } end note Service -> LLM: detectDecisionPatterns(prompt) activate LLM LLM -> OpenAI: POST /chat/completions activate OpenAI note right 요청 파라미터: - model: gpt-4o - temperature: 0.2 (정확한 패턴 감지 위해 낮은 값) - response_format: json_object - max_tokens: 1500 end note OpenAI -> OpenAI: 대화 텍스트 분석 note right 처리 단계: 1. 문장별로 결정 패턴 검사 2. "하기로 함" 등 키워드 탐지 3. 결정 내용 추출 및 정리 4. 발언자 식별 (누가 결정했나) 5. 결정 맥락 파악 6. 신뢰도 계산 - 명확한 결정 표현: 0.9-1.0 - 암묵적 합의: 0.7-0.9 - 추정: 0.5-0.7 7. 카테고리 분류 - 기술: 기술 스택, 아키텍처 - 일정: 마감일, 일정 조정 - 리소스: 인력, 예산 - 정책: 프로세스, 규칙 end note OpenAI --> LLM: 결정사항 제안 목록 (JSON) deactivate OpenAI LLM --> Service: decisionSuggestions deactivate LLM == 제안 검증 및 필터링 == Service -> Service: 결정사항 검증 note right 검증 기준: - 신뢰도 70% 이상만 선택 - 중복 제거 (이미 확정된 결정) - 명확성 검증 * 주어, 목적어가 명확한가? * 결정 내용이 구체적인가? - 카테고리별 정렬 - 신뢰도 높은 순 정렬 end note loop 각 제안마다 Service -> Service: 제안 메타데이터 보강 note right 추가 정보: - 생성 시각 - 회의 진행 시점 (분) - 원문 위치 (라인 번호) - 상태: PENDING - 관련 논의사항 참조 end note end == 제안 저장 == loop 각 검증된 제안마다 Service -> Repo: saveSuggestion(meetingId, decision) activate Repo Repo -> DB: INSERT INTO ai_suggestions activate DB note right 저장 데이터: - meeting_id - suggestion_type: 'DECISION' - content: {decision 내용} - category: 결정 카테고리 - decision_maker: 결정자 - participants: 참여자 목록 (JSON) - confidence_score: 0.0-1.0 - extracted_from: 원문 - context: 결정 배경 - status: PENDING - created_at end note DB --> Repo: suggestionId deactivate DB Repo --> Service: suggestionId deactivate Repo end == 응답 구성 == Service -> Service: 응답 데이터 구성 note right 프론트엔드 전달 형식: { "suggestions": [ { "id": "suggestion-uuid", "content": "결정 내용", "category": "기술", "decisionMaker": "김철수", "confidence": 0.85, "extractedFrom": "원문 발췌", "context": "결정 배경 설명", "canApply": true } ], "totalCount": 제안 개수, "displayHint": "오른쪽 탭 '결정사항' 섹션" } end note Service --> Controller: 결정사항 제안 생성 완료 deactivate Service Controller --> Controller: 200 OK 응답 반환 note right 프론트엔드 처리: - 오른쪽 "추천" 탭의 "결정사항" 섹션 표시 - "적용" 버튼 활성화 - 신뢰도 표시 (%) - 카테고리별 아이콘 표시 - 원문 보기 링크 제공 end note == 사용자가 제안 적용 시 == note over Controller 사용자가 "적용" 버튼 클릭 시: PUT /api/ai/suggestions/{suggestionId}/apply end note Controller -> Service: applySuggestion(suggestionId, meetingId) activate Service Service -> Repo: updateSuggestionStatus(suggestionId, "APPLIED") activate Repo Repo -> DB: UPDATE ai_suggestions\nSET status = 'APPLIED',\napplied_at = NOW() activate DB DB --> Repo: 업데이트 완료 deactivate DB Repo --> Service: 완료 deactivate Repo Service -> Service: 결정사항을 회의록에 추가 note right Meeting Service API 호출하여 "결정사항" 섹션에 항목 추가 end note Service --> Controller: 적용 완료 deactivate Service Controller --> Controller: 200 OK note over Controller, DB 처리 시간: - 맥락 조회: 100-200ms - LLM 패턴 감지: 2-3초 - 검증 및 필터링: 100-200ms - 저장 처리: 200-300ms 총 처리 시간: 약 3-4초 제안 정책: - 신뢰도 70% 이상만 제안 - 명확한 결정 표현 우선 - 중복 제거 (이미 확정된 것 제외) - 카테고리별로 최대 10개까지 - 실시간으로 계속 감지 end note @enduml