내부,외부 시퀀스 기능 추가

This commit is contained in:
hjmoons 2025-10-22 17:22:10 +09:00
parent 5fe399e248
commit 4a4899e24d
7 changed files with 1350 additions and 11 deletions

View File

@ -0,0 +1,282 @@
@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<<E>>" as OpenAI
database "PostgreSQL<<E>>" 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

View File

@ -0,0 +1,261 @@
@startuml
!theme mono
title AI Service 내부 시퀀스 - 논의사항제안
participant "SuggestionController" as Controller
participant "DiscussionSuggestionService" as Service
participant "LLMClient" as LLM
participant "SuggestionRepository" as Repo
participant "TranscriptRepository" as TranscriptRepo
database "Azure OpenAI<<E>>" as OpenAI
database "PostgreSQL<<E>>" as DB
== 실시간 논의사항 제안 요청 ==
note over Controller
TranscriptService로부터 호출
또는 API 직접 호출:
POST /api/ai/suggestions/discussion
Body: {
"meetingId": "{meetingId}",
"transcriptText": "최근 대화 내용"
}
end note
Controller -> Service: suggestDiscussionTopics(meetingId, transcriptText)
activate Service
== 회의 맥락 정보 조회 ==
Service -> TranscriptRepo: getMeetingContext(meetingId)
activate TranscriptRepo
TranscriptRepo -> DB: SELECT meeting_info, agenda, participants\nFROM meeting_context
activate DB
DB --> TranscriptRepo: 회의 정보
deactivate DB
TranscriptRepo --> Service: meetingContext
deactivate TranscriptRepo
Service -> TranscriptRepo: getPreviousDiscussions(meetingId)
activate TranscriptRepo
TranscriptRepo -> DB: SELECT discussed_topics\nFROM ai_transcripts\nWHERE meeting_id = {meetingId}
activate DB
DB --> TranscriptRepo: 이미 논의한 주제 목록
deactivate DB
TranscriptRepo --> Service: discussedTopics
deactivate TranscriptRepo
== LLM 기반 논의사항 제안 생성 ==
Service -> Service: 제안 프롬프트 생성
note right
시스템 프롬프트:
- 역할: 회의 퍼실리테이터
- 목표: 회의 안건 대비 빠진 논의 찾기
사용자 프롬프트:
- 회의 안건: {agenda}
- 이미 논의한 주제: {discussedTopics}
- 현재 대화 내용: {transcriptText}
- 참석자 정보: {participants}
지시사항:
- 안건에 있지만 아직 안 다룬 항목 찾기
- 대화 흐름상 빠진 중요 논의 식별
- 추가하면 좋을 주제 제안
- 우선순위 부여
응답 형식:
{
"suggestions": [
{
"topic": "논의 주제",
"reason": "제안 이유",
"priority": "HIGH|MEDIUM|LOW",
"relatedAgenda": "관련 안건 항목",
"estimatedTime": 분 단위 예상 시간
}
]
}
end note
Service -> LLM: generateDiscussionSuggestions(prompt)
activate LLM
LLM -> OpenAI: POST /chat/completions
activate OpenAI
note right
요청 파라미터:
- model: gpt-4o
- temperature: 0.4
- response_format: json_object
- max_tokens: 1500
end note
OpenAI -> OpenAI: 회의 맥락 분석
note right
분석 단계:
1. 안건 항목별 진행 상황 체크
2. 이미 논의한 주제와 비교
3. 현재 대화 맥락 이해
4. 빠진 중요 논의 식별
5. 추가 제안 생성
6. 우선순위 결정
- HIGH: 안건 필수 항목
- MEDIUM: 중요하지만 선택적
- LOW: 추가 고려사항
end note
OpenAI --> LLM: 논의사항 제안 목록 (JSON)
deactivate OpenAI
LLM --> Service: discussionSuggestions
deactivate LLM
== 제안 검증 및 필터링 ==
Service -> Service: 제안 품질 검증
note right
검증 기준:
- 중복 제거 (이미 논의한 주제)
- 관련성 검증 (회의 목적과 부합)
- 우선순위별 정렬
- 최대 5개까지만 선택
(너무 많으면 오히려 방해)
end note
loop 각 제안마다
Service -> Service: 제안 메타데이터 보강
note right
추가 정보:
- 생성 시각
- 제안 신뢰도 점수
- 회의 진행 시점 (분)
- 상태: PENDING
end note
end
== 제안 저장 ==
loop 각 검증된 제안마다
Service -> Repo: saveSuggestion(meetingId, suggestion)
activate Repo
Repo -> DB: INSERT INTO ai_suggestions
activate DB
note right
저장 데이터:
- meeting_id
- suggestion_type: 'DISCUSSION'
- content: {topic, reason}
- priority: HIGH/MEDIUM/LOW
- related_agenda: "안건 항목"
- estimated_time: 예상 시간
- confidence_score: 0.0-1.0
- 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",
"topic": "논의 주제",
"reason": "제안 이유",
"priority": "HIGH",
"relatedAgenda": "관련 안건",
"estimatedTime": 10,
"canApply": true
}
],
"totalCount": 제안 개수,
"displayHint": "오른쪽 탭에 표시"
}
end note
Service --> Controller: 논의사항 제안 생성 완료
deactivate Service
Controller --> Controller: 200 OK 응답 반환
note right
프론트엔드 처리:
- 오른쪽 "추천" 탭에 표시
- "적용" 버튼 활성화
- 우선순위별 색상 표시
* HIGH: 빨강
* MEDIUM: 주황
* LOW: 초록
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초
제안 정책:
- 최대 5개까지만 제안
- 우선순위 HIGH가 1개 이상
- 이미 논의한 주제는 제외
- 제안은 회의 중 언제든 생성 가능
end note
@enduml

