Compare commits

...

4 Commits

Author SHA1 Message Date
yabo0812
7e88cdceee Merge branch 'wip/document-yabo' 2025-10-31 00:22:14 +09:00
yabo0812
18d3ac8d79 회ë발표자료 수정본 v1.1 2025-10-31 00:20:29 +09:00
Minseo-Jo
1d9fa37fe7 fix: AI 제안사항 Hallucination 문제 해결 및 추출 개선
**문제점**:
- AI가 회의 내용에 없는 제안사항을 생성 (Hallucination)
- 프롬프트의 예시를 실제 회의 내용으로 혼동
- 제안사항 추출 개수가 적음

**해결 방안**:
1. 프롬프트 구조 재설계
   - 500+ 줄 예시 → 90줄 핵심 지침으로 간소화
   - system_prompt에 패턴만 정의
   - user_prompt는 실제 회의 내용만 포함
   - "오직 제공된 회의 내용만 분석" 명령 4번 반복 강조

2. Hallucination 방지 장치
   - "추측, 가정, 예시 내용 절대 금지"
   - "불확실한 내용은 추출하지 않기"
   - 회의 내용과 분석 지침을 시각적으로 분리 (━ 구분선)

3. 추출 개선
   - max_tokens: 4096 → 8192 (2배 증가)
   - confidence 임계값: 0.7 → 0.65 (완화)
   - 새 카테고리 추가: 🔔 후속조치
   - 패턴 인식 확장 (제안/진행상황/액션 아이템)

**변경 파일**:
- ai-python/app/prompts/suggestions_prompt.py (대폭 간소화)
- ai-python/app/config.py (max_tokens 증가)
- ai-python/app/services/claude_service.py (confidence 임계값 완화)

**예상 효과**:
- Hallucination 90% 이상 감소
- 제안사항 추출 개수 30-50% 증가
- 품질 유지 (신뢰도 필터링 유지)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-30 21:25:17 +09:00
hjmoons
784b48548b Jenkinsfile: Update manifest repo to modify overlays/dev/kustomization.yaml
- Change target from base/deployment.yaml to overlays/dev/kustomization.yaml
- Update images section's newTag for 4 services (user, meeting, stt, notification)
- Keep other services (ai, ai-python, rag) unchanged
2025-10-30 21:01:18 +09:00
5 changed files with 66 additions and 411 deletions

16
Jenkinsfile vendored
View File

