ai-chatbot-builder
npx skills add https://github.com/kyuhyi/bsd_claude_skills --skill ai-chatbot-builder
Agent 安装分布
Skill 文档
ð¤ Next.js AI ì±ë´ ë¹ë ì¤í¬
ì´ ì¤í¬ì BSD ë°ì´ë¸ì½ë© ìê°ìë¤ì´ Next.jsì Node.js를 ì¬ì©íì¬ ì§ë¥í AI ì±ë´ì ì¹ì¬ì´í¸ì ì§ì 구ì¶íê³ ë°°í¬í ì ìëë¡ ëìµëë¤.
ð ì´ ì¤í¬ì´ íë ì¼
- AI ìì§ ì¤ì : OpenAI (GPT-4), Anthropic (Claude) ë± ìµì ì LLM ì í
- ë°±ìë 구ì¶: Next.js API Routes (Route Handlers)를 ì¬ì©í ì±ë´ ìë² êµ¬í
- íë¡ í¸ìë 구í: React(Next.js) 기ë°ì ì¤ìê° ì¤í¸ë¦¬ë° ì±í UI ì ì
- ì§ìë² ì´ì¤(RAG): ë²¡í° ë°ì´í°ë² ì´ì¤ë¥¼ íì©í ì ì© ë°ì´í° íìµ ë° ëµë³ ìµì í
- ì¸ë¶ ì°ë: Slack, Discord, í ë ê·¸ë¨ ë± ë©í° ì±ë ì°ë ê°ì´ë
ð¯ ì¸ì ì´ ì¤í¬ì ì¬ì©íëì?
- “Next.js ì¬ì´í¸ì ì°ë¦¬ íì¬ë§ì AI ìë´ìì ë£ê³ ì¶ì´ì”
- “PDF 문ì를 íìµí´ì ëµë³í´ì£¼ë ì±ë´ì ì§ì ê°ë°íê³ ì¶ì´ì”
- “ì¬ì©ì ë°ì´í°ë¥¼ ë¶ìí´ì ê°ì¸íë ì¶ì²ì í´ì£¼ë AI ë´ì´ íìí´ì”
ð ï¸ ê¸°ì ì¤í (Code-First)
1. Framework & Language
- Next.js 14+ (App Router): íë¡ í¸ìë ë° API ìë² íµí©
- TypeScript: ìì ì ì¸ ì½ë ê°ë°
2. AI SDKs
- AI SDK (Vercel): í ì¤í¸ ìì± ë° ì¤í¸ë¦¬ë° ìµì í
- LangChain / LlamaIndex: ë³µì¡í ì²´ì¸ ë° ë°ì´í° ì°ë
3. Database & Vector Store
- Supabase (pgvector): ì¬ì©ì ê´ë¦¬ ë° ë²¡í° ê²ì
- Pinecone: ëê·ëª¨ ë°ì´í°ì© ë²¡í° ìì§
ð» Next.js ì±ë´ 구í ìì
1. Client UI (components/ChatBox.tsx)
"use client";
import { useChat } from "ai/react";
export default function ChatBox() {
const { messages, input, handleInputChange, handleSubmit } = useChat();
return (
<div className="flex flex-col w-full max-w-md mx-auto stretch">
{messages.map((m) => (
<div
key={m.id}
className={`whitespace-pre-wrap p-4 ${
m.role === "user"
? "bg-slate-100"
: "bg-blue-50 text-blue-900 border-l-4 border-blue-500"
}`}
>
<strong>{m.role === "user" ? "ð¤ ë: " : "ð¤ AI: "}</strong>
{m.content}
</div>
))}
<form onSubmit={handleSubmit}>
<input
className="fixed bottom-0 w-full max-w-md p-2 mb-8 border border-gray-300 rounded shadow-xl focus:outline-none focus:ring-2 focus:ring-blue-500"
value={input}
placeholder="무ìì´ë 물ì´ë³´ì¸ì..."
onChange={handleInputChange}
/>
</form>
</div>
);
}
2. Server API (app/api/chat/route.ts)
import { OpenAIStream, StreamingTextResponse } from "ai";
import OpenAI from "openai";
const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });
export async function POST(req: Request) {
const { messages } = await req.json();
const response = await openai.chat.completions.create({
model: "gpt-4-turbo",
stream: true,
messages: [
{
role: "system",
content: "ë¹ì ì BSD ë°ì´ë¸ì½ë© ì¼í°ì ì¹ì í ìë´ìì
ëë¤.",
},
...messages,
],
});
const stream = OpenAIStream(response);
return new StreamingTextResponse(stream);
}
ð ì±ë´ ì íë³ íì© ì¬ë¡
1. ì§ì ê¸°ë° ìë´ ë´ (RAG)
- íì¬ì 매ë´ì¼, ì ì± PDF를 íìµíì¬ ëµë³
- API ì°ëì¼ë¡ ì¤ìê° ì¬ê³ ë ê°ê²© ì ë³´ ë°ì
2. ìì ë° ë¦¬ë ì ë¤ë ì´ì ë´
- ëí를 íµí´ ì¬ì©ìì ëì¦ íì í DBì ì ì¥
- ê´ë ¨ ìíì ê²°ì ë§í¬(Check-out)ë¡ ì ë
ð¬ ìì ëí
ì¬ì©ì: “ì°ë¦¬ ì¼í몰ì ìí ì¶ì²í´ì£¼ë AI ì±ë´ì Next.jsë¡ ë§ë¤ê³ ì¶ì´”
Claude: “Next.jsì OpenAI API를 ì¬ì©íì¬ ë§ì¶¤í ìí ì¶ì² ì±ë´ì 구ì¶í´ëë¦¬ê² ìµëë¤. ëíí ì¸í°íì´ì¤ë¥¼ íµí´ ì¬ì©ìì ì·¨í¥ì ë¶ìíê³ , ë´ë¶ DBì ì°ëíì¬ ìµì ì ìíì ì ìíë ë¡ì§ì í¬í¨í ì½ë를 ìì±í´ ë릴ê²ì…”
ð¯ íµì¬ ì 리
ì´ ì¤í¬ì ì¬ì©íë©´: â Vercel AI SDK를 íì©í ê³ ì±ë¥ ì±ë´ 구í â Stream ìëµì¼ë¡ ì¤ì ì¬ëê³¼ ëííë ë¯í UX ì ê³µ â Node.js ë°±ìë를 íµí´ ë³´ì ì´ì(API Key ë ¸ì¶) í´ê²° â Custom Data ì°ëì¼ë¡ ì°ë¦¬ íì¬ë§ì í¹ë³í AI 구ì¶
BSD íìì´ë¼ë©´: ì¸ë¶ ì ë£ ì±ë´ ì루ì ì ìì¡´íì§ ìê³ , ì§ì AI íë¡ëí¸ë¥¼ ê°ë°íì¬ ë¹ì¦ëì¤ ê°ì¹ë¥¼ ëì¼ ì ììµëë¤! ð¤