Tous les articles

Comment industrialiser le RAG en entreprise : guide complet sécurisation, architecture et production

Comment industrialiser le RAG en entreprise : guide complet sécurisation, architecture et production

Industrialiser le RAG en entreprise : de la preuve de concept à la production

La génération augmentée par récupération (RAG) est devenue la voie privilégiée pour déployer des assistants IA fiables sur des données internes (documentation, emails, tickets, ERP, intranet). Si les POC sont rapides à monter, le passage en production requiert une architecture robuste, une gouvernance solide et des pratiques d’exploitation de niveau industriel. Dans cet article, nous partageons une approche pragmatique, outillée et sécurisée pour réussir ce passage à l’échelle.

Pourquoi le RAG en contexte B2B

  • Réduction des hallucinations en ancrant les réponses sur des sources vérifiables.
  • Maîtrise des données: pas de fine-tuning systématique, conservation on-prem/hybride.
  • Rapidité d’évolution: indexation incrémentale, mises à jour continues.
  • Traçabilité: citations et vérifiabilité des réponses pour la conformité.

Architecture de référence: cloud hybride, sécurité native

Composants clés

  • Ingestion et normalisation:
    • Connecteurs (SharePoint, Confluence, S3, SAP, Odoo, Git, bases SQL)
    • Extraction/partitionnement (PDF, DOCX, HTML) et enrichment (titres, métadonnées)
  • Index vectoriel:
    • PostgreSQL + pgvector, Qdrant, Weaviate, Milvus ou Pinecone
    • Stratégie de chunking et embeddings (OpenAI text-embedding-3, BGE, E5)
  • Orchestration RAG:
    • LangChain/LlamaIndex, ou implémentation maison (retrieval + reranking + prompt)
    • Reranking (cross-encodeur, Cohere/Jina, bge-reranker)
  • Modèles:
    • LLM managé (Azure OpenAI, Amazon Bedrock, Google Vertex AI) ou open-source (Llama, Mistral) via vLLM/OSS
  • Serving & Ops:
    • Docker + Kubernetes, KServe/Ray Serve, observabilité (OpenTelemetry, Prometheus)
    • Feature store et monitoring qualité (Langfuse, Phoenix, W&B), évaluation (RAGAS, TruLens)
  • Sécurité & gouvernance:
    • RBAC/ABAC, PII redaction, chiffrement, réseau privé/VPC, journaux d’audit
    • Filtrage de contenu et politiques de sécurité (Guardrails, modération)

Schéma logique (vue textuelle)

Sources internes → Pipeline ETL (ingestion, parsing, chunking, embeddings) → Base vectorielle + Store documents → Service RAG (retrieval + rerank + prompt) → LLM → Sortie avec citations → Monitoring/Eval → Boucle d’amélioration continue

Bonnes pratiques de conception

  • Données et sémantique

    • Adopter des chunks guidés par la structure: sections, titres, tables, références.
    • Standardiser les métadonnées (source, version, classification, périmètre RGPD).
    • Indexer à la fois embeddings et texte brut pour citations complètes.
  • Retrieval et reranking

    • Combiner recherche sémantique (top-k) et mot-clé (BM25) en hybrid search.
    • Reranking cross-encodeur pour la précision finale sur k réduit.
    • Limiter k pour la latence, grouper par source pour la diversité des preuves.
  • Prompting et contrôle qualité

    • Gabarits stables, instructions de citation, format JSON pour intégration SI.
    • Groundedness checks: rejeter ou demander précision si preuves faibles.
    • Tests unitaires de prompts et scénarios métiers (promptfoo, golden sets).
  • Sécurité et conformité

    • PII redaction côté ingestion et côté requête (pré/prompt filters).
    • Chiffrement au repos (KMS) et en transit (TLS), tokens en secret manager.
    • Pas de données sensibles en contexte si le modèle est hors périmètre privé.
  • Coûts et performance

    • Cache de réponses/embeddings (Redis) et de rerankings.
    • Sélection adaptative du modèle (router small/large), prompts compacts.
    • Index incrémentaux, batch ingestion nocturne, backpressure sur la file ETL.

Exemple technique: RAG avec Azure OpenAI et pgvector

Pré-requis:

  • PostgreSQL 15+ avec extension pgvector
  • Azure OpenAI (gpt-4o-mini, text-embedding-3-large/small)
  • Python 3.11, LangChain

SQL d’initialisation:

CREATE EXTENSION IF NOT EXISTS vector;
CREATE TABLE IF NOT EXISTS documents (
  id uuid PRIMARY KEY,
  source text,
  metadata jsonb,
  content text,
  embedding vector(1536)
);
CREATE INDEX IF NOT EXISTS idx_documents_embedding ON documents USING ivfflat (embedding vector_l2_ops);

Ingestion Python (embeddings + insert):

import os, uuid, psycopg
from openai import AzureOpenAI
from langchain_text_splitters import RecursiveCharacterTextSplitter

client = AzureOpenAI(
    api_key=os.environ["AZURE_OPENAI_KEY"],
    api_version="2024-02-15-preview",
    azure_endpoint=os.environ["AZURE_OPENAI_ENDPOINT"],
)

def embed(texts: list[str]) -> list[list[float]]:
    resp = client.embeddings.create(
        model=os.environ["AZURE_EMBEDDING_DEPLOYMENT"],
        input=texts
    )
    return [d.embedding for d in resp.data]

def chunk(text: str) -> list[str]:
    splitter = RecursiveCharacterTextSplitter(
        chunk_size=800, chunk_overlap=120,
        separators=["\n\n", "\n", ". ", " ", ""]
    )
    return splitter.split_text(text)