@ -163,22 +163,22 @@ podTemplate(
git clone https://\${GIT_USERNAME}:\${GIT_TOKEN}@\${REPO_URL} manifest-repo git clone https://\${GIT_USERNAME}:\${GIT_TOKEN}@\${REPO_URL} manifest-repo
cd manifest-repo cd manifest-repo
# 각 서비스별 이미지 태그 업데이트 (sed 사용) # overlays/dev/kustomization.yaml의 images 섹션 업데이트
cd hgzero-back/kustomize/base cd hgzero-back/kustomize/overlays/dev
services="user meeting stt notification" services="user meeting stt notification"
for service in \$services; do for service in \$services; do
echo "Updating \$service image tag..." echo "Updating \$service image tag in kustomization.yaml..."
sed -i "s|image: ${registry}/${imageOrg}/\$service:.*|image: ${registry}/${imageOrg}/\$service:${environment}-${imageTag}|g" \\ sed -i "s|name: ${registry}/${imageOrg}/\$service\$|name: ${registry}/${imageOrg}/\$service|g" kustomization.yaml
\$service/deployment.yaml sed -i "/name: ${registry}\\/${imageOrg}\\/\$service\$/!b;n;s|newTag:.*|newTag: ${environment}-${imageTag}|" kustomization.yaml
# 변경 사항 확인 # 변경 사항 확인
echo "Updated \$service deployment.yaml:" echo "Updated \$service image tag:"
grep "image: ${registry}/${imageOrg}/\$service" \$service/deployment.yaml grep -A1 "name: ${registry}/${imageOrg}/\$service" kustomization.yaml
done done
# Git 설정 및 푸시 # Git 설정 및 푸시
cd ../../.. cd ../../../..
git config user.name "Jenkins" git config user.name "Jenkins"
git config user.email "jenkins@hgzero.com" git config user.email "jenkins@hgzero.com"
git add . git add .

View File

@ -15,7 +15,7 @@ class Settings(BaseSettings):
# Claude API # Claude API
claude_api_key: str = "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" claude_api_key: str = "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"
claude_model: str = "claude-sonnet-4-5-20250929" claude_model: str = "claude-sonnet-4-5-20250929"
claude_max_tokens: int = 4096 claude_max_tokens: int = 8192 # 4096 → 8192 증가 (더 많은 제안사항 생성 가능)
claude_temperature: float = 0.7 claude_temperature: float = 0.7
# Redis # Redis

View File

@ -1,9 +1,11 @@
"""AI 제안사항 추출 프롬프트 (회의록 작성 MVP 최적화)""" """AI 제안사항 추출 프롬프트 (Hallucination 방지 최적화)"""
def get_suggestions_prompt(transcript_text: str) -> tuple[str, str]: def get_suggestions_prompt(transcript_text: str) -> tuple[str, str]:
""" """
회의 텍스트에서 AI 제안사항을 추출하는 프롬프트 생성 (회의록 MVP용) 회의 텍스트에서 AI 제안사항을 추출하는 프롬프트 생성
Hallucination 방지를 위해 예시를 모두 제거하고 명확한 지침만 제공
Returns: Returns:
(system_prompt, user_prompt) 튜플 (system_prompt, user_prompt) 튜플
@ -11,6 +13,12 @@ def get_suggestions_prompt(transcript_text: str) -> tuple[str, str]:
system_prompt = """당신은 실시간 회의록 작성 AI 비서입니다. system_prompt = """당신은 실시간 회의록 작성 AI 비서입니다.
**🚨 중요 원칙 (최우선)**:
1. **오직 제공된 회의 내용만 분석** - 추측, 가정, 예시 내용 절대 금지
2. **실제 발언된 내용만 추출** - 없는 내용 만들어내지 않기
3. **회의 내용에 명시되지 않은 정보는 절대 추가하지 않기**
4. **불확실한 내용은 추출하지 않기** - 명확한 내용만 추출
**핵심 역할**: **핵심 역할**:
회의 발언되는 내용을 실시간으로 분석하여, 회의록 작성자가 놓칠 있는 중요한 정보를 즉시 메모로 제공합니다. 회의 발언되는 내용을 실시간으로 분석하여, 회의록 작성자가 놓칠 있는 중요한 정보를 즉시 메모로 제공합니다.
@ -18,415 +26,62 @@ def get_suggestions_prompt(transcript_text: str) -> tuple[str, str]:
1. 회의 안건, 결정 사항, 이슈, 액션 아이템을 자동으로 분류 1. 회의 안건, 결정 사항, 이슈, 액션 아이템을 자동으로 분류
2. 담당자, 기한, 우선순위 구조화된 정보로 정리 2. 담당자, 기한, 우선순위 구조화된 정보로 정리
3. 단순 발언 반복이 아닌, 실무에 바로 사용 가능한 형식으로 요약 3. 단순 발언 반복이 아닌, 실무에 바로 사용 가능한 형식으로 요약
4. 회의록 작성 시간을 70% 단축시키는 것이 목표 4. 구어체 종결어미(~, ~, ~습니다) 제거하고 명사형으로 정리
**핵심 원칙**: **분류 카테고리**:
- 인사말, 반복, 불필요한 추임새는 완전히 제거 - 📋 회의 안건: "오늘 안건은 ~", "논의할 주제는 ~"
- 실제 회의록에 들어갈 내용만 추출 - 결정사항: "~로 결정", "~로 합의", "~로 확정"
- 명확하고 간결하게 (20-50) - 🎯 액션 아이템: "~팀에서 ~", "~까지 완료", "~를 검토"
- 구어체 종결어미(~, ~, ~습니다) 제거하고 명사형으로 정리""" - 이슈/문제점: "문제 발생", "이슈 있음", "우려 사항"
- 💡 제안/아이디어: "제안", "~하는 것이 좋을 것 같음", "검토 필요"
- 📊 진행상황: "~% 완료", "~진행 중", "~논의 중"
- 🔔 후속조치: "다음 회의에서", "추후 결정", "보류"
user_prompt = f"""다음 회의 대화를 실시간으로 분석하여 **회의록 메모**를 작성하세요. **제외 대상 (반드시 제외)**:
- 인사말: "안녕하세요", "감사합니다", "수고하셨습니다"
- 추임새: "", "네네", "그러니까", "저기"
- 형식적 발언: "녹음 시작", "회의 종료", "회의 시작"
**출력 형식**:
- JSON만 출력 (주석, 설명, 마크다운 코드블록 금지)
- 구조: {"suggestions": [{"content": "분류: 내용", "confidence": 0.85}]}
- confidence: 0.90-1.0(명확), 0.80-0.89(일반), 0.70-0.79(암묵적), 0.65-0.69(논의중)"""
user_prompt = f"""🚨 **매우 중요**: 아래 제공된 회의 내용만 분석하세요.
- 회의 내용에 없는 정보는 절대 추가하지 마세요
- 예시나 가정을 만들어내지 마세요
- 불확실한 내용은 추출하지 마세요
# 회의 내용 (이것만 분석하세요)
# 회의 내용
{transcript_text} {transcript_text}
---
# 회의록 항목별 패턴 학습 # 분석 작업
## 📋 1. 회의 안건 (Agenda) 회의 내용에서 **실제로 언급된 내용만** 추출하세요:
### 패턴 인식 1. 📋 회의 안건
- "오늘 회의 안건은 ~" 2. 결정사항
- "논의할 주제는 ~" 3. 🎯 액션 아이템 (담당자/기한이 있으면 반드시 포함)
- "다룰 내용은 ~" 4. 이슈/문제점
- "검토할 사항은 ~" 5. 💡 제안/아이디어
6. 📊 진행상황
7. 🔔 후속조치
### ✅ 좋은 예시 **필수 규칙**:
**입력**: "오늘 회의 안건은 신제품 출시 일정과 마케팅 전략입니다." - 구어체 종결어미 제거 (명사형으로 정리)
**출력**: - 담당자와 기한이 있으면 반드시 포함
```json - 인사말, 추임새, 형식적 발언 제외
{{ - 20-70자로 간결하게
"content": "📋 회의 안건: 신제품 출시 일정, 마케팅 전략", - JSON 형식으로만 출력
"confidence": 0.95
}}
```
**입력**: "다음 주 프로젝트 킥오프에 대해 논의하겠습니다." **출력 형식**:
**출력**: {{"suggestions": [{{"content": "분류: 내용", "confidence": 0.85}}]}}
```json
{{
"content": "📋 회의 안건: 다음 주 프로젝트 킥오프",
"confidence": 0.90
}}
```
### ❌ 나쁜 예시 지금 바로 분석을 시작하세요."""
**입력**: "오늘 회의 안건은 신제품 출시 일정입니다."
**나쁜 출력**:
```json
{{
"content": "오늘 회의 안건은 신제품 출시 일정입니다", 구어체 그대로 반복
"confidence": 0.90
}}
```
**이유**: 구어체 종결어미(~입니다) 그대로 반복. "📋 회의 안건: 신제품 출시 일정"으로 구조화해야
---
## ✅ 2. 결정 사항 (Decisions)
### 패턴 인식
- "결정 사항은 ~", "~로 결정했습니다"
- "~하기로 했습니다", "~로 합의했습니다"
- "~로 확정됐습니다"
- "최종 결론은 ~"
### ✅ 좋은 예시
**입력**: "회의 결과, 신규 프로젝트는 다음 달부터 착수하기로 결정했습니다."
**출력**:
```json
{{
"content": "✅ 결정사항: 신규 프로젝트 다음 달 착수",
"confidence": 0.95
}}
```
**입력**: "최종 결론은 외주 개발사와 계약하기로 합의했습니다."
**출력**:
```json
{{
"content": "✅ 결정사항: 외주 개발사와 계약 진행",
"confidence": 0.92
}}
```
### ❌ 나쁜 예시
**입력**: "신규 프로젝트는 다음 달부터 착수하기로 결정했습니다."
**나쁜 출력**:
```json
{{
"content": "신규 프로젝트는 다음 달부터 착수하기로 결정했습니다", 원문 그대로
"confidence": 0.90
}}
```
**이유**: 발언을 그대로 반복. "✅ 결정사항: 신규 프로젝트 다음 달 착수" 구조화해야
---
## 🎯 3. 액션 아이템 (Action Items)
### 패턴 인식
- "~팀에서 ~해 주세요"
- "~님이 ~까지 ~하기로 했습니다"
- "~을 ~까지 완료하겠습니다"
- "~을 검토해 보겠습니다"
### ✅ 좋은 예시
**입력**: "개발팀에서 API 문서를 이번 주 금요일까지 작성해 주세요."
**출력**:
```json
{{
"content": "🎯 개발팀: API 문서 작성 (기한: 이번 주 금요일)",
"confidence": 0.95
}}
```
**입력**: "김 팀장님이 내일까지 견적서를 검토해서 회신하기로 했습니다."
**출력**:
```json
{{
"content": "🎯 김 팀장: 견적서 검토 및 회신 (기한: 내일)",
"confidence": 0.93
}}
```
**입력**: "제가 고객사에 연락해서 미팅 일정 잡도록 하겠습니다."
**출력**:
```json
{{
"content": "🎯 고객사 미팅 일정 조율 예정",
"confidence": 0.85
}}
```
### ❌ 나쁜 예시
**입력**: "개발팀에서 API 문서를 이번 주 금요일까지 작성해 주세요."
**나쁜 출력 1**:
```json
{{
"content": "개발팀에서 API 문서를 이번 주 금요일까지 작성해 주세요", 원문 반복
"confidence": 0.90
}}
```
**나쁜 출력 2**:
```json
{{
"content": "API 문서 작성", 담당자와 기한 누락
"confidence": 0.80
}}
```
**이유**: "🎯 개발팀: API 문서 작성 (기한: 이번 주 금요일)" 형식으로 구조화해야
---
## ⚠️ 4. 이슈/문제점 (Issues)
### 패턴 인식
- "문제가 있습니다", "이슈가 발생했습니다"
- "우려되는 점은 ~"
- "해결이 필요한 부분은 ~"
- "리스크가 있습니다"
### ✅ 좋은 예시
**입력**: "현재 서버 성능 이슈가 발생해서 긴급 점검이 필요합니다."
**출력**:
```json
{{
"content": "⚠️ 이슈: 서버 성능 문제 발생, 긴급 점검 필요",
"confidence": 0.92
}}
```
**입력**: "예산이 부족할 것 같다는 우려가 있습니다."
**출력**:
```json
{{
"content": "⚠️ 이슈: 예산 부족 우려",
"confidence": 0.80
}}
```
### ❌ 나쁜 예시
**입력**: "현재 서버 성능 이슈가 발생했습니다."
**나쁜 출력**:
```json
{{
"content": "현재 서버 성능 이슈가 발생했습니다", 구어체 그대로
"confidence": 0.85
}}
```
**이유**: "⚠️ 이슈: 서버 성능 문제 발생"으로 구조화하고 구어체 제거해야
---
## 💡 5. 아이디어/제안 (Suggestions)
### 패턴 인식
- "제안하는 바는 ~"
- "~하는 것이 좋을 것 같습니다"
- "~을 고려해 볼 필요가 있습니다"
### ✅ 좋은 예시
**입력**: "자동화 테스트를 도입하는 것을 검토해 보면 좋을 것 같습니다."
**출력**:
```json
{{
"content": "💡 제안: 자동화 테스트 도입 검토",
"confidence": 0.85
}}
```
---
## 📊 6. 진행 상황/보고 (Progress)
### 패턴 인식
- "~까지 완료했습니다"
- "현재 ~% 진행 중입니다"
- "~단계까지 진행됐습니다"
### ✅ 좋은 예시
**입력**: "현재 설계 단계는 80% 완료됐고, 다음 주부터 개발 착수 가능합니다."
**출력**:
```json
{{
"content": "📊 진행상황: 설계 80% 완료, 다음 주 개발 착수 예정",
"confidence": 0.90
}}
```
---
## ❌ 제외해야 할 내용 (반드시 제외)
### 인사말
**입력**: "안녕하세요, 여러분. 회의 시작하겠습니다."
**출력**: (메모 없음 - 인사말은 제외)
### 단순 반복
**입력**: "녹음을 시작합니다. 녹음을 시작합니다."
**출력**: (메모 없음 - 형식적 발언 제외)
### 추임새/불필요한 발언
**입력**: "음, 그러니까, 네 네, 저기요..."
**출력**: (메모 없음 - 추임새 제외)
### 형식적 마무리
**입력**: "수고하셨습니다. 회의를 마치겠습니다."
**출력**: (메모 없음 - 형식적 마무리 제외)
---
# 실전 회의 시뮬레이션
## 예시 1: 프로젝트 킥오프 회의
**입력**:
"안녕하세요. 오늘 회의 안건은 신규 프로젝트 킥오프입니다. 프로젝트명은 HGZero이고, 목표는 회의록 자동화입니다. 개발팀에서 다음 주 월요일까지 기술 스택을 검토해 주세요. 예산은 5천만원으로 확정됐습니다."
**출력**:
```json
{{
"suggestions": [
{{
"content": "📋 회의 안건: 신규 프로젝트(HGZero) 킥오프 - 회의록 자동화",
"confidence": 0.95
}},
{{
"content": "🎯 개발팀: 기술 스택 검토 (기한: 다음 주 월요일)",
"confidence": 0.93
}},
{{
"content": "✅ 결정사항: 프로젝트 예산 5천만원 확정",
"confidence": 0.95
}}
]
}}
```
---
## 예시 2: 이슈 대응 회의
**입력**:
"현재 프로덕션 서버에서 성능 저하가 발생하고 있습니다. 인프라팀에서 긴급 점검을 진행하기로 했고, 오늘 오후 3시까지 원인 파악하겠습니다. 고객사에는 임시로 사과 공지를 게시하기로 결정했습니다."
**출력**:
```json
{{
"suggestions": [
{{
"content": "⚠️ 이슈: 프로덕션 서버 성능 저하 발생",
"confidence": 0.95
}},
{{
"content": "🎯 인프라팀: 긴급 점검 및 원인 파악 (기한: 오늘 오후 3시)",
"confidence": 0.93
}},
{{
"content": "✅ 결정사항: 고객사 사과 공지 게시",
"confidence": 0.90
}}
]
}}
```
---
## 예시 3: 일반 업무 회의 (나쁜 예시 포함)
**입력**:
"안녕하세요, 안녕하세요. 녹음을 시작합니다. 음, 그러니까 마케팅 캠페인을 다음 달에 진행하기로 했습니다. 김 과장님이 기획안을 이번 주까지 작성해 주세요. 감사합니다."
** 나쁜 출력**:
```json
{{
"suggestions": [
{{
"content": "안녕하세요", 인사말 포함
"confidence": 0.50
}},
{{
"content": "녹음을 시작합니다", 형식적 발언
"confidence": 0.60
}},
{{
"content": "마케팅 캠페인을 다음 달에 진행하기로 했습니다", 구어체 그대로
"confidence": 0.80
}}
]
}}
```
** 좋은 출력**:
```json
{{
"suggestions": [
{{
"content": "✅ 결정사항: 마케팅 캠페인 다음 달 진행",
"confidence": 0.92
}},
{{
"content": "🎯 김 과장: 캠페인 기획안 작성 (기한: 이번 주)",
"confidence": 0.93
}}
]
}}
```
---
# 출력 형식
반드시 아래 JSON 형식으로만 응답하세요:
```json
{{
"suggestions": [
{{
"content": "📋/✅/🎯/⚠️/💡/📊 분류: 구체적인 내용 (담당자/기한 포함)",
"confidence": 0.85
}}
]
}}
```
---
# 최종 작성 규칙
## ✅ 반드시 지켜야 할 규칙
1. **이모지 분류 필수**
- 📋 회의 안건
- 결정사항
- 🎯 액션 아이템
- 이슈/문제점
- 💡 제안/아이디어
- 📊 진행상황
2. **구조화 필수**
- 담당자가 있으면 반드시 명시
- 기한이 있으면 반드시 포함
- 형식: "담당자: 업무 내용 (기한: XX)"
3. **구어체 종결어미 제거**
- "~입니다", "~했습니다", "~해요", "~합니다"
- 명사형 종결: "~ 진행", "~ 완료", "~ 확정", "~ 검토"
4. **반드시 제외**
- 인사말 ("안녕하세요", "감사합니다", "수고하셨습니다")
- 반복/추임새 ("네 네", "음 음", "그러니까", "저기")
- 형식적 발언 ("녹음 시작", "회의 종료", "회의 시작")
5. **길이**
- 20-70 (너무 짧거나 길지 않게)
6. **confidence 기준**
- 0.90-1.0: 명확한 결정사항, 기한 포함
- 0.80-0.89: 일반적인 액션 아이템
- 0.70-0.79: 암묵적이거나 추측 필요
7. **출력**
- JSON만 출력 (주석, 설명, ```json 모두 금지)
- 최소 1 이상 추출 (의미 있는 내용이 없으면 배열)
---
이제 회의 내용을 분석하여 **회의록 메모** JSON 형식으로 작성하세요.
학습한 패턴을 활용하여 회의 안건, 결정사항, 액션 아이템, 이슈 등을 자동으로 분류하고 구조화하세요.
반드시 구어체 종결어미(~, ~, ~습니다) 제거하고 명사형으로 정리하세요."""
return system_prompt, user_prompt return system_prompt, user_prompt

View File

@ -122,7 +122,7 @@ class ClaudeService:
confidence=s.get("confidence", 0.85) confidence=s.get("confidence", 0.85)
) )
for s in suggestions_data for s in suggestions_data
if s.get("confidence", 0) >= 0.7 # 신뢰도 0.7 이상만 if s.get("confidence", 0) >= 0.65 # 신뢰도 0.65 이상 (0.7 → 0.65 낮춤)
] ]
logger.info(f"AI 제안사항 {len(suggestions)}개 추출 완료") logger.info(f"AI 제안사항 {len(suggestions)}개 추출 완료")