반응형
React와 AI 통합: ChatGPT API · Hugging Face로 챗봇, 추천, 스마트 폼 만들기
요약: 이 글에서는 React에서 OpenAI(ChatGPT API)와 Hugging Face 같은 AI API를 손쉽게 연결하는 법을 설명합니다.
챗봇 UI, AI 추천 시스템, 스마트 폼 등 실무 예제 중심으로 구성했습니다.
1. 기본 구조
- 클라이언트(React): 입력 UI, 채팅 인터페이스
- 서버 프록시(API Route): API 키 보호 및 검증
- AI API: OpenAI, Hugging Face 등
TIP: 브라우저에서 직접 비공개 키를 쓰면 안 됩니다. 반드시 서버에서 호출하세요.
2. 환경 변수 설정
# .env (서버 전용)
OPENAI_API_KEY=your-openai-key
HF_API_TOKEN=your-huggingface-token
3. 서버 API 라우트 만들기
3.1 OpenAI Chat API (Next.js 14 기준)
// app/api/chat/route.ts
import { NextResponse } from "next/server";
export async function POST(req: Request) {
const { messages } = await req.json();
const res = await fetch("https://api.openai.com/v1/chat/completions", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.OPENAI_API_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
model: "gpt-4o-mini",
messages,
stream: true
})
});
return new NextResponse(res.body, {
headers: { "Content-Type": "text/event-stream" }
});
}
3.2 Hugging Face API (텍스트 분류 등)
// app/api/hf/route.ts
import { NextResponse } from "next/server";
export async function POST(req: Request) {
const { inputs, model = "sentence-transformers/all-MiniLM-L6-v2" } = await req.json();
const res = await fetch(`https://api-inference.huggingface.co/models/${model}`, {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.HF_API_TOKEN}`,
"Content-Type": "application/json"
},
body: JSON.stringify({ inputs })
});
const data = await res.json();
return NextResponse.json(data);
}
4. React 챗봇 UI 예제
// app/chat/page.tsx
"use client";
import { useState, useEffect, useRef } from "react";
export default function ChatPage() {
const [messages, setMessages] = useState([]);
const [input, setInput] = useState("");
const viewRef = useRef(null);
const send = async () => {
const next = [...messages, { role: "user", content: input }];
setMessages(next);
setInput("");
const res = await fetch("/api/chat", {
method: "POST",
body: JSON.stringify({ messages: next }),
headers: { "Content-Type": "application/json" }
});
const reader = res.body?.getReader();
const decoder = new TextDecoder();
let text = "";
while (true) {
const { value, done } = await reader.read();
if (done) break;
text += decoder.decode(value);
setMessages([...next, { role: "assistant", content: text }]);
}
};
useEffect(() => {
viewRef.current?.scrollTo({ top: viewRef.current.scrollHeight });
}, [messages]);
return (
<main style={{ maxWidth: 600, margin: "0 auto" }}>
<h2>AI 챗봇</h2>
<div ref={viewRef} style={{ height: 300, overflowY: "auto", border: "1px solid #333", padding: 10 }}>
{messages.map((m, i) => (
<div key={i}><b>{m.role}:</b> {m.content}</div>
))}
</div>
<form onSubmit={(e) => { e.preventDefault(); send(); }} style={{ display: "flex", marginTop: 10 }}>
<input value={input} onChange={(e) => setInput(e.target.value)} style={{ flex: 1, padding: "8px" }} />
<button type="submit">보내기</button>
</form>
</main>
);
}
5. AI 추천 시스템 (임베딩 기반)
// app/api/embed/route.ts
import { NextResponse } from "next/server";
export async function POST(req: Request) {
const { texts } = await req.json();
const res = await fetch("https://api.openai.com/v1/embeddings", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.OPENAI_API_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({ model: "text-embedding-3-small", input: texts })
});
const data = await res.json();
return NextResponse.json(data.data.map((d) => d.embedding));
}
// utils/similarity.ts
export function cosine(a, b) {
let dot = 0, na = 0, nb = 0;
for (let i = 0; i < a.length; i++) {
dot += a[i] * b[i];
na += a[i] * a[i];
nb += b[i] * b[i];
}
return dot / (Math.sqrt(na) * Math.sqrt(nb));
}
이 함수를 이용하면, 사용자의 쿼리와 임베딩 벡터 간 유사도를 계산해 AI 추천을 구현할 수 있습니다.
6. 스마트 폼 (AI 교정 / 요약)
// app/api/rewrite/route.ts
import { NextResponse } from "next/server";
export async function POST(req: Request) {
const { text } = await req.json();
const res = await fetch("https://api.openai.com/v1/chat/completions", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.OPENAI_API_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
model: "gpt-4o-mini",
messages: [
{ role: "system", content: "You are a helpful Korean writing assistant." },
{ role: "user", content: `이 문장을 자연스럽게 교정해줘:\n${text}` }
]
})
});
const data = await res.json();
return NextResponse.json({ output: data.choices[0].message.content });
}
// app/form/page.tsx
"use client";
import { useState } from "react";
export default function SmartForm() {
const [text, setText] = useState("");
const [output, setOutput] = useState("");
const handle = async () => {
const res = await fetch("/api/rewrite", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ text })
});
const { output } = await res.json();
setOutput(output);
};
return (
<div style={{ maxWidth:600, margin:"0 auto" }}>
<h3>AI 교정 폼</h3>
<textarea value={text} onChange={(e) => setText(e.target.value)} rows={5} style={{ width:"100%", padding:"8px" }} />
<button onClick={handle} style={{ marginTop:10 }}>AI 교정</button>
<pre>{output}</pre>
</div>
);
}
7. OpenAI vs Hugging Face 비교
| 항목 | OpenAI | Hugging Face |
|---|---|---|
| 강점 | 고품질 언어모델, 간단한 API | 모델 다양성, 커스텀 가능 |
| 속도 | 빠름 (상용 인프라) | 모델별 상이 |
| 사용예 | Chatbot, Smart Form | 추천, 감정분석, 요약 |
| 비용 | API 기반, 토큰 단위 과금 | 무료/유료 모델 선택 가능 |
8. 결론
React + AI API는 복잡하지 않습니다. 핵심은 다음 세 가지입니다:
- 서버 프록시를 통해 키를 숨긴다.
- 스트리밍 응답으로 실시간 UX 구현.
- RSC/클라이언트 컴포넌트로 역할 분리.
이 구조를 기반으로 챗봇, 추천 시스템, 스마트 입력 폼 등 다양한 AI 기능을 React에서 구현할 수 있습니다.
반응형
'개발' 카테고리의 다른 글
| [2026 대비] 프론트엔드 개발 트렌드 핵심 요약: RSC부터 AI 코딩까지 (0) | 2025.11.26 |
|---|---|
| React Server Components (RSC): Next.js 14 이후의 웹 렌더링 혁신 가이드 [2025 업데이트] (0) | 2025.10.31 |
| 웹뷰로 앱 개발 장점과 단점: 효율적인 선택일까? (2025년 가이드) (0) | 2025.10.25 |
| 🔥 Tailwind CSS vs CSS-in-JS 2025 비교 가이드: 속도, DX, React Compiler 궁합까지 완전 분석 (1) | 2025.10.25 |
| ⚡ Vite vs Webpack 2025 완벽 비교: React Compiler 시대의 최적 빌드 툴은? (1) | 2025.10.25 |