eval-system-premium BFF 가 ai_engine 의 capabilities 를 가장 잘 쓸 수 있는 방법 — endpoint + 모델 + 응답 schema 기반 매핑
작성: 2026-05-21대상: jodal-eval-ai/pps-mono-repoai_engine 위치: services/ai_engine/BFF 측 어댑터: app/adapters/ai_engine_client.py
1TL;DR
핵심 결론: ai_engine 은 3-layer 풀스택 LLM 백엔드 — Online (실시간 chat) / Offline (배치 추출/매칭) / Embedding (벡터). 현재 BFF 는 /online/eval-chatbot/chat 1개만 사용. 9개 더 활용 가능. 특히 EvalChatResponse 의 ui_actions·citations·suggested_actions·tabular_data 가 데모 임팩트 핵심.
현재 활용도 BFF 는 chat 1 endpoint 만. evidence drill-down + summary 만 추가했음. Offline / Embedding 0 활용
놓치고 있는 가치 tabular_data + ui_actions 활용 안 함. matcher 가 cross-DB write 로 BFF 가 못 읽음. embedding RAG 검색 미사용
2ai_engine 의 capability 전체 맵
Layer 1 — Online API 실시간 응답
Endpoint
용도
응답 스키마
POST/online/chatbot/generate
RFP 요구사항 생성 (rfp-gen 전용)
GenerateRequirementResponse
POST/online/chatbot/chat
RFP 요구사항 편집 챗 (rfp-gen 전용)
ChatResponse
POST/online/document-assistant/adapt-sections
RFP 섹션 일괄 적응
AdaptSectionsResponse
POST/online/document-assistant/edit-section
단일 섹션 편집
EditSectionResponse
POST/online/eval-chatbot/chat★ 평가 핵심
기술평가 챗봇 — proposal 분석 / 비교 / RAG / UI 제어
EvalChatResponse (풍부함 ↓)
GET/online/eval-chatbot/health
health check
{status}
GET/online/health
overall health
{status}
Layer 2 — Offline API 비동기 / 배치 / Celery
Endpoint
용도
활용 시점
POST/offline/rfp/structure
RFP 전체 구조 분석 (목차 + 섹션 + 메타)
RFP 업로드 직후 1회
POST/offline/rfp/extract-toc
목차 추출
RFP 구조 분석 단계
POST/offline/rfp/find-section-boundary
섹션 시작/끝 위치 찾기
목차 → 본문 매핑
POST/offline/rfp/find-section
키워드 기반 섹션 검색
특정 요구사항 위치 찾기
POST/offline/rfp/extract-value
값 추출 (date/number/text)
스칼라 필드 자동 채우기
POST/offline/rfp/analyze-image
이미지 분석 (Qwen3-VL)
시험성적서·도면 OCR/분석
POST/offline/rfp/extract-requirements
일반 요구사항 추출
RFP → requirement_items 시드
POST/offline/rfp/extract-tech-requirements
주요기술 추출
tech_match seed 의 item 마스터
POST/offline/rfp/extract-evaluation-items
평가항목 추출
eval_item_match seed 의 item 마스터
GET/offline/rfp/task/{task_id}
비동기 작업 결과 폴링
Celery task 결과 가져오기
Layer 3 — Embedding API 의미 검색
Endpoint
용도
모델
POST/embed
단일 텍스트 → 벡터
KURE-v1 (native 1024 dim)
POST/embed/batch
다수 텍스트 → 벡터 배열
KURE-v1
GET/embed/models
사용 가능한 임베딩 모델 목록
—
3모델 슬롯 (.env.onprem)
슬롯
모델
KIND
PURPOSE
URL
활용
qwen3_32b
Qwen/Qwen3-32B
llm
rfp-structure
:8305
offline RFP 추출 일체
qwen3_vl_8b_instruct
Qwen/Qwen3-VL-8B-Instruct
vision
rfp-image-analysis
:8303
시험성적서·도면 OCR/분석
qwen3_32b_eval
Qwen/Qwen3-32B
llm
eval-chatbot
:8305
평가 챗봇 + evidence + summary
local_embedding
nlpai-lab/KURE-v1
embedding
semantic-search
:8306
제안서·RFP 벡터 검색 (RAG)
주의 — EMBEDDING_DIM 불일치 (5/22 D-1 결정 리스크):.env.onprem:58 = 1536, KURE-v1 native = 1024. 배포 직후 curl :8306/embed 응답 벡터 길이 확인 → 1024 면 env 수정 후 컨테이너 재기동.
4EvalChatResponse — ★ 데모 임팩트의 핵심
BFF 가 가장 많이 호출하는 /online/eval-chatbot/chat 의 응답에는 단순 텍스트가 아니라 UI 제어까지 포함됩니다. 현재 BFF 는 reply_message 만 사용 — 나머지 5개 필드 미활용.
필드
타입
현재 활용
권장 활용
reply_message
str
✅ 사용
그대로
ui_actions
List[UIAction]
❌ 미사용
navigate / highlight_element / filter 자동 발화 — "○○ 업체 강조" 클릭 한 번에 표 정렬·하이라이트
citations
List[{file_name, page_number, content_snippet}]
⚠️ 일부 (evidence)
모든 응답에 출처 인용 표시 — 평가위원 신뢰도 ↑
suggested_actions
List[{label, action_payload}]
❌ 미사용
후속 질문 버튼 자동 생성 — "다른 업체와 비교?", "특허 조회?"
tabular_data
Dict (headers + rows)
❌ 미사용
비교 표를 LLM 이 직접 만들어 반환 — frontend 가 그대로 render
error_code
ErrorCode enum
⚠️ 일부
OUT_OF_DOMAIN / MALICIOUS_INTENT_BLOCKED 등 가드레일 표시
input_tokens / output_tokens
int
✅ summary 에서 사용
사용량 추적 / 비용 관리
UIAction 의 위력
LLM 이 답변하면서 동시에 frontend 에 "이것 하이라이트해", "이 탭으로 이동해", "이 필터 적용해" 명령 발행. 평가위원의 클릭 부담 0.
UIActionType:
- NAVIGATE // target_view 로 이동 (compare_overview / item_compare / company_detail_analysis)
- HIGHLIGHT_ELEMENT // element_id 강조
- FILTER // metadata 의 조건으로 표 필터
UserIntentType — LLM 의 의도 분류
PROPOSAL_ANALYSIS // 제안서 분석/검색
COMPARISON // 복수 업체 비교
REQUIREMENT_CHECK // RFP 요구사항 확인
NAVIGATION // UI 네비게이션
GENERAL_QUESTION // 일반 질의 (도메인 내)
OUT_OF_DOMAIN // 도메인 외 → 가드레일
5BFF 기준 use case × ai_engine 매핑
Use case (BFF)
ai_engine endpoint
모델
왜
제안서 한 줄 요약 (POST /api/proposals/{id}/summary — 이미 구현)
현재 상태:services/analysis_pipeline/eval_system/result_saver.py 가 knowledge_hub.eval_db 로 write. BFF compare endpoint 는 자기 DB (eval_system_premium) 만 read → 매칭 결과 못 봄 → fixture fallback 활성
해결 옵션
옵션
방법
장단점
A. matcher dual write
result_saver 가 두 DB 모두 write
일관성 보장. 코드 변경 ~50 lines
B. BFF 가 양쪽 read
BFF 가 knowledge_hub.eval_db 직접 query
BFF 가 두 DB 의존 — 헥사고날 깨짐
C. matcher 가 BFF DB 만 write
knowledge_hub 측 제거
knowledge_hub 의 다른 소비자 깨짐
D. Celery → BFF webhook
matcher 결과를 BFF webhook 으로 push (현재 hwpx 패턴과 동일)
일관된 패턴. 비동기 안정성 ↑
권장: D 옵션 — hwpx /internal/done webhook 패턴 재사용. matcher 가 BFF 의 /internal/match-done 로 결과 push → BFF DB upsert. 헥사고날 유지 + 비동기.