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)
- Choix LLM 2026 : Mistral pour RGPD strict, Claude pour qualité, OpenAI pour écosystème.
- SDK conseillé : Vercel AI SDK (
ainpm) — streaming natif, hooks React, switch provider en 1 ligne. - Streaming obligatoire : sans ça, l'UX paraît cassée.
- RAG > fine-tuning : pour 95 % des cas. Stack : embeddings + Postgres + pgvector.
- RGPD : choisir endpoint EU + opt-out training + anonymiser PII.
- Coût type : 100-400 € / 1 000 users actifs / mois selon le LLM et l'usage du caching.
1. Comparatif Claude vs GPT vs Mistral en 2026
| Critère | Claude Sonnet 4.6 | GPT-5 (OpenAI) | Mistral Large 2 |
|---|---|---|---|
| Context window | 1 M tokens | 200 K tokens | 128 K tokens |
| Prix input / M tokens | ~3 $ | ~5 $ | ~3 $ |
| Prix output / M tokens | ~15 $ | ~15 $ | ~9 $ |
| Caching prompt | Natif (-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 natif | AWS Bedrock Frankfurt | Azure OpenAI EU | Paris (natif) |
| Tool use / function calling | Oui (très propre) | Oui (mature) | Oui |
| SDK officiel TypeScript | @anthropic-ai/sdk | openai | @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
- Recherche conversationnelle : "trouve-moi une chemise blanche en lin moins de 80 €" → tool use vers le catalogue.
- Génération descriptions produits : 5 000 références importées en CSV → prompts batch avec caching.
- Support client first-line : agent qui cherche dans la base FAQ + commandes (RAG) avant escalation humaine.
- Recommandations cross-sell : "j'ai mis ce manteau dans le panier, qu'est-ce qui irait bien avec ?"
SaaS B2B
- Onboarding intelligent : agent qui pose des questions et configure l'app pour le user.
- Assistant in-app : "comment je crée un rapport mensuel ?" → réponse contextuelle basée sur la doc + actions in-app via tool use.
- Génération de contenu : posts LinkedIn, emails commerciaux, réponses RFP.
- Analyse de données : "résume-moi les NPS du dernier trimestre, identifie les 3 thèmes principaux".
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.
8. Conformité RGPD : 3 leviers obligatoires
Endpoint EU
- Mistral : Paris natif, aucune action requise — c'est l'option la plus simple côté RGPD.
- OpenAI : passer par Azure OpenAI en région France Central ou West Europe. Tarification proche de l'API directe, mais hébergement Microsoft Azure EU.
- Claude : passer par AWS Bedrock en région Frankfurt (eu-central-1) ou Paris (eu-west-3 — Bedrock dispo selon modèles). Légèrement plus cher (+10 à +15 %) mais hosting EU garanti.
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 :
- Calculer le coût quotidien / hebdo / mensuel par feature
- Identifier les power-users qui plombent les coûts
- Imposer des hard caps par utilisateur free vs payant
- Détecter les anomalies (un user à 1 M tokens/jour = bug ou abus)
Outils prêts : Helicone (gratuit jusqu'à 100K logs/mois, dashboard joli) ou Langfuse (open-source, self-hostable).
10. Erreurs typiques à éviter
- Ne pas streamer — UX cassée. Toujours streamer.
- Stocker la clé API côté client — un attaquant peut la voler. Toujours côté serveur.
- Pas de rate-limit utilisateur — un utilisateur peut vider votre crédit en 5 minutes. Limite à 50-200 messages / jour selon le plan.
- Ignorer le caching de prompts — vous payez 90 % de plus pour rien si votre system prompt fait 2000 tokens et qu'il est répété à chaque requête.
- Faire confiance à la sortie — un LLM peut halluciner. Pour des données critiques (ex: prix produit), utilisez tool use forcé ou structured outputs.
- Pas de logging — impossible de débugger en prod. Loggez tous les appels.
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 →