1. 프로젝트 개요
기본 정보
- 프로젝트 명: ZIPFIT (집핏) - 나에게 딱 맞는 공공주택 찾기 챗봇
- 수행 역할: 시스템 설계 총괄 및 백엔드 개발
- 핵심 기여: REST API 서버 구축, AI 대화 흐름 설계(LangGraph), 하이브리드 검색 엔진 설계(RRF), PDF 표 데이터 전처리 파이프라인 구축
2. 핵심 아키텍처 및 워크플로우
2.1. AI 대화 파이프라인 구조

사용자 메시지를 1회 LLM 호출로 의도를 파악하고, 5가지 처리 흐름 중 하나로 자동 분기하는 상태 그래프 기반 구조.
- 의도 분류: GPT-4o-mini 1회 호출로 사용자 의도를 파악하고 적절한 흐름으로 분기. 상태 이상(선택 가능한 공고 없이 선택 시도 등) 시 자동 보정
- 공고 검색: DB 조건 필터(상태·지역·유형)와 AI 벡터 검색 결합. 신규·추가·이전 검색 복원 3가지 모드 지원
- 공고 선택: 목록 번호 또는 공고명 일부 입력으로 대상 공고 특정
- 상세 조회: 선택된 공고 문서에서 AI 검색으로 관련 정보 추출. 면적·임대료 질문 시 표 데이터를 추가 보강하여 답변 품질 향상
- 공고 비교: 복수 공고 각각에 대해 자격·임대료·면적·신청기간 정보를 AI 검색한 뒤 병합 응답
- 일반 대화: 최신 정책 등 공고 외 질문 시 실시간 웹 검색 연동
2.2. 멀티턴 대화 상태 관리
대화 전체의 문맥을 서버에서 연속 유지하는 8가지 상태 항목을 설계. 이전 검색 결과나 선택 공고가 다음 대화에서도 유지되어 자연스러운 대화 흐름 구현.
| 상태 항목 | 역할 |
|---|---|
| 현재 의도 / 추출 데이터 | 사용자가 무엇을 원하는지 분류 결과 |
| 검색된 공고 목록 | "1번 선택"과 같은 후속 발화의 참조 기준 |
| 현재 선택된 공고 | 상세조회·비교 시 AI 검색의 대상 기준 |
| 비교용 복수 공고 | 다중 공고 비교 처리용 |
| 검색 기록 (최대 5건) | 이전 검색 결과 복원용 |
| AI 검색 결과 단위 문서 | LLM 답변 생성에 사용될 문서 조각 |
| 사용자 프로필 | 희망지역·연령·혼인·자녀·소득 정보 |
| 대화 이력 (최근 10턴) | 맥락 연속성 유지용 |
2.3. 하이브리드 검색 엔진
PostgreSQL 전문 검색(Full-Text Search)과 AI 임베딩 기반 벡터 유사도 검색을 RRF(Reciprocal Rank Fusion) 알고리즘으로 결합.
- 키워드 검색(FTS): 텍스트 일치 기반 검색. 한국어 조사(은/는/이/가/을/를 등) 전처리 후 검색
- 의미 검색(벡터): AI 임베딩 모델로 의미적으로 유사한 문서 검색 (상위 100개 후보)
- RRF 통합: 키워드 결과(가중치 0.4)와 의미 결과(가중치 0.6)를 순위 기반으로 통합
- 쿼리 확장: 사용자 질문의 동의어·유의어 자동 확장 (신혼부부 → 혼인/예비신혼부부, 면적 → 전용면적/계약면적/㎡ 등)
2.4. DB 설계 (4개 테이블)
- 공고 메타데이터: 공고명·URL·지역·상태·마감일 등 저장. 서비스 노출 여부 플래그로 공개 공고 관리
- 공고 첨부 파일: PDF 등 원본 파일 경로 관리
- 문서 단위 조각(청크): 공고 문서를 텍스트/표 단위로 분할 저장. 각 조각에 AI 임베딩 벡터와 키워드 검색 인덱스 동시 보유
- 대화 세션·메시지: 세션 단위 대화 내용 저장, 메시지 순서 관리
3. 시스템 인프라 및 설계

