- 코드 블록 제거, 파일명:줄번호만 사용 - 116줄 → 105줄로 축약 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
106 lines
3.1 KiB
Markdown
106 lines
3.1 KiB
Markdown
# 콜드메일 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줄):**
|
|
- 18줄: 파라미터 document_id → team_id로 변경
|
|
- 28줄: /api/query → /api/search
|
|
- 29-35줄: payload를 query, team_id, limit, threshold로 변경
|
|
|
|
**call_llm() 함수 (48-74줄):**
|
|
- rb8001 LLM 서비스(app/llm/llm_service.py) 사용으로 전체 변경
|
|
- LLMService, LLMRequest import 추가
|
|
|
|
### 우선순위 2: DB 제약조건 추가
|
|
|
|
- 51123 서버: startup_valuation 테이블 UNIQUE 제약조건 추가
|
|
|
|
### 우선순위 3: 테스트 재실행
|
|
|
|
- git push → Gitea Actions 배포 → 테스트 재실행
|
|
|
|
---
|
|
|
|
## 교훈
|
|
|
|
### API 엔드포인트 검증 부족
|
|
- 구현 시 skill-rag-file API 스펙 미확인
|
|
- 추측으로 /api/query 사용, 실제는 /api/search
|
|
- 교훈: 스킬 통합 전 API 문서 또는 코드 직접 확인 필수
|
|
|
|
### LLM 서비스 중복 구현
|
|
- ir_analyzer가 독립 LLM 서비스 가정
|
|
- rb8001은 이미 LLM 서비스 내장
|
|
- 교훈: 기존 서비스 재사용 우선, 새 의존성 추가 지양
|