Tous les articles

Architecture de référence pour déployer un assistant IA d’entreprise sécurisé et scalable sur Azure avec RAG hybride et API

Architecture de référence Kairox pour déployer un assistant IA connecté aux données internes avec RAG hybride, gouvernance, observabilité et contrôle des coûts sur Azure.

IA GénérativeRAGAzureDevOpsSécuritéMLOpsIntégrationAPI
Architecture de référence pour déployer un assistant IA d’entreprise sécurisé et scalable sur Azure avec RAG hybride et API

Industrialiser un assistant IA d’entreprise : RAG, API et sécurité sur Azure

Les assistants IA basés sur des LLM transforment l’accès à l’information et l’automatisation des tâches. Mais pour un usage d’entreprise, un simple chatbot ne suffit pas. Il faut relier l’IA aux systèmes internes, garantir la confidentialité, maîtriser les coûts, tracer les échanges et éviter les hallucinations. Dans cet article, l’équipe Kairox présente une architecture de référence pour déployer un assistant IA fiable et maintenable sur Azure, avec RAG hybride, intégration API, sécurité et observabilité.

Pourquoi un chatbot “boîte noire” ne suffit pas

  • Données internes non prises en compte sans RAG ni connecteurs.
  • Risques de fuites (prompts, documents, PII) sans cloisonnement réseau et contrôle d’accès.
  • Réponses non sourcées et parfois erronées, difficiles à auditer.
  • Coûts incontrôlés sans cache, routage de modèles ou politiques de tokens.
  • Maintenance complexe sans CI/CD, métriques, journaux et garde-fous.

Architecture de référence Kairox sur Azure

Composants clés:

  • Canaux: Web, Teams, mobile; authentification via Azure AD.
  • API Gateway: Azure API Management (APIM) pour auth, quotas, journaux, transformations.
  • Service d’orchestration: microservice Python/Node orchestrant le RAG, le tool-calling et les connecteurs (ERP, SharePoint, Jira, Odoo, SAP via BAPI/OData).
  • Moteur RAG hybride: Azure AI Search (full-text BM25 + vecteurs), filtres par métadonnées et sécurité (security trimming).
  • Stockage & pipeline docs: Azure Blob/SharePoint → Azure Data Factory/Azure Functions pour ingestion, normalisation, chunking, embeddings.
  • Modèles: Azure OpenAI (chat, embeddings), avec Private Link et Managed Identity.
  • Sécurité: VNet isolation, Private DNS, Key Vault, RBAC, chiffrement au repos/en transit.
  • Observabilité: OpenTelemetry (traces), Azure Monitor, App Insights, stockage de prompts et feedback.
  • CI/CD & IaC: Bicep/Terraform, GitHub Actions/Azure DevOps, tests unitaires/évaluations IA.

Pipeline d’ingestion et d’indexation

Étapes recommandées:

  1. Collecte: SharePoint, ERP, bases SQL, Confluence.
  2. Normalisation: extraction texte (PDF, DOCX), nettoyage, détection de langue.
  3. Sécurité: classification, pseudonymisation/masquage PII si nécessaire.
  4. Segmentation: chunking 300–800 tokens avec overlap, conservation du contexte logique (titres, sections).
  5. Métadonnées: source, propriétaire, ACL, date, version, tags métiers.
  6. Embeddings: génération avec un modèle embeddings adapté au multilingue.
  7. Indexation: upsert dans Azure AI Search (champ texte + vecteur), partitionnement par BU/projet.
  8. Rafraîchissement: incrémental/scheduler, gestion des suppressions.

Exemple (Python) simplifié pour embeddings + upsert Azure AI Search:

import os, hashlib, base64
from azure.core.credentials import AzureKeyCredential
from azure.search.documents import SearchClient
from openai import AzureOpenAI

