Aller au contenu principal

File Search : indexer et interroger des documents

File Search : indexer et interroger des documents

File Search permet au modele de chercher dans vos documents prives. Vous uploadez des fichiers dans un vector store, et le modele les interroge automatiquement quand il a besoin d’une information. C’est la base du RAG integre a l’API OpenAI.

Creer un vector store

Avant d’utiliser File Search, vous devez creer un espace d’indexation :

from openai import OpenAI

client = OpenAI()

# Creer le vector store
vector_store = client.vector_stores.create(
    name="documentation-produit"
)
print(f"Vector store cree : {vector_store.id}")

Uploader et indexer des fichiers

Ajoutez vos documents au vector store. Les formats supportes incluent PDF, DOCX, TXT, MD, HTML, JSON, CSV et bien d’autres :

import os

# Upload d'un seul fichier
with open("guide-utilisateur.pdf", "rb") as f:
    fichier = client.files.create(file=f, purpose="assistants")

# Attacher au vector store
client.vector_stores.files.create(
    vector_store_id=vector_store.id,
    file_id=fichier.id
)

# Upload en lot
dossier = "./documentation/"
for nom_fichier in os.listdir(dossier):
    chemin = os.path.join(dossier, nom_fichier)
    if os.path.isfile(chemin):
        with open(chemin, "rb") as f:
            fichier = client.files.create(file=f, purpose="assistants")
        client.vector_stores.files.create(
            vector_store_id=vector_store.id,
            file_id=fichier.id
        )
        print(f"Indexe : {nom_fichier}")

Utilisez file_search dans le tableau tools et referencez le vector store :

response = client.responses.create(
    model="gpt-5.3",
    input="Quelle est la procedure de remboursement pour les clients premium ?",
    tools=[{
        "type": "file_search",
        "vector_store_ids": [vector_store.id]
    }]
)

print(response.output_text)

Le modele cherche automatiquement dans vos documents et formule une reponse basee sur le contenu trouve.

Examiner les resultats de recherche

La reponse inclut des annotations qui pointent vers les passages utilises :

response = client.responses.create(
    model="gpt-5.3",
    input="Quels sont les SLA garantis dans le contrat ?",
    tools=[{
        "type": "file_search",
        "vector_store_ids": [vector_store.id]
    }]
)

# Parcourir les annotations
for item in response.output:
    if item.type == "message":
        for block in item.content:
            if hasattr(block, "annotations"):
                for ann in block.annotations:
                    if ann.type == "file_citation":
                        print(f"Fichier : {ann.file_id}")
                        print(f"Position : {ann.start_index}-{ann.end_index}")

Configurer la recherche

Nombre de resultats

Controlez combien de passages sont recuperes :

response = client.responses.create(
    model="gpt-5.3",
    input="Liste toutes les clauses de penalite du contrat",
    tools=[{
        "type": "file_search",
        "vector_store_ids": [vector_store.id],
        "max_num_results": 20  # Defaut : 5, max : 50
    }]
)

Filtrage par metadonnees

Ajoutez des metadonnees a vos fichiers pour filtrer les recherches :

# Upload avec metadonnees
with open("contrat-2026.pdf", "rb") as f:
    fichier = client.files.create(file=f, purpose="assistants")

client.vector_stores.files.create(
    vector_store_id=vector_store.id,
    file_id=fichier.id,
    attributes={
        "type_document": "contrat",
        "annee": 2026,
        "client": "acme-corp"
    }
)

# Recherche filtree
response = client.responses.create(
    model="gpt-5.3",
    input="Quelle est la date d'echeance ?",
    tools=[{
        "type": "file_search",
        "vector_store_ids": [vector_store.id],
        "filters": {
            "type": "eq",
            "key": "type_document",
            "value": "contrat"
        }
    }]
)

Filtres composes

Combinez plusieurs criteres avec des operateurs logiques :

response = client.responses.create(
    model="gpt-5.3",
    input="Resume les obligations contractuelles de 2026",
    tools=[{
        "type": "file_search",
        "vector_store_ids": [vector_store.id],
        "filters": {
            "type": "and",
            "filters": [
                {"type": "eq", "key": "type_document", "value": "contrat"},
                {"type": "gte", "key": "annee", "value": 2026}
            ]
        }
    }]
)

Gerer le cycle de vie du vector store

Surveiller l’indexation

# Verifier le statut du vector store
vs = client.vector_stores.retrieve(vector_store.id)
print(f"Statut : {vs.status}")
print(f"Fichiers : {vs.file_counts.completed} indexes, "
      f"{vs.file_counts.in_progress} en cours, "
      f"{vs.file_counts.failed} en echec")

Supprimer des fichiers obsoletes

# Lister les fichiers du vector store
fichiers = client.vector_stores.files.list(vector_store.id)
for f in fichiers.data:
    print(f"{f.id} - {f.status}")

# Detacher un fichier
client.vector_stores.files.delete(
    vector_store_id=vector_store.id,
    file_id="file_abc123"
)

Exemple complet : assistant documentaire

def assistant_documentaire(question: str, vs_id: str) -> dict:
    """Assistant qui repond en se basant sur la documentation interne."""
    response = client.responses.create(
        model="gpt-5.3",
        instructions=(
            "Tu es un assistant documentaire. Reponds uniquement en te basant "
            "sur les documents fournis. Si l'information n'est pas dans les "
            "documents, dis-le clairement. Cite les sources."
        ),
        input=question,
        tools=[{
            "type": "file_search",
            "vector_store_ids": [vs_id],
            "max_num_results": 10
        }]
    )

    return {
        "reponse": response.output_text,
        "modele": response.model,
        "tokens": response.usage.total_tokens
    }

Points cles a retenir

  • Creez un vector store et uploadez vos fichiers pour activer File Search
  • Le modele decide seul quand chercher dans les documents
  • max_num_results controle la profondeur de recherche
  • Les metadonnees et filtres permettent une recherche ciblee
  • Surveillez le statut d’indexation avant d’interroger