def upsert(conn, source, content, metadata):
    parts = chunk(content)
    vecs = embed(parts)
    with conn.cursor() as cur:
        for p, v in zip(parts, vecs):
            cur.execute(
                "INSERT INTO documents (id, source, metadata, content, embedding) VALUES (%s,%s,%s,%s,%s) "
                "ON CONFLICT (id) DO NOTHING",
                (uuid.uuid4(), source, metadata, p, v)
            )

with psycopg.connect(os.environ["PG_DSN"]) as conn:
    upsert(conn, "SharePoint/Guide_Sécurité.pdf", open("guide.pdf.txt").read(), {"confidentiality": "internal"})

Retrieval + génération (hybrid search simple + citations):

import json, psycopg
from openai import AzureOpenAI
from typing import List, Tuple

client = AzureOpenAI(
    api_key=os.environ["AZURE_OPENAI_KEY"],
    api_version="2024-02-15-preview",
    azure_endpoint=os.environ["AZURE_OPENAI_ENDPOINT"],
)

def semantic_search(conn, query_vec, k=6) -> List[Tuple[str, dict]]:
    with conn.cursor() as cur:
        cur.execute(
            "SELECT content, metadata FROM documents ORDER BY embedding <-> %s LIMIT %s",
            (query_vec, k)
        )
        return cur.fetchall()

def embed_query(q: str) -> List[float]:
    return client.embeddings.create(
        model=os.environ["AZURE_EMBEDDING_DEPLOYMENT"],
        input=[q]
    ).data[0].embedding

def answer(question: str):
    qv = embed_query(question)
    with psycopg.connect(os.environ["PG_DSN"]) as conn:
        docs = semantic_search(conn, qv, k=6)
    context = "\n\n---\n\n".join([d[0] for d in docs[:4]])
    sys = "Tu es un assistant d'entreprise. Réponds uniquement à partir du CONTEXTE et cite les sources si possible."
    user = f"Question: {question}\n\nCONTEXTE:\n{context}"
    resp = client.chat.completions.create(
        model=os.environ["AZURE_GPT_DEPLOYMENT"],
        temperature=0.2,
        messages=[{"role":"system","content":sys},{"role":"user","content":user}]
    )
    return {
        "answer": resp.choices[0].message.content,
        "citations": [json.dumps(d[1]) for d in docs[:4]]
    }

print(answer("Quelles sont les exigences de chiffrement au repos ?"))

Exposition API avec FastAPI:

from fastapi import FastAPI
app = FastAPI()

@app.get("/rag")
def rag(q: str):
    return answer(q)

Déploiement CI/CD (extrait GitHub Actions):

name: build-deploy
on: [push]
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: docker/setup-buildx-action@v3
      - uses: docker/login-action@v3
        with:
          registry: ghcr.io
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}
      - run: docker build -t ghcr.io/org/rag-api:${{ github.sha }} .
      - run: docker push ghcr.io/org/rag-api:${{ github.sha }}
  deploy:
    needs: build
    runs-on: ubuntu-latest
    steps:
      - uses: azure/setup-kubectl@v4
      - run: helm upgrade --install rag-api chart/ --set image.tag=${{ github.sha }}

Observabilité, évaluation et amélioration continue

  • Télémétrie

    • Traces distribuées (OTel), logs structurés, corrélation requête → retrieval → LLM.
    • Métriques: latence p95, taux de null answers, taille prompts, coût par requête.
  • Qualité

    • Jeux de tests anonymisés par cas d’usage métier.
    • Évaluation offline/online (A/B) avec scores de groundedness (RAGAS/TruLens).
    • Boucles de feedback utilisateur et labelisation assistée.
  • Sûreté et garde-fous

    • Politiques de confidentialité dans le prompt, refus contrôlés.
    • Classifieurs de sécurité en pré et post-génération.
    • Fallback: réponse courte + lien vers source si confiance insuffisante.

Intégration SI et gouvernance des accès

  • Intégration SSO/IDP (OIDC, SAML), mapping des rôles vers filtres de retrieval (row-level security).
  • Multilocataires: séparation stricte des espaces d’index, clés KMS distinctes.
  • Journalisation conformité: qui a consulté quelles données, quelle version de source.

Trajectoire projet recommandée

  1. Cadrage
  • Cartographier les sources prioritaires, les risques (PII, secrets), et les KPI métier.
  • Choisir la plateforme LLM (managée vs on-prem) et la base vectorielle.
  1. POC guidé par la valeur
  • Un cas d’usage, un persona, un socle minimal de sécurité et de monitoring.
  1. Passage à l’échelle
  • Pipelines d’ingestion industrialisés, observabilité complète, CI/CD, gouvernance.
  1. Optimisation continue
  • Router de modèles, caching, hybrid search + reranking, évaluation régulière.

Comment Kairox vous accompagne

Kairox conçoit et opère des plateformes IA de bout en bout:

  • Audit et architecture RAG adaptées à votre SI (cloud, on-prem, hybride)
  • Ingestion sécurisée multiconnecteurs, bases vectorielles et pipelines MLOps
  • Orchestration RAG, garde-fous, évaluation et observabilité
  • Déploiement Kubernetes, CI/CD, FinOps, et gouvernance des accès
  • Transfert de compétences, documentation et support opérationnel

Vous avez un POC à industrialiser ou un SI à moderniser avec le RAG ? Contactez l’équipe Kairox pour une étude flash et une trajectoire pragmatique vers la production.