Skip to content

Latest commit

 

History

History
265 lines (204 loc) · 7.55 KB

File metadata and controls

265 lines (204 loc) · 7.55 KB

AX Prontier API

메타 에이전트 기반 대학 정보 통합 AI 서비스의 Spring Boot 백엔드입니다.

현재 단계에서는 로그인 없이 익명 대화 단위로 사용자의 질문과 AI 응답 이력을 저장하는 프로토타입 구조를 잡았습니다. 백엔드는 대화, 질문, AI 호출 기록, 라우팅 결과, 최종 응답, 문서 검토 결과, 도서 검색 로그, 감사 로그를 관리합니다.

크롤링 원문, 청크, 임베딩, 벡터 검색, 프롬프트, 에이전트 실행 내부 로직, 도서 원천 데이터, 문서 검토 규칙은 AI 서버 또는 RAG 저장소가 소유합니다.

기술 스택

Java 21
Spring Boot
Gradle Groovy
PostgreSQL
Spring Data JPA
Spring Web
Validation

프로젝트 구조

com.axprontier.api
├── global        공통 설정
├── conversation  익명 대화
├── query         질문/응답 흐름
├── ai            AI 서버 연동
├── crawler       크롤링 실행 요청/결과 로그
├── review        문서 검토
├── library       도서관/도서 검색
└── audit         감사 로그

각 기능 패키지는 아래 구조를 기본으로 사용합니다.

controller  API 요청을 받는 곳
service     비즈니스 흐름을 처리하는 곳
repository  DB에 접근하는 곳
entity      DB 테이블과 매핑되는 클래스
dto         요청/응답 데이터 클래스

기능별 책임

global        공통 설정, 예외, 응답 포맷
conversation  익명 대화 세션
query         사용자 질문, 라우팅 결과, 에이전트 실행 기록, 최종 응답
ai            AI 서버 호출 DTO, 클라이언트, 요청/응답 로그
crawler       Python 크롤링 API 호출, 크롤링 요청/결과 로그
review        전자결재 문서 검토 요청, 결과, 지적사항
library       도서 검색 요청/결과 로그
audit         감사 로그

주요 엔티티

Conversation
Query
QueryRoute
AgentRun
QueryResponse
AiRequestLog
AiResponseLog
CrawlerJobLog
ReviewRequest
ReviewResult
ReviewFinding
BookSearchLog
AuditLog

로컬 개발 환경

팀원은 아래 도구를 설치합니다.

Java 21
Docker
Git

환경변수 파일을 만듭니다.

cp .env.example .env

로컬 PostgreSQL을 실행합니다.

docker compose up -d

Spring Boot를 실행합니다.

export $(cat .env | xargs)
./gradlew bootRun

초기 API

대화를 생성합니다.

POST /api/conversations

대화에 질문을 추가하고 AI 오케스트레이터를 호출합니다.

POST /api/conversations/{conversationUid}/queries

Python 크롤링 API를 호출하고 요청/결과 로그를 저장합니다.

POST /api/crawlers/trigger

Python 크롤링 작업 상태를 조회하고 로그를 갱신합니다.

GET /api/crawlers/status/{jobId}

Spring Boot는 크롤링 작업 내용을 직접 처리하지 않고, Python 서버에 실행만 요청합니다. 실제 크롤링, 문서 생성, 청킹, 임베딩, RAG 저장소 갱신은 Python 서버가 담당합니다.

Python 서버 연동 주소는 아래 계약을 기준으로 합니다.

POST ${AI_SERVER_BASE_URL}/ingestion/run
GET  ${AI_SERVER_BASE_URL}/ingestion/status/{jobId}

/ingestion/run 응답으로 받은 jobIdCrawlerJobLog에 저장하고, Spring Scheduler가 주기적으로 상태를 polling하여 로그를 갱신합니다.

Library Agent 연동

학술정보관 전용 챗봇 로직은 Python FastAPI의 Library Agent가 담당합니다. Spring Boot는 사용자 질문과 최종 응답 흐름을 관리하고, Library Agent 응답에 포함된 도서 검색 메타데이터만 library.book_search_logs에 저장합니다.

FastAPI 내부 계약은 아래 형태를 기준으로 합니다.

POST /library/chat
{
  "queryUid": "uuid",
  "traceId": "uuid",
  "conversationUid": "uuid",
  "message": "도서 검색 또는 학술정보관 안내 질문"
}

