# SAM AI 관리 종합 가이드

> **작성일**: 2026-03-03
> **상태**: 확정
> **대상 독자**: SAM 프로젝트에 투입되는 모든 개발자

---

## 1. 개요

### 1.1 목적

SAM 시스템에서 사용하는 AI 서비스(Google Gemini, Anthropic Claude, OpenAI)의 **설정 구조, 호출 흐름, 모델 관리, 비용 추적**을 한눈에 파악할 수 있는 종합 가이드다.

### 1.2 현재 상태 (2026-03-03)

| Provider | 모델 | 용도 | 상태 |
|----------|------|------|------|
| **Google Gemini** | `gemini-2.5-flash` | 명함 OCR, 사업자등록증 OCR, 재무 리포트, 회의 요약, 동영상 스크립트 | ✅ 운영 중 |
| Anthropic Claude | `claude-sonnet-4-20250514` | AI 재무 분석 (예비) | 🟡 코드 준비 |
| OpenAI | `gpt-4o` | 범용 AI (예비) | 🟡 코드 준비 |
| Google Cloud STT | Chirp 2 | 음성 녹음 → 텍스트 변환 | ✅ 운영 중 |
| Google Cloud Storage | Standard | 음성 파일 백업 | ✅ 운영 중 |

---

## 2. 아키텍처

### 2.1 설정 흐름도

```
┌─────────────────────────────────────────────────────────────┐
│  .env 파일 (환경별 4곳)                                      │
│  ┌───────────────────────────────────────────┐              │
│  │ GEMINI_API_KEY=AIzaSy...                  │              │
│  │ GEMINI_MODEL=gemini-2.5-flash             │ ← ① 핵심    │
│  │ GEMINI_BASE_URL=https://...googleapis...  │              │
│  └───────────────────────────────────────────┘              │
└────────────────────────┬────────────────────────────────────┘
                         ↓
┌─────────────────────────────────────────────────────────────┐
│  config/services.php                                         │
│  ┌───────────────────────────────────────────┐              │
│  │ 'gemini' => [                             │              │
│  │   'model' => env('GEMINI_MODEL',          │              │
│  │              'gemini-2.5-flash'),          │ ← ② fallback│
│  │ ]                                         │              │
│  └───────────────────────────────────────────┘              │
└────────────────────────┬────────────────────────────────────┘
                         ↓
┌─────────────────────────────────────────────────────────────┐
│  AiConfig::getActiveGemini()                                 │
│  ┌───────────────────────────────────────────┐              │
│  │ config('services.gemini.model',           │              │
│  │        'gemini-2.5-flash')                │ ← ③ fallback│
│  └───────────────────────────────────────────┘              │
└────────────────────────┬────────────────────────────────────┘
                         ↓
┌─────────────────────────────────────────────────────────────┐
│  서비스 클래스 (실제 API 호출)                                 │
│  ┌─────────────────────────────────────────────────────┐    │
│  │ BusinessCardOcrService    → AiConfig::getActiveGemini│    │
│  │ TradingPartnerOcrService  → AiConfig::getActiveGemini│    │
│  │ AiReportService (API)     → config('services.gemini')│    │
│  │ GeminiScriptService       → AiConfig::getActiveGemini│    │
│  │ NotionService             → AiConfig::getActiveGemini│    │
│  └─────────────────────────────────────────────────────┘    │
└─────────────────────────────────────────────────────────────┘
```

> **핵심**: `.env`의 `GEMINI_MODEL` 값만 바꾸면 전체 서비스가 새 모델을 사용한다.

### 2.2 프로젝트별 역할

| 프로젝트 | AI 관련 역할 |
|----------|-------------|
| **MNG** | 명함 OCR, 사업자등록증 OCR, 동영상 스크립트, AI 설정 관리 UI, 토큰 사용량 조회 |
| **API** | 재무 AI 리포트 생성, 토큰 사용량 저장, AI 가격 설정 |
| **React** | AI 기능 없음 (Google Maps만 사용) |

---

## 3. 환경변수 설정

### 3.1 Gemini AI 설정

```env
# ─── Google Gemini AI ───
GEMINI_API_KEY=AIzaSy...               # Google AI Studio에서 발급
GEMINI_MODEL=gemini-2.5-flash          # 사용할 모델명
GEMINI_BASE_URL=https://generativelanguage.googleapis.com/v1beta
GEMINI_PROJECT_ID=codebridge-chatbot   # GCP 프로젝트 ID
```

### 3.2 환경별 .env 위치