View File

@ -0,0 +1,321 @@
@startuml
!theme mono
title AI Service 내부 시퀀스 - 실시간Todo추출
participant "SuggestionController" as Controller
participant "RealtimeTodoService" as Service
participant "LLMClient" as LLM
participant "SuggestionRepository" as Repo
participant "TranscriptRepository" as TranscriptRepo
database "Azure OpenAI<<E>>" as OpenAI
database "PostgreSQL<<E>>" as DB
== 실시간 액션아이템 추출 요청 ==
note over Controller
TranscriptService로부터 호출
또는 API 직접 호출:
POST /api/ai/suggestions/action-item
Body: {
"meetingId": "{meetingId}",
"transcriptText": "최근 대화 내용"
}
end note
Controller -> Service: extractRealtimeActionItems(meetingId, transcriptText)
activate Service
== 회의 맥락 및 참석자 정보 조회 ==
Service -> TranscriptRepo: getMeetingContext(meetingId)
activate TranscriptRepo
TranscriptRepo -> DB: SELECT meeting_info, participants, roles\nFROM meeting_context
activate DB
DB --> TranscriptRepo: 회의 및 참석자 정보
deactivate DB
TranscriptRepo --> Service: meetingContext
deactivate TranscriptRepo
Service -> Repo: getPreviousActionItems(meetingId)
activate Repo
Repo -> DB: SELECT content FROM ai_suggestions\nWHERE meeting_id = {meetingId}\nAND suggestion_type = 'ACTION_ITEM'\nAND status IN ('PENDING', 'APPLIED')
activate DB
DB --> Repo: 이미 추출된 액션아이템
deactivate DB
Repo --> Service: previousActionItems
deactivate Repo
== LLM 기반 액션아이템 패턴 감지 ==
Service -> Service: 액션아이템 추출 프롬프트 생성
note right
시스템 프롬프트:
- 역할: 액션아이템 추출 전문가
- 목표: 실시간으로 Todo 발생 감지
액션아이템 패턴 예시:
- "제가 ~하겠습니다"
- "~까지 완료하겠습니다"
- "~을 담당하겠습니다"
- "~을 해보겠습니다"
- "~를 처리하겠습니다"
- "[이름]님, ~해주시겠어요?"
- "~하기로 했습니다" (결정 + 액션)
사용자 프롬프트:
- 회의 참석자: {participants}
- 이미 추출된 Todo: {previousActionItems}
- 현재 대화 내용: {transcriptText}
지시사항:
- 위 패턴이 포함된 문장 찾기
- Todo 내용 명확화
- 담당자 식별 (발언자 또는 지정된 사람)
- 마감일 추출 (명시적 또는 추정)
- 우선순위 판단
- 신뢰도 점수 계산
응답 형식:
{
"actionItems": [
{
"content": "할 일 내용",
"assignee": "담당자 이름",
"dueDate": "YYYY-MM-DD" or null,
"priority": "HIGH|MEDIUM|LOW",
"confidence": 0.0-1.0,
"extractedFrom": "원문 발췌",
"relatedDecision": "관련 결정사항 ID"
}
]
}
end note
Service -> LLM: detectActionItemPatterns(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. 마감일 추출
- 명시적: "내일까지", "이번 주 금요일"
- 암묵적: "빨리", "다음 회의 전"
- 없으면 null
6. 우선순위 판단
- HIGH: 긴급, 중요, 블로커
- MEDIUM: 중요하지만 여유 있음
- LOW: 추가 작업, 선택적
7. 신뢰도 계산
- 명확한 약속: 0.9-1.0
- 추정 약속: 0.7-0.9
- 암묵적 합의: 0.5-0.7
end note
OpenAI --> LLM: 액션아이템 후보 목록 (JSON)
deactivate OpenAI
LLM --> Service: actionItemSuggestions
deactivate LLM
== 제안 검증 및 필터링 ==
Service -> Service: 액션아이템 검증
note right
검증 기준:
- 신뢰도 70% 이상만 선택
- 중복 제거
* 이미 추출된 것과 비교
* 유사도 90% 이상이면 제외
- 담당자 검증
* 참석자 목록에 있는지 확인
* 없으면 "미지정"으로 표시
- 내용 명확성 검증
* 동사가 있는지
* 구체적인 작업인지
- 마감일 형식 검증
- 우선순위별 정렬
end note
loop 각 제안마다
Service -> Service: 제안 메타데이터 보강
note right
추가 정보:
- 생성 시각
- 회의 진행 시점 (분)
- 원문 위치 (라인 번호)
- 상태: PENDING
- 관련 결정사항 참조
- 관련 논의 섹션 참조
end note
end
== 제안 저장 ==
loop 각 검증된 제안마다
Service -> Repo: saveSuggestion(meetingId, actionItem)
activate Repo
Repo -> DB: INSERT INTO ai_suggestions
activate DB
note right
저장 데이터:
- meeting_id
- suggestion_type: 'ACTION_ITEM'
- content: 할 일 내용
- assignee: 담당자
- due_date: 마감일
- priority: HIGH/MEDIUM/LOW
- confidence_score: 0.0-1.0
- extracted_from: 원문
- related_decision_id: 관련 결정
- 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": "할 일 내용",
"assignee": "김철수",
"dueDate": "2025-02-01",
"priority": "HIGH",
"confidence": 0.85,
"extractedFrom": "원문 발췌",
"relatedDecision": "decision-uuid",
"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
Body: {
"assignee": "김철수" (수정 가능),
"dueDate": "2025-02-01" (수정 가능)
}
end note
Controller -> Service: applySuggestion(suggestionId, updateData)
activate Service
Service -> Repo: updateSuggestionStatus(suggestionId, "APPLIED")
activate Repo
Repo -> DB: UPDATE ai_suggestions\nSET status = 'APPLIED',\napplied_at = NOW(),\nassignee = {updateData.assignee},\ndue_date = {updateData.dueDate}
activate DB
DB --> Repo: 업데이트 완료
deactivate DB
Repo --> Service: 완료
deactivate Repo
Service -> Service: Meeting Service에 Todo 생성 요청
note right
POST /meetings/{meetingId}/todos
Body: {
"content": "할 일 내용",
"assignee": "담당자",
"dueDate": "마감일",
"priority": "우선순위",
"relatedSection": "관련 회의록 섹션"
}
Meeting Service에서:
- Todo 생성
- TodoCreated 이벤트 발행
- 담당자에게 알림 발송
end note
Service --> Controller: 적용 완료
deactivate Service
Controller --> Controller: 200 OK
note over Controller, DB
처리 시간:
- 맥락 조회: 100-200ms
- LLM 패턴 감지: 1-2초
- 검증 및 필터링: 100-200ms
- 저장 처리: 200-300ms
총 처리 시간: 약 2-3초
제안 정책:
- 신뢰도 70% 이상만 제안
- 명확한 액션 표현 우선
- 중복 제거 (유사도 90% 기준)
- 실시간으로 계속 감지
- 최대 20개까지 누적 표시
- 적용된 것은 회색 처리
차이점 (회의 종료 후 Todo 추출과):
- 실시간: 5초마다 즉시 추출
- 종료 후: 전체 회의록 기반 종합 추출
- 실시간은 "후보"로 제시
- 종료 후는 "확정" 추출 후 자동 생성
end note
@enduml

View File

@ -1,10 +1,11 @@
@startuml
!theme mono
title AI Service 내부 시퀀스 - 회의록자동작성
title AI Service 내부 시퀀스 - 회의록자동작성 (실시간 추천 포함)
participant "TranscriptController" as Controller
participant "TranscriptService" as Service
participant "SuggestionService" as SuggestService
participant "LLMClient" as LLM
participant "VectorService" as Vector
participant "TranscriptRepository" as Repo
@ -119,9 +120,134 @@ deactivate VectorDB
Vector --> Service: 임베딩 생성 완료
deactivate Vector
== 실시간 추천 병렬 처리 ==
Service -> SuggestService: generateRealtimeSuggestions(meetingId, transcriptText)
activate SuggestService
par 논의사항 제안 생성
SuggestService -> LLM: suggestDiscussionTopics(meetingId, transcript)
activate LLM
LLM -> OpenAI: POST /chat/completions
activate OpenAI
note right
프롬프트:
- 현재 대화 맥락 분석
- 빠진 논의 항목 찾기
- 추가하면 좋을 주제 제안
응답 형식:
{
"suggestions": [
{
"topic": "논의 주제",
"reason": "제안 이유",
"priority": "HIGH|MEDIUM|LOW"
}
]
}
end note
OpenAI --> LLM: 논의사항 제안 목록
deactivate OpenAI
LLM --> SuggestService: discussionSuggestions
deactivate LLM
SuggestService -> Repo: saveSuggestions(meetingId, "DISCUSSION", suggestions)
activate Repo
Repo -> DB: INSERT INTO ai_suggestions
activate DB
DB --> Repo: 저장 완료
deactivate DB
deactivate Repo
else 결정사항 제안 생성
SuggestService -> LLM: suggestDecisions(meetingId, transcript)
activate LLM
LLM -> OpenAI: POST /chat/completions
activate OpenAI
note right
프롬프트:
- "~하기로 함" 패턴 감지
- "~로 결정" 패턴 감지
- 결정 내용 구조화
응답 형식:
{
"decisions": [
{
"content": "결정 내용",
"category": "기술|일정|리소스",
"confidence": 0.0-1.0
}
]
}
end note
OpenAI --> LLM: 결정사항 제안 목록
deactivate OpenAI
LLM --> SuggestService: decisionSuggestions
deactivate LLM
SuggestService -> Repo: saveSuggestions(meetingId, "DECISION", suggestions)
activate Repo
Repo -> DB: INSERT INTO ai_suggestions
activate DB
DB --> Repo: 저장 완료
deactivate DB
deactivate Repo
else 실시간 액션아이템 추출
SuggestService -> LLM: extractRealtimeActionItems(meetingId, transcript)
activate LLM
LLM -> OpenAI: POST /chat/completions
activate OpenAI
note right
프롬프트:
- "~까지 하겠습니다" 패턴 감지
- "제가 담당하겠습니다" 패턴 감지
- 담당자 및 마감일 추출
응답 형식:
{
"actionItems": [
{
"content": "할 일 내용",
"assignee": "담당자",
"dueDate": "YYYY-MM-DD",
"priority": "HIGH|MEDIUM|LOW"
}
]
}
end note
OpenAI --> LLM: 액션아이템 후보 목록
deactivate OpenAI
LLM --> SuggestService: actionItemSuggestions
deactivate LLM
SuggestService -> Repo: saveSuggestions(meetingId, "ACTION_ITEM", suggestions)
activate Repo
Repo -> DB: INSERT INTO ai_suggestions
activate DB
DB --> Repo: 저장 완료
deactivate DB
deactivate Repo
end
SuggestService --> Service: 모든 추천사항 생성 완료
deactivate SuggestService
== 이벤트 발행 ==
Service -> Controller: 회의록 생성 완료 응답
Service -> Controller: 회의록 및 추천사항 생성 완료 응답
deactivate Service
Controller -> Controller: TranscriptSummaryCreated 발행
@ -130,15 +256,23 @@ note right
- meetingId
- transcriptId
- content
- suggestions:
* discussionTopics: []
* decisions: []
* actionItems: []
end note
note over Controller, DB
처리 시간:
- 맥락 조회: 100-200ms
- LLM 생성: 3-5초
- LLM 회의록 생성: 3-5초
- 저장: 100-200ms
- 벡터화: 500ms-1초
총: 약 4-7초
- 실시간 추천 병렬 처리: 5-8초
* 논의사항 제안: 2-3초
* 결정사항 제안: 2-3초
* 액션아이템 추출: 1-2초
총: 약 9-15초
end note
@enduml
@enduml

View File

@ -0,0 +1,144 @@
@startuml
!theme mono
title AI Service 내부 시퀀스 - 회의록자동작성
participant "TranscriptController" as Controller
participant "TranscriptService" as Service
participant "LLMClient" as LLM
participant "VectorService" as Vector
participant "TranscriptRepository" as Repo
database "Azure OpenAI" as OpenAI <<external>>
database "Vector DB" as VectorDB <<external>>
database "PostgreSQL" as DB <<external>>
== TranscriptReady 이벤트 수신 ==
note over Controller
Azure Event Hubs로부터
TranscriptReady 이벤트 수신
end note
Controller -> Service: processTranscript(meetingId, transcriptText)
activate Service
Service -> Service: 회의 맥락 정보 조회 준비
== 병렬 처리: 맥락 정보 수집 ==
par 회의 정보 조회
Service -> Repo: getMeetingContext(meetingId)
activate Repo
Repo -> DB: SELECT meeting_info
activate DB
DB --> Repo: 회의 정보 반환
deactivate DB
Repo --> Service: 회의 맥락 정보
deactivate Repo
else 이전 내용 조회
Service -> Repo: getPreviousTranscripts(meetingId)
activate Repo
Repo -> DB: SELECT previous_content
activate DB
DB --> Repo: 이전 회의록
deactivate DB
Repo --> Service: 이전 내용
deactivate Repo
end
Service -> Service: 프롬프트 생성
note right
시스템 프롬프트 생성
- 역할 정의
- 변환 규칙 적용
end note
== LLM 기반 회의록 작성 ==
Service -> LLM: generateMinutes(prompt, context)
activate LLM
LLM -> OpenAI: POST /chat/completions
activate OpenAI
note right
model: gpt-4o
temperature: 0.3
max_tokens: 2000
end note
OpenAI -> OpenAI: 텍스트 분석 및 정리
OpenAI --> LLM: 정리된 회의록 내용
deactivate OpenAI
LLM --> Service: 회의록 초안
deactivate LLM
== 회의록 저장 ==
Service -> Service: 회의록 데이터 구조화
Service -> Repo: saveTranscriptDraft(meetingId, content)
activate Repo
Repo -> DB: INSERT INTO ai_transcripts
activate DB
note right
저장 데이터:
- meeting_id
- content (JSON)
- status: DRAFT
end note
DB --> Repo: 저장 완료
deactivate DB
Repo --> Service: transcriptId
deactivate Repo
== 벡터 임베딩 생성 ==
Service -> Vector: createEmbedding(transcriptId, content)
activate Vector
Vector -> OpenAI: POST /embeddings
activate OpenAI
note right
model: text-embedding-3-large
end note
OpenAI --> Vector: 임베딩 벡터
deactivate OpenAI
Vector -> VectorDB: INSERT embedding
activate VectorDB
VectorDB --> Vector: 저장 완료
deactivate VectorDB
Vector --> Service: 임베딩 생성 완료
deactivate Vector
== 이벤트 발행 ==
Service -> Controller: 회의록 생성 완료 응답
deactivate Service
Controller -> Controller: TranscriptSummaryCreated 발행
note right
이벤트 데이터:
- meetingId
- transcriptId
- content
end note
note over Controller, DB
처리 시간:
- 맥락 조회: 100-200ms
- LLM 생성: 3-5초
- 저장: 100-200ms
- 벡터화: 500ms-1초
총: 약 4-7초
end note
@enduml

View File

@ -74,13 +74,43 @@ deactivate Frontend
EventHub -> AI: TranscriptReady 이벤트 구독
activate AI
AI -> AI: [1] 회의록 내용 정리 (LLM)
AI -> AI: [2] 전문용어 추출 (RAG)
AI -> AI: [3] 관련 자료 검색
par 회의록 내용 정리
AI -> AI: [1] 회의록 내용 정리 (LLM)
else 전문용어 추출
AI -> AI: [2] 전문용어 추출 (RAG)
else 관련 자료 검색
AI -> AI: [3] 관련 자료 검색
else 논의사항 제안
AI -> AI: [4] 추가할 논의사항 제안 (LLM)
note right
실시간으로 대화 맥락 분석하여
추가할만한 논의 항목 제안
end note
else 결정사항 제안
AI -> AI: [5] 결정사항 제안 (LLM)
note right
"~하기로 함", "~로 결정" 등의
결정 패턴 감지 및 구조화
end note
else 실시간 액션아이템 추출
AI -> AI: [6] 실시간 액션아이템 추출 (LLM)
note right
"~까지 하겠습니다" 등
즉시 감지하여 Todo 후보 추출
end note
end
AI -> AI: AI 분석 결과 저장
AI -> EventHub: TranscriptSummaryCreated 발행
note right
이벤트 데이터:
- 회의록 내용
- 전문용어 목록
- 논의사항 제안 목록
- 결정사항 제안 목록
- 액션아이템 후보 목록
end note
AI --> EventHub: AI 분석 완료
deactivate AI
@ -99,14 +129,55 @@ deactivate Cache
Meeting -> Frontend: WebSocket 메시지 전송
activate Frontend
note right
WebSocket 데이터:
- 회의록 내용
- 논의사항 제안 (오른쪽 탭)
- 결정사항 제안 (오른쪽 탭)
- 액션아이템 후보 (오른쪽 탭)
- 전문용어 하이라이트
end note
Meeting --> EventHub: 동기화 완료
deactivate Meeting
deactivate EventHub
Frontend -> Frontend: 회의록 화면 업데이트
Frontend -> Frontend: 오른쪽 탭에 추천 항목 표시
Frontend --> User: 실시간 회의록 표시
Frontend --> User: 실시간 회의록 + 추천사항 표시
deactivate Frontend
== 사용자 추천 적용 ==
User -> Frontend: 추천 항목 "적용" 버튼 클릭
activate Frontend
note right
논의사항/결정사항/액션아이템 중
원하는 항목 선택하여 적용
end note
Frontend -> Frontend: 추천 내용을 회의록에 반영
Frontend -> Gateway: PUT /api/meetings/{meetingId}/transcript
activate Gateway
note right
사용자가 적용한 내용으로
회의록 업데이트
end note
Gateway -> Meeting: PUT /meetings/{meetingId}/transcript
activate Meeting
Meeting -> Meeting: 회의록 업데이트
Meeting --> Gateway: 200 OK
deactivate Meeting
Gateway --> Frontend: 200 OK
deactivate Gateway
Frontend --> User: 회의록 업데이트 완료
deactivate Frontend
end
@ -114,8 +185,13 @@ end
note over User, EventHub
처리 시간:
- STT 변환: 1-3초
- AI 병렬 처리: 5-8초
- AI 병렬 처리: 8-12초
* 회의록 정리: 3-5초
* 전문용어: 2-4초
* 논의사항 제안: 2-3초
* 결정사항 제안: 2-3초
* 액션아이템 추출: 1-2초
- 회의록 저장: 1-2초
- 총 처리 시간: 7-13초
- 총 처리 시간: 10-17
end note
@enduml

View File

@ -0,0 +1,121 @@
@startuml
!theme mono
title 회의시작및실시간회의록작성 외부 시퀀스
actor "사용자" as User
participant "Web App" as Frontend
participant "API Gateway" as Gateway
participant "Meeting Service" as Meeting
participant "STT Service" as STT
participant "AI Service" as AI
database "Redis Cache" as Cache
queue "Azure Event Hubs" as EventHub
== 회의 시작 ==
User -> Frontend: 회의 시작 버튼 클릭
activate Frontend
Frontend -> Gateway: POST /api/meetings/{meetingId}/start
activate Gateway
Gateway -> Meeting: POST /meetings/{meetingId}/start
activate Meeting
Meeting -> Meeting: 회의 세션 생성
Meeting -> EventHub: MeetingStarted 이벤트 발행
activate EventHub
Meeting --> Gateway: 201 Created
deactivate Meeting
Gateway --> Frontend: 201 Created
deactivate Gateway
Frontend -> Frontend: 회의 화면으로 전환
Frontend --> User: 회의 진행 화면 표시
deactivate Frontend
== 음성 녹음 시작 ==
EventHub -> STT: MeetingStarted 이벤트 구독
activate STT
STT -> STT: 음성 녹음 준비
STT --> EventHub: 녹음 준비 완료
deactivate STT
deactivate EventHub
== 실시간 회의록 작성 (반복) ==
loop 5초 간격 배치 처리
User -> Frontend: 발언 (음성 입력)
activate Frontend
Frontend -> STT: 음성 데이터 스트리밍
activate STT
STT -> STT: 음성 인식 처리
STT -> EventHub: TranscriptReady 이벤트 발행
activate EventHub
STT --> Frontend: 음성 처리 중 표시
deactivate STT
deactivate Frontend
== AI 병렬 처리 ==
EventHub -> AI: TranscriptReady 이벤트 구독
activate AI
AI -> AI: [1] 회의록 내용 정리 (LLM)
AI -> AI: [2] 전문용어 추출 (RAG)
AI -> AI: [3] 관련 자료 검색
AI -> AI: AI 분석 결과 저장
AI -> EventHub: TranscriptSummaryCreated 발행
AI --> EventHub: AI 분석 완료
deactivate AI
== 회의록 저장 및 실시간 동기화 ==
EventHub -> Meeting: TranscriptSummaryCreated 구독
activate Meeting
Meeting -> Meeting: 회의록 데이터 저장
Meeting -> Cache: 캐시 무효화
activate Cache
Cache --> Meeting: 캐시 삭제 완료
deactivate Cache
Meeting -> Frontend: WebSocket 메시지 전송
activate Frontend
Meeting --> EventHub: 동기화 완료
deactivate Meeting
deactivate EventHub
Frontend -> Frontend: 회의록 화면 업데이트
Frontend --> User: 실시간 회의록 표시
deactivate Frontend
end
note over User, EventHub
처리 시간:
- STT 변환: 1-3초
- AI 병렬 처리: 5-8초
- 회의록 저장: 1-2초
- 총 처리 시간: 7-13초
end note
@enduml