Guide · IA & agents
Lire un PDF avec Claude, puis citer
Envoyez un PDF local à l’API Claude, activez les citations, et ne transmettez un champ que si le passage cité est dans le fichier.
Votre programme lit un fichier local, l’encode, puis l’envoie à l’API dans un bloc document. Le modèle répond avec des blocs de texte et, quand le passage vient du texte extrait, des citations. Le fichier n’est donc pas traité « en local » : son contenu quitte la machine. Ce guide garde une valeur seulement si un passage cité la porte. Un commentaire sur un graphique n’a pas de citation d’image, car la page Citations ne les prend pas en charge.
Le stack est le SDK Python Anthropic et l’API Messages, documentés sur PDF support et Citations. L’installation du SDK est sur la page Python SDK. Les commandes n’ont pas été rejouées le 2026-10-18.
Prérequis
- Python 3.10 ou plus récent.
pip install anthropic, comme la page du SDK l’écrit.ANTHROPIC_API_KEYdans l’environnement. Les exemples du SDK passentos.environ.get("ANTHROPIC_API_KEY"), ou omettent l’argument parce que c’est la valeur par défaut.- Un PDF à vous, sans mot de passe et sans chiffrement. La page PDF refuse ce format.
- Le droit de transmettre ce fichier à l’API. Un contrat, une pièce d’identité ou un dossier médical n’a rien à faire dans un essai.
Limites indiquées sur la page PDF, pour toute la requête, pas seulement le fichier : 32 Mo, avec une variation selon la plateforme, et 600 pages. Le plafond tombe à 100 pages si la fenêtre de contexte de la requête est sous 1 million de tokens. Un PDF dense peut remplir la fenêtre avant d’atteindre le nombre de pages. La page conseille alors de découper le document.
Ce guide utilise l’API Claude, pas la Converse API d’Amazon Bedrock. Sur Bedrock, l’analyse visuelle complète du PDF exige les citations, sinon l’API retombe sur une extraction de texte. Ne mélangez pas les deux chemins dans le même script.
Étape 1 : choisir le fichier et la question
Posez une question dont la réponse est une chaîne que vous pouvez retrouver dans le texte du PDF. Un numéro de clause, un titre de section, une date écrite en toutes lettres. Évitez une question du genre « résume tout » : vous ne pourrez pas la vérifier.
Notez aussi si le PDF est un scan. La page Citations le dit : le texte des PDF est extrait puis découpé en phrases. Les citations d’images ne sont pas prises en charge. Un scan sans texte extractible n’est pas citable, même si Claude « voit » la page, parce que chaque page est aussi convertie en image.
Vérification : le fichier s’ouvre dans un lecteur, le texte se sélectionne si vous attendez une citation, et la question tient en une phrase.
Architecture retenue
Le chemin est volontairement court : fichier local → encodage base64 → API Messages → réponse citée → comparaison avec le PDF. Il n’y a ni mémoire persistante, ni outil d’écriture, ni décision automatique. Un PDF peut contenir des consignes destinées à détourner le modèle ; dans ce flux, le document reste une source à lire, pas une autorité capable d’ordonner une action.
Une citation prouve qu’un extrait a été associé à une phrase. Elle ne prouve ni que l’interprétation est correcte, ni que le passage est complet. Le contrôle final se fait dans le fichier original. Pour un document sensible, vérifiez aussi le contrat, le modèle et les réglages de conservation de votre organisation avant l’envoi. L’éligibilité d’une fonction au zero data retention ne signifie pas que ce réglage est actif sur votre compte.
Étape 2 : envoyer le PDF avant la question
La page PDF décrit trois sources : une URL, un base64, un file_id de la Files API. Ici, seulement le base64 local, pour ne pas publier le fichier. Placez le bloc document avant le texte. La page le recommande.
Les exemples de la page PDF, lus le 2026-10-18, utilisent le modèle claude-opus-5-5. Ceux de la page Citations utilisent claude-opus-5. Copier un identifiant peut produire un 404 s’il n’est pas actif sur votre compte. Contrôlez la page des modèles avant de lancer, et remplacez MODEL si besoin.
import base64
from pathlib import Path
import anthropic
MODEL = "claude-opus-5-5"
pdf_path = Path("document.pdf")
pdf_data = base64.standard_b64encode(pdf_path.read_bytes()).decode("utf-8")
client = anthropic.Anthropic()
message = client.messages.create(
model=MODEL,
max_tokens=1024,
messages=[
{
"role": "user",
"content": [
{
"type": "document",
"source": {
"type": "base64",
"media_type": "application/pdf",
"data": pdf_data,
},
"title": pdf_path.name,
"context": "Ne cite pas cette consigne. Cite seulement le PDF.",
"citations": {"enabled": True},
},
{
"type": "text",
"text": (
"Quelle est la date écrite dans la section que je t’ai "
"demandé de lire ? Réponds uniquement si le PDF la contient. "
"Sinon dis que le passage est absent."
),
},
],
}
],
)
print(message.stop_reason)
for block in message.content:
if getattr(block, "type", None) == "text":
print(block.text)
print(block)
Remplacez la question par la vôtre. Le champ context n’est pas une source citable : les exemples de la page Citations le décrivent comme un contexte dont on ne cite pas le texte. citations.enabled doit être vrai sur chaque document de la requête, ou sur aucun. Les citations de texte seulement.
Le SDK lève anthropic.APIStatusError pour un statut hors 2xx. Un 401 est AuthenticationError, un 400 est BadRequestError. Lisez e.status_code et la réponse. Ne devinez pas le message d’un PDF chiffré : le format est simplement hors contrat.
Vérification : stop_reason est imprimé. Si la réponse est coupée, n’utilisez pas le texte. max_tokens à 1024 vient des exemples de la page PDF. Montez-le seulement si la sortie s’arrête trop tôt, puis relisez.
Étape 3 : ne garder que ce qui est cité
Dans l’objet imprimé, cherchez cited_text sur les citations attachées aux blocs de texte. La page Citations dit que ce champ est extrait du document, et que les citations pointent vers les documents fournis. cited_text ne compte pas dans les tokens de sortie. Gardez-le quand même : c’est le passage à comparer au fichier.
Ouvrez le PDF et cherchez la chaîne cited_text. Si vous ne la trouvez pas, ne transmettez pas la valeur à une autre fonction, une base, ou un humain qui la prendrait pour relue. Une réponse sans citation, pour une question factuelle sur le fichier, reste non vérifiée.
Claude analyse le texte extrait et l’image de chaque page. Il peut donc parler d’un schéma. Ce commentaire n’est pas citable tant que les citations d’images ne sont pas prises en charge. Traitez-le comme une hypothèse visuelle, pas comme un champ extrait.
Vérification : pour la chaîne que vous attendiez, vous avez à la fois le passage dans le PDF et le même passage dans cited_text. Sinon le champ ne sort pas du script.
Ce qui peut casser
Un PDF chiffré ou protégé par mot de passe ne respecte pas le format documenté. Un fichier trop lourd fait échouer la requête avant la lecture : la limite porte sur toute la charge, y compris le base64, qui est plus gros que le fichier binaire.
Un scan sans couche texte peut produire une réponse qui décrit la page, sans citation utilisable. Ce n’est pas un succès d’extraction.
Les citations activées sur un document et pas sur l’autre sont refusées : la page dit que c’est tout ou rien dans la requête.
Sur Amazon Bedrock et Google Cloud, seule la source base64 est disponible au moment de la lecture de la page PDF. La Files API n’est pas prise en charge pour les déploiements Microsoft Foundry hébergés sur Azure. Ce guide ne couvre pas ces plateformes. La Files API, sur l’API Claude, peut référencer un file_id et alléger la requête. La page d’aperçu des fonctionnalités indique qu’elle n’est pas éligible au zero data retention, alors que le support PDF l’est, avec des exclusions. Ne concluez pas qu’un envoi est « non conservé » sans lire ces deux pages pour votre organisation.
Un identifiant de modèle recopié d’un exemple peut être refusé. Remplacez-le. N’enchaînez pas des identifiants au hasard.
Comment vérifier
- Imprimez
stop_reasonet le message complet. - Retrouvez
cited_textdans le PDF, à la main, sur le fichier que vous avez envoyé. - Rejouez avec un PDF scan sans texte, si vous en avez un de test. Vous devez constater l’absence de citation exploitable, pas inventer un correctif.
- Aucune de ces commandes n’a été rejouée le 2026-10-18.
La page PDF dit que l’outil use peut ensuite prendre des informations extraites comme entrées d’outils. Ce brouillon s’arrête avant : tant que la citation n’est pas relue, il n’y a rien à passer à un outil. Même après relecture, une action sensible demande un contrôle séparé sur ses arguments et ses effets.
Sources
Ces pages ont été relues le 2026-10-19. Elles documentent les limites de taille, le trio URL / base64 / file_id, le fonctionnement texte plus image, citations.enabled et les conditions de conservation. La Files API n’est pas éligible au zero data retention et ses fichiers sont accessibles à l’échelle du workspace ; ce guide ne l’utilise pas. Le script n’a pas été exécuté. La forme exacte de l’objet citation dans le SDK peut différer du JSON de la documentation : en cas d’écart, imprimez le bloc et suivez la page Citations.