| 환경 | API 경로 | MNG 경로 |
|------|---------|---------|
| 로컬 (Docker) | `/home/aweso/sam/api/.env` | `/home/aweso/sam/mng/.env` |
| 개발서버 | `/home/webservice/api/.env` | `/home/webservice/mng/.env` |
| 운영서버 | `/home/webservice/api/.env` | `/home/webservice/mng/.env` |

> API와 MNG는 같은 `GEMINI_MODEL` 값을 사용해야 한다.

---

## 4. 서비스별 AI 호출 매핑

### 4.1 MNG 프로젝트

| 서비스 | 파일 | 용도 | 설정 소스 |
|--------|------|------|----------|
| 명함 OCR | `app/Services/BusinessCardOcrService.php` | 명함 이미지 → 연락처 정보 추출 | `AiConfig::getActiveGemini()` |
| 사업자등록증 OCR | `app/Services/TradingPartnerOcrService.php` | 사업자등록증 → 거래처 정보 추출 | `AiConfig::getActiveGemini()` |
| 동영상 스크립트 | `app/Services/Video/GeminiScriptService.php` | 영상 자막/스크립트 생성 | `AiConfig::getActiveGemini()` |
| Notion 연동 | `app/Services/NotionService.php` | Notion 콘텐츠 AI 분석 | `AiConfig::getActiveGemini()` |

### 4.2 API 프로젝트

| 서비스 | 파일 | 용도 | 설정 소스 |
|--------|------|------|----------|
| 재무 AI 리포트 | `app/Services/AiReportService.php` | 지출/매출/매입 데이터 AI 분석 | `config('services.gemini')` |

### 4.3 공통 유틸

| 파일 | 역할 |
|------|------|
| `mng/app/Helpers/AiTokenHelper.php` | 토큰 사용량 저장 (Gemini, Claude, GCS, STT) |
| `mng/app/Models/System/AiConfig.php` | AI 설정 모델 (Provider별 활성 설정 조회) |
| `mng/app/Models/System/AiPricingConfig.php` | 토큰 단가 설정 (비용 계산) |
| `mng/app/Models/System/AiTokenUsage.php` | 토큰 사용 이력 |

---

## 5. 관리 화면

### 5.1 AI 설정 관리

- **URL**: `/system/ai-config`
- **기능**: Provider별 API 키, 모델명, Base URL 관리 / 연결 테스트 / 활성화 토글
- **컨트롤러**: `app/Http/Controllers/System/AiConfigController.php`

### 5.2 AI 토큰 사용량

- **URL**: `/system/ai-token-usage`
- **기능**: 일별/메뉴별 토큰 사용량 조회 / 비용(USD, KRW) 통계 / 단가 설정
- **컨트롤러**: `app/Http/Controllers/System/AiTokenUsageController.php`

### 5.3 Google Cloud AI 가이드

- **URL**: `/google-cloud/ai-guide`
- **기능**: SAM에서 사용하는 Google AI 서비스 전체 현황 / 아키텍처 다이어그램

---

## 6. 모델 변경 이력 (버전 관리)

| 날짜 | 변경 내용 | 이유 | 영향 범위 |
|------|----------|------|----------|
| 2026-01-27 | 최초 설정: `gemini-2.0-flash` | SAM AI 기능 도입 | 전체 |
| **2026-03-03** | **`gemini-2.0-flash` → `gemini-2.5-flash`** | **Google 2026-06-01 서비스 종료 예고** | **전체** |

### 2026-03-03 변경 상세

**배경**: Google이 2026년 6월 1일부로 Gemini 2.0 Flash 모델 서비스를 종료한다는 통보를 함.

**수정된 파일 (코드)**:

| 프로젝트 | 파일 | 변경 내용 |
|----------|------|----------|
| API | `config/services.php` | fallback 기본값 변경 |
| API | `app/Services/AiReportService.php` | fallback 기본값 변경 |
| MNG | `config/services.php` | fallback 기본값 변경 |
| MNG | `app/Models/System/AiConfig.php` | DEFAULT_MODELS 상수 + getActiveGemini() fallback 변경 |
| MNG | `app/Services/NotionService.php` | fallback 기본값 변경 |
| MNG | `resources/views/system/ai-config/index.blade.php` | UI placeholder/기본값 변경 |
| MNG | `resources/views/google-cloud/ai-guide/index.blade.php` | 서비스 현황 모델명 변경 |
| MNG | `resources/views/academy/env-management.blade.php` | 환경 변수 예시 변경 |

**수정된 .env (환경별)**:

| 환경 | 수정 대상 | 담당 |
|------|----------|------|
| 로컬 api/.env | `GEMINI_MODEL=gemini-2.5-flash` | ✅ 완료 |
| 로컬 mng/.env | `GEMINI_MODEL=gemini-2.5-flash` | ✅ 완료 |
| 개발서버 api, mng | `GEMINI_MODEL=gemini-2.5-flash` | 배포 후 SSH 수정 필요 |
| 운영서버 api, mng | `GEMINI_MODEL=gemini-2.5-flash` | 개발팀장 직접 수정 |

**수정하지 않은 파일 (의도적)**:

| 파일 | 이유 |
|------|------|
| `api/database/migrations/` (3개) | 이미 실행 완료된 마이그레이션 — 변경 금지 |
| `cloud-api-pricing/index.blade.php` | `2.0 → 2.5` 마이그레이션 안내 UI — 이전 모델명이 의도적 |

---

## 7. 모델 업데이트 워크플로우

> 상세 절차: [ai-model-update-workflow.md](./ai-model-update-workflow.md)

### 7.1 요약 (7단계)

```
① 사전 확인     — 새 모델명, API 호환성, 가격 확인
② 로컬 테스트   — .env 수정 → config:clear → 연결 테스트
③ 코드 업데이트  — fallback 기본값 5곳 + 뷰 파일
④ 개발서버 배포  — 코드 push + .env 수정 + 기능 테스트
⑤ 단가 설정     — MNG 관리 화면에서 새 모델 단가 추가
⑥ 운영서버 배포  — cherry-pick + .env 수정 (개발팀장)
⑦ 사후 모니터링  — 토큰 로그 확인 + 에러 로그 감시 (1일)
```

### 7.2 긴급 롤백

```bash
# .env만 이전 모델로 변경 (코드 배포 불필요)
GEMINI_MODEL=gemini-2.0-flash
php artisan config:clear
```

---

## 8. 비용 관리

### 8.1 토큰 단가 (ai_pricing_configs)

| 모델 | 입력 ($/1M tokens) | 출력 ($/1M tokens) | 비고 |
|------|-------------------|--------------------|------|
| gemini-2.5-flash | 0.15 | 0.60 | 2026-03-03~ |
| gemini-2.0-flash | 0.10 | 0.40 | ~2026-06-01 종료 예정 |

> 단가는 MNG `/system/ai-token-usage` → 단가 설정에서 관리

### 8.2 비용 계산 흐름

```
API 호출 → 응답의 usageMetadata에서 토큰 수 추출
  ↓
AiTokenHelper::saveGeminiUsage()
  ↓
ai_pricing_configs에서 단가 조회 (캐시 60분)
  ↓
ai_token_usages 테이블에 기록 (토큰 수, USD, KRW)
```

---

## 9. 신규 개발자 온보딩 체크리스트

AI 관련 작업을 시작하기 전:

- [ ] 이 문서 전체 읽기
- [ ] 로컬 `.env`에 `GEMINI_API_KEY`, `GEMINI_MODEL` 설정 확인
- [ ] MNG `/system/ai-config` 화면에서 연결 테스트 성공 확인
- [ ] AI 호출 서비스 파일 위치 파악 (섹션 4 참조)
- [ ] `AiConfig::getActiveGemini()` 사용법 이해
- [ ] `AiTokenHelper::saveGeminiUsage()` 로 토큰 추적하는 패턴 이해

### 새 AI 기능 추가 시

```php
// 1. AiConfig에서 활성 설정 가져오기
$config = AiConfig::getActiveGemini();
if (!$config) throw new \RuntimeException('Gemini API 설정이 없습니다.');

// 2. API 호출
$url = "{$config->base_url}/models/{$config->model}:generateContent?key={$config->api_key}";
$response = Http::timeout(30)->post($url, [ ... ]);

// 3. 토큰 사용량 기록
AiTokenHelper::saveGeminiUsage(
    $response->json()['usageMetadata'] ?? [],
    $config->model,
    '메뉴명'
);
```

---

## 관련 문서

| 문서 | 경로 | 설명 |
|------|------|------|
| AI 설정 기술문서 | `docs/guides/ai-config-settings.md` | DB 구조, 메서드, 코드 예시 |
| 모델 업데이트 워크플로우 | `docs/guides/ai-model-update-workflow.md` | 모델 변경 시 Step-by-Step 절차 |
| 변경 이력 | `docs/changes/20260303_gemini_model_upgrade.md` | 2.0→2.5 마이그레이션 상세 기록 |

---

**최종 업데이트**: 2026-03-03
