콘텐츠로 이동

RAG 서비스 구현

  • Elasticsearch 메타데이터를 활용한 RAG(Retrieval-Augmented Generation) 컨텍스트 생성
  • OpenAI 키워드 확장 품질 향상
  • 도메인 특화 키워드 추천
파일설명
app/services/rag_service.pyRAG 서비스 메인 클래스
app/data/context/service_categories.json서비스 카테고리 메타데이터
app/data/context/field_mappings.jsonES 필드 매핑 정보

┌─────────────────────────────────────────────────────────────┐
│ RAG Context │
├─────────────────────────────────────────────────────────────┤
│ 1. 서비스 카테고리 정보 │
│ - 지도로 본 서울 (196건) │
│ - 통계로 본 서울 (73건) │
│ - ... │
├─────────────────────────────────────────────────────────────┤
│ 2. 감지된 데이터 카테고리 │
│ - 인구/가구: 인구, 출산, 고령화... │
│ - 경제/산업: 일자리, 소득, 물가... │
├─────────────────────────────────────────────────────────────┤
│ 3. 지역 정보 (감지 시) │
│ - 강남구, 송파구 등 25개 자치구 │
├─────────────────────────────────────────────────────────────┤
│ 4. 시간 컨텍스트 │
│ - 최근/현재, 역사적 변화, 비교/증감 │
├─────────────────────────────────────────────────────────────┤
│ 5. ES 샘플 데이터 (선택적) │
│ - 관련 콘텐츠 제목, 서비스명, 연도 │
└─────────────────────────────────────────────────────────────┘
검색어 입력
┌───────────────────┐
│ 카테고리 감지 │ → 인구/경제/환경/교통...
├───────────────────┤
│ 지역 감지 │ → 강남구, 송파구...
├───────────────────┤
│ 시간 컨텍스트 감지 │ → 최근/역사/추세
└───────────────────┘
┌───────────────────┐
│ ES 샘플 조회 │ → 관련 콘텐츠 5건
└───────────────────┘
┌───────────────────┐
│ 컨텍스트 조합 │ → 전체 RAG 컨텍스트 생성
└───────────────────┘
┌───────────────────┐
│ OpenAI 호출 │ → 컨텍스트 포함 키워드 확장
└───────────────────┘
확장 키워드 반환

3.1 서비스 카테고리 (service_categories.json)

섹션 제목: “3.1 서비스 카테고리 (service_categories.json)”
{
"service_categories": {
"지도로 본 서울": {
"count": 196,
"description": "서울의 공간 데이터를 지도로 시각화한 콘텐츠",
"keywords": ["지도", "공간", "분포", "위치", "지역"]
},
...
},
"data_categories": {
"인구/가구": {
"keywords": ["인구", "가구", "세대", "출산", ...],
"related_fields": ["field_category_data:인구"]
},
...
},
"seoul_districts": ["종로구", "중구", "용산구", ...],
"time_keywords": {
"recent": ["최근", "현재", "올해", ...],
"historical": ["과거", "역사", "변천", ...],
"comparison": ["비교", "증가", "감소", ...]
}
}
{
"elasticsearch_index_datasi_new_si": {
"description": "데이터로 본 서울 인덱스",
"total_documents": 519,
"fields": {
"title": {"type": "text", "searchable": true},
"body": {"type": "text", "searchable": true},
"service_title": {"type": "keyword", "searchable": true}
}
}
}

from app.services import get_rag_service
rag = get_rag_service()
result = await rag.expand_keywords_with_rag(
query="인구",
max_keywords=5
)

출력:

{
"original_query": "인구",
"expanded_keywords": ["인구변화", "출생률", "고령화율", "인구밀도", "세대수"],
"source": "openai_rag",
"context_used": true,
"detected_categories": ["인구/가구"],
"detected_district": null,
"usage": {...}
}
result = await rag.expand_keywords_with_samples(
query="강남구 아파트",
max_keywords=5
)

출력:

{
"original_query": "강남구 아파트",
"expanded_keywords": ["강남구 부동산", "아파트 가격", "주택 시세", "재건축", "분양"],
"source": "openai_rag_extended",
"context_used": true,
"sample_count": 5,
"detected_categories": ["주거/부동산"],
"usage": {...}
}
context = rag.build_context("인구 고령화")
print(context)

출력:

## 서울연구데이터서비스 콘텐츠 유형
- 지도로 본 서울 (196건): 서울의 공간 데이터를 지도로 시각화한 콘텐츠...
- 통계로 본 서울 (73건): 서울시 각종 통계 데이터 분석...
...
## 검색어 관련 카테고리: 인구/가구
- 인구/가구 관련 키워드: 인구, 가구, 세대, 출산, 사망, 고령화...
## 키워드 확장 가이드
- 서울 통계 데이터에 특화된 키워드를 추천하세요
...

Provider컨텍스트ES 샘플특징
ollamaXX기본 키워드 확장
openaiXX빠른 응답, 일반적 품질
openai_ragOX도메인 특화 키워드
openai_rag_extendedOO최고 품질, 실제 데이터 반영

카테고리감지 키워드 예시
인구/가구인구, 출산, 고령화, 1인가구
경제/산업경제, 일자리, 소득, 물가
주거/부동산주택, 아파트, 전세, 재개발
환경/에너지환경, 미세먼지, 녹지, 에너지
교통지하철, 버스, 교통사고, 주차
문화/관광문화, 관광, 축제, 도서관
복지/보건복지, 의료, 건강, 노인
안전안전, 범죄, 화재, 재난
교육교육, 학교, 학생, 대학

서울시 25개 자치구 자동 감지:

  • 종로구, 중구, 용산구, 성동구, 광진구…
유형감지 키워드
recent최근, 현재, 올해, 2024, 최신
historical과거, 역사, 변천, 추이, 변화
comparison비교, 증가, 감소, 변동, 추세

  • 타임아웃: 10초
  • 최대 샘플: 5건
  • 실패 시 graceful degradation (샘플 없이 진행)
  • 평균 컨텍스트 크기: ~1,500자
  • 샘플 포함 시: ~2,000자
  • 토큰 증가량: ~500 tokens