mirror of
https://github.com/hwanny1128/HGZero.git
synced 2025-12-06 13:46:24 +00:00
322 lines
8.1 KiB
Plaintext
322 lines
8.1 KiB
Plaintext
@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
|