Réponse rapide : En 2026, la stack défaut pour un SaaS français est Mistral Large 2 (hosting France) pour les cas RGPD-stricts, Claude Sonnet 4.6 pour la qualité maximale sur des tâches complexes, ou GPT-5 pour l'écosystème complet (DALL-E, Whisper). Le Vercel AI SDK abstrait les 3 providers, et le pattern RAG + pgvector remplace 95 % des cas où nous serions tenté de fine-tuner.

En résumé (TL;DR)

1. Comparatif Claude vs GPT vs Mistral en 2026

CritèreClaude Sonnet 4.6GPT-5 (OpenAI)Mistral Large 2
Context window1 M tokens200 K tokens128 K tokens
Prix input / M tokens~3 $~5 $~3 $
Prix output / M tokens~15 $~15 $~9 $
Caching promptNatif (-90 %)Natif (-50 %)Natif (-50 %)
Latence first token (médiane)~400 ms~350 ms~300 ms
Qualité raisonnement complexe★★★★★★★★★★★★★★
Qualité code★★★★★★★★★★★★★
Vision (analyse images)Oui (excellent)Oui (excellent)Pixtral séparé
Hosting EU natifAWS Bedrock FrankfurtAzure OpenAI EUParis (natif)
Tool use / function callingOui (très propre)Oui (mature)Oui
SDK officiel TypeScript@anthropic-ai/sdkopenai@mistralai/mistralai

Sources : tarifs vérifiés mai 2026 sur les pages pricing officielles. Latence mesurée via tests internes Visionary sur 1 000 prompts identiques.

2. Cas d'usage typiques par secteur

E-commerce

SaaS B2B

Service Visionary

Intégration LLM dans votre SaaS — devis 24h

3. Setup Next.js 15 + Vercel AI SDK

Nous utilisons le Vercel AI SDK qui abstrait les 3 providers et offre des hooks React pour le streaming. Initialisation :

npm install ai @ai-sdk/anthropic @ai-sdk/openai @ai-sdk/mistral
npm install @types/node typescript
# Optionnel : choisir UN provider parmi les 3 ci-dessus

Variables d'environnement .env.local (au choix) :

ANTHROPIC_API_KEY=sk-ant-...
OPENAI_API_KEY=sk-proj-...
MISTRAL_API_KEY=...

4. Route Handler avec streaming

Création de app/api/chat/route.ts — endpoint POST qui stream la réponse :

import { anthropic } from '@ai-sdk/anthropic';
// ou : import { openai } from '@ai-sdk/openai';
// ou : import { mistral } from '@ai-sdk/mistral';
import { streamText, convertToCoreMessages } from 'ai';

export const maxDuration = 30; // secondes

export async function POST(req: Request) {
  const { messages } = await req.json();

  const result = await streamText({
    model: anthropic('claude-sonnet-4-6'),
    // model: openai('gpt-5'),
    // model: mistral('mistral-large-2'),
    system: 'Tu es un assistant Visionary spécialisé dans le développement web. Réponds en français, clair et concis.',
    messages: convertToCoreMessages(messages),
    maxTokens: 1024,
    temperature: 0.5,
  });

  return result.toDataStreamResponse();
}

Switcher de provider = changer 1 ligne. Le format messages est unifié.

5. Composant Chat client (React)

app/chat/page.tsx — interface de chat avec streaming token par token :

'use client';
import { useChat } from 'ai/react';

export default function ChatPage() {
  const { messages, input, handleInputChange, handleSubmit, isLoading } = useChat();

  return (
    <div className="flex flex-col h-screen max-w-2xl mx-auto p-6">
      <div className="flex-1 overflow-y-auto space-y-4 pb-4">
        {messages.map(m => (
          <div key={m.id} className={m.role === 'user' ? 'text-right' : 'text-left'}>
            <span className="inline-block px-4 py-2 rounded-2xl bg-cacao text-creme">
              {m.content}
            </span>
          </div>
        ))}
        {isLoading && <div className="text-moka text-sm">Réflexion…</div>}
      </div>

      <form onSubmit={handleSubmit} className="flex gap-2">
        <input
          value={input}
          onChange={handleInputChange}
          placeholder="Posez votre question…"
          className="flex-1 px-4 py-3 border rounded-xl"
        />
        <button type="submit" disabled={isLoading} className="px-6 py-3 bg-cacao text-creme rounded-xl">
          Envoyer
        </button>
      </form>
    </div>
  );
}

useChat gère automatiquement l'état des messages, le streaming token par token, le scroll, et les erreurs. 30 lignes de code pour un chat production-ready.

6. Tool use — l'agent qui agit dans votre app

Le tool use permet au LLM d'appeler des fonctions de votre code. Exemple : un agent e-commerce qui cherche dans le catalogue.

// app/api/chat/route.ts
import { anthropic } from '@ai-sdk/anthropic';
import { streamText, tool } from 'ai';
import { z } from 'zod';
import { db } from '@/lib/db';