# Env: AZURE_OPENAI_ENDPOINT, AZURE_OPENAI_API_KEY, AZURE_OPENAI_API_VERSION, AZURE_SEARCH_ENDPOINT, AZURE_SEARCH_KEY, AZURE_SEARCH_INDEX
aoai = AzureOpenAI(
    azure_endpoint=os.environ["AZURE_OPENAI_ENDPOINT"],
    api_key=os.environ["AZURE_OPENAI_API_KEY"],
    api_version=os.environ["AZURE_OPENAI_API_VERSION"]
)

search = SearchClient(
    endpoint=os.environ["AZURE_SEARCH_ENDPOINT"],
    index_name=os.environ["AZURE_SEARCH_INDEX"],
    credential=AzureKeyCredential(os.environ["AZURE_SEARCH_KEY"])
)

def doc_id(text, meta):
    raw = (text + str(sorted(meta.items()))).encode("utf-8")
    return hashlib.sha256(raw).hexdigest()

def embed(text):
    res = aoai.embeddings.create(
        model="text-embedding-3-large",
        input=text
    )
    return res.data[0].embedding

def upsert_chunk(text, meta):
    vector = embed(text)
    document = {
        "id": doc_id(text, meta),
        "content": text,
        "content_vector": vector,
        "source": meta.get("source"),
        "acl": meta.get("acl", []),
        "title": meta.get("title"),
        "lang": meta.get("lang", "fr")
    }
    search.upload_documents([document])

# Exemple
upsert_chunk("Politique voyage : plafond hôtel 120€ HT nuit. Réserver via Concur.", {
    "source": "SharePoint/Policies/Travel.md",
    "acl": ["aad:group:Finance", "aad:group:AllEmployees"],
    "title": "Politique Voyage",
    "lang": "fr"
})

Notes:

  • content_vector correspond à un champ vector défini dans l’index (cosine).
  • Pour un RAG multilingue, veillez à l’alignement de la langue des embeddings.

Orchestration RAG avec garde-fous

Principes:

  • Recherche hybride: combine BM25 + vecteurs + filtres ACL.
  • Prompting encadré: consigne système stricte, format de sortie, refus hors périmètre.
  • Tool-calling: connecteurs sûrs (lecture ERP, création ticket), validation d’inputs.
  • Grounding: citations/sources retournées à l’utilisateur.
  • Rate limiting et timeouts côté orchestrateur.

Exemple (Python) de requête RAG:

from azure.search.documents.models import QueryType
from openai import AzureOpenAI

SYSTEM_PROMPT = """Tu es un assistant d’entreprise. Réponds de façon factuelle et concise.
- Si la réponse ne figure pas dans les documents fournis, dis que tu ne sais pas.
- Cites toujours les sources sous forme de liste.
- N’exécute aucune action sans instruction explicite validée.
"""

def retrieve(query, user_acl, k=5):
    flt = " or ".join([f"acl/any(a: a eq '{g}')" for g in user_acl]) or "*"
    # Hybrid: search + semantic vector
    results = search.search(
        search_text=query,
        filter=flt,
        query_type=QueryType.SIMPLE,
        top=k,
        vector={"value": embed(query), "fields": "content_vector", "k": k},
        select=["id","content","source","title"]
    )
    docs = []
    for r in results:
        docs.append({"content": r["content"], "source": r["source"], "title": r["title"]})
    return docs

def answer(query, user_acl):
    docs = retrieve(query, user_acl)
    context = "\n\n---\n".join([f"Source: {d['source']}\n{d['content']}" for d in docs])
    user_content = f"Question: {query}\n\nContexte:\n{context}"
    resp = aoai.chat.completions.create(
        model="gpt-4o",
        temperature=0.2,
        max_tokens=500,
        messages=[
            {"role":"system", "content": SYSTEM_PROMPT},
            {"role":"user", "content": user_content}
        ],
        response_format={"type":"text"}  # préférer JSON pour structuration si nécessaire
    )
    return resp.choices[0].message.content

print(answer("Quel est le plafond hôtel ?", ["aad:group:AllEmployees"]))

