03. 보유 기술 아키텍처 상세 — PPS 모노레포

본 과제의 기반 자산인 PPS(Public Procurement System) 플랫폼의 아키텍처와 컴포넌트별 기술을 정리한다. 사업계획서 「수행실적 / 시스템 구성도」 작성 근거.


1. 플랫폼 개요

PPS는 AI 기반 공공조달 통합 플랫폼으로, 제안요청서(RFP) 자동 생성·기술평가 보조·조달사 챗봇을 제공하는 모노레포다. 본 정책자금 신청서 과제와 동일한 기술 도메인(한글 행정문서 + LLM + RAG + 서식 출력)에서 운영된다.

                         ┌──────────────────────────────────────┐
   사용자(웹/SSO)  ───►  │  portal-nginx  (5-scope auth_request) │
                         └───────────────┬──────────────────────┘
                       ┌─────────────────┼──────────────────────┐
                       ▼                 ▼                       ▼
              ┌───────────────┐  ┌───────────────┐     ┌────────────────┐
              │  앱(Frontend) │  │  앱(Backend)  │     │  ai_dashboard  │
              │  rfp-gen      │  │  FastAPI/SB   │     │  작업·비용모니터 │
              │  eval-system  │  └──────┬────────┘     └────────────────┘
              └───────────────┘         │
        ┌──────────────┬────────────────┼─────────────────┬───────────────┐
        ▼              ▼                 ▼                 ▼               ▼
  ┌───────────┐  ┌───────────┐   ┌──────────────┐  ┌────────────┐  ┌────────────┐
  │ ai_engine │  │knowledge_ │   │data_pipeline │  │analysis_   │  │ core_utils │
  │ LLM 오케  │◄─┤ hub (RAG) │   │수집·파싱·벡터화│  │pipeline    │  │ HWP 파서   │
  │ 모델팩토리 │  │ Qdrant    │   │ G2B/Upstage  │  │교차문서분석 │  │ Upstage    │
  └─────┬─────┘  └─────┬─────┘   └──────────────┘  └────────────┘  └────────────┘
        │              │
  Celery+Redis    Qdrant / PostgreSQL / MinIO
  (분산 비동기 큐)  (벡터·RDB·오브젝트 스토리지)

2. 기술 스택

영역 기술
백엔드 Python 3.11 · FastAPI 0.124 · Pydantic v2 · SQLAlchemy 2.0 · Alembic / (eval-system) Java 17 · Spring Boot 3.4.6
비동기/큐 Celery 5.4 · Redis 7
프론트엔드 Next.js 15~16 · React 19 · TypeScript 5 · Tailwind CSS
AI/LLM Gemini · OpenRouter · Qwen(vLLM) · HyperCLOVA X / 임베딩 KURE-v1(1024d 한국어)
벡터/저장 Qdrant(벡터) · PostgreSQL 16 · MinIO(S3 호환)
문서 자체 HWP/HWPX 파서(olefile·lxml) · python-hwpx 생성 · Upstage 문서 디지털화
인프라 Docker Compose(cloud/onprem/onprem-mock 3모드) · nginx · Infisical · K8s(템플릿)
수집 나라장터(G2B) OpenAPI

규모: Python 약 538개 · TS/TSX 약 309개 · Java 약 55개 소스 파일.


3. 코어 서비스 상세

3.1 ai_engine — LLM 오케스트레이션 (포트 8200)

  • 모델 팩토리 (core/engines/factory.py, base.py): provider별 엔진을 공통 인터페이스로 추상화. 민간 API와 로컬 vLLM을 동일 코드로 운용.
  • 동적 모델 설정 (core/model_config.py): ModelConfig dataclass + 환경변수 로드 → 코드 수정 없이 모델 교체.
  • 모델 선택/Fallback (core/model_selector.py): select_model(purpose, kind) — 목적별 라우팅 + 미일치 시 동종 fallback.
  • 프롬프트 레지스트리 (core/prompts/registry.py): .md/.yaml frontmatter 로드, 도메인별 디렉토리, 메타데이터(temperature·token 추정).
  • 비동기 작업 (tasks/rfp_tasks.py, core/celery_app.py): Celery로 항목별 생성 분해, prerun/postrun 시그널로 상태 추적.
  • 사용량 추적 (core/engines/mixins/llm_mixin.py, logging_mixin.py): 토큰·latency·비용 추정 누적.

3.2 knowledge_hub — RAG·벡터검색·인증 (포트 8100)

  • 벡터 DB (core/storage/vector_db/vector_db.py): VectorDBClient — Qdrant 래퍼.
  • 3-tier 인덱싱 (core/rfp/rfp_indexer.py): documents/sections/requirements 컬렉션, 청킹(5000자/overlap 300).
  • 하이브리드 검색 (core/rfp/rfp_query_service.py): RRF(40%) + cosine(60%).
  • 임베딩: KURE-v1 1024차원 한국어 모델(docs/development/embedding_strategy.md), ai_engine /embed 위임.
  • 포털 인증 (app/api/portal_auth.py, core/storage/rdb/portal_db/jwt.py): 5-scope JWT·쿠키 분리, nginx auth_request 검증 엔드포인트.

