Skip to content

Project Overview

donghoong2 edited this page Oct 28, 2026 · 1 revision

프로젝트 개요

dev a9974a0 (2026-10-12) 기준

AI 손해사정 플랫폼(팀 윤동주)의 AI 엔진 저장소다. 사용자가 사고 정보와 진단서·보험증권을 올리면 이 엔진이 문서를 읽고(OCR), 개인정보를 가리고, 약관·판례·분쟁조정사례를 검색해 보험금 리포트 초안을 만든다. 초안은 사용자에게 바로 가지 않고 등록 손해사정사의 검수를 거친다. 서비스 전체의 문제 정의와 B2B2C 구조는 Backend 위키의 프로젝트 개요에 있다.

서비스 흐름 6단계: 계약자 입력(손해사정 요청) → 문서 처리(OCR·개인정보 마스킹) → 리포트 초안 생성(약관·판례 검색, 쟁점 분석) → 손해사정사 검수 → 최종 리포트 → 상담

서비스 흐름. 이 저장소가 맡는 곳은 2~3단계(문서 처리·초안 생성)다. 사람이 손대지 않는 구간이라, 틀린 값이 사람에게 닿기 전에 걸러지도록 단계마다 게이트를 둔다

무엇을 만드는가

컴포넌트 방식 하는 일 위치
OCR 워커 SQS 워커 (ocr-job-queue 소비) GPU OCR, 문서 분류·추출, PII 마스킹(텍스트+이미지), 하이브리드 VLM, 청구 단위 fan-in, report-job 발행 src/ocr_worker · 구성
리포트 워커 SQS 워커 (report-job 소비) LangGraph 멀티에이전트로 진단 분류·약관 대조·판례·후유장해·보험금 범위·리포트 초안 src/report_worker · 구성
챗봇 FastAPI WebSocket 직결, 비스트리밍 입력 가드레일 → RAG → LLM → 출력 가드레일, 완성 응답 1회 src/chatbot
RAG 공용 모듈 키워드(tsvector + trigram) + 벡터(pgvector HNSW) → RRF src/rag · 파이프라인
가드레일 공용 모듈 입력(PII·도메인 차단) / 생성(단정 금액 치환·인용 강제) / 출력(고지문·LLM Judge) src/guardrail
corpus 워커 상시 폴링 데몬 Notion의 약관 PDF를 PG에 미러링하고 우선순위대로 S3에 스테이징 src/corpus_worker

AI 모델은 모두 자체 GPU 인스턴스의 Ollama로 서빙한다. 사용자 문서의 개인정보가 외부 API로 나가지 않게 하려는 것이고, 약관처럼 반복 처리량이 큰 작업에서 외부 LLM API 비용을 피하려는 것이기도 하다.

용도 모델
OCR surya-ocr 0.17.x (in-process, GPU)
이름 NER KoELECTRA-small 계열 한국어 NER (CPU)
VLM 표 전사 qwen3.6:35b-a3b
VLM PII 좌표 qwen3-vl:8b-instruct
리포트·챗봇 LLM Ollama 서빙 LLM (설정값 LLM_MODEL)
임베딩 qwen3:embedding 1024d (폴백 BGE-M3)

백엔드와의 경계

전체 아키텍처: 클라이언트(Next.js 웹, RN 앱) → Spring Boot 4 API → Amazon SQS → OCR Worker·Report Worker → Ollama GPU EC2. 공유 데이터 계층 PostgreSQL(RDS)+pgvector·S3·Redis. 오프라인 파이프라인 보험 약관 PDF → Policy-Chunker → pgvector

전체 구조. 무거운 작업(OCR·리포트)은 SQS 뒤의 워커로 가고, 워커와 API는 같은 RDS·S3를 쓴다. 약관은 오프라인 파이프라인이 미리 청킹해 pgvector에 넣어 둔다

  • 업로드·JWT·S3 저장·SQS 발행은 Spring Boot 게이트웨이가 맡는다. AI 엔진은 백엔드를 호출하지 않는다.
  • 백엔드는 청구의 문서마다 OCR 트리거를 하나씩 보낸다. 메시지에는 식별자만 있고 문서 내용은 없다.
  • 결과와 상태는 공유 DB에 쓴다. 그래서 스키마 소유권과 상태값 계약을 양쪽이 같이 지켜야 한다.
