diff --git a/backend/src/main/java/com/zioinfo/mes/rag/RagMesService.java b/backend/src/main/java/com/zioinfo/mes/rag/RagMesService.java index e61c055..4896660 100644 --- a/backend/src/main/java/com/zioinfo/mes/rag/RagMesService.java +++ b/backend/src/main/java/com/zioinfo/mes/rag/RagMesService.java @@ -155,6 +155,10 @@ public class RagMesService { defect.put("sources", res.get("sources")); defect.put("steps", res.get("steps")); // 에이전트 추론 스텝(tool-use 시) defect.put("answerId", res.get("answer_id")); + // 환각차단·근거검증 통과 필드(계약 추가·기존 불변): WISE AI 화면 인용/보류 UX 용 + defect.put("abstained", res.get("abstained")); + defect.put("grounded", res.get("grounded")); + defect.put("faithfulness", res.get("faithfulness")); out.put("defect", defect); out.put("engine", "RAG_" + technique.toUpperCase()); out.put("degraded", false); @@ -230,8 +234,13 @@ public class RagMesService { if (res.get("data") instanceof Map) interp.putAll((Map) res.get("data")); if (res.get("answer") != null) interp.put("narrative", res.get("answer")); interp.put("citations", res.get("citations")); + interp.put("sources", res.get("sources")); interp.put("steps", res.get("steps")); interp.put("answerId", res.get("answer_id")); + // 환각차단·근거검증 통과 필드(계약 추가·기존 불변): WISE AI 화면 인용/보류 UX 용 + interp.put("abstained", res.get("abstained")); + interp.put("grounded", res.get("grounded")); + interp.put("faithfulness", res.get("faithfulness")); out.put("interpretation", interp); out.put("engine", "RAG_" + technique.toUpperCase()); out.put("degraded", false); diff --git a/doc/guardia-mes_개발자지침서_v1.0.pptx b/doc/guardia-mes_개발자지침서_v1.0.pptx new file mode 100644 index 0000000..ee3e50d Binary files /dev/null and b/doc/guardia-mes_개발자지침서_v1.0.pptx differ diff --git a/doc/guardia-mes_사용자지침서_v1.0.pptx b/doc/guardia-mes_사용자지침서_v1.0.pptx new file mode 100644 index 0000000..1e1b5df Binary files /dev/null and b/doc/guardia-mes_사용자지침서_v1.0.pptx differ diff --git a/doc/guardia-mes_아키텍처설계서_v1.1.pptx b/doc/guardia-mes_아키텍처설계서_v1.1.pptx new file mode 100644 index 0000000..32a314c Binary files /dev/null and b/doc/guardia-mes_아키텍처설계서_v1.1.pptx differ diff --git a/doc/guardia-mes_운영자지침서_v1.0.pptx b/doc/guardia-mes_운영자지침서_v1.0.pptx new file mode 100644 index 0000000..55a97e6 Binary files /dev/null and b/doc/guardia-mes_운영자지침서_v1.0.pptx differ diff --git a/frontend/src/components/Sidebar.tsx b/frontend/src/components/Sidebar.tsx index a3c1a1c..de88ba9 100644 --- a/frontend/src/components/Sidebar.tsx +++ b/frontend/src/components/Sidebar.tsx @@ -50,7 +50,7 @@ const masterLinks: Link[] = [ ] const commonLinks: Link[] = [ { to: '/analytics', label: '분석 / KPI', icon: BarChart3 }, - { to: '/ai-tools', label: 'AI 도구', icon: Sparkles }, + { to: '/ai-tools', label: 'WISE AI', icon: Sparkles }, { to: '/ai-techniques', label: 'AI 기법 설정', icon: Cpu, min: 'MANAGER' }, ] // 업무 (UIWS 이식) — 업무일지/일정/쪽지/업무통계 diff --git a/frontend/src/pages/AiTools.tsx b/frontend/src/pages/AiTools.tsx index 8de8a1f..8176a62 100644 --- a/frontend/src/pages/AiTools.tsx +++ b/frontend/src/pages/AiTools.tsx @@ -2,7 +2,7 @@ import { useEffect, useState } from 'react' import { Link } from 'react-router-dom' import { Sparkles, AlertTriangle, TrendingUp, Wrench, LineChart, Search, Boxes, CalendarClock, - Cpu, ThumbsUp, ThumbsDown, + Cpu, ThumbsUp, ThumbsDown, Quote, } from 'lucide-react' import { Card, Btn, Field } from '../components/ui' import { @@ -68,6 +68,50 @@ function LocalFeedbackBar({ feature, question, answer }: { feature: string; ques ) } +/** 인용 라벨 — 문서명·위치·근거지지도. citation/source 객체 형태 방어적 처리. */ +function citeLabel(c: any): string { + if (c == null) return '문서' + if (typeof c === 'string') return c + const src = c.source || c.document || c.doc || c.title || c.chunk_id || c.id || '문서' + const loc = c.page != null ? ` p.${c.page}` : (c.location ? ` ${c.location}` : '') + const sup = c.support != null ? ` · ${Math.round(Number(c.support) * 100)}%` : '' + return `${src}${loc}${sup}` +} + +/** + * WISE 근거 UX — 인용 카드(sources/citations) + 환각차단(abstained) 배지. + * node = 응답의 defect / interpretation 서브객체. 근거·보류 정보가 있을 때만 노출. + */ +function WiseEvidence({ node }: { node: any }) { + if (node == null) return null + const citations: any[] = Array.isArray(node.citations) ? node.citations : [] + const sources: any[] = Array.isArray(node.sources) ? node.sources : [] + const items = citations.length ? citations : sources + const abstained = node.abstained === true + if (!abstained && items.length === 0) return null + return ( +
+ {abstained && ( +
+ 근거가 부족해 답변을 보류했습니다 (오류 아님 · 안내) +
+ )} + {items.length > 0 ? ( + <> +
근거 인용 ({items.length})
+
+ {items.map((c, i) => ( + {citeLabel(c)} + ))} +
+ + ) : ( +
근거 문서 없음
+ )} +
+ ) +} + function Output({ data }: { data: any }) { if (data == null) return null if (typeof data === 'string') return
{data}
@@ -82,8 +126,8 @@ export default function AiTools() {
-

AI 도구

-

불량분석 · 생산예측 · 예지보전 · SPC이상 · 자연어조회 · 안전재고 · 일정최적화 (Ollama 온프레미스 + Java 폴백)

+

WISE AI

+

Enterprise AI for Trusted Knowledge · 근거·인용·환각차단(중앙 guardia-rag) + 불량분석·생산예측·예지보전·SPC이상 (Ollama 온프레미스 + Java 폴백)

@@ -93,7 +137,7 @@ export default function AiTools() { {/* ── 최신 기법 (중앙 guardia-rag 경유) — 대표 2개 기능 ───────────── */}
-

최신 AI 기법 (RAG · 에이전틱 · 구조화)

+

WISE AI · 근거 기반 분석 (RAG · 에이전틱 · 구조화)

기법 토글 설정 →
@@ -137,6 +181,7 @@ function RagDefectTool() { {busy ? '분석 중…' : 'RCA + SPC 분석'} + ) @@ -184,6 +229,7 @@ function RagPredictTool() { {busy ? '분석 중…' : '예측 + 해석'} + )