반응형
AIKit — PHP 연동 가이드
왜 클라이언트 사이드 AI인가
"JavaScript 라이브러리를 PHP 프로젝트에 어떻게 쓰지?"라는 질문을 받는다. 답은 클라이언트 사이드에서 AI를 처리하고, PHP는 데이터 저장만 담당하는 구조다.
전통적 방식 vs 클라이언트 사이드 AI
| 항목 | 서버 사이드 AI | 클라이언트 사이드 AI (AIKit) |
|---|---|---|
| API 호출 | PHP → AI API | 브라우저 → AI API |
| 서버 부하 | 모든 요청이 서버 경유 | 서버 부하 0 |
| 응답 속도 | 서버 왕복 추가 | 직접 통신 (빠름) |
| 프로바이더 변경 | 백엔드 재배포 | 프론트엔드만 수정 |
아키텍처
브라우저
├── AIKit (CDN) → AI API 직접 통신
└── AJAX → PHP 서버 → DB 저장
- PHP: 인증, 데이터 저장, 비즈니스 로직
- AIKit: AI 통신, 응답 처리, 클라이언트 캐싱
- DB: 대화 이력, 사용자 설정
프로젝트 구조
php-ai-app/
├── public/
│ ├── index.php ← 메인 페이지
│ └── api/
│ ├── save-chat.php ← 대화 저장 API
│ └── load-chats.php ← 대화 불러오기 API
├── config/
│ └── database.php ← DB 설정
└── vendor/
DB 스키마
CREATE TABLE conversations (
id INT AUTO_INCREMENT PRIMARY KEY,
user_id INT NOT NULL,
title VARCHAR(255),
provider VARCHAR(50),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE messages (
id INT AUTO_INCREMENT PRIMARY KEY,
conversation_id INT NOT NULL,
role ENUM('user', 'assistant') NOT NULL,
content TEXT NOT NULL,
tokens_used INT DEFAULT 0,
cost DECIMAL(10, 6) DEFAULT 0,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
API 키는 DB에 저장하지 않는다. 사용자의 브라우저(localStorage)에만 존재한다.
PHP API 엔드포인트
대화 저장
// api/save-chat.php
$data = json_decode(file_get_contents('php://input'), true);
$stmt = $pdo->prepare('
INSERT INTO messages (conversation_id, role, content, tokens_used, cost)
VALUES (:conv_id, :role, :content, :tokens, :cost)
');
$stmt->execute([
':conv_id' => $data['conversation_id'],
':role' => $data['role'],
':content' => $data['content'],
':tokens' => $data['tokens_used'] ?? 0,
':cost' => $data['cost'] ?? 0
]);
echo json_encode(['success' => true]);
Prepared Statement를 반드시 사용한다. SQL Injection 방지는 기본이다.
대화 불러오기
// api/load-chats.php
$stmt = $pdo->prepare('
SELECT m.* FROM messages m
WHERE m.conversation_id = :conv_id
ORDER BY m.created_at ASC
');
$stmt->execute([':conv_id' => $_GET['id']]);
echo json_encode($stmt->fetchAll(PDO::FETCH_ASSOC));
프론트엔드 연동
// AIKit 초기화
const ai = new AIKit({
provider: 'openai',
apiKey: localStorage.getItem('apiKey'),
enableCostTracking: true
});
// 메시지 전송 + 서버 저장
async function sendMessage(message) {
const response = await ai.chat(message);
// AI 응답을 서버에 저장
await fetch('/api/save-chat.php', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
conversation_id: currentConvId,
role: 'assistant',
content: response.content,
tokens_used: response.usage?.total_tokens || 0,
cost: ai.getCostReport().total
})
});
return response;
}
AI 통신은 브라우저에서 직접 하고, 결과만 PHP 서버에 저장한다.
보안 원칙
| 원칙 | 설명 |
|---|---|
| API 키 서버 미저장 | localStorage에만 보관, 서버로 전송하지 않음 |
| Prepared Statement | 모든 DB 쿼리에 바인딩 사용 |
| Input Escape | htmlspecialchars()로 출력 시 이스케이프 |
| CSRF 토큰 | 폼/AJAX 요청에 토큰 검증 |
Laravel 연동
Laravel 프로젝트라면 라우트와 컨트롤러를 이용한다.
// routes/web.php
Route::middleware('auth')->group(function () {
Route::post('/chat/save', [ChatController::class, 'save']);
Route::get('/chat/history', [ChatController::class, 'history']);
});
// ChatController.php
public function save(Request $request) {
$validated = $request->validate([
'conversation_id' => 'required|integer',
'role' => 'required|in:user,assistant',
'content' => 'required|string|max:10000',
]);
Message::create($validated);
return response()->json(['success' => true]);
}
마무리
PHP + AIKit 조합의 핵심은 역할 분리다. AI 통신은 클라이언트에서, 데이터 저장은 서버에서. 서버 부하는 줄이고 응답 속도는 높인다.
다음 편에서는 React와 Vue에서 AIKit을 사용하는 방법을 다룬다.
기술 스택: PHP, JavaScript, AIKit, MySQL, Laravel
소스 코드: GitHub
반응형
'프로젝트 > AIKit' 카테고리의 다른 글
| AIKit #7 - AI API 비용 90% 줄이기 (0) | 2026.02.09 |
|---|---|
| AIKit #6 - React & Vue에서 AIKit 사용하기 (0) | 2026.02.08 |
| AIKit #4 - 5분 만에 AI 챗봇 만들기 (0) | 2026.02.07 |
| AIKit #3 - QA 개발자가 만든 AI 라이브러리 (0) | 2026.02.07 |
| AIKit #2 - Adapter Pattern으로 멀티 프로바이더 지원하기 (0) | 2026.02.06 |