3.1. 기술 스택 (Tech Stack)
Frontend:
ReactViteAxiosBackend:DjangoDjango REST FrameworkNginxGunicornAI & Model:LangGraphgpt-4o-minitext-embedding-3-smallTavily (웹검색)Data:PostgreSQLpgvectortsvector (FTS)Infra:DockerDocker Compose
3.2. 데이터 수집 및 적재 파이프라인
공고 수집부터 AI 검색 DB 저장까지 4단계 자동화 파이프라인 구현.
3.2.1. 공고 목록 수집
- LH 공식 사이트의 내부 API를 POST 방식으로 직접 호출하여 공고 데이터를 수집. 페이지를 반복 순회하며 2024년 11월 이후 게시된 공고를 모두 수집
- 공고 유형(임대 13종 / 분양 2종 / 기타)을 자동 분류하여 메타데이터와 함께 임시 테이블에 우선 적재 후 서비스 DB에 반영
3.2.2. 공고 PDF 다운로드
- 각 공고의 첨부 파일 목록 API를 추가 호출하여 "공고문(PDF)" 유형의 파일만 선별 다운로드
3.2.3. PDF 파싱 (하이브리드 방식)
- AI 파서(LlamaParse): PDF 전체를 마크다운으로 변환하여 텍스트·표·제목 구조 추출
- 표 전용 파서(Camelot): LlamaParse가 추출한 표를 Camelot 결과(정확도 70% 이상)로 교체. 복잡한 표 구조를 더 정확하게 추출하기 위한 이중 처리
3.2.4. 문서 청킹 및 AI 임베딩 저장
- 텍스트와 표를 별도 전략으로 분할
- 텍스트: 단락 → 문장 순서로 분할, 직전 단락을 다음 청크와 일부 중복(overlap) 포함하여 맥락 연속성 유지
- 표: 헤더 행을 모든 분할 조각에 반복 보존. 표 앞 제목·단락에서 단지명·항목명을 자동 추출하여 각 조각에 맥락 헤더 부착
- AI 임베딩 벡터 생성 후 키워드 검색 인덱스와 함께 검색 DB에 저장
3.3. PDF 표 데이터 전처리
- 깨진 행 복원: PDF 추출 시 셀 내 줄바꿈이 행 분리로 잘못 인식되는 문제를 병합 로직으로 복원 (예:
공급\n형별→공급형별) - 텍스트 정규화: HTML 태그 제거, 연속 공백 정리, 한글 문자 간 불필요한 줄바꿈 제거
- 표 제목 자동 추출: 표 앞의 제목·설명에서 단지명·항목명을 자동 추출하여 각 문서 조각에 맥락 헤더로 부착
4. 개발 과정 및 문제 해결 (Development & Problem Solving)
4.1. 기술적 의사결정 (Architecture Decision)
4.1.1. 선형 파이프라인 → LangGraph 상태 그래프 전환
- 문제: 기존 구조에서 사용자 메시지 1건 처리에 LLM을 4~5회 순차 호출하여 응답 지연 발생. 매 대화 턴마다 이전 검색 결과와 선택 공고 정보가 초기화되어 문맥 연속 대화 불가
- 결과: 상태 그래프 도입으로 대화 문맥을 서버에서 영속 관리. 의도 분류를 1회 LLM 호출로 처리하고 해당 흐름으로 직접 분기하여 API 호출 최소화
4.1.2. 단순 벡터 검색 → RRF 하이브리드 검색 도입
- 문제: "신혼부부", "행복주택", "접수중" 등 도메인 특화 키워드가 빈번한 공고문 특성상, 의미 기반 벡터 검색만으로는 키워드 정확 매칭 품질 부족
- 결과: 키워드 검색(가중치 0.4)과 의미 검색(가중치 0.6)을 RRF로 통합하여 두 검색 방식의 장점을 동시에 확보
4.2. 트러블슈팅 (Troubleshooting)
4.2.1. 멀티턴 대화 시 이전 공고 맥락 유실
- 현상: "1번 선택" 입력 시 직전 검색 공고 목록이 사라져 에이전트가 대상 공고를 특정하지 못함. "신청자격 알려줘" 입력 시 선택된 공고 정보가 없어 AI 문서 검색 불가
- 해결: 검색 목록·선택 공고·검색 이력을 서버 상태로 명시적 관리. 의도 분류 시 상태 오류 자동 보정 — 선택 가능한 공고 없이 선택 의도 감지 시 자동으로 검색 흐름으로 전환
- 결과: 검색 → 선택 → 상세조회 → 비교의 전체 대화 흐름이 단절 없이 연결
4.2.2. PDF 표 구조 파괴로 인한 면적·임대료 정보 누락
- 현상: 공고문 PDF의 면적·임대료 표가 추출 과정에서 셀 내 줄바꿈이 행 분리로 잘못 인식됨. AI 검색 시 해당 정보가 조회되지 않아 "면적 정보 없음" 응답 발생
- 해결: 깨진 행을 병합 복원하는 전처리 모듈 구현. 표 단위 문서 조각 생성 시 앞 단락 제목을 자동으로 맥락 헤더로 부착하여 검색 품질 향상. 면적·임대료 질문 시 표 데이터 조각을 키워드 조건으로 추가 보강
- 결과: 면적·임대료 정보 검색 누락 방지, LLM의 표 데이터 해석 정확도 향상
4.2.3. 지역명 통칭 처리 (예: "전라도" → 복수 지역 매핑)
- 현상: "전라도 공고" 입력 시 DB의 "전라남도", "전북특별자치도"와 직접 매칭되지 않아 검색 결과 누락
- 해결: 의도 분류 단계에서 지역 통칭 처리 규칙을 AI 프롬프트에 명시. DB 지역 목록을 맥락으로 제공하여 통칭 입력 시 해당하는 모든 지역값을 자동 변환 후 OR 조건 필터 적용
- 결과: "전라도" →
[전라남도, 전북특별자치도]자동 변환 후 OR 필터로 정확한 지역 검색 지원


