# AI 견적서 자동생성 엔진 개발 계획 > **작성일**: 2026-03-02 > **상태**: 기획 초안 > **프로젝트**: SAM API + MNG > **우선순위**: 🔴 필수 > **참조**: `docs/features/ai/README.md`, `docs/features/quotes/README.md`, `docs/rules/customer-pricing.md` --- ## 1. 개요 ### 1.1 목적 SAM 계약 완료 후 매니저가 고객사 직원과 인터뷰를 진행할 때, **인터뷰 내용을 AI가 분석하여 SAM 표준 견적서 형태로 자동 변환**하는 엔진을 구축한다. 현재 매니저가 수동으로 수행하는 프로세스: ``` ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ SAM 계약 │ → │ 현장 인터뷰 │ → │ 업무 파악 │ → │ 견적서 작성 │ │ 완료 │ │ (매니저+직원)│ │ (수동 정리) │ │ (수동 작성) │ └──────────────┘ └──────────────┘ └──────────────┘ └──────────────┘ ``` AI 엔진 도입 후: ``` ┌──────────────┐ ┌──────────────┐ ┌──────────────────────┐ ┌──────────────┐ │ SAM 계약 │ → │ 현장 인터뷰 │ → │ AI 엔진 │ → │ 견적서 초안 │ │ 완료 │ │ (매니저+직원)│ │ (음성/텍스트 분석) │ │ (자동 생성) │ │ │ │ │ │ (업무 매핑) │ │ (매니저 확인)│ └──────────────┘ └──────────────┘ └──────────────────────┘ └──────────────┘ ``` ### 1.2 핵심 원칙 | 원칙 | 설명 | |------|------| | **자체 AI 엔진** | Claude API 기반으로 SAM 전용 AI 서비스 구축 | | **기존 인프라 활용** | `ai_configs`, `ai_token_usages`, `ai_pricing_configs` 테이블 재사용 | | **견적 시스템 연동** | 기존 `quotes`, `quote_items` 테이블과 직접 연동 | | **Multi-tenant** | 모든 데이터에 `tenant_id` 격리 적용 | | **점진적 확장** | Phase 1 텍스트 → Phase 2 음성 (STT 구현 완료, 통합만 필요) → Phase 3 학습 고도화 | ### 1.3 기존 인프라 현황 #### AI 인프라 (구축 완료) | 구성요소 | 상태 | 비고 | |---------|------|------| | `ai_configs` 테이블 | ✅ 완료 | Claude provider 설정 가능 | | `ai_token_usages` 테이블 | ✅ 완료 | 토큰/비용 자동 추적 | | `ai_pricing_configs` 테이블 | ✅ 완료 | Claude 모델 단가 등록 | | `AiTokenHelper` | ✅ 완료 | `saveClaudeUsage()` 메서드 존재 | | MNG AI 설정 UI | ✅ 완료 | `/system/ai-config` | #### 견적 시스템 (구축 완료) | 구성요소 | 상태 | 비고 | |---------|------|------| | `quotes` 테이블 | ✅ 완료 | 견적 마스터 | | `quote_items` 테이블 | ✅ 완료 | 견적 품목 상세 | | `QuoteService` | ✅ 완료 | 견적 CRUD, 상태 관리 | | `QuoteCalculationService` | ✅ 완료 | BOM 10단계 계산 | | 견적 API 엔드포인트 | ✅ 완료 | REST API 전체 | #### 음성 녹음/STT (구축 완료) | 구성요소 | 상태 | 비고 | |---------|------|------| | `ai_voice_recordings` 테이블 | ✅ 완료 | DB 스키마 + CRUD | | GCS 업로드 | ✅ 완료 | `GoogleCloudService` — GCS 저장/조회/삭제 | | Google Cloud STT 변환 | ✅ 완료 | `GoogleCloudService::speechToText()` — LongRunningRecognize, ko-KR | | Web Speech API (브라우저 STT) | ✅ 완료 | `voice-recorder.blade.php` — 실시간 음성→텍스트 (무료) | | STT + Gemini AI 분석 | ✅ 완료 | `AiVoiceRecordingService` — 음성→STT→AI 분석 파이프라인 | | 화자 분리 (Diarization) | ✅ 완료 | `MeetingMinuteService` — Speaker Diarization | | 영업 상담 음성 녹음 | ✅ 완료 | `ConsultationController` — MediaRecorder + STT + GCS 백업 | > **참조 구현 파일:** > - `mng/app/Services/GoogleCloudService.php` — Google Cloud STT/GCS 통합 서비스 > - `mng/app/Services/AiVoiceRecordingService.php` — STT + Gemini 분석 > - `mng/app/Services/MeetingMinuteService.php` — 회의록 STT + 화자분리 > - `mng/app/Http/Controllers/Sales/ConsultationController.php` — 영업 상담 음성 > - `mng/resources/views/sales/modals/voice-recorder.blade.php` — 브라우저 음성 녹음 UI > - `docs/features/voice-input-stt-guide.md` — STT 기술 가이드 --- ## 📍 현재 진행 상태 | 항목 | 내용 | |------|------| | **마지막 완료 작업** | 기획 초안 작성 | | **다음 작업** | Phase 1 상세 설계 → 구현 | | **진행률** | 0/4 Phase (0%) | | **마지막 업데이트** | 2026-03-02 | --- ## 2. 시스템 아키텍처 ### 2.1 전체 구조 ``` ┌─────────────────────────────────────────────────────────────────┐ │ SAM AI 견적 엔진 │ ├─────────────────────────────────────────────────────────────────┤ │ │ │ ┌───────────────┐ ┌───────────────────────┐ │ │ │ 입력 채널 │ │ AI 분석 파이프라인 │ │ │ │ │ │ │ │ │ │ 📝 텍스트 │───→│ 1. 인터뷰 전처리 │ │ │ │ 🎤 음성(P2) │ │ 2. 업무 도메인 분류 │ │ │ │ 📄 문서(P3) │ │ 3. SAM 모듈 매핑 │ │ │ └───────────────┘ │ 4. 견적 항목 추출 │ │ │ │ 5. 금액 산출 │ │ │ └──────────┬────────────┘ │ │ │ │ │ ▼ │ │ ┌───────────────────────────────────────────────┐ │ │ │ 견적서 생성기 │ │ │ │ │ │ │ │ SAM 표준 모듈 카탈로그 ←──→ Claude API │ │ │ │ 고객 요금 정책 ←──→ 프롬프트 엔진 │ │ │ │ 기존 견적 템플릿 ←──→ 결과 파서 │ │ │ └──────────────────────┬────────────────────────┘ │ │ │ │ │ ▼ │ │ ┌───────────────────────────────────────────────┐ │ │ │ 출력 │ │ │ │ │ │ │ │ 📊 견적서 초안 (quotes 테이블) │ │ │ │ 📋 업무 분석 리포트 │ │ │ │ 💡 추천 모듈 목록 │ │ │ └───────────────────────────────────────────────┘ │ │ │ └─────────────────────────────────────────────────────────────────┘ ``` ### 2.2 Claude API 연동 구조 ``` ┌──────────────────┐ ┌──────────────────┐ │ SAM API Server │ │ Claude API │ │ (Laravel) │ │ (Anthropic) │ │ │ │ │ │ AiQuotation │ ──HTTP──→ Messages API │ │ Service │ ←─JSON── (claude-sonnet) │ │ │ │ │ │ ┌────────────┐ │ │ System Prompt: │ │ │ Prompt │ │ │ - SAM 모듈 목록 │ │ │ Engine │ │ │ - 요금 정책 │ │ │ │ │ │ - 견적 구조 │ │ │ - 모듈목록 │ │ │ - 출력 형식 │ │ │ - 요금표 │ │ │ │ │ │ - 템플릿 │ │ │ │ │ └────────────┘ │ │ │ └──────────────────┘ └──────────────────┘ ``` ### 2.3 데이터 흐름 ``` 매니저 인터뷰 입력 │ ▼ ┌──────────────────────────────────────────────────┐ │ Step 1: 인터뷰 전처리 │ │ - 텍스트 정규화 (불필요한 표현 제거) │ │ - 핵심 키워드 추출 │ │ - 업무 도메인 태깅 │ └──────────────────────┬───────────────────────────┘ ▼ ┌──────────────────────────────────────────────────┐ │ Step 2: Claude API 1차 호출 — 업무 분석 │ │ - 고객사 업종/규모 파악 │ │ - 현재 업무 프로세스 분석 │ │ - 디지털화 필요 영역 식별 │ │ - Pain Point 도출 │ │ 출력: 구조화된 업무 분석 JSON │ └──────────────────────┬───────────────────────────┘ ▼ ┌──────────────────────────────────────────────────┐ │ Step 3: SAM 모듈 매핑 │ │ - 업무 분석 결과 ↔ SAM 모듈 카탈로그 대조 │ │ - 필수/선택 모듈 분류 │ │ - 사용자 수, 데이터량 추정 │ │ 출력: 추천 모듈 목록 + 근거 │ └──────────────────────┬───────────────────────────┘ ▼ ┌──────────────────────────────────────────────────┐ │ Step 4: Claude API 2차 호출 — 견적 생성 │ │ - SAM 요금 정책 적용 │ │ - 모듈별 개발비 + 월 구독료 계산 │ │ - 추가 옵션 (AI 토큰, 저장공간) 산출 │ │ - 할인 정책 적용 (통합 패키지 등) │ │ 출력: 견적서 JSON (SAM 표준 형식) │ └──────────────────────┬───────────────────────────┘ ▼ ┌──────────────────────────────────────────────────┐ │ Step 5: 견적서 초안 저장 │ │ - quotes 테이블에 저장 (status: draft) │ │ - quote_items에 모듈별 항목 저장 │ │ - 업무 분석 리포트 첨부 │ │ - 매니저에게 알림 → 검토/수정 → 확정 │ └──────────────────────────────────────────────────┘ ``` --- ## 3. SAM 모듈 카탈로그 (AI 프롬프트용) > **참조**: `docs/rules/customer-pricing.md` AI가 인터뷰 내용을 SAM 견적으로 변환하려면, SAM이 제공하는 모듈과 요금을 정확히 알아야 한다. 이 데이터는 **DB 테이블로 관리**하여 프롬프트에 동적 주입한다. ### 3.1 모듈 카탈로그 테이블 설계 ```sql CREATE TABLE ai_quotation_modules ( id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY, tenant_id BIGINT UNSIGNED NOT NULL, module_code VARCHAR(50) NOT NULL, -- 'HR', 'SALES', 'FINANCE' 등 module_name VARCHAR(100) NOT NULL, -- '인사관리', '영업관리', '재무관리' category ENUM('basic', 'individual', 'addon') NOT NULL, description TEXT, -- 모듈 기능 설명 keywords JSON, -- AI 매핑용 키워드 목록 dev_cost DECIMAL(12,0) DEFAULT 0, -- 개발비 (원) monthly_fee DECIMAL(10,0) DEFAULT 0, -- 월 구독료 (원) is_active BOOLEAN DEFAULT TRUE, sort_order INT DEFAULT 0, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, INDEX idx_tenant (tenant_id), INDEX idx_category (category), UNIQUE KEY uk_tenant_module (tenant_id, module_code) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; ``` ### 3.2 초기 데이터 (customer-pricing.md 기준) | module_code | module_name | category | dev_cost | monthly_fee | |-------------|-------------|----------|----------|-------------| | `BASIC_PKG` | 기본 패키지 (인사+근태+급여+게시판) | basic | 5,000,000 | 200,000 | | `HR` | 인사관리 | individual | 2,000,000 | 80,000 | | `ATTENDANCE` | 근태관리 | individual | 1,500,000 | 60,000 | | `PAYROLL` | 급여관리 | individual | 2,500,000 | 100,000 | | `BOARD` | 게시판/공지사항 | individual | 500,000 | 20,000 | | `SALES` | 영업관리 (CRM+견적+수주) | individual | 5,000,000 | 150,000 | | `PURCHASE` | 구매/자재관리 | individual | 3,000,000 | 100,000 | | `PRODUCTION` | 생산관리 (MES) | individual | 8,000,000 | 250,000 | | `QUALITY` | 품질관리 | individual | 4,000,000 | 120,000 | | `FINANCE` | 재무/회계관리 | individual | 5,000,000 | 150,000 | | `LOGISTICS` | 물류/출하관리 | individual | 3,000,000 | 100,000 | | `APPROVAL` | 전자결재 | individual | 3,000,000 | 80,000 | | `DOCUMENT` | 문서관리 (전자서명) | individual | 2,000,000 | 60,000 | | `EQUIPMENT` | 설비관리 | individual | 3,000,000 | 100,000 | | `INTEGRATED` | 통합 패키지 | basic | 30,000,000 | 800,000 | | `AI_TOKEN` | AI 토큰 추가 | addon | 0 | 별도 | | `STORAGE` | 파일 저장공간 추가 | addon | 0 | 별도 | | `CUSTOM_DEV` | 커스텀 개발 | addon | 별도 협의 | 0 | ### 3.3 keywords 필드 예시 ```json // HR 모듈 { "keywords": ["직원", "사원", "인사", "조직도", "부서", "입퇴사", "인력"], "pain_points": ["엑셀로 직원 관리", "입퇴사 관리가 번거로움", "조직도 없음"], "business_needs": ["직원 정보 통합", "조직 구조 관리", "인력 현황 파악"] } // PRODUCTION 모듈 { "keywords": ["생산", "제조", "작업지시", "공정", "LOT", "불량", "MES"], "pain_points": ["생산 현황을 수기로 기록", "불량 추적 불가", "납기 관리 어려움"], "business_needs": ["실시간 생산현황", "불량률 관리", "작업지시 자동화"] } ``` --- ## 4. AI 프롬프트 엔진 ### 4.1 시스템 프롬프트 구조 ``` ┌─────────────────────────────────────────────────────┐ │ System Prompt │ ├─────────────────────────────────────────────────────┤ │ │ │ [역할 정의] │ │ 너는 SAM ERP/MES 솔루션의 컨설팅 AI이다. │ │ 고객 인터뷰를 분석하여 맞춤형 견적서를 작성한다. │ │ │ │ [SAM 모듈 카탈로그] ← DB에서 동적 로드 │ │ 각 모듈의 기능, 키워드, 가격 정보 │ │ │ │ [요금 정책] ← customer-pricing 기반 │ │ 기본패키지, 개별모듈, 추가옵션 요금 체계 │ │ 할인 정책 (통합 패키지 할인 등) │ │ │ │ [출력 형식] │ │ JSON Schema 명시 (견적서 구조) │ │ │ │ [분석 지침] │ │ - 고객 업종/규모별 권장 모듈 기준 │ │ - 우선순위 결정 기준 (필수 vs 선택) │ │ - 비용 최적화 원칙 (패키지 vs 개별) │ │ │ └─────────────────────────────────────────────────────┘ ``` ### 4.2 프롬프트 템플릿 (1차: 업무 분석) ``` 당신은 SAM(Smart Automation Management) ERP/MES 솔루션의 전문 컨설턴트입니다. 아래는 고객사 직원과의 인터뷰 내용입니다. 이를 분석하여 구조화된 업무 분석 보고서를 작성하세요. ## 고객 정보 - 회사명: {company_name} - 업종: {industry} - 직원 수: {employee_count} - 인터뷰 대상: {interviewee_role} ## 인터뷰 내용 {interview_content} ## 분석 기준 다음 SAM 모듈 영역에 맞춰 분석하세요: {module_catalog_json} ## 출력 형식 (JSON) { "company_analysis": { "industry": "업종 분류", "scale": "소규모/중소/중견", "current_systems": ["현재 사용 중인 시스템"], "digitalization_level": "상/중/하" }, "business_domains": [ { "domain": "인사/급여", "current_process": "현재 처리 방식 설명", "pain_points": ["문제점 1", "문제점 2"], "improvement_needs": ["개선 필요사항"], "priority": "필수/높음/보통/낮음", "matched_modules": ["HR", "PAYROLL"] } ], "recommendations": { "essential_modules": ["반드시 필요한 모듈 코드"], "recommended_modules": ["권장 모듈 코드"], "optional_modules": ["선택 모듈 코드"], "package_suggestion": "BASIC_PKG 또는 INTEGRATED 또는 individual", "reasoning": "패키지 추천 근거" } } ``` ### 4.3 프롬프트 템플릿 (2차: 견적 생성) ``` 아래 업무 분석 결과를 바탕으로 SAM 견적서를 생성하세요. ## 업무 분석 결과 {analysis_result_json} ## SAM 요금 정책 {pricing_policy_json} ## 견적 생성 규칙 1. 필수 모듈은 반드시 포함 2. 통합 패키지가 개별 합산보다 저렴하면 패키지 추천 3. 직원 수 기반 사용자 라이선스 산출 4. AI 토큰은 월 기본 100만 토큰 포함, 초과분 별도 5. 파일 저장공간은 기본 10GB, 초과분 별도 ## 출력 형식 (JSON) { "quotation": { "title": "견적서 제목", "client_name": "고객사명", "valid_until": "견적 유효기간", "items": [ { "category": "기본서비스/추가모듈/추가옵션", "module_code": "모듈코드", "module_name": "모듈명", "description": "포함 기능 설명", "dev_cost": 0, "monthly_fee": 0, "quantity": 1, "note": "비고" } ], "summary": { "total_dev_cost": 0, "total_monthly_fee": 0, "discount_type": "패키지할인/볼륨할인/없음", "discount_rate": 0, "final_dev_cost": 0, "final_monthly_fee": 0 }, "implementation_plan": { "estimated_months": 0, "phases": [ { "phase": 1, "name": "단계명", "modules": ["모듈코드"], "duration_weeks": 0 } ] }, "analysis_summary": "업무 분석 요약 (고객 설명용)" } } ``` --- ## 5. API 설계 ### 5.1 엔드포인트 | Method | Path | 설명 | |--------|------|------| | `POST` | `/api/v1/ai/quotation/analyze` | 인터뷰 분석 (1차) | | `POST` | `/api/v1/ai/quotation/generate` | 견적서 생성 (2차) | | `POST` | `/api/v1/ai/quotation/generate-full` | 분석+생성 통합 (원스텝) | | `GET` | `/api/v1/ai/quotation/{id}` | AI 견적 상세 조회 | | `GET` | `/api/v1/ai/quotation` | AI 견적 목록 | | `PUT` | `/api/v1/ai/quotation/{id}` | AI 견적 수정 (매니저) | | `POST` | `/api/v1/ai/quotation/{id}/confirm` | 정식 견적으로 전환 | | `DELETE` | `/api/v1/ai/quotation/{id}` | AI 견적 삭제 | ### 5.2 요청/응답 예시 #### POST `/api/v1/ai/quotation/analyze` **Request:** ```json { "client_id": 15, "client_name": "(주)대한기계", "industry": "기계제조업", "employee_count": 45, "interviewee_role": "관리부 팀장", "interview_content": "현재 직원 관리는 엑셀로 하고 있어요. 출퇴근도 수기로 기록하고... 영업팀에서는 견적서를 한글 프로그램으로 만들어서 이메일로 보내는데, 이력 관리가 안 돼요. 생산 현장에서는 작업일보를 종이에 쓰고 있고, 불량이 나면 어디서 발생했는지 추적이 안 됩니다. 재고도 실사를 해봐야 알 수 있어요...", "interview_type": "text" } ``` **Response:** ```json { "success": true, "data": { "id": 1, "analysis": { "company_analysis": { "industry": "기계제조업", "scale": "중소기업 (45명)", "current_systems": ["엑셀", "한글 프로그램", "종이 문서"], "digitalization_level": "하" }, "business_domains": [ { "domain": "인사/급여", "current_process": "엑셀로 직원 관리, 수기 출퇴근 기록", "pain_points": ["인사정보 분산", "출퇴근 수기 기록"], "priority": "필수", "matched_modules": ["HR", "ATTENDANCE", "PAYROLL"] }, { "domain": "영업관리", "current_process": "한글 프로그램 견적서, 이메일 발송", "pain_points": ["견적 이력 관리 불가", "영업 현황 파악 어려움"], "priority": "높음", "matched_modules": ["SALES"] }, { "domain": "생산관리", "current_process": "종이 작업일보, 수동 불량 관리", "pain_points": ["불량 추적 불가", "생산현황 실시간 파악 불가"], "priority": "필수", "matched_modules": ["PRODUCTION", "QUALITY"] }, { "domain": "재고/물류", "current_process": "실사로만 재고 파악", "pain_points": ["실시간 재고 파악 불가"], "priority": "높음", "matched_modules": ["PURCHASE", "LOGISTICS"] } ], "recommendations": { "essential_modules": ["HR", "ATTENDANCE", "PAYROLL", "PRODUCTION", "QUALITY"], "recommended_modules": ["SALES", "PURCHASE", "LOGISTICS"], "optional_modules": ["APPROVAL", "DOCUMENT"], "package_suggestion": "INTEGRATED", "reasoning": "8개 이상 모듈이 필요하므로 통합 패키지(30,000,000원)가 개별 합산(34,500,000원)보다 경제적" } }, "token_usage": { "prompt_tokens": 1250, "completion_tokens": 890, "cost_krw": 45 } } } ``` ### 5.3 컨트롤러 / 서비스 구조 ``` app/Http/Controllers/Api/V1/ └── AiQuotationController.php ├── analyze() ← 인터뷰 분석 ├── generate() ← 견적 생성 ├── generateFull() ← 통합 (분석+생성) ├── index() ← 목록 ├── show() ← 상세 ├── update() ← 수정 ├── confirm() ← 정식 견적 전환 └── destroy() ← 삭제 app/Services/ └── AiQuotationService.php ├── analyzeInterview() ← 1차: 인터뷰 분석 ├── generateQuotation() ← 2차: 견적 생성 ├── generateFull() ← 통합 처리 ├── confirmToQuote() ← quotes 테이블로 전환 │ ├── buildAnalysisPrompt() ← 분석 프롬프트 조립 ├── buildQuotationPrompt() ← 견적 프롬프트 조립 ├── loadModuleCatalog() ← DB에서 모듈 카탈로그 로드 ├── loadPricingPolicy() ← DB에서 요금 정책 로드 ├── callClaudeApi() ← Claude API 호출 ├── parseResponse() ← 응답 JSON 파싱 └── saveTokenUsage() ← 토큰 사용량 기록 app/Http/Requests/V1/AiQuotation/ ├── AiQuotationAnalyzeRequest.php ├── AiQuotationGenerateRequest.php ├── AiQuotationUpdateRequest.php └── AiQuotationConfirmRequest.php ``` --- ## 6. 데이터베이스 설계 ### 6.1 신규 테이블 #### ai_quotations (AI 견적 마스터) ```sql CREATE TABLE ai_quotations ( id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY, tenant_id BIGINT UNSIGNED NOT NULL, -- 고객 정보 client_id BIGINT UNSIGNED NULL, client_name VARCHAR(200) NOT NULL, industry VARCHAR(100) NULL, employee_count INT NULL, interviewee_role VARCHAR(100) NULL, -- 인터뷰 데이터 interview_content TEXT NOT NULL, interview_type ENUM('text', 'voice', 'document') DEFAULT 'text', voice_recording_id BIGINT UNSIGNED NULL, -- ai_voice_recordings 참조 -- AI 분석 결과 analysis_result JSON NULL, -- 1차 분석 결과 quotation_result JSON NULL, -- 2차 견적 결과 -- 상태 관리 status ENUM('analyzing', 'analyzed', 'generating', 'generated', 'confirmed', 'failed') DEFAULT 'analyzing', error_message TEXT NULL, -- 연결 quote_id BIGINT UNSIGNED NULL, -- 정식 견적 전환 시 quotes.id -- 금액 요약 total_dev_cost DECIMAL(12,0) DEFAULT 0, total_monthly_fee DECIMAL(10,0) DEFAULT 0, discount_rate DECIMAL(5,2) DEFAULT 0, final_dev_cost DECIMAL(12,0) DEFAULT 0, final_monthly_fee DECIMAL(10,0) DEFAULT 0, -- 토큰 사용 total_tokens INT DEFAULT 0, total_cost_krw DECIMAL(12,2) DEFAULT 0, -- 감사 created_by BIGINT UNSIGNED NULL, updated_by BIGINT UNSIGNED NULL, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, deleted_at TIMESTAMP NULL, INDEX idx_tenant_status (tenant_id, status), INDEX idx_tenant_client (tenant_id, client_id), INDEX idx_created (created_at) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; ``` #### ai_quotation_items (AI 견적 항목) ```sql CREATE TABLE ai_quotation_items ( id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY, ai_quotation_id BIGINT UNSIGNED NOT NULL, category ENUM('basic', 'module', 'addon') NOT NULL, module_code VARCHAR(50) NOT NULL, module_name VARCHAR(100) NOT NULL, description TEXT NULL, dev_cost DECIMAL(12,0) DEFAULT 0, monthly_fee DECIMAL(10,0) DEFAULT 0, quantity INT DEFAULT 1, priority ENUM('essential', 'recommended', 'optional') DEFAULT 'recommended', ai_reasoning TEXT NULL, -- AI가 이 모듈을 추천한 근거 matched_pain_points JSON NULL, -- 매칭된 고객 Pain Point sort_order INT DEFAULT 0, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, INDEX idx_quotation (ai_quotation_id), FOREIGN KEY (ai_quotation_id) REFERENCES ai_quotations(id) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; ``` ### 6.2 기존 테이블 활용 | 테이블 | 용도 | 연동 방식 | |--------|------|----------| | `ai_configs` | Claude API 키/모델 설정 | provider='claude' 조회 | | `ai_token_usages` | 토큰 비용 추적 | menu_name='AI견적' | | `ai_pricing_configs` | Claude 모델 단가 | provider='claude' | | `quotes` | 정식 견적 전환 대상 | `confirm` 시 생성 | | `clients` | 고객사 정보 | client_id 참조 | --- ## 7. Phase별 개발 계획 ### Phase 1: 텍스트 인터뷰 → AI 견적 (MVP) > **목표**: 텍스트 인터뷰 입력 → Claude 분석 → 견적서 자동생성 > **기간**: 2~3주 > **우선순위**: 🔴 필수 | 단계 | 작업 | 프로젝트 | 상태 | |------|------|---------|------| | 1-1 | `ai_quotation_modules` 마이그레이션 + 시더 | API | ⏳ | | 1-2 | `ai_quotations`, `ai_quotation_items` 마이그레이션 | API | ⏳ | | 1-3 | 모델 생성 (`AiQuotation`, `AiQuotationItem`, `AiQuotationModule`) | API | ⏳ | | 1-4 | `AiQuotationService` — Claude API 연동 | API | ⏳ | | 1-5 | 프롬프트 엔진 구현 (분석 + 견적 템플릿) | API | ⏳ | | 1-6 | `AiQuotationController` + FormRequest | API | ⏳ | | 1-7 | API 라우트 등록 (`routes/api/v1/common.php`) | API | ⏳ | | 1-8 | 정식 견적 전환 로직 (`confirmToQuote`) | API | ⏳ | | 1-9 | MNG AI 견적 관리 화면 (목록/상세/수정) | MNG | ⏳ | | 1-10 | 테스트 (인터뷰 샘플 3건 이상) | API | ⏳ | ### Phase 2: 음성 인터뷰 연동 > **목표**: 현장에서 녹음한 음성 → STT 변환 → AI 분석 → 견적 생성 > **기간**: 1주 (기존 STT 인프라 재사용으로 단축) > **선행 조건**: Phase 1 완료 | 단계 | 작업 | 프로젝트 | 상태 | 비고 | |------|------|---------|------|------| | 2-1 | Google STT 서비스 구현 | MNG | ✅ 완료 | `GoogleCloudService::speechToText()` 재사용 | | 2-2 | 음성 업로드 API (GCS 저장) | MNG | ✅ 완료 | `AiVoiceRecordingService`, `ConsultationController` 재사용 | | 2-3 | STT → 텍스트 변환 파이프라인 | MNG | ✅ 완료 | LongRunningRecognize + 폴링 패턴 구현됨 | | 2-4 | 음성 인터뷰 → AI 견적 통합 플로우 | API | ⏳ | 기존 STT 결과를 Claude 분석에 연결 | | 2-5 | MNG 음성 녹음 업로드 UI | MNG | ✅ 완료 | `voice-recorder.blade.php` 재사용 가능 | > **핵심**: Google Cloud STT, GCS, 브라우저 음성 녹음 UI가 모두 구현 완료 상태. > Phase 2에서는 기존 STT 결과를 AI 견적 파이프라인(Claude API)에 연결하는 **통합 플로우(2-4)만 신규 개발**하면 된다. ### Phase 3: 학습 데이터 고도화 > **목표**: 과거 견적 데이터를 활용하여 AI 정확도 향상 > **기간**: 2주 > **선행 조건**: Phase 1 + 실제 사용 데이터 축적 | 단계 | 작업 | 프로젝트 | 상태 | |------|------|---------|------| | 3-1 | 과거 견적 데이터 → 프롬프트 Few-shot 예시 구성 | API | ⏳ | | 3-2 | 확정된 AI 견적 → 학습 데이터 피드백 루프 | API | ⏳ | | 3-3 | 업종별 견적 패턴 분석 → 추천 정확도 향상 | API | ⏳ | | 3-4 | 프롬프트 A/B 테스트 프레임워크 | API | ⏳ | ### Phase 4: 고객 셀프서비스 (확장) > **목표**: 고객이 직접 간단한 질문에 답변하면 견적 자동 생성 > **기간**: 3주 > **선행 조건**: Phase 1~3 안정화 | 단계 | 작업 | 프로젝트 | 상태 | |------|------|---------|------| | 4-1 | 고객용 인터뷰 설문 폼 설계 | React | ⏳ | | 4-2 | 단계별 질문 → AI 분석 통합 | API + React | ⏳ | | 4-3 | 견적서 미리보기 + PDF 다운로드 | React | ⏳ | | 4-4 | 매니저 알림 → 후속 상담 연결 | API + MNG | ⏳ | --- ## 8. Claude API 연동 상세 ### 8.1 SDK 설치 ```bash # API 프로젝트에 Anthropic SDK 설치 docker exec sam-api-1 composer require anthropic-ai/laravel ``` > **참고**: `anthropic-ai/laravel` 패키지는 Laravel용 공식 래퍼로, HTTP Client 기반으로 Claude API를 호출한다. 미출시/미지원 시 `GuzzleHttp`로 직접 HTTP 호출한다. ### 8.2 Claude API 호출 패턴 ```php // app/Services/AiQuotationService.php class AiQuotationService { private function callClaudeApi(string $systemPrompt, string $userMessage): array { // 1. ai_configs에서 Claude 설정 로드 $config = AiConfig::where('provider', 'claude') ->where('is_active', true) ->first(); // 2. HTTP 호출 $response = Http::withHeaders([ 'x-api-key' => $config->api_key, 'anthropic-version' => '2023-06-01', 'content-type' => 'application/json', ])->post($config->base_url . '/messages', [ 'model' => $config->model, // claude-sonnet-4-20250514 'max_tokens' => 4096, 'temperature' => 0.3, // 견적은 일관성 중요 'system' => $systemPrompt, 'messages' => [ ['role' => 'user', 'content' => $userMessage] ], ]); // 3. 토큰 사용량 기록 $usage = $response->json('usage'); AiTokenHelper::saveClaudeUsage( tenantId: auth()->user()->tenant_id, menuName: 'AI견적', promptTokens: $usage['input_tokens'], completionTokens: $usage['output_tokens'], model: $config->model, ); // 4. 응답 파싱 $content = $response->json('content.0.text'); return json_decode($content, true); } } ``` ### 8.3 비용 예측 | 항목 | 토큰 | 비용 (USD) | 비용 (KRW) | |------|------|-----------|------------| | 1차 분석 프롬프트 (시스템+사용자) | ~2,000 입력 | $0.0005 | ~1원 | | 1차 분석 응답 | ~1,500 출력 | $0.0019 | ~3원 | | 2차 견적 프롬프트 | ~3,000 입력 | $0.0008 | ~1원 | | 2차 견적 응답 | ~2,000 출력 | $0.0025 | ~4원 | | **견적 1건 합계** | **~8,500** | **~$0.006** | **~9원** | > Claude Sonnet 기준. 1건당 약 **9원**으로 매우 경제적이다. --- ## 9. MNG 관리 화면 ### 9.1 화면 목록 | 화면 | URL | 설명 | |------|-----|------| | AI 견적 목록 | `/ai-quotation` | 생성된 AI 견적 목록 | | AI 견적 생성 | `/ai-quotation/create` | 인터뷰 입력 폼 | | AI 견적 상세 | `/ai-quotation/{id}` | 분석 결과 + 견적서 조회 | | AI 견적 수정 | `/ai-quotation/{id}/edit` | 매니저가 수정 | | 모듈 카탈로그 관리 | `/ai-quotation/modules` | SAM 모듈 목록 관리 | ### 9.2 AI 견적 생성 화면 구성 ``` ┌─────────────────────────────────────────────────────┐ │ AI 견적서 생성 │ ├─────────────────────────────────────────────────────┤ │ │ │ [고객 정보] │ │ ┌─────────────┐ ┌─────────────┐ │ │ │ 고객사 선택 ▼│ │ 업종 │ │ │ └─────────────┘ └─────────────┘ │ │ ┌─────────────┐ ┌─────────────┐ │ │ │ 직원 수 │ │ 인터뷰 대상 │ │ │ └─────────────┘ └─────────────┘ │ │ │ │ [인터뷰 내용] │ │ ┌─────────────────────────────────────────────┐ │ │ │ │ │ │ │ (텍스트 입력 또는 음성 녹음 업로드) │ │ │ │ │ │ │ │ │ │ │ └─────────────────────────────────────────────┘ │ │ │ │ [🔄 분석 시작] [📊 분석+견적 한번에] │ │ │ ├─────────────────────────────────────────────────────┤ │ [분석 결과] (Ajax 응답) │ │ │ │ 📊 업무 도메인 분석 │ │ ┌──────────┬──────────┬──────────┬──────────┐ │ │ │ 도메인 │ 현재상태 │ 문제점 │ 추천모듈 │ │ │ ├──────────┼──────────┼──────────┼──────────┤ │ │ │ 인사/급여 │ 엑셀관리 │ 분산관리 │ HR,PAYROLL│ │ │ │ 생산관리 │ 종이기록 │ 추적불가 │PRODUCTION │ │ │ └──────────┴──────────┴──────────┴──────────┘ │ │ │ │ 💰 견적서 초안 │ │ ┌──────────┬──────────┬──────────┬──────────┐ │ │ │ 모듈 │ 개발비 │ 월구독료 │ 우선순위 │ │ │ ├──────────┼──────────┼──────────┼──────────┤ │ │ │ 통합패키지 │30,000,000│ 800,000 │ 필수 │ │ │ │ AI토큰 │ 0│ 50,000 │ 선택 │ │ │ └──────────┴──────────┴──────────┴──────────┘ │ │ 합계: 개발비 30,000,000원 / 월 850,000원 │ │ │ │ [✅ 정식 견적으로 전환] [✏️ 수정] [🗑️ 삭제] │ │ │ └─────────────────────────────────────────────────────┘ ``` --- ## 10. 보안 및 운영 ### 10.1 보안 고려사항 | 항목 | 대책 | |------|------| | API 키 노출 | `ai_configs` 테이블에 암호화 저장, .env 폴백 | | 인터뷰 데이터 보호 | tenant_id 격리, 접근 권한 제어 | | Claude API 비용 제어 | 일일/월별 토큰 한도 설정 (ai_configs.options) | | 프롬프트 인젝션 | 사용자 입력 sanitize, 시스템 프롬프트 분리 | ### 10.2 모니터링 | 항목 | 방법 | |------|------| | API 호출 성공/실패 | `ai_quotations.status` + `error_message` | | 토큰 사용량 | `ai_token_usages` 테이블 (기존 인프라) | | 비용 추적 | MNG `/system/ai-token-usage` (기존 UI) | | 견적 전환율 | `ai_quotations` → `quotes` 전환 비율 통계 | ### 10.3 에러 처리 ```php try { $result = $this->callClaudeApi($systemPrompt, $userMessage); } catch (ConnectionException $e) { // Claude API 연결 실패 $aiQuotation->update(['status' => 'failed', 'error_message' => 'Claude API 연결 실패']); } catch (JsonException $e) { // 응답 JSON 파싱 실패 $aiQuotation->update(['status' => 'failed', 'error_message' => 'AI 응답 파싱 실패']); } ``` --- ## 11. 기대 효과 | 항목 | Before (현재) | After (AI 엔진) | |------|--------------|-----------------| | 견적 작성 시간 | 2~4시간 (수동) | 5~10분 (AI 초안 + 검토) | | 모듈 누락 위험 | 매니저 경험 의존 | AI가 체계적으로 분석 | | 고객 맞춤화 | 표준 템플릿 복사 | 인터뷰 기반 맞춤 견적 | | 비용 최적화 | 수동 비교 | AI가 패키지 vs 개별 자동 비교 | | 견적 1건 AI 비용 | — | ~9원 (Claude Sonnet) | --- ## 변경 이력 | 날짜 | 내용 | |------|------| | 2026-03-02 | 기획 초안 작성 | --- ## 관련 문서 | 문서 | 경로 | |------|------| | SAM 프로젝트 개요 | `docs/SAM_PROJECT_OVERVIEW_FOR_AI.md` | | 견적 기능 상세 | `docs/features/quotes/README.md` | | 견적 시스템 분석 | `docs/data/견적/견적시스템_분석문서.md` | | AI 기능 현황 | `docs/features/ai/README.md` | | AI 설정 가이드 | `docs/guides/ai-config-settings.md` | | 고객 요금 안내 | `docs/rules/customer-pricing.md` | | 내부 과금 정책 | `docs/rules/billing-policy.md` | | 단가 정책 | `docs/rules/pricing-policy.md` | | Plans 가이드 | `docs/plans/GUIDE.md` | --- **최종 업데이트**: 2026-03-02