Supabase AI Stack 2026: pgvector + Edge Functions + Realtime Streaming

Build full-stack AI apps with user-scoped RAG, Edge Functions, and streaming

返回教程列表
进阶45 分钟

Supabase AI Stack 2026: pgvector + Edge Functions + Realtime Streaming

Build full-stack AI apps with user-scoped RAG, Edge Functions, and streaming

Complete Supabase AI tutorial. pgvector for semantic search, Edge Functions for AI inference, real-time streaming, Row Level Security for user-scoped RAG, and a Next.js chat component.

supabasepgvectoredge functionsragnextjsstreaming

Supabase AI Stack 2026: pgvector + Edge Functions + Realtime

Supabase provides everything for production AI: pgvector, Edge Functions, Auth, and Real-time in one platform.

Why Supabase for AI?

  • pgvector built-in: semantic search without a separate database
  • Edge Functions: AI inference at the edge, low latency
  • Row Level Security: user-scoped RAG automatically
  • Real-time: stream AI responses to the UI
  • Auth: JWT-based user management
  • Schema with pgvector

    sql
    CREATE EXTENSION IF NOT EXISTS vector;

    CREATE TABLE documents ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), user_id UUID REFERENCES auth.users(id) ON DELETE CASCADE, content TEXT NOT NULL, embedding vector(1536), created_at TIMESTAMPTZ DEFAULT NOW() );

    CREATE INDEX ON documents USING hnsw (embedding vector_cosine_ops);

    ALTER TABLE documents ENABLE ROW LEVEL SECURITY; CREATE POLICY user_owns ON documents USING (auth.uid() = user_id);

    Edge Function (AI + Streaming)

    typescript
    // supabase/functions/chat/index.ts
    import { serve } from 'https://deno.land/std@0.208.0/http/server.ts';
    import { createClient } from 'https://esm.sh/@supabase/supabase-js@2';
    import OpenAI from 'https://esm.sh/openai@4';

    const openai = new OpenAI({ apiKey: Deno.env.get('OPENAI_API_KEY') });

    serve(async (req) => { const { question } = await req.json(); const sb = createClient( Deno.env.get('SUPABASE_URL')!, Deno.env.get('SUPABASE_ANON_KEY')!, { global: { headers: { Authorization: req.headers.get('Authorization')! } } } ); const { data: { user } } = await sb.auth.getUser(); if (!user) return new Response('Unauthorized', { status: 401 });

    const emb = await openai.embeddings.create({ model: 'text-embedding-3-small', input: question }); const embedding = emb.data[0].embedding;

    const { data: docs } = await sb.rpc('match_docs', { query_embedding: embedding, count: 5 }); const ctx = docs?.map((d: any) => d.content).join('\n\n') || '';

    const stream = await openai.chat.completions.create({ model: 'gpt-4o-mini', stream: true, messages: [ { role: 'system', content: 'Answer using context:\n\n' + ctx }, { role: 'user', content: question } ] });

    const enc = new TextEncoder(); const body = new ReadableStream({ async start(ctrl) { for await (const chunk of stream) { const text = chunk.choices[0]?.delta?.content || ''; ctrl.enqueue(enc.encode('data: ' + JSON.stringify({ text }) + '\n\n')); } ctrl.close(); } }); return new Response(body, { headers: { 'Content-Type': 'text/event-stream' } }); });

    Next.js Chat UI

    tsx
    'use client'
    import { createClient } from '@/utils/supabase/client'
    import { useState } from 'react'

    export function Chat() { const [msgs, setMsgs] = useState<{role: string; content: string}[]>([]) const [input, setInput] = useState('') const sb = createClient()

    async function send() { const q = input setInput('') setMsgs(p => [...p, {role: 'user', content: q}]) const { data: { session } } = await sb.auth.getSession() const res = await fetch( process.env.NEXT_PUBLIC_SUPABASE_URL + '/functions/v1/chat', { method: 'POST', headers: { Authorization: 'Bearer ' + session?.access_token }, body: JSON.stringify({ question: q }) } ) const reader = res.body!.getReader() let ai = '' setMsgs(p => [...p, {role: 'assistant', content: ''}]) while (true) { const { done, value } = await reader.read() if (done) break for (const line of new TextDecoder().decode(value).split('\n').filter(l => l.startsWith('data: '))) { ai += JSON.parse(line.slice(6)).text setMsgs(p => [...p.slice(0, -1), {role: 'assistant', content: ai}]) } } }

    return (

    {msgs.map((m, i) =>

    {m.role}: {m.content}

    )} setInput(e.target.value)} />
    ) }

    Conclusion

    Supabase is the fastest path to a production AI app with proper auth, user-scoped search, and streaming. pgvector + Edge Functions + RLS in one platform.

    相关工具

    supabaseopenainextjs