응답은 기존 오케스트레이터 응답 필드에 Library 검색 로그용 필드를 선택적으로 포함합니다.

{
  "targetAgent": "LIBRARY",
  "intent": "BOOK_SEARCH",
  "answer": "답변 본문",
  "sources": [],
  "confidence": 0.9,
  "fallbackUsed": false,
  "fallbackReason": null,
  "searchKeyword": "검색어",
  "resultCount": 3,
  "matchedBooks": []
}

Main Agent / Orchestrator 연동

학사 공지 등 일반 학교 문의는 Python FastAPI의 Main Agent와 Orchestrator 계약을 따릅니다.

POST /orchestrator/route
POST /main/chat

/main/chat 응답 스키마는 기존 오케스트레이터 응답과 동일합니다. Spring Boot는 answer 문자열을 파싱하지 않고 저장 및 프론트 응답 payload로 그대로 전달합니다. 공식 링크 렌더링에 필요한 구조화 데이터는 sources를 우선 사용합니다.

{
  "targetAgent": "MAIN",
  "intent": "ACADEMIC_NOTICE",
  "answer": "\"복수전공 신청 기간\"와 관련해 확인할 수 있는 공식 링크를 찾았습니다.\n아래 링크들은 검색 결과에서 유사도가 높은 한성대학교 공지입니다.\n\n1. 2026학년도 1학기 복수·부전공 신청 및 변경신청 안내\n   복수·부전공 신청 안내에 대한 답변입니다.\n   이동하시려면 아래 링크를 눌러주세요.\n   https://www.hansung.ac.kr/bbs/hansung/2127/219610/artclView.do\n",
  "sources": [
    {
      "id": 219610,
      "title": "2026학년도 1학기 복수·부전공 신청 및 변경신청 안내",
      "sourceUrl": "https://www.hansung.ac.kr/bbs/hansung/2127/219610/artclView.do",
      "updatedAt": "2026-05-08"
    }
  ],
  "confidence": 0.9,
  "fallbackUsed": false,
  "fallbackReason": null,
  "searchKeyword": null,
  "resultCount": null,
  "matchedBooks": null
}

프론트에서 sources를 별도 링크 카드로 렌더링하는 경우 answer 내부 URL과 중복 표시될 수 있습니다. 링크 UI는 sources를 기준으로 구성하고, answer는 안내 문구 원문으로 표시하는 것을 권장합니다.

/orchestrator/routetargetAgent, intent, confidence, evidence 필드 구조는 유지됩니다. Spring Boot는 Orchestrator가 반환한 targetAgent를 신뢰해 대상 Agent를 호출하며, evidence.mainReason 같은 evidence.*Reason 문자열은 디버깅용으로만 취급하고 비즈니스 분기 조건으로 사용하지 않습니다.

Swagger

서버 실행 후 아래 주소에서 API 문서를 확인합니다.

http://localhost:8080/swagger-ui.html

환경변수

실제 .env 파일은 Git에 올리지 않습니다. 레포에는 .env.example만 공유합니다.

DB_URL
DB_USERNAME
DB_PASSWORD
AI_SERVER_BASE_URL
AI_SERVER_LIBRARY_PATH
AI_SERVER_DOCUMENT_REVIEW_PATH
AI_SERVER_TIMEOUT_SECONDS
CRAWLER_API_TRIGGER_PATH
CRAWLER_API_STATUS_PATH
CRAWLER_SCHEDULE_CRON
CRAWLER_DEFAULT_SOURCES
CRAWLER_DEFAULT_SINCE_MONTHS
CRAWLER_DEFAULT_MAX_PAGES
CRAWLER_DEFAULT_MAX_NOTICE_PAGES
CRAWLER_POLLING_ENABLED
CRAWLER_POLLING_FIXED_DELAY_MS
CORS_ALLOWED_ORIGINS

초기 배포 방향

프로토타입 단계에서는 비용과 복잡도를 줄이기 위해 아래 구조로 시작합니다.

FE
↓
Spring Boot BE on EC2
↓
AI Server

Spring Boot BE
↓
RDS PostgreSQL

초기에는 EC2 1대와 RDS PostgreSQL Single-AZ 최소 사양으로 시작합니다. NAT Gateway, Load Balancer, Multi-AZ 구성은 사용하지 않고, 필요해지는 시점에 확장합니다.

AWS에서는 배포 전에 Budgets 월 예산 알림을 먼저 설정합니다.