export async function POST(req: Request) {
  const { messages } = await req.json();

  const result = await streamText({
    model: anthropic('claude-sonnet-4-6'),
    system: 'Tu es un assistant shopping Visionary.',
    messages,
    tools: {
      searchProducts: tool({
        description: 'Recherche des produits dans le catalogue Visionary par mot-clé et fourchette de prix.',
        parameters: z.object({
          query: z.string().describe('mot-clé recherché'),
          maxPrice: z.number().optional().describe('prix max en €'),
        }),
        execute: async ({ query, maxPrice }) => {
          const products = await db.product.findMany({
            where: {
              name: { contains: query, mode: 'insensitive' },
              price: maxPrice ? { lte: maxPrice } : undefined,
            },
            take: 5,
          });
          return products;
        },
      }),
      addToCart: tool({
        description: 'Ajoute un produit au panier de l\'utilisateur.',
        parameters: z.object({ productId: z.string(), quantity: z.number().default(1) }),
        execute: async ({ productId, quantity }) => {
          // logique panier...
          return { ok: true, productId };
        },
      }),
    },
    maxSteps: 5, // permet plusieurs tool calls en chaîne
  });

  return result.toDataStreamResponse();
}

Le LLM décide quand appeler quel tool, vous l'exécutez, vous renvoyez le résultat. maxSteps: 5 autorise des chaînes : "cherche produit → vérifie stock → ajoute au panier" en une seule conversation.

7. RAG avec Postgres + pgvector

Le RAG (Retrieval-Augmented Generation) injecte vos documents dans le prompt pour des réponses contextuelles. Stack standard : embeddings + Postgres + pgvector.

Indexation des documents

// lib/rag/index.ts
import { embed } from 'ai';
import { openai } from '@ai-sdk/openai';
import { db } from '@/lib/db';

export async function indexDocument(content: string, metadata: object) {
  // chunking : 1 chunk par paragraphe, ~500 tokens max
  const chunks = content.split(/\n\n+/).filter(c => c.trim().length > 50);

  for (const chunk of chunks) {
    const { embedding } = await embed({
      model: openai.embedding('text-embedding-3-large'),
      value: chunk,
    });

    await db.$executeRaw`
      INSERT INTO documents (content, metadata, embedding)
      VALUES (${chunk}, ${JSON.stringify(metadata)}::jsonb, ${embedding}::vector)
    `;
  }
}

Recherche au moment de la requête

// lib/rag/search.ts
import { embed } from 'ai';
import { openai } from '@ai-sdk/openai';
import { db } from '@/lib/db';

export async function search(query: string, k = 5) {
  const { embedding } = await embed({
    model: openai.embedding('text-embedding-3-large'),
    value: query,
  });

  return db.$queryRaw`
    SELECT content, metadata, 1 - (embedding <=> ${embedding}::vector) AS similarity
    FROM documents
    ORDER BY embedding <=> ${embedding}::vector
    LIMIT ${k}
  `;
}

Injection dans le prompt

// app/api/chat/route.ts (version RAG)
import { search } from '@/lib/rag/search';

export async function POST(req: Request) {
  const { messages } = await req.json();
  const lastUserMessage = messages.filter(m => m.role === 'user').pop()?.content;

  const docs = await search(lastUserMessage);
  const context = docs.map((d, i) => `[Doc ${i+1}] ${d.content}`).join('\n\n');

  const result = await streamText({
    model: anthropic('claude-sonnet-4-6'),
    system: `Tu es un assistant Visionary. Réponds UNIQUEMENT à partir des documents ci-dessous. Si la réponse n'y est pas, dis-le.

DOCUMENTS :
${context}`,
    messages,
  });

  return result.toDataStreamResponse();
}

Coût indicatif RAG : 5-10 €/mois pour 100 K chunks indexés (embeddings 1 fois) + ~0,001 €/requête au runtime.

Boilerplate complet · ZIP téléchargeable

Recevez le boilerplate Next.js 15 + LLM

Code complet : Next.js 15 App Router, Vercel AI SDK, route handler streaming, composant Chat, tool use catalog + cart, RAG pgvector, gardes RGPD, monitoring coûts. README détaillé.

8. Conformité RGPD : 3 leviers obligatoires

Endpoint EU

Opt-out training

Tous les providers majeurs offrent un mode "no training on data". Anthropic et OpenAI : par défaut sur les plans Business / Enterprise. Mistral : par défaut sur tous les plans payants. À vérifier dans le dashboard et inclure dans votre DPA.

Anonymisation PII avant envoi

Recommandé pour les données sensibles : remplacer les emails, noms, numéros de téléphone, IBAN par des tokens avant d'envoyer au LLM, puis dé-tokeniser dans la réponse. Lib utile : Microsoft Presidio (open-source, supporte le français), ou regex custom pour les cas simples.

