Introduction
Les chatbots IA sont devenus incontournables pour le support client et l'engagement utilisateur. Dans ce tutoriel, nous allons construire un chatbot complet avec la technique RAG (Retrieval-Augmented Generation).
Architecture du chatbot
Notre chatbot utilise une architecture en 3 couches :
- Interface React : UI conversationnelle avec historique
- Supabase Edge Function : Orchestration du RAG
- Supabase pgvector : Stockage et recherche vectorielle
Schema de la base
-- Extension pour les vecteurs
CREATE EXTENSION IF NOT EXISTS vector;
-- Table des documents indexes
CREATE TABLE documents (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
content TEXT NOT NULL,
embedding VECTOR(1536),
metadata JSONB DEFAULT '{}'::jsonb,
created_at TIMESTAMPTZ DEFAULT now()
);
-- Index pour la recherche par similarite
CREATE INDEX ON documents
USING ivfflat (embedding vector_cosine_ops)
WITH (lists = 100);Implementer le RAG
Etape 1 : Indexer les documents
import { OpenAI } from 'openai'
import { supabase } from './lib/supabase'
const openai = new OpenAI()
async function indexDocument(content: string, metadata: Record<string, unknown>) {
// Generer l'embedding
const response = await openai.embeddings.create({
model: 'text-embedding-3-small',
input: content,
})
const embedding = response.data[0].embedding
// Stocker dans Supabase
await supabase.from('documents').insert({
content,
embedding,
metadata,
})
}Etape 2 : Recherche par similarite
async function searchSimilar(query: string, limit = 5) {
const response = await openai.embeddings.create({
model: 'text-embedding-3-small',
input: query,
})
const queryEmbedding = response.data[0].embedding
const { data } = await supabase.rpc('match_documents', {
query_embedding: queryEmbedding,
match_threshold: 0.7,
match_count: limit,
})
return data
}Etape 3 : Generer la reponse
async function generateResponse(query: string) {
const context = await searchSimilar(query)
const response = await openai.chat.completions.create({
model: 'gpt-4o',
messages: [
{
role: 'system',
content: `Reponds en utilisant le contexte suivant :\n${context.map((d) => d.content).join('\n')}`,
},
{ role: 'user', content: query },
],
})
return response.choices[0].message.content
}Conseil de securite : Ne jamais exposer votre cle API OpenAI cote client. Utilisez une Edge Function Supabase comme proxy securise.
Interface React
Le composant chat utilise un design minimaliste :
function ChatWidget() {
const [messages, setMessages] = useState<Message[]>([])
const [input, setInput] = useState('')
const handleSend = async () => {
if (!input.trim()) return
const userMessage = { role: 'user', content: input }
setMessages((prev) => [...prev, userMessage])
setInput('')
const response = await fetch('/api/chat', {
method: 'POST',
body: JSON.stringify({ message: input }),
})
const data = await response.json()
setMessages((prev) => [...prev, { role: 'assistant', content: data.reply }])
}
return (
<div className="chat-widget">
<div className="messages">
{messages.map((msg, i) => (
<div key={i} className={msg.role}>{msg.content}</div>
))}
</div>
<input value={input} onChange={(e) => setInput(e.target.value)} />
<button onClick={handleSend}>Envoyer</button>
</div>
)
}Conclusion
Avec Supabase pgvector et les Edge Functions, vous avez tout ce qu'il faut pour construire un chatbot IA performant sans infrastructure complexe. Le RAG garantit des reponses contextuelles et precises basees sur vos propres donnees.