Conseils:

  • Utiliser des sorties structurées (JSON Schema) quand l’assistant nourrit un workflow.
  • Détecter et bloquer l’injection de prompt via filtres de pattern et classification.
  • Enrichir les métadonnées (fraîcheur, score) pour reranker côté app.

Sécurité et conformité

  • Réseau: VNet, Private Link pour Azure OpenAI et Azure AI Search, pas d’exfiltration publique.
  • Identités: Managed Identity pour services, secrets dans Key Vault.
  • Accès: RBAC par groupe AAD, security trimming dans l’index, chiffrement clé client si requis.
  • Données: masquage PII (pré-ingestion), journalisation minimisée et hachage des payloads sensibles.
  • Gouvernance: catalogue des prompts, politique de rétention des logs, revue régulière des jeux d’instructions.

Observabilité, qualité et évaluation continue

  • Traces: OpenTelemetry pour corréler requêtes API, retrieval, LLM et latence bout-en-bout.
  • Métriques: latence P50/P95, coût par requête, taux de réponses “non sûres”, longueur de contexte.
  • Qualité: échantillons d’or, évaluations humaines assistées, LLM-as-judge avec garde-fous, score de “groundedness”.
  • Retour utilisateur: bouton “utile/pas utile”, collecte d’exemples pour affiner prompts et filtres.

Exemple minimal de trace OpenTelemetry (Python):

from opentelemetry import trace
tracer = trace.get_tracer("kairox.assistant")

with tracer.start_as_current_span("rag_query") as span:
    span.set_attribute("user.tenant", "Finance")
    span.set_attribute("rag.k", 5)
    # ... retrieval + LLM call ...
    span.set_attribute("llm.tokens_prompt", 1200)
    span.set_attribute("llm.tokens_completion", 180)

Coûts et performances

  • Routage de modèles: privilégier un modèle “light” pour les requêtes simples, basculer vers un modèle “large” pour les cas complexes.
  • Contexte: limiter les tokens de contexte, préférer reranking/summarization des passages.
  • Cache: résultats de retrieval et de complétions déterministes (température faible).
  • Batching & streaming: batch embeddings, streamer les réponses UI.
  • Indexation: nettoyage des doublons, tailles de chunks adaptées au domaine.

Déploiement sur AKS et CI/CD

  • Conteneurs: microservice orchestrateur + sidecar de policy (OPA, filtration PII).
  • Scalabilité: HPA sur CPU/RAM et métriques personnalisées (RPS, tokens/s).
  • Blue/Green: déploiement progressif avec feature flags pour nouveaux prompts/outils.
  • IaC: Bicep/Terraform pour OpenAI, AI Search, APIM, Key Vault, réseaux.
  • Tests: unitaires (parsers), intégration (connecteurs), éval IA (régression sémantique), sécurité (CIS).

Cas d’usage concrets

  • Base de connaissances RH/IT avec citations et politiques à jour.
  • Assistance ERP: interrogation des commandes, seuils de stock, génération de brouillons d’achats (lecture seule + actions contrôlées).
  • Support client: réponses sourcées depuis Confluence/CRM et création de tickets avec validation.

Comment Kairox vous accompagne

  • Cadrage: ateliers data, sécurité, use cases, KPI de réussite.
  • Prototype encadré: pilote RAG sur un périmètre réduit, mesure de qualité et UX.
  • Industrialisation: CI/CD, observabilité, sécurité avancée, intégration SI.
  • Opérations: gouvernance des prompts/outils, optimisation coûts, roadmap d’évolutions.

Conclusion

Déployer un assistant IA réellement utile en entreprise exige bien plus qu’un modèle puissant. Il faut une architecture robuste, des connecteurs maîtrisés, un RAG fiable, des garde-fous et de l’observabilité. Kairox conçoit et opère ces plateformes sur Azure avec une approche industrielle, pragmatique et sécurisée. Parlons de vos cas d’usage et construisons un assistant IA qui crée de la valeur, en confiance.