From 61082a70274f0f7ad4a35d78744cad6e1d23f5fe Mon Sep 17 00:00:00 2001 From: happybell80 Date: Mon, 13 Oct 2025 23:43:44 +0900 Subject: [PATCH] =?UTF-8?q?docs:=20=EC=BD=9C=EB=93=9C=EB=A9=94=EC=9D=BC=20?= =?UTF-8?q?IR=20=EB=B6=84=EC=84=9D=20=EC=98=A4=EB=A5=98=20=EB=AC=B8?= =?UTF-8?q?=EC=84=9C=20=EB=B0=8F=20=EB=AC=B8=EC=84=9C=20=EC=9E=91=EC=84=B1?= =?UTF-8?q?=20=EC=9B=90=EC=B9=99=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - troubleshooting/251013_coldmail_ir_analyzer_fix.md: 3가지 에러 분석 및 해결 방안 - 300_architecture/312_문서_작성_원칙.md: 트러블슈팅/아키텍처 문서 작성 규칙 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- 300_architecture/312_문서_작성_원칙.md | 205 ++++++++++++++++++ .../251013_coldmail_ir_analyzer_fix.md | 116 ++++++++++ 2 files changed, 321 insertions(+) create mode 100644 300_architecture/312_문서_작성_원칙.md create mode 100644 troubleshooting/251013_coldmail_ir_analyzer_fix.md diff --git a/300_architecture/312_문서_작성_원칙.md b/300_architecture/312_문서_작성_원칙.md new file mode 100644 index 0000000..efd30a6 --- /dev/null +++ b/300_architecture/312_문서_작성_원칙.md @@ -0,0 +1,205 @@ +# 문서 작성 원칙 + +**작성일**: 2025-10-13 +**참고**: CLAUDE.md, 311_FastAPI_구조_원칙.md + +--- + +## 1. 문서 종류별 규칙 + +### 트러블슈팅 문서 + +**경로**: `DOCS/troubleshooting/` +**파일명**: `yymmdd_주제.md` (예: 251013_coldmail_ir_analyzer_fix.md) +**규칙**: +- 주제별 파일 분리 (날짜 중복 허용) +- 시간순 작성 +- 교훈 섹션 필수 +- 100줄 이하 유지 + +**필수 헤더**: +```markdown +# 제목 + +**날짜**: 2025-10-13 +**작성자**: happybell80 +**관련 파일**: `경로/파일명.py` + +--- +``` + +### 아키텍처 문서 + +**경로**: `DOCS/300_architecture/` +**파일명**: `3NN_주제.md` (예: 311_FastAPI_구조_원칙.md) +**규칙**: +- 작성일/수정일 명시 +- 섹션 번호 사용 +- 표, 다이어그램 권장 +- 코드 예시 (올바름/금지) 포함 + +### 계획 문서 + +**경로**: `DOCS/plans/` +**규칙**: +- 미래 계획, 아이디어 +- 구현 완료 시 troubleshooting으로 이동 + +--- + +## 2. 작성 규칙 + +### 절대 금지 사항 + +| 금지 | 이유 | +|------|------| +| 의사코드, 추측, 예측 | 실제 동작하는 코드만 작성 | +| "아마", "것 같다", "추정" | 확인된 사실만 기록 | +| 불필요한 코드 블록 | 파일명:줄번호만 명시 | +| 이모지 사용 | 명시적 요청 시만 허용 | + +### 파일 참조 형식 + +**올바름**: +```markdown +- naverworks_briefing.py:58-74: 폴백 제거 +- ir_analyzer.py:28: /api/query → /api/search +``` + +**금지**: +```markdown +- naverworks_briefing.py에서 폴백 제거 +- ir_analyzer.py 파일 수정 +``` + +### 코드 블록 최소화 + +**올바름** (파일명:줄번호 + 간단 설명): +```markdown +**수정 필요:** +- ir_analyzer.py:28: url = f"{SKILL_RAG_FILE_URL}/api/search" +- ir_analyzer.py:29-32: payload에 team_id 추가 +``` + +**금지** (전체 코드 복사): +```markdown +**수정 필요:** +```python +# ir_analyzer.py 전체 함수 코드 50줄 복사... +``` +``` + +--- + +## 3. 문서 구조 + +### 트러블슈팅 문서 구조 + +```markdown +# 제목 + +**날짜**, **작성자**, **관련 파일** + +--- + +## 문제 상황 +- 현상, 에러 메시지 + +## 해결 방안 +- 파일명:줄번호 명시 +- 수정 내용 간결히 + +## 구현 완료 (선택) +- 커밋 해시, 날짜 + +## 교훈 (필수) +- 왜 발생했는가 +- 다음에 어떻게 방지할 것인가 +``` + +### 아키텍처 문서 구조 + +```markdown +# 제목 + +**작성일**: 2025-10-13 +**수정일**: 2025-10-13 (수정 이유) + +## 1. 원칙 +## 2. 규칙 +## 3. 예시 +## 4. 체크리스트 +## 5. 참고 +``` + +--- + +## 4. 파일 크기 제한 + +### 규칙 +- 모든 문서: 100줄 이하 +- 초과 시: 주제별 분리 또는 참고/실행용 분리 + +### 예외 +- 아키텍처 문서: 200줄까지 허용 (섹션 많은 경우) +- 단, 분리 가능하면 분리 우선 + +--- + +## 5. 교훈 작성 규칙 + +### 필수 항목 +1. **원인**: 왜 문제가 발생했는가 +2. **교훈**: 다음에 어떻게 방지할 것인가 +3. **원칙**: 위반한 원칙이 있는가 + +### 올바른 예시 +```markdown +## 교훈 + +### API 엔드포인트 검증 부족 +- 구현 시 skill-rag-file API 스펙 미확인 +- 추측으로 /api/query 사용, 실제는 /api/search +- 교훈: 스킬 통합 전 API 문서 또는 코드 직접 확인 필수 +``` + +### 금지 예시 +```markdown +## 교훈 + +에러가 발생했습니다. 다음에 조심하겠습니다. +``` + +--- + +## 6. 비난조 문장 금지 + +### 금지 표현 +- "잘못 작성됨" +- "버그가 많음" +- "엉망진창" + +### 권장 표현 +- "수정 필요" +- "개선 가능" +- "리팩토링 대상" + +--- + +## 7. 체크리스트 + +문서 작성 전: +- [ ] 파일명 형식 준수 (yymmdd_주제.md) +- [ ] 파일명:줄번호로 위치 명시 +- [ ] 의사코드/추측 제거 +- [ ] 100줄 이하 확인 +- [ ] 교훈 섹션 작성 (트러블슈팅) +- [ ] 이모지 제거 (명시 요청 없으면) + +--- + +## 8. 참고 문서 + +- CLAUDE.md: 전체 개발 가이드 +- 311_FastAPI_구조_원칙.md: 코드 구조 원칙 +- troubleshooting/ 폴더: 트러블슈팅 예시 diff --git a/troubleshooting/251013_coldmail_ir_analyzer_fix.md b/troubleshooting/251013_coldmail_ir_analyzer_fix.md new file mode 100644 index 0000000..bcb544b --- /dev/null +++ b/troubleshooting/251013_coldmail_ir_analyzer_fix.md @@ -0,0 +1,116 @@ +# 콜드메일 IR 분석 시스템 오류 수정 + +**날짜**: 2025-10-13 +**작성자**: happybell80 +**관련 파일**: `rb8001/app/services/ir_analyzer.py` + +--- + +## 문제 상황 + +### 테스트 실행 +- 경로: rb8001/tests/test_coldmail_briefing.py --test scheduler +- 결과: 3가지 에러 발생, Slack 전송 도달 실패 + +### 성공한 부분 +1. 콜드메일 필터링: 30개 중 1건 탐지 (굿베이션 투자제안서, 확률 0.7755) +2. 첨부파일 다운로드: skill-email에서 PDF 다운로드 성공 +3. skill-rag-file 업로드: document_id c9c9a7a8-18d3-475a-b14e-746e14c9e55c, 14 chunks 생성 + +--- + +## 에러 분석 + +### 에러 1: RAG 쿼리 404 (6회 발생) + +**에러 메시지:** +``` +ERROR:app.services.ir_analyzer:RAG query failed: 404 +``` + +**원인:** +- ir_analyzer.py:28 - `/api/query` 엔드포인트 호출 +- skill-rag-file은 POST `/api/search` 제공 (search.py:19) +- 엔드포인트 불일치 + +**수정 필요:** +- ir_analyzer.py:28: `/api/query` → `/api/search` +- ir_analyzer.py:29-32: payload 구조 변경 (document_id 제거, team_id 추가) + +### 에러 2: LLM 연결 실패 + +**에러 메시지:** +``` +ERROR:app.services.ir_analyzer:Error calling LLM: Cannot connect to host localhost:8080 +``` + +**원인:** +- ir_analyzer.py:15: LLM_API_URL = http://localhost:8080/api/llm +- rb8001 컨테이너 내부에 localhost:8080 LLM 서비스 없음 +- rb8001은 자체 LLM 서비스 사용 (app/llm/llm_service.py) + +**수정 필요:** +- ir_analyzer.py:48-74: call_llm() 함수를 rb8001 LLM 서비스 사용으로 변경 +- app/llm/llm_service.py의 LLMService, LLMRequest 사용 + +### 에러 3: DB 제약조건 없음 + +**에러 메시지:** +``` +asyncpg.exceptions.InvalidColumnReferenceError: there is no unique or exclusion constraint +``` + +**원인:** +- startup_valuation.py:249: ON CONFLICT 절 사용 +- startup_valuation 테이블에 UNIQUE 제약조건 미설정 + +**수정 필요:** +- 51123 서버 DB: startup_valuation 테이블에 UNIQUE 제약조건 추가 + +--- + +## 해결 방안 + +### 우선순위 1: ir_analyzer.py 수정 + +**query_rag() 함수 (18-45줄):** +- 28줄: url = f"{SKILL_RAG_FILE_URL}/api/search" +- 29-35줄: payload 변경 + ``` + 기존: {"document_id": document_id, "query": query} + 변경: {"query": query, "team_id": team_id, "limit": 10, "threshold": 0.5} + ``` +- team_id 파라미터 추가 필요 + +**call_llm() 함수 (48-74줄):** +- rb8001 LLM 서비스 사용으로 전체 변경 +- from app.llm.llm_service import LLMService, LLMRequest +- LLMRequest(message=prompt, user_id="system", robeing_id="rb8001", model="gemini-2.5-flash-lite") + +### 우선순위 2: DB 제약조건 추가 + +**51123 서버 DB 작업:** +- startup_valuation 테이블에 UNIQUE 제약조건 추가 +- 중복 방지 컬럼 조합 확인 필요 + +### 우선순위 3: 테스트 재실행 + +**배포 프로세스:** +1. 로컬 수정 완료 +2. git push +3. Gitea Actions 배포 대기 +4. docker exec -it rb8001 python tests/test_coldmail_briefing.py --test scheduler + +--- + +## 교훈 + +### API 엔드포인트 검증 부족 +- 구현 시 skill-rag-file API 스펙 미확인 +- 추측으로 /api/query 사용, 실제는 /api/search +- 교훈: 스킬 통합 전 API 문서 또는 코드 직접 확인 필수 + +### LLM 서비스 중복 구현 +- ir_analyzer가 독립 LLM 서비스 가정 +- rb8001은 이미 LLM 서비스 내장 +- 교훈: 기존 서비스 재사용 우선, 새 의존성 추가 지양