// lib/rag/redact.ts
function redactPII(text: string): { redacted: string, mappings: Record<string, string> } {
  const mappings: Record<string, string> = {};
  let counter = 0;
  let redacted = text;

  // Emails
  redacted = redacted.replace(/[\w.+-]+@[\w-]+\.[\w.-]+/g, m => {
    const tok = `[EMAIL_${++counter}]`;
    mappings[tok] = m;
    return tok;
  });

  // Téléphones FR
  redacted = redacted.replace(/(?:\+33|0)\s?[1-9](?:[\s.-]?\d{2}){4}/g, m => {
    const tok = `[PHONE_${++counter}]`;
    mappings[tok] = m;
    return tok;
  });

  return { redacted, mappings };
}

9. Monitoring des coûts en production

Toujours logger les appels avec leurs tokens. Schéma minimum :

CREATE TABLE llm_calls (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  user_id UUID NOT NULL,
  model TEXT NOT NULL,
  input_tokens INT NOT NULL,
  output_tokens INT NOT NULL,
  cached_tokens INT DEFAULT 0,
  cost_usd NUMERIC(10, 6) NOT NULL,
  feature TEXT NOT NULL,
  created_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE INDEX idx_llm_calls_user_date ON llm_calls(user_id, created_at);

Avec ce schéma, vous pouvez facilement :

Outils prêts : Helicone (gratuit jusqu'à 100K logs/mois, dashboard joli) ou Langfuse (open-source, self-hostable).

10. Erreurs typiques à éviter

La règle 2026 : commencez par Vercel AI SDK + Mistral Large 2 + RAG pgvector. C'est conforme RGPD par défaut, économique, switchable vers Claude ou GPT en 1 ligne si vous changez d'avis. Pas besoin de framework lourd type LangChain pour 95 % des cas.

Questions fréquentes

Quelle API LLM choisir en 2026 : Claude, OpenAI ou Mistral ?

Claude Sonnet 4.6 offre le meilleur rapport qualité-prix pour des tâches complexes (raisonnement, code, écriture). GPT-5 excelle sur des cas généralistes avec un écosystème mature. Mistral Large 2 est le seul leader avec hosting 100 % France/EU. Pour une app française B2B : Mistral. Pour qualité maximale : Claude. Pour écosystème complet : OpenAI.

Combien coûte une intégration LLM en production ?

Coût type pour 1 000 users actifs / mois avec 20 messages chacun et 2 000 tokens par message : Claude ~360 €/mois, GPT-5 ~400 €/mois, Mistral ~240 €/mois. Avec le caching de prompts (–90 %), ces chiffres tombent à 100-200 €/mois.

Comment garantir la conformité RGPD avec une API LLM ?

Trois leviers : endpoint EU (Mistral natif, Azure OpenAI EU, AWS Bedrock Frankfurt), opt-out training (par défaut sur les plans Business), anonymisation PII avec Microsoft Presidio ou regex maison. Compléter avec un DPA signé.

Qu'est-ce que le RAG et faut-il l'implémenter ?

RAG (Retrieval-Augmented Generation) consiste à récupérer des documents pertinents avant d'envoyer la requête au LLM. Avantages : le LLM répond sur VOS données, sans fine-tuning, sans hallucination. Stack : embeddings + Postgres + pgvector. Coût : ~5-10 € / mois pour 100K chunks.

Streaming, c'est quoi et pourquoi obligatoire ?

Le streaming envoie la réponse token par token. UX : l'utilisateur voit l'écriture en temps réel (~100 ms premier token vs 5-15 s réponse complète). C'est le standard depuis ChatGPT 2022 — sans streaming, votre UX paraîtra cassée.

Tool use / function calling, dans quels cas ?

Le tool use permet au LLM d'appeler des fonctions de votre code (rechercher produit, créer commande, etc.). Cas typiques : agent support client, assistant e-commerce, agent SaaS. Tous les LLM modernes le supportent.

Comment éviter les jailbreaks et injections de prompt ?

Quatre mesures : system prompt clair, validation stricte des inputs, output guardrails (tool_use forcé ou structured outputs), monitoring. Pour un usage critique, prévoir une couche de modération.

Faut-il fine-tuner ou utiliser RAG ?

Pour 95 % des cas : RAG. Le fine-tuning coûte 50-500 €, prend 6-24h, doit être refait à chaque update. RAG s'update en temps réel et coûte quelques centimes. Le fine-tuning ne sert que pour : ton/style spécifique, format ultra-strict, sécurité maximale.

Quels SDKs utiliser en TypeScript pour Next.js ?

Vercel AI SDK (ai) pour abstraire les 3 providers : streaming natif, hooks React, doc impeccable. Sinon : @anthropic-ai/sdk, openai, @mistralai/mistralai directement. Vercel AI SDK est notre recommandation.

Comment monitorer les coûts en production ?

Quatre leviers : limites de quotas dans les dashboards providers, logging maison (table llm_calls), tableau de bord interne par feature/user/cohorte, hard cap par user côté code. Outils : Helicone, Langfuse.

Intégrer une IA dans votre SaaS, proprement ?

Choix du LLM, architecture streaming + tool use + RAG, conformité RGPD, monitoring coûts. SaaS sur-mesure dès 5600 €.

Voir l'offre SaaS →