3.3 data_pipeline — 수집·파싱·벡터화 (포트 8101)

  • G2B 수집 (rfp2/ingest.py, keyword_search.py): 나라장터 입찰공고·사전규격 API.
  • 파싱/추출 (rfp2/parse.py, extract.py, requirement_extractor.py): 필드 추출·TOC 평탄화·요구사항 추출.
  • 검색 API (app/api/rfp_search.py): bids/prespecs/integrated 엔드포인트.

3.4 analysis_pipeline — 교차 문서 분석 (포트 8102)

  • 다중 문서 비교·분석 오케스트레이션.

3.5 ai_dashboard — 작업·비용 모니터링 (FE 8889 / BE 8890)

  • 워커/작업 모니터링 (backend/app/api/workers.py, tasks.py): 상태 집계·페이징·상세.
  • 토큰 집계: 작업별 input/output/total 토큰 노출. (예산 임계 차단은 미구현 → 04 참조)

3.6 core_utils — 공용 문서 라이브러리

  • HWP/HWPX 파서 (hwp_parser/parser/parse.py, services/hwpx_service.py): olefile(바이너리)·lxml(XML), 자동 포맷 감지.
  • Upstage 디지털화 (upstage/document_digitizer.py): PDF·HWP→HTML 보조 경로.

4. 애플리케이션 — rfp-gen (본 과제 직접 원형)

정책자금 신청서 과제와 가장 직접적으로 대응하는 앱. RFP(제안요청서) 초안을 키워드/소스 기반으로 생성·편집·서식 출력하는 전체 흐름을 이미 구현.

계층 구현
백엔드(FastAPI) apps/rfp-gen/backend/app/main.py — export/document/chatbot/search/section/session/template 라우터
생성 흐름 services/ai_engine_client.py(generate_requirement·adapt_sections·edit_section), section_seeder.py(deterministic+AI 배치)
RAG 연동 services/knowledge_hub_client.py — 유사 RFP·요구사항·TOC 조회
프론트(Next.js) frontend/app/workspace/[id]/document/[docId]/layout.tsx — 7단계 진행, 목차/사이드바
인라인 편집/재생성 frontend/components/document/DocumentWriteStep.tsx — 문단 클릭 직접수정·챗봇편집, openEditSegment·applyChatSuggestion, 목차 변경 시 증분 시딩(기존 보존)
A4 미리보기 HWPX 렌더러 기반 HTML 렌더(render_hwpx_preview), A4 210×297mm
HWP 출력 services/document_builder/hwpx_generator.py(python-hwpx)
DB knowledge_hub/.../rfp_db/models.pyRFPSourceFile·RFPSection·RFPRequirement·RFPAIExecution 등 / Alembic asyncpg

RFP 요구의 "키워드 입력 → 항목별 초안 생성 → 웹 에디터 인라인 편집·항목별 재생성 → HWP/PDF 출력" 흐름이 rfp-gen에 사실상 그대로 존재. 정책자금 도메인(서식·프롬프트·분류 라벨)만 교체하면 PoC 골격 완성.


5. 배포 아키텍처 (3-모드)

모드 파일 특성
Cloud docker-compose.cloud.yml 인터넷/공공 모드, 민간 LLM, Cloudflare Origin Cert, self-hosted Infisical, HTTPS 쿠키
OnPrem(폐쇄망) docker-compose.onprem.yml pull_policy: never + 외부 레지스트리 차단, docker load < pps-images.tar 오프라인 반입
OnPrem-Mock docker-compose.onprem-mock.yml 내부 vLLM(pps-kanana-2-30b·pps-qwen3-vl-8b) overlay, GPU 없는 검증용
  • 모드 전환 스크립트: scripts/start.sh(pps_resolve_mode, 네트워크 브리지).
  • RFP의 CSAP 인증 외부망 독립(CPU 기반) 요구는 OnPrem 모드로 직접 충족 — 통상 가장 까다로운 인프라 요건을 기보유 자산으로 해결.

6. 네트워크 격리

네트워크 범위
pps-network portal-nginx 허브 + 코어 서비스
pps_rfp-net rfp-gen 백엔드/프론트 격리
pps_eval-net eval-system 격리(전용 PostgreSQL 5433)
jodal-pps-net eval-system-premium 격리

DB·캐시는 앱 내부망에만 노출, portal-nginx가 프록시 — RFP의 "보안·외부망 독립" 요구에 부합하는 격리 설계.