sequenceDiagram
    participant BE as Spring Boot
    participant Q1 as SQS ocr-job-queue
    participant OCR as OCR 워커
    participant Q2 as SQS report-job
    participant RPT as 리포트 워커
    participant DB as PostgreSQL
    BE->>DB: reports·첨부 shell 행 생성
    BE->>Q1: OcrJob × 문서 수 (claim_id, report_id, doc_index, doc_total)
    Q1->>OCR: 롱폴링 수신
    OCR->>DB: ai.ocr_results 저장 + 종결 카운트 (같은 트랜잭션)
    Note over OCR: 청구의 모든 문서가 종결될 때까지 대기 (fan-in)
    OCR->>Q2: ReportJob 1건 (ocr_quality = ok / needs_reupload)
    Q2->>RPT: 수신
    alt ocr_quality = needs_reupload
        RPT->>DB: reports.status = NEEDS_REUPLOAD
    else 정상
        RPT->>DB: 리포트 초안 저장 (report_id 기준 덮어쓰기)
    end
    BE->>DB: 상태·초안 조회, 실패·재업로드 상태는 스윕으로 알림
Loading
스키마 소유 다른 쪽의 권한
core 백엔드 워커는 필요한 테이블·컬럼만 읽고, reports.status는 정해진 값만 갱신
ai AI 엔진 (OCR·리포트) 백엔드는 ocr_job_failures·report_drafts SELECT, ocr_results는 식별·상태 7개 컬럼만 SELECT
corpus corpus 워커·청킹 파이프라인 리포트·챗봇은 검색용 SELECT

워커가 다른 워커의 테이블에 쓰지 않고 메시지로 넘긴다는 규칙은 청구 fan-in 기록에서, 마이그레이션을 워커별로 나눈 이유는 스키마 기록에서 볼 수 있다.

배포

AWS 구성: VPC 안 private subnet에 frontend(next.js), backend/report-worker, PostgreSQL, monitoring(grafana), ai(ollama/ocr-worker). 메시지는 SQS, 이미지는 ECR, 알림은 Discord

Docker Compose 시기의 AWS 구성. GPU가 필요한 OCR 워커와 Ollama는 별도 GPU 인스턴스, 리포트 워커는 백엔드와 같은 범용 인스턴스에 있었다

서비스 배포 대상 경로
OCR 워커 GPU EC2 (Ollama 동거) GitHub Actions → ECR → SSM
corpus 워커 경량 EC2 GitHub Actions → ECR → SSM
리포트 워커·챗봇 dev Kubernetes GitHub Actions가 매니페스트 레포의 image.tag를 커밋 → Argo CD 반영 (PR #69, 2026-10-12)
  • 마이그레이션 경로 필터는 워커별로 나뉘어, 마이그레이션만 바뀌어도 해당 워커가 다시 배포된다(PR #51).
  • GPU 인스턴스는 node-exporter·cAdvisor·DCGM exporter·Alloy로 중앙 모니터링에 편입했다(2026-09-03).
  • Argo CD 경로에서 CI 성공은 "매니페스트를 커밋했다"는 뜻일 뿐이다. 실제 반영 결과는 Argo CD 알림이 보내고, CI는 실패만 알린다(PR #70).

처음 그렸던 구조와 비교

초기 리포트 생성 그래프 스케치: 사용자 Input(진단서·수술확인서·보험증권·입퇴원확인서) → 컨텍스트 조립 → 진단 분류 → 약관 분석/검색 → 판례 검색 → (장해 분석인 경우) 장해율 산정 → 리포트 생성 완료, 오른쪽에 State 필드 목록

초기 리포트 그래프 스케치. 지금 그래프([리포트 워커 구성](Report-Worker))에는 입력·출구 가드레일, 장해 분류 감수, 규칙 기반 합산, 보험금 계산이 단계로 더해졌다

  • 브로커: Kafka(MSK)에서 SQS로 바뀌었다(PR #53, 2026-08-10). 메시지 계약(OcrJob·ReportJob JSON)은 그대로 두고 수신 방식만 바꿨다. 경위는 Backend: OCR 트리거 브로커를 Kafka에서 MSK를 거쳐 SQS로 전환에 있다.
  • OCR 엔진: 기획 단계의 PaddleOCR에서 surya-ocr로 바뀌었고, 표·저화질 문서에는 VLM을 더했다(VLM 하이브리드 기록).
  • 업로드 주체: 처음엔 FastAPI가 문서를 받아 동기 OCR로 폼을 채우는 안도 검토했다. GPU 인스턴스가 비싸 API를 같이 올리기 어려웠고, 결국 업로드는 Spring Boot가, OCR은 큐 뒤의 워커가 맡았다.
  • 청구 단위 처리: 문서 1건 = 리포트 1건에서, 청구의 모든 문서를 모아 리포트 1건으로 바뀌었다.

결정마다의 경위는 결정 로그에, 용어는 용어집에 모았다.

Clone this wiki locally