← Blog & Conférences
Renaultconf

AI.GENERATE dans BigQuery ML — Vertex AI Gemini intégré au SQL

Renault Data & AI — Google Cloud SummitMars 2025📍 Technocentre Renault, Guyancourt

Durant mon stage chez Ampère (Renault Group), j'ai assisté à une session interne organisée par l'équipe Renault Data & AI en partenariat avec Google Cloud. Le sujet : AI.GENERATE, la nouvelle fonction BigQuery ML qui intègre directement les modèles Gemini dans le SQL — sans pipeline externe, sans orchestration supplémentaire.

Ce qu'est AI.GENERATE

AI.GENERATE envoie des requêtes à un modèle Gemini via Vertex AI et retourne un STRUCT contenant trois champs : result (la réponse du modèle), full_response (la réponse brute JSON), et status (le statut de l'appel). L'idée centrale : enrichir des données structurées avec de l'inférence IA directement dans une requête SQL, sur des tables BigQuery existantes.

Génération de texte sur des données tabulaires

Le cas le plus simple : passer un champ texte dans un prompt et récupérer une réponse. Exemple présenté — résumé d'articles BBC en une phrase :

SELECT
  title,
  AI.GENERATE(
    CONCAT("Summarize in one sentence: ", body)
  ).result AS article_summary
FROM `bigquery-public-data.bbc_news.fulltext`
LIMIT 3;

Le prompt est construit par concaténation — n'importe quelle colonne STRING peut être injectée. Le modèle par défaut est gemini-2.5-flash si aucun endpoint n'est précisé.

Extraction structurée sur schéma personnalisé

Ce qui m'a le plus intéressé : l'argument output_schema. Au lieu d'un result texte libre, le modèle retourne directement des colonnes typées selon un schéma défini en SQL. Exemple — extraction d'entités dans une description de patient :

SELECT
  AI.GENERATE(
    input,
    output_schema => '''
      name STRING,
      age INT64,
      address STRUCT<
        street_address STRING,
        city STRING,
        state STRING OPTIONS(description = '2-letter abbreviation')
      >,
      is_married BOOL,
      phone_number ARRAY<STRING>,
      weight_in_pounds FLOAT64
    '''
  ) AS info
FROM mydataset.patient_data;

Types supportés : STRING, INT64, FLOAT64, BOOL, ARRAY, STRUCT. La clause OPTIONS(description = ...) permet de guider le modèle sur l'interprétation d'un champ — c'est du prompt engineering au niveau du schéma.

Analyse d'images depuis Cloud Storage

La fonction accepte aussi des ObjectRefRuntime — des références vers des objets GCS obtenues via OBJ.GET_ACCESS_URL. Le prompt peut combiner texte et image dans un STRUCT :

SELECT
  uri,
  AI.GENERATE(
    ("What is this: ", OBJ.GET_ACCESS_URL(ref, 'r')),
    output_schema =>
      "image_description STRING, entities_in_the_image ARRAY<STRING>"
  ).*
FROM bqml_tutorial.product_images
WHERE uri LIKE "%aquarium%";

Contrainte présentée : une seule vidéo par prompt, durée max 2 minutes (seules les deux premières minutes sont traitées si plus long).

Grounding — Google Search et Google Maps

Via model_params, il est possible d'activer le grounding Search ou Maps pour ancrer les réponses du modèle dans des données temps-réel. Requis : Gemini 2.0+.

SELECT
  name,
  AI.GENERATE(
    ('Please check the weather of ', name, ' for today.'),
    model_params => JSON '{"tools": [{"googleSearch": {}}]}'
  )
FROM UNNEST(['Paris', 'Tokyo', 'New York']) AS name;

Modèle de quota et coûts

Deux modes de quota présentés — l'argument request_type contrôle lequel est utilisé :

  • DSQ (Dynamic Shared Quota) — quota partagé, pas d'achat préalable. Valeur SHARED.
  • Provisioned Throughput — quota dédié acheté à l'avance, débit garanti. Valeur DEDICATED. Si non disponible, erreur renvoyée.
  • UNSPECIFIED (défaut) — Provisioned Throughput en priorité si acheté, overflow sur DSQ sinon.

Point important soulevé : BigQuery peut traiter plus de lignes qu'attendu sur des requêtes complexes (JOIN, ORDER BY ... LIMIT). La recommandation présentée — matérialiser les résultats intermédiaires dans une table avant d'appeler AI.GENERATE dessus, pour contrôler strictement le volume facturé.

Ce que j'en retiens

Ce qui m'a frappé dans cette session c'est la cohérence avec ce que je faisais au quotidien sur mon pipeline ETL chez Ampère : tout reste dans BigQuery, pas de glue-code externe, pas de microservice à maintenir juste pour appeler un LLM. L'output_schema en particulier — c'est une façon propre de traiter de l'extraction structurée sur du texte non structuré, directement en SQL, sans post-traitement. La limite reste le contrôle des coûts sur des requêtes non trivialement simples.