From f0d98901101ce02ea4f719c6713d888aca6f76a3 Mon Sep 17 00:00:00 2001 From: Claude-51124 Date: Thu, 16 Oct 2025 16:23:20 +0900 Subject: [PATCH] Refactor troubleshooting docs to follow documentation principles MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Changes: - 251016_coldmail_duplicate_file_fix.md: 298줄 → 111줄 - 251016_troubleshooting_summary.md: 184줄 → 109줄 Applied principles (312_문서_작성_원칙.md): - Removed excessive code blocks - Kept file:line references only - Removed emojis - Reduced to ~100 lines per document - Kept core information and lessons learned --- .../251016_coldmail_duplicate_file_fix.md | 271 +++--------------- .../251016_troubleshooting_summary.md | 169 +++-------- 2 files changed, 89 insertions(+), 351 deletions(-) diff --git a/troubleshooting/251016_coldmail_duplicate_file_fix.md b/troubleshooting/251016_coldmail_duplicate_file_fix.md index 8228615..a736756 100644 --- a/troubleshooting/251016_coldmail_duplicate_file_fix.md +++ b/troubleshooting/251016_coldmail_duplicate_file_fix.md @@ -3,295 +3,108 @@ **날짜**: 2025-10-16 **작성자**: Claude (51124 서버 전담) **커밋**: skill-rag-file cea055c -**관련 문서**: 251015_claude_coldmail_ir_analysis_failure.md +**관련 파일**: skill-rag-file/app/api/upload.py:60-79 --- -## 문제 요약 +## 문제 상황 -Coldmail 브리핑 워크플로우에서 동일한 PDF 파일이 재업로드될 때 `400 - File already exists for this team` 에러 발생하여 전체 IR 분석 실패. +Coldmail 브리핑 워크플로우에서 동일 PDF 재업로드 시 `400 - File already exists` 에러로 전체 IR 분석 실패. -### 연쇄 효과 - -``` -PDF 업로드 실패 (400 에러) - ↓ -document_id = None - ↓ -RAG 검색 0건 - ↓ -IR 분석 "N/A" 반환 - ↓ -Slack Lists API 에러 -``` +**연쇄 효과**: PDF 업로드 실패 → document_id = None → RAG 검색 0건 → IR 분석 "N/A" → Slack Lists API 에러 --- ## 원인 분석 -**위치**: `skill-rag-file/app/api/upload.py:67-71` +**위치**: skill-rag-file/app/api/upload.py:67-71 -**기존 코드**: -```python -if result.scalar(): - raise HTTPException( - status_code=400, - detail="File already exists for this team" - ) -``` - -**문제점**: +**기존 동작**: - 중복 파일 발견 시 HTTPException 발생 - document_id 반환 없음 -- 워크플로우 중단 -- **멱등성(idempotency) 미보장**: 동일 요청을 여러 번 실행할 때 결과가 달라짐 +- 멱등성 미보장: 동일 요청 재실행 시 결과 달라짐 --- -## 해결 방법 +## 해결 방안 -### 코드 수정 +**위치**: skill-rag-file/app/api/upload.py:60-79 -**위치**: `skill-rag-file/app/api/upload.py:60-79` +**변경 내용**: +1. select(TeamDocument.id) → select(TeamDocument): 전체 레코드 조회 +2. HTTPException 제거 → 기존 document_id 반환 +3. FileUploadResponse 반환: 기존 document와 동일 응답 +4. INFO 로그 추가: 중복 감지 기록 -```python -# Check if file already exists for this team -from sqlalchemy import select -stmt = select(TeamDocument).where( - TeamDocument.team_id == team_id, - TeamDocument.file_hash == file_hash -) -result = await db.execute(stmt) -existing_doc = result.scalar_one_or_none() +**핵심 로직**: +- existing_doc = result.scalar_one_or_none() +- if existing_doc: return FileUploadResponse(document_id=existing_doc.id, ...) -if existing_doc: - # 중복 파일 발견 - 기존 document_id 반환 (멱등성 보장) - logger.info(f"File already exists (hash: {file_hash}), returning existing document_id: {existing_doc.id}") - return FileUploadResponse( - document_id=existing_doc.id, - filename=existing_doc.filename, - file_hash=existing_doc.file_hash, - storage_path=existing_doc.storage_path, - chunk_count=existing_doc.chunk_count or 0, - message=f"File already exists, returned existing document_id: {existing_doc.id}" - ) -``` +--- -### 핵심 변경사항 +## 구현 완료 -1. **select(TeamDocument.id) → select(TeamDocument)**: 전체 레코드 조회 -2. **HTTPException 제거**: 에러 대신 기존 데이터 반환 -3. **FileUploadResponse 반환**: 기존 document_id와 메타데이터 제공 -4. **INFO 로그 추가**: 중복 감지 로그 기록 +**배포**: 2025-10-16 +- 커밋 해시: cea055c +- 상태: skill-rag-file 컨테이너 재시작 완료 (healthy) --- ## 효과 -### 1. 멱등성 보장 +### 멱등성 보장 -**Before**: -``` -1st upload: 성공 → document_id: abc-123 -2nd upload: 실패 → 400 에러 -``` +**Before**: 1차 성공, 2차 400 에러 +**After**: 1차/2차/3차 모두 동일 document_id 반환 -**After**: -``` -1st upload: 성공 → document_id: abc-123 -2nd upload: 성공 → document_id: abc-123 (동일) -3rd upload: 성공 → document_id: abc-123 (동일) -``` +### Coldmail 워크플로우 안정성 -### 2. Coldmail 워크플로우 안정성 +PDF 업로드 → document_id 항상 획득 → RAG 검색 정상 → IR 분석 정확 → Slack 전송 성공 -``` -PDF 업로드 (멱등성 보장) - ↓ -document_id 항상 획득 ✅ - ↓ -RAG 검색 정상 작동 ✅ - ↓ -IR 분석 정확한 데이터 ✅ - ↓ -Slack Lists API 성공 ✅ -``` +### 재시도 안전성 -### 3. 재시도 안전성 - -네트워크 오류, 타임아웃 등으로 재시도 시에도 안전하게 작동: -- 1차 시도: 파일 저장, 벡터 생성 (느림) +- 1차 시도: 파일 저장 + 벡터 생성 (느림) - 2차 시도: 기존 document_id 즉시 반환 (빠름) --- -## 배포 - -### 커밋 정보 - -```bash -cd /home/admin/ivada_project/skill-rag-file - -git add app/api/upload.py -git commit -m "Fix duplicate file handling in upload API - -Change duplicate file behavior from HTTPException to idempotent response. -When same file (hash) uploaded by team, return existing document_id instead -of raising 400 error. This ensures coldmail workflow continues when PDFs -are re-uploaded. - -Fixes: Coldmail IR analysis failure due to PDF upload rejection" - -git push origin main -``` - -**커밋 해시**: cea055c - -### 배포 확인 - -```bash -docker compose down && docker compose up -d --build - -# 상태 확인 -docker ps --filter name=skill-rag-file -# NAMES STATUS -# skill-rag-file Up 2 minutes (healthy) - -# 로그 확인 -docker logs skill-rag-file --tail 20 -# INFO: Application startup complete. -# INFO: Uvicorn running on http://0.0.0.0:8508 -``` - ---- - ## 검증 계획 -### 즉시 검증 (수동) +### 내일 실전 검증 (2025-10-17 09:05) -1. **동일 파일 2회 업로드 테스트**: -```bash -# 1차 업로드: 성공, document_id 획득 -# 2차 업로드: 성공, 동일 document_id 획득 -``` - -2. **로그 확인**: -```bash -docker logs skill-rag-file | grep "File already exists" -# 예상: INFO - File already exists (hash: ...), returning existing document_id: ... -``` - -### 실전 검증 (내일 09:05) - -**Coldmail 브리핑 실행 시**: +**Coldmail 브리핑 실행 시 확인**: 1. PDF 업로드 성공 여부 -2. IR 분석 "N/A" 아닌 실제 데이터 반환 여부 -3. Slack Lists 전송 성공 여부 +2. IR 분석 실제 데이터 반환 확인 +3. Slack Lists 전송 성공 확인 -**로그 체크 포인트**: -```bash -# rb8001 로그 (09:05 이후) -docker logs rb8001 --since "2025-10-17T09:00:00" | grep -iE "upload|document_id" - -# skill-rag-file 로그 -docker logs skill-rag-file --since "2025-10-17T09:00:00" | grep "File already exists" -``` - ---- - -## 관련 이슈 해결 상태 - -### 해결됨 ✅ - -1. **중복 파일 처리 개선**: HTTPException → 기존 document_id 반환 -2. **멱등성 보장**: 동일 요청 여러 번 실행 가능 -3. **Coldmail 워크플로우 안정성**: PDF 업로드 실패로 인한 전체 실패 방지 - -### 향후 개선 사항 - -1. **Slack Lists 동적 컬럼 매핑**: - - 현재: 하드코딩된 컬럼 ID (Col09HQTDUM0T 등) - - 개선: Lists 컬럼 조회 API + 컬럼명 기반 동적 매핑 - -2. **LangGraph 체크포인트 + 에러 복구**: - - 현재: Stateless 실행 - - 개선: PostgresSaver 체크포인트 + 실패 지점부터 재시도 - - LLM 기반 에러 페이로드 수정 및 재전송 +**로그 체크**: +- rb8001: docker logs rb8001 --since "2025-10-17T09:00:00" | grep -iE "upload|document_id" +- skill-rag-file: docker logs skill-rag-file --since "2025-10-17T09:00:00" | grep "File already exists" --- ## 교훈 -### 1. 멱등성은 필수 (Idempotency is Critical) +### 멱등성은 필수 **원칙**: 동일 요청을 여러 번 실행해도 결과가 같아야 함 **적용**: - POST 요청이라도 리소스 생성/조회에는 멱등성 필요 -- 중복 체크 시 "에러"가 아닌 "기존 리소스 반환"이 정답 +- 중복 체크 시 에러가 아닌 기존 리소스 반환 - 네트워크 불안정, 재시도 상황에서 안전성 보장 -### 2. Cascading Failure 방지 +### Cascading Failure 방지 -**문제**: 한 단계 실패 → 전체 워크플로우 실패 +**원인**: 한 단계 실패가 전체 워크플로우 실패로 연쇄 **해결**: - 각 단계의 실패 격리 - 재시도 가능한 설계 - Graceful degradation (부분 성공 허용) -### 3. 에러 메시지의 의미 +### 에러 메시지의 의미 -**"File already exists"는 에러가 아니다**: -- 상태 확인 메시지로 취급 +"File already exists"는 에러가 아니라 상태 확인 메시지: - 이미 존재하는 리소스 정보 반환 - 클라이언트는 정상 처리 가능 - -### 4. 프레임워크 활용의 실효성 - -**LangGraph 도입 vs 실제 활용**: -- 체크포인트 없는 LangGraph = 코드 정리 효과만 -- 핵심 기능(체크포인트, 재시도)까지 구현해야 프레임워크 가치 발휘 -- 점진적 개선: 멱등성 → 체크포인트 → LLM 복구 - ---- - -## 다음 단계 - -### 즉시 수행 - -- [x] 코드 수정 및 배포 -- [x] Docker 재시작 확인 -- [x] 헬스체크 정상 확인 - -### 내일 확인 (2025-10-17 09:05) - -- [ ] Coldmail 브리핑 실행 성공 여부 -- [ ] PDF 업로드 로그에서 "File already exists" 메시지 확인 -- [ ] IR 분석 결과에 실제 데이터 포함 확인 -- [ ] Slack Lists API 전송 성공 확인 - -### 향후 개선 - -- [ ] Slack Lists 동적 컬럼 매핑 구현 -- [ ] LangGraph 체크포인트 활성화 -- [ ] LLM 기반 에러 복구 로직 추가 - ---- - -## 결론 - -✅ **Coldmail IR 분석 실패 해결 완료** - -**2025-10-16, skill-rag-file 중복 파일 처리 개선 배포** - -### 핵심 성과 - -1. **멱등성 보장**: 동일 파일 재업로드 시 기존 document_id 반환 -2. **워크플로우 안정성**: PDF 업로드 실패로 인한 전체 실패 방지 -3. **재시도 안전성**: 네트워크 오류, 타임아웃 상황에서도 안전 -4. **즉시 배포**: skill-rag-file 컨테이너 재시작 완료 - -### 검증 대기 - -내일 09:05 Coldmail 브리핑 실행 시 실전 검증 예정. diff --git a/troubleshooting/251016_troubleshooting_summary.md b/troubleshooting/251016_troubleshooting_summary.md index 9abb0e6..320e7e8 100644 --- a/troubleshooting/251016_troubleshooting_summary.md +++ b/troubleshooting/251016_troubleshooting_summary.md @@ -6,178 +6,103 @@ --- -## 완료된 이슈 +## 완료된 이슈 (51124 서버) -### 1. Coldmail IR 분석 실패 - 중복 파일 처리 개선 ✅ +### 1. Coldmail IR 분석 실패 - 중복 파일 처리 -**문제**: 동일 PDF 재업로드 시 `400 - File already exists` 에러로 전체 IR 분석 실패 +**문제**: 동일 PDF 재업로드 시 400 에러로 전체 IR 분석 실패 -**해결**: -- 위치: `skill-rag-file/app/api/upload.py:60-79` -- HTTPException 제거 → 기존 document_id 반환 (멱등성 보장) +**해결**: skill-rag-file/app/api/upload.py:60-79 +- HTTPException 제거, 기존 document_id 반환 (멱등성 보장) - 커밋: cea055c -- 상태: 배포 완료, skill-rag-file 컨테이너 정상 작동 -**효과**: -- 동일 파일 여러 번 업로드 가능 -- Coldmail 워크플로우 안정성 확보 -- 네트워크 재시도 시 안전 +**효과**: Coldmail 워크플로우 안정화, 네트워크 재시도 안전 -**문서**: `251016_coldmail_duplicate_file_fix.md` +**상세**: 251016_coldmail_duplicate_file_fix.md --- -### 2. NaverWorks Briefing 'system' UUID 오류 ✅ +### 2. NaverWorks Briefing system UUID 오류 -**문제**: 시스템 메시지의 user_id="system"이 UUID 타입 불일치로 emotion_readings 저장 실패 +**문제**: user_id="system" 문자열이 UUID 타입 불일치로 emotion_readings 저장 실패 -**해결**: -- 위치: `rb8001/app/state/database.py:145-155` -- "system" user_id 발견 시 저장 skip (return True) +**해결**: rb8001/app/state/database.py:145-155 +- "system" user_id 발견 시 저장 skip - 커밋: 2f767b3 -- 상태: 배포 완료, rb8001 컨테이너 정상 작동 -**효과**: -- NaverWorks Briefing 정상 작동 (감정 저장 제외) -- ERROR 로그 제거 -- 기능 영향 없음 +**효과**: NaverWorks Briefing 정상 작동, ERROR 로그 제거 -**향후 개선**: 전용 시스템 UUID 생성 또는 emotion_readings.user_id nullable 변경 (51123 서버 작업 필요) +**향후**: 전용 시스템 UUID 생성 또는 emotion_readings.user_id nullable 변경 (51123 서버) --- -### 3. gRPC + uvloop BlockingIOError 로그 노이즈 억제 ✅ +### 3. gRPC + uvloop BlockingIOError 로그 노이즈 -**문제**: gRPC (Vertex AI 호출)와 uvloop 이벤트 루프 경합으로 BlockingIOError 로그 노이즈 발생 +**문제**: gRPC (Vertex AI)와 uvloop 이벤트 루프 경합으로 로그 노이즈 발생 -**해결**: -- 위치: `rb8001/app/core/logger.py:41-44` -- gRPC 로거 레벨 → CRITICAL -- asyncio 로거 레벨 → WARNING +**해결**: rb8001/app/core/logger.py:41-44 +- gRPC 로거 레벨 CRITICAL +- asyncio 로거 레벨 WARNING - 커밋: adae74c -- 상태: 배포 완료, rb8001 컨테이너 정상 작동 -**효과**: -- BlockingIOError 로그 숨김 -- 실제 오류 추적 용이 -- 기능 영향 없음 (로그만 억제) +**효과**: BlockingIOError 로그 숨김, 실제 오류 추적 용이 --- -## 미해결 이슈 (51123 서버 작업 필요) +## 미해결 이슈 (51123 서버) -### 4. Slack 봇 설치 workspace_id 컬럼 오류 ⏸️ +### 4. Slack 봇 설치 workspace_id 컬럼 오류 -**문제**: auth-server의 workspace_member 테이블에 workspace_id 컬럼 없음 +**상태**: 해결 완료 (2025-10-16, 사용자 작업) -**위치**: `auth-server/app/providers/slack.py:408-418` +**문제**: workspace_member 테이블에 workspace_id 컬럼 없음 -**해결 방법**: -- `workspace_member.workspace_id` → `user.team_id` 변경 -- 또는 workspace_member 테이블에 workspace_id 컬럼 추가 - -**상태**: 51123 서버 작업 필요 (auth-server) +**해결**: auth-server/app/providers/slack.py:414-419 +- workspace_member.workspace_id → user.team_id 사용 --- ## 배포 상태 -### skill-rag-file -- 커밋: cea055c -- 상태: Up (healthy) -- 변경: 중복 파일 멱등성 보장 - -### rb8001 -- 커밋: adae74c -- 상태: Up (healthy) -- 변경: system UUID 처리 + gRPC 로그 억제 +**skill-rag-file**: cea055c (healthy) - 중복 파일 멱등성 보장 +**rb8001**: adae74c (healthy) - system UUID 처리 + gRPC 로그 억제 --- ## 검증 계획 -### 즉시 확인 ✅ -- [x] skill-rag-file 컨테이너 정상 작동 -- [x] rb8001 컨테이너 정상 작동 -- [x] 헬스체크 통과 +### 내일 실전 검증 (2025-10-17) -### 내일 검증 (2025-10-17) -- [ ] **09:00 NaverWorks Briefing**: system UUID 오류 로그 사라짐 확인 -- [ ] **09:00 NaverWorks Briefing**: gRPC BlockingIOError 로그 사라짐 확인 -- [ ] **09:05 Coldmail Briefing**: PDF 업로드 성공 확인 -- [ ] **09:05 Coldmail Briefing**: IR 분석 실제 데이터 반환 확인 -- [ ] **09:05 Coldmail Briefing**: Slack Lists 전송 성공 확인 +**09:00 NaverWorks Briefing**: +- system UUID 오류 로그 사라짐 확인 +- gRPC BlockingIOError 로그 사라짐 확인 -### 로그 체크 포인트 -```bash -# NaverWorks Briefing (09:00) -docker logs rb8001 --since "2025-10-17T09:00:00" | grep -iE "system|grpc|blocking" +**09:05 Coldmail Briefing**: +- PDF 업로드 성공 확인 +- IR 분석 실제 데이터 반환 확인 +- Slack Lists 전송 성공 확인 -# Coldmail Briefing (09:05) -docker logs rb8001 --since "2025-10-17T09:05:00" | grep -iE "upload|document_id" -docker logs skill-rag-file --since "2025-10-17T09:05:00" | grep "File already exists" -``` +**로그 체크**: +- rb8001: docker logs rb8001 --since "2025-10-17T09:00:00" | grep -iE "system|grpc|blocking" +- rb8001: docker logs rb8001 --since "2025-10-17T09:05:00" | grep -iE "upload|document_id" +- skill-rag-file: docker logs skill-rag-file --since "2025-10-17T09:05:00" | grep "File already exists" --- ## 교훈 -### 1. 멱등성 설계 (Idempotency) +### 멱등성 설계 -**원칙**: 동일 요청을 여러 번 실행해도 결과가 같아야 함 +동일 요청 여러 번 실행 시 결과 동일해야 함. 중복 체크 시 에러가 아닌 기존 리소스 반환. -**적용**: 중복 체크 시 "에러"가 아닌 "기존 리소스 반환" +### 시스템 사용자 처리 정책 -### 2. 시스템 사용자 처리 정책 +시스템 작업의 user_id 처리 미정의. 단기는 skip, 장기는 전용 UUID 생성. -**문제**: 사용자가 아닌 시스템 작업의 user_id 처리 미정의 +### 로그 레벨 관리 -**해결**: -- 단기: 시스템 user_id 감지 후 skip -- 장기: 전용 시스템 UUID 생성 +외부 라이브러리 로그는 필요 시 레벨 조정으로 노이즈 제거. -### 3. 로그 레벨 관리 +### Cascading Failure 방지 -**원칙**: 외부 라이브러리 로그는 필요 시 레벨 조정 - -**적용**: gRPC, asyncio 로거 레벨 상향 조정 - -### 4. Cascading Failure 방지 - -**원칙**: 한 단계 실패가 전체 워크플로우 실패로 이어지지 않도록 - -**적용**: -- PDF 업로드 실패 → IR 분석 실패 → Slack 전송 실패 (연쇄) -- 멱등성으로 PDF 업로드 안정화 - ---- - -## 다음 단계 - -### 51124 서버 (완료) -- [x] Coldmail 중복 파일 처리 개선 -- [x] NaverWorks system UUID 오류 해결 -- [x] gRPC 로그 노이즈 억제 - -### 51123 서버 (향후) -- [ ] Slack 봇 설치 workspace_id 오류 수정 (auth-server) -- [ ] emotion_readings.user_id nullable 또는 시스템 UUID 생성 - ---- - -## 결론 - -✅ **51124 서버 트러블슈팅 완료 (3/4 이슈 해결)** - -**2025-10-16, 트러블슈팅 이슈 3건 해결 배포** - -### 핵심 성과 - -1. **Coldmail IR 분석 안정화**: 중복 파일 멱등성 보장 -2. **NaverWorks Briefing 정상화**: system UUID 오류 해결 -3. **로그 품질 개선**: gRPC 노이즈 억제로 실제 오류 추적 용이 -4. **즉시 배포**: skill-rag-file + rb8001 재시작 완료 - -### 검증 대기 - -내일 09:00-09:10 브리핑 실행 시 실전 검증 예정. +한 단계 실패가 전체 워크플로우 실패로 연쇄되지 않도록 설계. 멱등성으로 안정화.