Files
sam-kd/strategy/longterm_chatbot.php
hskwon aca1767eb9 초기 커밋: 5130 레거시 시스템
- URL 하드코딩 → .env APP_URL 기반 동적 URL로 변경
- DB 연결 하드코딩 → .env 기반으로 변경
- MySQL strict mode DATE 오류 수정
2025-12-10 20:14:31 +09:00

1326 lines
48 KiB
PHP

<?php
require_once($_SERVER['DOCUMENT_ROOT'] . "/session.php");
?>
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>장기적 AI 챗봇 솔루션 전략 - Vertex AI Search</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
overflow-x: hidden;
}
.presentation-container {
width: 100%;
height: 100vh;
position: relative;
overflow: hidden;
}
.slide {
width: 100%;
height: 100vh;
display: none;
align-items: flex-start;
justify-content: center;
padding: 40px;
position: absolute;
top: 0;
left: 0;
overflow-y: auto;
overflow-x: hidden;
}
.slide.active {
display: flex;
animation: slideInRight 0.5s ease-out;
}
.slide-content {
background: rgba(255, 255, 255, 0.95);
border-radius: 20px;
padding: 60px;
max-width: 1200px;
width: 100%;
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
animation: fadeIn 0.8s ease-out;
margin: auto 0;
}
h1 {
color: #0066cc;
font-size: 3em;
margin-bottom: 20px;
text-align: center;
}
h2 {
color: #00b8d4;
font-size: 2.5em;
margin-bottom: 30px;
text-align: center;
border-bottom: 3px solid #0066cc;
padding-bottom: 15px;
}
h3 {
color: #0066cc;
font-size: 1.8em;
margin: 25px 0 15px 0;
}
h4 {
color: #00b8d4;
font-size: 1.3em;
margin: 15px 0 10px 0;
}
p, li {
font-size: 1.2em;
line-height: 1.8;
color: #333;
margin-bottom: 15px;
}
ul, ol {
margin-left: 30px;
}
.company-info {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
gap: 20px;
margin: 30px 0;
}
.info-card {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
padding: 25px;
border-radius: 15px;
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.2);
animation: scaleIn 0.5s ease-out;
}
.info-card h4 {
color: white;
font-size: 1.3em;
margin-bottom: 10px;
border-bottom: 2px solid rgba(255, 255, 255, 0.3);
padding-bottom: 8px;
}
.info-card p {
color: white;
font-size: 1em;
}
.comparison-table {
width: 100%;
border-collapse: collapse;
margin: 25px 0;
font-size: 1em;
}
.comparison-table th,
.comparison-table td {
padding: 12px;
border: 1px solid #ddd;
text-align: left;
}
.comparison-table thead tr {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
}
.comparison-table tbody tr:nth-of-type(even) {
background: #f3f3f3;
}
.feature-list {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 15px;
margin: 20px 0;
}
.feature-item {
background: #e3f2fd;
padding: 15px;
border-radius: 10px;
border-left: 4px solid #00b8d4;
}
.feature-item h4 {
color: #0066cc;
margin-top: 0;
}
.conclusion-box {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
padding: 30px;
border-radius: 15px;
margin: 20px 0;
text-align: center;
}
.conclusion-box p, .conclusion-box h3 {
color: white;
}
.warning-box {
background: #fff3cd;
border-left: 5px solid #ffc107;
padding: 25px;
border-radius: 15px;
margin: 20px 0;
}
.warning-box h3, .warning-box li {
color: #856404;
}
.flow-diagram {
background: #f5f5f5;
padding: 25px;
border-radius: 15px;
margin: 20px 0;
border: 2px solid #00b8d4;
}
.flow-diagram pre {
font-size: 1em;
line-height: 1.6;
color: #333;
overflow-x: auto;
}
.code-box {
background: #263238;
color: #aed581;
padding: 20px;
border-radius: 10px;
margin: 20px 0;
overflow-x: auto;
font-family: 'Courier New', monospace;
font-size: 0.9em;
}
.code-box pre {
margin: 0;
color: #aed581;
}
.navigation {
position: fixed;
bottom: 30px;
right: 30px;
display: flex;
gap: 15px;
z-index: 1000;
}
.nav-btn {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
border: none;
padding: 15px 30px;
border-radius: 50px;
cursor: pointer;
font-size: 1.1em;
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3);
transition: all 0.3s ease;
}
.nav-btn:hover {
transform: translateY(-3px);
box-shadow: 0 8px 20px rgba(0, 0, 0, 0.4);
}
.home-btn {
position: fixed;
top: 30px;
left: 30px;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
border: none;
padding: 12px 25px;
border-radius: 50px;
cursor: pointer;
font-size: 1em;
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3);
transition: all 0.3s ease;
z-index: 1000;
text-decoration: none;
display: inline-flex;
align-items: center;
gap: 8px;
}
.home-btn:hover {
transform: translateY(-3px);
box-shadow: 0 8px 20px rgba(0, 0, 0, 0.4);
background: linear-gradient(135deg, #764ba2 0%, #667eea 100%);
}
.slide-number {
position: fixed;
bottom: 30px;
left: 30px;
background: rgba(255, 255, 255, 0.9);
padding: 10px 20px;
border-radius: 25px;
font-size: 1.1em;
color: #0066cc;
font-weight: bold;
z-index: 1000;
}
@keyframes slideInRight {
from {
transform: translateX(100%);
opacity: 0;
}
to {
transform: translateX(0);
opacity: 1;
}
}
@keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
@keyframes scaleIn {
from {
transform: scale(0.9);
opacity: 0;
}
to {
transform: scale(1);
opacity: 1;
}
}
@media (max-width: 768px) {
.slide-content {
padding: 30px;
}
h1 {
font-size: 2em;
}
h2 {
font-size: 1.8em;
}
h3 {
font-size: 1.4em;
}
p, li {
font-size: 1em;
}
.navigation {
bottom: 15px;
right: 15px;
}
.nav-btn {
padding: 10px 20px;
font-size: 0.9em;
}
.slide-number {
bottom: 15px;
left: 15px;
padding: 8px 15px;
font-size: 0.9em;
}
.home-btn {
top: 15px;
left: 15px;
padding: 10px 20px;
font-size: 0.9em;
}
.comparison-table {
font-size: 0.8em;
}
.comparison-table th,
.comparison-table td {
padding: 8px;
}
}
</style>
</head>
<body>
<!-- Home Button -->
<a href="chatbot_index.php" class="home-btn">
<span>🏠</span>
<span>전략선택</span>
</a>
<div class="presentation-container">
<!-- Slide 1: Cover -->
<div class="slide active">
<div class="slide-content">
<h1>장기적 AI 챗봇 솔루션 전략</h1>
<h2 style="border: none; color: #00b8d4;">Vertex AI Search 기반 지능형 문서 검색 시스템</h2>
<div style="text-align: center; margin-top: 50px;">
<p style="font-size: 1.5em; color: #0066cc;">노트북LM 수준의 자연어 질의응답 시스템</p>
<p style="margin-top: 30px; color: #666;">RAG (검색 증강 생성) 기반 고객 지원 자동화</p>
</div>
</div>
</div>
<!-- Slide 2: Project Overview -->
<div class="slide">
<div class="slide-content">
<h2>프로젝트 개요</h2>
<div class="conclusion-box">
<h3 style="color: white; margin-top: 0;">배경</h3>
<p style="font-size: 1.2em;">중소기업의 고객 지원 자동화 필요성 증가<br>문서 기반 즉각적 답변 제공으로 업무 효율성 향상</p>
</div>
<div style="margin-top: 30px;">
<h3>핵심 목표</h3>
<ul>
<li><strong>자연어 질문 즉각 답변:</strong> 복잡한 질의에 대한 정확한 답변 제공</li>
<li><strong>노트북LM 유사 기술:</strong> Google의 Vertex AI Search RAG 기술 활용</li>
<li><strong>고객 지원 비용 절감:</strong> 자동화를 통한 인력 비용 및 시간 절약</li>
<li><strong>문서 기반 검색:</strong> PDF, DOCX, HTML 등 다양한 형식 지원</li>
</ul>
</div>
<div style="margin-top: 30px;">
<h3>프로젝트 범위</h3>
<div class="company-info">
<div class="info-card">
<h4>✅ 포함 범위</h4>
<p>Vertex AI Search 연동, Laravel 백엔드 구현, 챗봇 UI, 문서 인덱싱, 참고 자료 제공</p>
</div>
<div class="info-card">
<h4>❌ 제외 범위</h4>
<p>음성 인식, 이미지 분석, 실시간 영상 통화, 복잡한 워크플로우 자동화</p>
</div>
</div>
</div>
</div>
</div>
<!-- Slide 3: Vertex AI Search 기술 분석 -->
<div class="slide">
<div class="slide-content">
<h2>Vertex AI Search 기술 분석</h2>
<div class="feature-list">
<div class="feature-item">
<h4>🤖 완전 관리형 서비스</h4>
<p>인프라 관리 불필요, Google이 스케일링 및 유지보수 담당</p>
</div>
<div class="feature-item">
<h4>🔍 RAG (검색 증강 생성)</h4>
<p>문서 검색 + LLM 생성 결합으로 정확하고 맥락있는 답변</p>
</div>
<div class="feature-item">
<h4>🎯 Google 수준의 검색 품질</h4>
<p>Google 검색 기술 기반의 고품질 문서 검색</p>
</div>
<div class="feature-item">
<h4>📚 다양한 문서 형식 지원</h4>
<p>PDF, DOCX, HTML, JSON, 웹사이트 크롤링</p>
</div>
</div>
<div style="margin-top: 30px;">
<h3>핵심 특징</h3>
<ul>
<li><strong>Semantic Search:</strong> 키워드 매칭이 아닌 의미 기반 검색</li>
<li><strong>Personalization:</strong> 사용자별 맞춤 검색 결과 제공</li>
<li><strong>Multi-modal:</strong> 텍스트, 이미지, 비디오 등 다양한 데이터 타입</li>
<li><strong>Enterprise-grade Security:</strong> IAM 기반 접근 제어 및 데이터 격리</li>
</ul>
</div>
</div>
</div>
<!-- Slide 4: RAG 작동 원리 -->
<div class="slide">
<div class="slide-content">
<h2>RAG (검색 증강 생성) 작동 원리</h2>
<div style="margin-top: 30px;">
<h3>1단계: 데이터 수집 (Ingestion)</h3>
<div class="info-card" style="margin: 15px 0;">
<p>문서를 Vertex AI Search Data Store에 업로드 (PDF, DOCX, HTML 등)</p>
<p>자동으로 청크 단위로 분할 및 임베딩 벡터 생성</p>
</div>
</div>
<div style="margin-top: 30px;">
<h3>2단계: 인덱싱 (Indexing)</h3>
<div class="info-card" style="margin: 15px 0;">
<p>문서의 의미를 벡터로 변환하여 벡터 데이터베이스에 저장</p>
<p>메타데이터(제목, 작성자, 날짜 등)와 함께 인덱싱</p>
</div>
</div>
<div style="margin-top: 30px;">
<h3>3단계: 검색 및 생성 (Search & Generation)</h3>
<div class="info-card" style="margin: 15px 0;">
<p><strong>검색:</strong> 사용자 질문을 벡터로 변환 후 유사 문서 검색</p>
<p><strong>생성:</strong> 검색된 문서를 컨텍스트로 LLM(Gemini)이 답변 생성</p>
<p><strong>참조:</strong> 답변에 사용된 원본 문서 링크 제공</p>
</div>
</div>
</div>
</div>
<!-- Slide 5: Architecture Diagram -->
<div class="slide">
<div class="slide-content">
<h2>시스템 아키텍처</h2>
<div class="flow-diagram">
<pre>
┌─────────────┐
│ 사용자 │
└──────┬──────┘
│ 질문 입력
┌──────────────────┐
│ SAM Frontend │
│ (Vue.js/ │
│ React) │
└────────┬─────────┘
│ HTTP Request
┌──────────────────────────┐
│ SAM Backend (Laravel) │
│ ┌──────────────────────┐ │
│ │ ChatController │ │
│ │ - searchVertexAI() │ │
│ └──────────┬───────────┘ │
└────────────┼─────────────┘
│ API Call
┌────────────────────────────┐
│ Google Cloud Platform │
│ ┌────────────────────────┐ │
│ │ Vertex AI Search │ │
│ │ - Data Store │ │
│ │ - Search Engine │ │
│ └───────────┬────────────┘ │
│ │ │
│ ┌───────────▼────────────┐ │
│ │ LLM (Gemini 1.5) │ │
│ │ - Answer Generation │ │
│ └────────────────────────┘ │
└────────────────────────────┘
</pre>
</div>
<div style="margin-top: 30px;">
<h3>데이터 흐름</h3>
<ol>
<li>사용자가 프론트엔드에서 질문 입력</li>
<li>Laravel 백엔드가 Vertex AI Search API 호출</li>
<li>Vertex AI가 문서 검색 후 Gemini에 전달</li>
<li>Gemini가 검색 결과 기반 답변 생성</li>
<li>백엔드가 답변 + 참고 자료를 프론트엔드로 반환</li>
</ol>
</div>
</div>
</div>
<!-- Slide 6: Phase 1 - Google Cloud 설정 -->
<div class="slide">
<div class="slide-content">
<h2>Phase 1: Google Cloud 설정</h2>
<div style="margin-top: 30px;">
<h3>1. GCP 프로젝트 생성</h3>
<div class="code-box">
<pre>
# 프로젝트 ID: sam-chatbot-project
# 위치: asia-northeast3 (서울)</pre>
</div>
</div>
<div style="margin-top: 30px;">
<h3>2. 필수 API 활성화</h3>
<ul>
<li>Discovery Engine API (Vertex AI Search)</li>
<li>Vertex AI API</li>
<li>Cloud Storage API (문서 저장용)</li>
</ul>
</div>
<div style="margin-top: 30px;">
<h3>3. 서비스 계정 생성</h3>
<div class="code-box">
<pre>
# 서비스 계정 이름: sam-chatbot-sa
# 역할:
# - Discovery Engine Admin
# - Vertex AI User</pre>
</div>
</div>
<div style="margin-top: 30px;">
<h3>4. JSON 인증 키 다운로드</h3>
<div class="warning-box">
<h3>⚠️ 보안 주의사항</h3>
<ul>
<li>JSON 키 파일은 절대 Git에 커밋하지 않기</li>
<li>.gitignore에 추가 필수</li>
<li>환경 변수로 관리</li>
</ul>
</div>
</div>
</div>
</div>
<!-- Slide 7: Phase 2 - Vertex AI Search 데이터 스토어 구축 -->
<div class="slide">
<div class="slide-content">
<h2>Phase 2: Vertex AI Search 데이터 스토어 구축</h2>
<div style="margin-top: 30px;">
<h3>1. 앱 생성</h3>
<ul>
<li><strong>앱 유형:</strong> Chat (대화형)</li>
<li><strong>데이터 타입:</strong> Unstructured (비정형 문서)</li>
<li><strong>솔루션 타입:</strong> Search with Chat</li>
</ul>
</div>
<div style="margin-top: 30px;">
<h3>2. 문서 업로드</h3>
<div class="feature-list">
<div class="feature-item">
<h4>📂 Cloud Storage</h4>
<p>대량 문서 업로드 (gs://bucket-name/)</p>
</div>
<div class="feature-item">
<h4>🌐 웹사이트 크롤링</h4>
<p>sitemap.xml 기반 자동 수집</p>
</div>
<div class="feature-item">
<h4>📄 개별 업로드</h4>
<p>콘솔에서 직접 파일 업로드</p>
</div>
</div>
</div>
<div style="margin-top: 30px;">
<h3>3. 인덱싱</h3>
<div class="info-card">
<p>업로드 후 자동 인덱싱 시작 (10-30분 소요)</p>
<p>인덱싱 상태: Console → Vertex AI Search에서 확인</p>
</div>
</div>
<div style="margin-top: 30px;">
<h3>4. 테스트</h3>
<p>GCP Console의 Preview 기능으로 샘플 질문 테스트</p>
</div>
</div>
</div>
<!-- Slide 8: Phase 3 - Laravel 백엔드 구현 -->
<div class="slide">
<div class="slide-content">
<h2>Phase 3: Laravel 백엔드 구현</h2>
<div style="margin-top: 30px;">
<h3>1. Google Cloud PHP 클라이언트 설치</h3>
<div class="code-box">
<pre>
composer require google/cloud-discoveryengine</pre>
</div>
</div>
<div style="margin-top: 30px;">
<h3>2. 환경 변수 설정 (.env)</h3>
<div class="code-box">
<pre>
GOOGLE_CLOUD_PROJECT_ID=sam-chatbot-project
GOOGLE_CLOUD_LOCATION=asia-northeast3
GOOGLE_CLOUD_DATA_STORE_ID=your-data-store-id
GOOGLE_APPLICATION_CREDENTIALS=/path/to/service-account.json</pre>
</div>
</div>
<div style="margin-top: 30px;">
<h3>3. ChatController 구현</h3>
<div class="code-box">
<pre>
use Google\Cloud\DiscoveryEngine\V1\SearchServiceClient;
use Google\Cloud\DiscoveryEngine\V1\SearchRequest;
public function searchVertexAI(Request $request)
{
$query = $request->input('query');
$client = new SearchServiceClient([
'credentials' => env('GOOGLE_APPLICATION_CREDENTIALS')
]);
$servingConfig = sprintf(
'projects/%s/locations/%s/collections/default_collection/dataStores/%s/servingConfigs/default_config',
env('GOOGLE_CLOUD_PROJECT_ID'),
env('GOOGLE_CLOUD_LOCATION'),
env('GOOGLE_CLOUD_DATA_STORE_ID')
);
$searchRequest = new SearchRequest([
'serving_config' => $servingConfig,
'query' => $query,
'page_size' => 5
]);
$response = $client->search($searchRequest);
return response()->json([
'answer' => $response->getSummary(),
'references' => $response->getResults()
]);
}</pre>
</div>
</div>
</div>
</div>
<!-- Slide 9: Phase 4 - 프론트엔드 구현 -->
<div class="slide">
<div class="slide-content">
<h2>Phase 4: 프론트엔드 구현</h2>
<div style="margin-top: 30px;">
<h3>1. 챗봇 UI 컴포넌트</h3>
<div class="code-box">
<pre>
&lt;template&gt;
&lt;div class="chatbot-container"&gt;
&lt;div class="messages"&gt;
&lt;div v-for="msg in messages" :key="msg.id"&gt;
&lt;div :class="['message', msg.role]"&gt;
{{ msg.content }}
&lt;/div&gt;
&lt;div v-if="msg.references" class="references"&gt;
참고: &lt;a v-for="ref in msg.references" :href="ref.url"&gt;
{{ ref.title }}
&lt;/a&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;input v-model="userInput" @keyup.enter="sendMessage" /&gt;
&lt;/div&gt;
&lt;/template&gt;</pre>
</div>
</div>
<div style="margin-top: 30px;">
<h3>2. API 호출 로직</h3>
<div class="code-box">
<pre>
async sendMessage() {
const response = await axios.post('/api/chatbot/search', {
query: this.userInput
});
this.messages.push({
role: 'user',
content: this.userInput
});
this.messages.push({
role: 'assistant',
content: response.data.answer,
references: response.data.references
});
this.userInput = '';
}</pre>
</div>
</div>
</div>
</div>
<!-- Slide 10: 초기 투자 비용 분석 -->
<div class="slide">
<div class="slide-content">
<h2>초기 투자 비용 분석</h2>
<div style="margin-top: 30px;">
<h3>Vertex AI Search 비용 (월간 예상)</h3>
<table class="comparison-table">
<thead>
<tr>
<th>항목</th>
<th>단가</th>
<th>예상 사용량</th>
<th>월 비용</th>
</tr>
</thead>
<tbody>
<tr>
<td>데이터 저장</td>
<td>$0.10/GB</td>
<td>50GB</td>
<td>$5.00</td>
</tr>
<tr>
<td>질의 비용</td>
<td>$0.0025/query</td>
<td>3,000 queries</td>
<td>$7.50</td>
</tr>
<tr>
<td><strong>총 합계</strong></td>
<td colspan="2"></td>
<td><strong>$12.50</strong></td>
</tr>
</tbody>
</table>
</div>
<div style="margin-top: 30px;">
<h3>추가 비용 (선택사항)</h3>
<ul>
<li><strong>Cloud Storage:</strong> $0.023/GB (문서 백업용)</li>
<li><strong>Gemini API:</strong> 별도 호출 시 추가 비용 (RAG는 포함)</li>
<li><strong>네트워크 송신:</strong> $0.12/GB (아시아 → 외부)</li>
</ul>
</div>
<div class="conclusion-box" style="margin-top: 30px;">
<h3 style="color: white;">💰 월 $12.50 수준의 저렴한 운영 비용</h3>
<p>초기 3개월: 무료 크레딧 $300 활용 가능</p>
</div>
</div>
</div>
<!-- Slide 11: 인프라 확장 권고 -->
<div class="slide">
<div class="slide-content">
<h2>인프라 확장 권고사항</h2>
<div class="warning-box">
<h3>⚠️ 현재 인프라 분석</h3>
<ul>
<li><strong>현재 스펙:</strong> 2Core 4GB (부족)</li>
<li><strong>문제점:</strong> Laravel + MySQL + 챗봇 동시 운영 시 메모리 부족</li>
<li><strong>동시 사용자:</strong> 10-20명 수준으로 제한적</li>
</ul>
</div>
<div style="margin-top: 30px;">
<h3>권장 인프라 구성</h3>
<table class="comparison-table">
<thead>
<tr>
<th>구분</th>
<th>현재</th>
<th>권장</th>
<th>비고</th>
</tr>
</thead>
<tbody>
<tr>
<td>웹 서버</td>
<td>2Core 4GB</td>
<td>4Core 8GB</td>
<td>Laravel + 챗봇 동시 운영</td>
</tr>
<tr>
<td>DB 서버</td>
<td>통합</td>
<td>분리 (4Core 8GB)</td>
<td>MySQL 전용 서버</td>
</tr>
<tr>
<td>저장공간</td>
<td>100GB</td>
<td>200GB SSD</td>
<td>문서 저장 및 로그</td>
</tr>
<tr>
<td>백업</td>
<td>수동</td>
<td>자동 일일 백업</td>
<td>GCS 또는 별도 스토리지</td>
</tr>
</tbody>
</table>
</div>
<div style="margin-top: 30px;">
<h3>Cloud VM 이전 필수</h3>
<div class="info-card">
<p><strong>이유:</strong> Vertex AI와의 네트워크 레이턴시 최소화</p>
<p><strong>권장 위치:</strong> GCP asia-northeast3 (서울) 리전</p>
<p><strong>예상 비용:</strong> 웹서버 $80/월 + DB서버 $80/월 = $160/월</p>
</div>
</div>
</div>
</div>
<!-- Slide 12: 데이터 품질 관리 -->
<div class="slide">
<div class="slide-content">
<h2>데이터 품질 관리 전략</h2>
<div class="conclusion-box">
<h3 style="color: white; margin-top: 0;">핵심 원칙</h3>
<p style="font-size: 1.2em;">문서의 품질이 곧 답변의 품질을 결정합니다</p>
</div>
<div style="margin-top: 30px;">
<h3>1. 문서 최신화</h3>
<div class="feature-list">
<div class="feature-item">
<h4>📅 정기 업데이트</h4>
<p>월 1회 문서 검토 및 업데이트</p>
</div>
<div class="feature-item">
<h4>🗑️ 구버전 제거</h4>
<p>오래된 문서는 자동 아카이빙</p>
</div>
<div class="feature-item">
<h4>✅ 변경 추적</h4>
<p>버전 관리 시스템 도입</p>
</div>
</div>
</div>
<div style="margin-top: 30px;">
<h3>2. 문서 표준화</h3>
<ul>
<li><strong>구조화:</strong> 제목, 소제목, 본문이 명확한 구조</li>
<li><strong>포맷:</strong> PDF 또는 DOCX 권장 (일관된 포맷)</li>
<li><strong>언어:</strong> 한국어 또는 영어 중 하나로 통일</li>
<li><strong>메타데이터:</strong> 제목, 작성자, 작성일, 카테고리 필수 입력</li>
</ul>
</div>
<div style="margin-top: 30px;">
<h3>3. 품질 검증</h3>
<div class="info-card">
<p><strong>방법:</strong> 샘플 질문 10-20개로 주기적 테스트</p>
<p><strong>지표:</strong> 답변 정확도 90% 이상 유지</p>
<p><strong>개선:</strong> 부정확한 답변 발견 시 문서 보완</p>
</div>
</div>
</div>
</div>
<!-- Slide 13: 보안 - API 키 관리 -->
<div class="slide">
<div class="slide-content">
<h2>보안: API 키 및 인증 관리</h2>
<div style="margin-top: 30px;">
<h3>1. 서비스 계정 키 보안</h3>
<div class="warning-box">
<h3>⚠️ 절대 금지 사항</h3>
<ul>
<li>JSON 키 파일을 Git에 커밋</li>
<li>클라이언트 사이드 코드에 키 노출</li>
<li>공개 저장소에 키 업로드</li>
<li>불필요한 권한 부여</li>
</ul>
</div>
</div>
<div style="margin-top: 30px;">
<h3>2. .gitignore 설정</h3>
<div class="code-box">
<pre>
# Google Cloud 인증 키
service-account.json
google-credentials.json
*.json
# 환경 변수
.env
.env.local
.env.production</pre>
</div>
</div>
<div style="margin-top: 30px;">
<h3>3. 최소 권한 원칙</h3>
<table class="comparison-table">
<thead>
<tr>
<th>역할</th>
<th>권한</th>
<th>용도</th>
</tr>
</thead>
<tbody>
<tr>
<td>Discovery Engine User</td>
<td>검색 API 호출</td>
<td>일반 검색 요청</td>
</tr>
<tr>
<td>Storage Object Viewer</td>
<td>문서 읽기</td>
<td>문서 다운로드</td>
</tr>
<tr>
<td>Discovery Engine Admin</td>
<td>데이터 스토어 관리</td>
<td>관리자 전용 (제한적)</td>
</tr>
</tbody>
</table>
</div>
<div style="margin-top: 30px;">
<h3>4. 환경 변수 관리</h3>
<div class="info-card">
<p><strong>개발:</strong> .env.local 사용</p>
<p><strong>운영:</strong> 서버 환경 변수 또는 Secret Manager</p>
<p><strong>CI/CD:</strong> GitHub Secrets 또는 GitLab Variables</p>
</div>
</div>
</div>
</div>
<!-- Slide 14: Development Roadmap -->
<div class="slide">
<div class="slide-content">
<h2>개발 로드맵 (10-12주)</h2>
<table class="comparison-table">
<thead>
<tr>
<th>단계</th>
<th>기간</th>
<th>주요 작업</th>
<th>산출물</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>Phase 1</strong></td>
<td>W1-2</td>
<td>GCP 설정, Vertex AI Search 앱 생성, 샘플 문서 업로드</td>
<td>테스트용 데이터 스토어</td>
</tr>
<tr>
<td><strong>Phase 2</strong></td>
<td>W3-4</td>
<td>Laravel 백엔드 API 개발, 인증 구현</td>
<td>ChatController + API 엔드포인트</td>
</tr>
<tr>
<td><strong>Phase 3</strong></td>
<td>W5-6</td>
<td>프론트엔드 챗봇 UI 개발, 답변 표시, 참고자료 링크</td>
<td>챗봇 인터페이스</td>
</tr>
<tr>
<td><strong>Phase 4</strong></td>
<td>W7-8</td>
<td>전체 문서 업로드 및 인덱싱, 품질 테스트</td>
<td>프로덕션 데이터 스토어</td>
</tr>
<tr>
<td><strong>Phase 5</strong></td>
<td>W9</td>
<td>사용자 피드백 수집, 답변 품질 개선</td>
<td>베타 테스트 리포트</td>
</tr>
<tr>
<td><strong>Phase 6</strong></td>
<td>W10</td>
<td>인프라 확장 (4Core 8GB), DB 분리</td>
<td>스케일링 완료</td>
</tr>
<tr>
<td><strong>Phase 7</strong></td>
<td>W11</td>
<td>모니터링 및 로깅 시스템 구축</td>
<td>운영 대시보드</td>
</tr>
<tr>
<td><strong>Phase 8</strong></td>
<td>W12</td>
<td>정식 오픈, 운영 가이드 작성</td>
<td>프로덕션 런칭</td>
</tr>
</tbody>
</table>
</div>
</div>
<!-- Slide 15: 테스트 시나리오 -->
<div class="slide">
<div class="slide-content">
<h2>테스트 시나리오</h2>
<div style="margin-top: 30px;">
<h3>1. 문서 기반 질의응답</h3>
<table class="comparison-table">
<thead>
<tr>
<th>질문 예시</th>
<th>기대 결과</th>
</tr>
</thead>
<tbody>
<tr>
<td>"제품 A의 가격은 얼마인가요?"</td>
<td>제품 가격표 문서에서 정확한 가격 추출 및 답변</td>
</tr>
<tr>
<td>"반품 정책이 어떻게 되나요?"</td>
<td>반품 규정 문서 기반 상세 답변 + 링크</td>
</tr>
<tr>
<td>"Laravel 설치 방법 알려줘"</td>
<td>기술 문서에서 단계별 설치 가이드 제공</td>
</tr>
</tbody>
</table>
</div>
<div style="margin-top: 30px;">
<h3>2. 참조 자료 제공</h3>
<div class="info-card">
<p>모든 답변에 원본 문서 링크 포함</p>
<p>사용자가 상세 정보를 직접 확인할 수 있도록 지원</p>
</div>
</div>
<div style="margin-top: 30px;">
<h3>3. 다국어 지원 테스트</h3>
<ul>
<li>한국어 질문 → 한국어 문서 검색 → 한국어 답변</li>
<li>영어 질문 → 영어 문서 검색 → 영어 답변</li>
</ul>
</div>
<div style="margin-top: 30px;">
<h3>4. 답변 정확도 평가</h3>
<div class="feature-list">
<div class="feature-item">
<h4>✅ 정확도</h4>
<p>사실 기반 답변 90% 이상</p>
</div>
<div class="feature-item">
<h4>⏱️ 응답 속도</h4>
<p>평균 2-3초 이내</p>
</div>
<div class="feature-item">
<h4>📊 관련성</h4>
<p>질문과 답변 일치도 85% 이상</p>
</div>
</div>
</div>
</div>
</div>
<!-- Slide 16: KPI & Success Metrics -->
<div class="slide">
<div class="slide-content">
<h2>성공 지표 (KPI)</h2>
<table class="comparison-table">
<thead>
<tr>
<th>지표</th>
<th>목표</th>
<th>측정 방법</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>응답 정확도</strong></td>
<td>90% 이상</td>
<td>샘플 질문 100개 테스트, 사람이 정확도 평가</td>
</tr>
<tr>
<td><strong>평균 응답 시간</strong></td>
<td>3초 이내</td>
<td>API 응답 시간 모니터링</td>
</tr>
<tr>
<td><strong>고객 만족도</strong></td>
<td>85% 이상</td>
<td>답변 후 👍/👎 피드백 수집</td>
</tr>
<tr>
<td><strong>지원 티켓 감소</strong></td>
<td>50% 감소</td>
<td>챗봇 도입 전후 비교</td>
</tr>
<tr>
<td><strong>일일 활성 사용자</strong></td>
<td>100명</td>
<td>Google Analytics 추적</td>
</tr>
<tr>
<td><strong>문서 커버리지</strong></td>
<td>80% 이상</td>
<td>질문 중 문서에서 답변 가능한 비율</td>
</tr>
</tbody>
</table>
<div style="margin-top: 30px;">
<h3>ROI 분석</h3>
<div class="company-info">
<div class="info-card">
<h4>💰 비용 절감</h4>
<p>고객 지원 인력 50% 절감</p>
<p>월 $500 인건비 절약</p>
</div>
<div class="info-card">
<h4>⏱️ 시간 절약</h4>
<p>평균 응답 시간 30분 → 3초</p>
<p>고객 대기 시간 99% 감소</p>
</div>
<div class="info-card">
<h4>📈 만족도 향상</h4>
<p>즉각적 답변 제공</p>
<p>24/7 서비스 가능</p>
</div>
</div>
</div>
</div>
</div>
<!-- Slide 17: Thank You -->
<div class="slide">
<div class="slide-content">
<h1 style="font-size: 4em; margin-bottom: 40px;">감사합니다</h1>
<div style="text-align: center;">
<p style="font-size: 1.5em; color: #0066cc; margin-bottom: 30px;">장기적 AI 챗봇 솔루션 전략</p>
<p style="font-size: 1.2em; color: #00b8d4; margin-bottom: 40px;">Vertex AI Search 기반 지능형 문서 검색 시스템</p>
<div style="margin-top: 50px; padding: 30px; background: #e3f2fd; border-radius: 15px;">
<h3>프로젝트 요약</h3>
<div style="margin-top: 20px; text-align: left;">
<p><strong>🎯 목표:</strong> 노트북LM 수준의 자연어 질의응답 시스템 구축</p>
<p><strong>💰 비용:</strong> 월 $12.50 (Vertex AI Search) + $160 (인프라)</p>
<p><strong>⏱️ 기간:</strong> 10-12주</p>
<p><strong>📊 기대효과:</strong> 고객 지원 비용 50% 절감, 응답 시간 99% 단축</p>
</div>
</div>
<div style="margin-top: 40px; padding: 30px; background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%); border-radius: 15px;">
<h3 style="color: white;">문의 및 피드백</h3>
<p style="color: white; margin-top: 20px;">본 계획안에 대한 의견이나 추가 논의가 필요하신 경우</p>
<p style="color: white;">프로젝트 팀으로 연락 주시기 바랍니다.</p>
</div>
</div>
</div>
</div>
</div>
<div class="slide-number">
<span id="currentSlide">1</span> / <span id="totalSlides">17</span>
</div>
<div class="navigation">
<button class="nav-btn" id="prevBtn" onclick="changeSlide(-1)">← 이전</button>
<button class="nav-btn" id="nextBtn" onclick="changeSlide(1)">다음 →</button>
</div>
<script>
let currentSlide = 1;
const totalSlides = 17;
let touchStartX = 0;
let touchEndX = 0;
document.getElementById('totalSlides').textContent = totalSlides;
function showSlide(n) {
const slides = document.querySelectorAll('.slide');
if (n > totalSlides) {
currentSlide = 1;
}
if (n < 1) {
currentSlide = totalSlides;
}
slides.forEach(slide => {
slide.classList.remove('active');
});
slides[currentSlide - 1].classList.add('active');
document.getElementById('currentSlide').textContent = currentSlide;
document.getElementById('prevBtn').disabled = (currentSlide === 1);
document.getElementById('nextBtn').disabled = (currentSlide === totalSlides);
}
function changeSlide(direction) {
currentSlide += direction;
showSlide(currentSlide);
}
document.addEventListener('keydown', function(event) {
if (event.key === 'ArrowLeft') {
changeSlide(-1);
} else if (event.key === 'ArrowRight' || event.key === ' ') {
event.preventDefault();
changeSlide(1);
}
});
document.addEventListener('touchstart', function(event) {
touchStartX = event.changedTouches[0].screenX;
});
document.addEventListener('touchend', function(event) {
touchEndX = event.changedTouches[0].screenX;
handleSwipe();
});
function handleSwipe() {
if (touchEndX < touchStartX - 50) {
changeSlide(1);
}
if (touchEndX > touchStartX + 50) {
changeSlide(-1);
}
}
showSlide(currentSlide);
</script>
</body>
</html>