Aller au contenu principal

L'API Document QnA

Interroger vos documents en langage naturel

Document QnA combine la puissance de l’OCR avec un LLM Mistral pour vous permettre de poser des questions directement sur le contenu de vos documents. Plus besoin de lire 50 pages pour trouver une information : posez la question, obtenez la réponse.

Le workflow en deux étapes

Document QnA fonctionne en interne en deux étapes :

  1. OCR : le modèle extrait le texte, la structure et le formatage du document
  2. LLM : un modèle de chat Mistral analyse le contenu extrait pour répondre à votre question

Cette combinaison est transparente : un seul appel API suffit.

L’endpoint Chat avec documents

Contrairement à l’OCR pur (qui utilise client.ocr.process), le QnA utilise l’endpoint Chat standard client.chat.complete avec un type de contenu document_url :

import os
from mistralai import Mistral

client = Mistral(api_key=os.environ["MISTRAL_API_KEY"])

# Question sur un document public
response = client.chat.complete(
    model="mistral-small-latest",
    messages=[
        {
            "role": "user",
            "content": [
                {
                    "type": "text",
                    "text": "Quel est le chiffre d'affaires total mentionné ?"
                },
                {
                    "type": "document_url",
                    "document_url": "https://exemple.com/rapport-annuel.pdf"
                }
            ]
        }
    ]
)

print(response.choices[0].message.content)

Trois méthodes d’envoi

1. URL publique

La plus simple, pour les documents accessibles en ligne :

messages = [
    {
        "role": "user",
        "content": [
            {"type": "text", "text": "Résume les points principaux."},
            {
                "type": "document_url",
                "document_url": "https://arxiv.org/pdf/1805.04770"
            }
        ]
    }
]

response = client.chat.complete(
    model="mistral-small-latest",
    messages=messages
)

2. Document encodé en base64

Pour les fichiers locaux :

import base64

with open("contrat.pdf", "rb") as f:
    doc_base64 = base64.b64encode(f.read()).decode("utf-8")

messages = [
    {
        "role": "user",
        "content": [
            {
                "type": "text",
                "text": "Quelles sont les clauses de résiliation ?"
            },
            {
                "type": "document_base64",
                "document_base64": doc_base64
            }
        ]
    }
]

response = client.chat.complete(
    model="mistral-small-latest",
    messages=messages
)

3. Fichier uploadé

Pour les documents déjà uploadés via l’API Files :

uploaded = client.files.upload(
    file=open("rapport.pdf", "rb"),
    purpose="ocr"
)

messages = [
    {
        "role": "user",
        "content": [
            {"type": "text", "text": "Quel est le budget prévu ?"},
            {"type": "file_id", "file_id": uploaded.id}
        ]
    }
]

response = client.chat.complete(
    model="mistral-small-latest",
    messages=messages
)

Choix du modèle de chat

Vous pouvez utiliser différents modèles Mistral pour le QnA :

  • mistral-small-latest : rapide et économique, suffisant pour la plupart des questions
  • mistral-large-latest : plus précis pour les analyses complexes et le raisonnement
  • mistral-medium-latest : bon compromis entre vitesse et précision

Le choix dépend de la complexité de vos questions et de votre budget.

Conversation multi-tours

Vous pouvez poser des questions de suivi sur le même document :

historique = [
    {
        "role": "user",
        "content": [
            {"type": "text", "text": "Résume ce document en 3 points."},
            {
                "type": "document_url",
                "document_url": "https://exemple.com/rapport.pdf"
            }
        ]
    }
]

# Premier appel
response = client.chat.complete(
    model="mistral-small-latest",
    messages=historique
)

# Ajout de la réponse à l'historique
historique.append({
    "role": "assistant",
    "content": response.choices[0].message.content
})

# Question de suivi
historique.append({
    "role": "user",
    "content": "Détaille le deuxième point."
})

response = client.chat.complete(
    model="mistral-small-latest",
    messages=historique
)

print(response.choices[0].message.content)

Limites à connaître

  • Taille maximale : 50 Mo par fichier, 1 000 pages maximum
  • Consommation de tokens : les documents longs consomment beaucoup de tokens d’entrée
  • Pas de mémoire persistante : chaque appel est indépendant (sauf conversation multi-tours)
  • Précision : le LLM peut interpréter, pas seulement extraire, ce qui peut introduire des erreurs sur les chiffres précis

Points clés à retenir

  • Document QnA utilise l’endpoint Chat avec un contenu de type document_url ou document_base64
  • Le workflow interne est OCR puis LLM, mais un seul appel suffit
  • Trois méthodes d’envoi : URL, base64, fichier uploadé
  • Les conversations multi-tours permettent des analyses approfondies
  • Choisissez le modèle de chat selon la complexité de vos questions