# 크롤링 처리 흐름 및 DB 미적재 이슈 리포트 작성일: 2026-05-11 대상 프로젝트: C:\Users\lasta\MyProject\AI 테스트 사이트: https://the912.co.kr/ ## 1) 결론 요약 - 현재 구조는 `연결 테스트`와 `실제 크롤링/추출/저장`이 분리되어 있다. - 연결 테스트(`GET /v1/models`)는 모델 목록 확인만 하므로 DB에 아무것도 저장되지 않는다. - 사이트 크롤링 시에도 모든 페이지를 저장하지 않는다. 기본적으로 `product/brand/review` 타입만 추출/저장 대상이다. - `listing`으로 분류된 페이지는 `discovered`로 끝나며 엔티티/클레임이 저장되지 않는다. - LM Studio 응답 지연/타임아웃, 무효 JSON 응답, 중복 해시(upsert) 조건 때문에 “동작은 하는데 DB가 거의 안 쌓여 보이는” 현상이 발생한다. ## 2) 처음 연결 시 처리 주체 ### 2-1. UI - 프론트에서 Analyzer 테스트 버튼 실행 시 `/extractors/models` 호출. - 파일: `crawler_platform/app/web/static/app.js` ### 2-2. API - 백엔드는 provider별 모델 목록만 조회해서 반환. - LM Studio는 OpenAI 호환 엔드포인트의 `/v1/models`만 호출됨. - 파일: `crawler_platform/app/api/routes.py` ### 2-3. DB - 이 단계는 크롤링/추출/저장이 아니므로 DB 적재 없음. ## 3) 실제 처리(크롤링) 흐름 ### 3-1. 요청 진입 - `/crawl-site` 요청으로 `SiteCrawler` 인스턴스 생성 후 동기 처리. - 파일: `crawler_platform/app/api/routes.py` ### 3-2. 페이지 처리 파이프라인 - queue 기반으로 URL 순회 - robots 검사 - fetch(requests/playwright) - parse(clean_html) - classify_page(product/review/brand/listing) - 파일: `crawler_platform/app/core/crawler/site_crawler.py` ### 3-3. 추출기 선택 주체 - provider가 `lm_studio/openai/ollama`면 `LLMJsonExtractor` 사용 - 그 외 domain 기반 rule-based 사용 - 파일: `crawler_platform/app/core/extractor/factory.py` ### 3-4. 저장 주체 - `KnowledgeRepository.save_extraction_bundle()`에서 entities/claims/evidence/extraction_logs 저장 - page/entity/claim은 upsert/dedupe 규칙이 있어 신규 건수가 작을 수 있음 - 파일: `crawler_platform/app/core/database/repository.py` ## 4) “DB가 안 쌓이는 것처럼 보이는” 주요 원인 1. 분석 대상 제한 - 기본 분석 대상이 `product/brand/review`로 고정되어 있음. - listing/네비게이션/정책 페이지는 저장 대상에서 제외됨. 2. 타임아웃/클라이언트 disconnect - 로그에 `read timeout=300` 및 `Client disconnected` 패턴 확인. - 모델 생성이 느리면 API 클라이언트가 먼저 끊기고, 해당 건은 실패/부분 처리될 수 있음. 3. AI 응답 품질 문제 - 일부 응답은 JSON 파손/무효 엔티티/무효 클레임으로 실질 저장 0건 발생. 4. 중복 제거 정책 - 동일 canonical entity, 동일 claim_hash는 업데이트로 처리되어 "신규 카운트"가 늘지 않음. ## 5) 적용된 안정화(현재 코드 기준) `crawler_platform/app/core/extractor/ai_provider.py`에 다음이 반영됨: - LM Studio 기본 타임아웃을 300s -> 120s로 조정 - 2단계 추출 시도(primary -> compact_retry) - AI 결과 무효/오류 시 rule-based fallback 수행 - fallback 결과도 provider=`lm_studio`로 extraction_log에 남겨 추적 가능 - 프롬프트 노이즈 감소 및 입력 길이/출력 토큰 제한 ## 6) 2건 timeout + 1건 no-usable 오류의 해석 - `read timeout=300`: 모델 응답이 늦어 클라이언트가 먼저 끊긴 건 - `AI returned no usable entities or claims`: 모델이 응답은 했지만 저장 가능한 구조를 만들지 못한 건 - 현재 구조에서는 fallback으로 정상 저장 가능하도록 보완되어야 하며, 해당 보완이 반영되어 있음 ## 7) 운영 체크포인트 1. 처리량 확인은 `visited_count`가 아니라 `analyzed_count` 기준으로 본다. 2. 저장 확인은 entities/claims 증가 + extraction_logs(raw_output.extraction_mode)로 함께 본다. 3. listing 비중이 높은 사이트는 page_type 분류 규칙 또는 analyze_page_types 정책 재조정이 필요하다. 4. 동시 실행 테스트 시 SQLite lock 가능성이 있어 순차 테스트를 권장한다. ## 8) 다음 개선 권장 - 분류 규칙(classify_page) 한국어 토큰 정비(깨진 인코딩 토큰 정리 포함) - 페이지 유형별 프롬프트 분기(상품/브랜드/리뷰) - crawl_jobs 대시보드에 `failed/discovered/completed` 원인별 집계 표시 - timeout, fallback, no-usable 건수의 일별 지표화