5) { echo json_encode(['ok' => false, 'error' => '접근 권한이 없습니다.']); exit; } // POST 데이터 받기 $input = file_get_contents('php://input'); $data = json_decode($input, true); if (!isset($data['image'])) { echo json_encode(['ok' => false, 'error' => '이미지 데이터가 없습니다.']); exit; } $imageBase64 = $data['image']; $rawText = isset($data['raw_text']) ? $data['raw_text'] : null; // OCR 텍스트는 선택사항 // API 키 읽기 $apiKeyFile = $_SERVER['DOCUMENT_ROOT'] . '/apikey/claude_api.txt'; if (!file_exists($apiKeyFile)) { echo json_encode(['ok' => false, 'error' => 'API 키 파일이 존재하지 않습니다.']); exit; } $apiKey = trim(file_get_contents($apiKeyFile)); // Claude API 요청 $promptText = "제공된 사업자등록증 이미지를 직접 분석하여 아래 필드를 정확하게 추출해주세요.\n\n"; if ($rawText) { $promptText .= "참고: OCR 텍스트가 제공되었지만 부정확할 수 있으니, 이미지를 직접 읽어서 정확한 정보를 추출해주세요.\n"; $promptText .= "OCR 텍스트(참고용): {$rawText}\n\n"; } $promptText .= << 'claude-3-haiku-20240307', // haiku 모델 사용 (이미지 직접 분석 가능) 'max_tokens' => 4096, 'messages' => [ [ 'role' => 'user', 'content' => [ [ 'type' => 'image', 'source' => [ 'type' => 'base64', 'media_type' => $mediaType, 'data' => $imageData ] ], [ 'type' => 'text', 'text' => $promptText ] ] ] ] ]; $ch = curl_init($apiUrl); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_HTTPHEADER, [ 'Content-Type: application/json', 'x-api-key: ' . $apiKey, 'anthropic-version: 2023-06-01' ]); curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($requestBody)); $response = curl_exec($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); if ($httpCode !== 200) { error_log("Claude API Error: HTTP {$httpCode} - {$response}"); echo json_encode([ 'ok' => false, 'error' => 'Claude API 호출 실패 (HTTP ' . $httpCode . ')', 'details' => $response ]); exit; } $apiResponse = json_decode($response, true); if (!isset($apiResponse['content'][0]['text'])) { echo json_encode(['ok' => false, 'error' => 'Claude API 응답 형식 오류']); exit; } // Claude가 반환한 JSON 파싱 $claudeText = $apiResponse['content'][0]['text']; // JSON 부분만 추출 (코드블록이나 설명이 포함되어 있을 수 있음) if (preg_match('/\{[^{}]*(?:\{[^{}]*\}[^{}]*)*\}/s', $claudeText, $matches)) { $jsonText = $matches[0]; } else { $jsonText = $claudeText; } $extractedData = json_decode($jsonText, true); if (!$extractedData) { echo json_encode([ 'ok' => false, 'error' => 'Claude 응답 JSON 파싱 실패', 'raw_response' => $claudeText ]); exit; } // 성공 응답 echo json_encode([ 'ok' => true, 'data' => $extractedData, 'raw_response' => $claudeText ]);