Analizzare dati multimodali con SQL e UDF Python

Questo tutorial mostra come analizzare dati multimodali utilizzando query SQL e funzioni definite dall'utente (UDF) in Python.

Questo tutorial utilizza il catalogo prodotti del set di dati pubblico del negozio di animali Cymbal.

Obiettivi

  • Utilizza i valori ObjectRef per archiviare i dati delle immagini insieme ai dati strutturati in una tabella standard BigQuery.
  • Genera testo basato sui dati delle immagini di una tabella standard utilizzando la funzione AI.GENERATE_TABLE.
  • Trasforma le immagini esistenti per crearne di nuove utilizzando una UDF Python.
  • Dividi i PDF in blocchi per un'ulteriore analisi utilizzando una UDF Python.
  • Utilizza un modello Gemini e la funzione ML.GENERATE_TEXT per analizzare i dati PDF suddivisi in blocchi.
  • Genera incorporamenti basati sui dati delle immagini di una tabella standard utilizzando la funzione ML.GENERATE_EMBEDDING.
  • Elabora dati multimodali ordinati utilizzando array di valori ObjectRef.

Costi

In questo documento utilizzi i seguenti componenti fatturabili di Google Cloud:

  • BigQuery: you incur costs for the data that you process in BigQuery.
  • BigQuery Python UDFs: you incur costs for using Python UDFs.
  • Cloud Storage: you incur costs for the objects stored in Cloud Storage.
  • Vertex AI: you incur costs for calls to Vertex AI models.

Per generare una stima dei costi in base all'utilizzo previsto, utilizza il calcolatore prezzi.

I nuovi Google Cloud utenti potrebbero avere diritto a una prova gratuita.

Per ulteriori informazioni, consulta le seguenti pagine dei prezzi:

Prima di iniziare

  1. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  2. Make sure that billing is enabled for your Google Cloud project.

  3. Enable the BigQuery, BigQuery Connection, Cloud Storage, and Vertex AI APIs.

    Enable the APIs

Ruoli obbligatori

Per ottenere le autorizzazioni necessarie per completare questo tutorial, chiedi all'amministratore di concederti i seguenti ruoli IAM:

Per saperne di più sulla concessione dei ruoli, consulta Gestisci l'accesso a progetti, cartelle e organizzazioni.

Potresti anche riuscire a ottenere le autorizzazioni richieste tramite i ruoli personalizzati o altri ruoli predefiniti.

Configura

In questa sezione, crei il set di dati, la connessione, le tabelle e i modelli utilizzati in questo tutorial.

Crea un set di dati

Crea un set di dati BigQuery che contenga gli oggetti che crei in questo tutorial:

  1. Nella console Google Cloud , vai alla pagina BigQuery.

    Vai a BigQuery

  2. Nel riquadro Explorer, seleziona il progetto.

  3. Espandi l'opzione Azioni e fai clic su Crea set di dati. Si apre il riquadro Crea set di dati.

  4. In ID set di dati, digita cymbal_pets.

  5. Fai clic su Crea set di dati.

Crea un bucket

Crea un bucket Cloud Storage per archiviare gli oggetti trasformati:

  1. Vai alla pagina Bucket.

    Vai a Bucket

  2. Fai clic su Crea.

  3. Nella pagina Crea un bucket, inserisci un nome univoco globale che soddisfi i requisiti per il nome del bucket nella sezione Inizia.

  4. Fai clic su Crea.

Crea una connessione

Crea una connessione risorsa Cloud e ottieni il account di servizio della connessione. BigQuery utilizza la connessione per accedere agli oggetti in Cloud Storage:

  1. Vai alla pagina BigQuery.

    Vai a BigQuery

  2. Nel riquadro Explorer, fai clic su Aggiungi dati.

    Si apre la finestra di dialogo Aggiungi dati.

  3. Nel riquadro Filtra per, seleziona Applicazioni aziendali nella sezione Tipo di origine dati.

    In alternativa, nel campo Cerca origini dati, puoi inserire Vertex AI.

  4. Nella sezione Origini dati in evidenza, fai clic su Vertex AI.

  5. Fai clic sulla scheda della soluzione Vertex AI Models: BigQuery Federation.

  6. Nell'elenco Tipo di connessione, seleziona Modelli remoti di Vertex AI, funzioni remote e BigLake (risorsa Cloud).

  7. Nel campo ID connessione, digita cymbal_conn.

  8. Fai clic su Crea connessione.

  9. Fai clic su Vai alla connessione.

  10. Nel riquadro Informazioni sulla connessione, copia l'ID del account di servizio da utilizzare in un passaggio successivo.

Concedi le autorizzazioni al account di servizio della connessione

Concedi all'account di servizio della connessione i ruoli appropriati per accedere ad altri servizi. Devi concedere questi ruoli nello stesso progetto che hai creato o selezionato nella sezione Prima di iniziare. La concessione dei ruoli in un progetto diverso genera l'errore bqcx-1234567890-xxxx@gcp-sa-bigquery-condel.iam.gserviceaccount.com does not have the permission to access resource.

Concedere le autorizzazioni per il bucket Cloud Storage

Concedi all'account di servizio l'accesso per utilizzare gli oggetti nel bucket che hai creato:

  1. Vai alla pagina Bucket.

    Vai a Bucket

  2. Fai clic sul nome del bucket che hai creato.

  3. Fai clic su Autorizzazioni.

  4. Fai clic su Concedi l'accesso. Si apre la finestra di dialogo Concedi l'accesso.

  5. Nel campo Nuove entità, inserisci l'ID account di servizio che hai copiato in precedenza.

  6. Nel campo Seleziona un ruolo, scegli Cloud Storage e poi seleziona Utente oggetti Storage.

  7. Fai clic su Salva.

Concedi le autorizzazioni per utilizzare i modelli Vertex AI

Concedi all'account di servizio l'accesso per utilizzare i modelli Vertex AI:

  1. Vai alla pagina IAM e amministrazione.

    Vai a IAM e amministrazione

  2. Fai clic su Concedi l'accesso. Si apre la finestra di dialogo Concedi l'accesso.

  3. Nel campo Nuove entità, inserisci l'ID account di servizio che hai copiato in precedenza.

  4. Nel campo Seleziona un ruolo, seleziona Vertex AI, quindi seleziona Utente Vertex AI.

  5. Fai clic su Salva.

Crea le tabelle dei dati di esempio

Crea tabelle per archiviare le informazioni sui prodotti per animali domestici Cymbal.

Crea la tabella products

Crea una tabella standard contenente le informazioni sui prodotti per animali domestici Cymbal:

  1. Nella console Google Cloud , vai alla pagina BigQuery.

    Vai a BigQuery

  2. Nell'editor di query, esegui la seguente query per creare la tabella products:

    LOAD DATA OVERWRITE cymbal_pets.products
    FROM
      FILES(
        format = 'avro',
        uris = [
          'gs://cloud-samples-data/bigquery/tutorials/cymbal-pets/tables/products/products_*.avro']);

Crea la tabella product_images

Crea una tabella degli oggetti che contenga le immagini dei prodotti per animali domestici Cymbal:

  • Nell'editor di query della pagina BigQuery, esegui la query seguente per creare la tabella product_images:

    CREATE OR REPLACE EXTERNAL TABLE cymbal_pets.product_images
      WITH CONNECTION `us.cymbal_conn`
      OPTIONS (
        object_metadata = 'SIMPLE',
        uris = ['gs://cloud-samples-data/bigquery/tutorials/cymbal-pets/images/*.png'],
        max_staleness = INTERVAL 30 MINUTE,
        metadata_cache_mode = AUTOMATIC);

Crea la tabella product_manuals

Crea una tabella degli oggetti che contenga i manuali dei prodotti per gli animali domestici Cymbal:

  • Nell'editor di query della pagina BigQuery, esegui la query seguente per creare la tabella product_manuals:

    CREATE OR REPLACE EXTERNAL TABLE cymbal_pets.product_manuals
      WITH CONNECTION `us.cymbal_conn`
      OPTIONS (
        object_metadata = 'SIMPLE',
        uris = ['gs://cloud-samples-data/bigquery/tutorials/cymbal-pets/documents/*.pdf']);

Creare un modello di generazione del testo

Crea un modello remoto BigQuery ML che rappresenti un modello Gemini di Vertex AI:

  • Nell'editor di query della pagina BigQuery, esegui la seguente query per creare il modello remoto:

    CREATE OR REPLACE MODEL `cymbal_pets.gemini`
      REMOTE WITH CONNECTION `us.cymbal_conn`
      OPTIONS (ENDPOINT = 'gemini-2.0-flash');

Crea un modello di generazione di incorporamenti

Crea un modello remoto BigQuery ML che rappresenti un modello di incorporamento multimodale Vertex AI:

  • Nell'editor di query della pagina BigQuery, esegui la seguente query per creare il modello remoto:

    CREATE OR REPLACE MODEL `cymbal_pets.embedding_model`
      REMOTE WITH CONNECTION `us.cymbal_conn`
      OPTIONS (ENDPOINT = 'multimodalembedding@001');

Crea una tabella products_mm con dati multimodali

Crea una tabella products_mm che contenga una colonna image compilata con le immagini dei prodotti della tabella degli oggetti product_images. La colonna image che viene creata è una colonna STRUCT che utilizza il formato ObjectRef.

  1. Nell'editor di query della pagina BigQuery, esegui la query seguente per creare la tabella products_mm e compilare la colonna image:

    CREATE OR REPLACE TABLE cymbal_pets.products_mm
    AS
    SELECT products.* EXCEPT (uri), ot.ref AS image FROM cymbal_pets.products
    INNER JOIN cymbal_pets.product_images ot
    ON ot.uri = products.uri;
  2. Nell'editor di query della pagina BigQuery, esegui la seguente query per visualizzare i dati della colonna image:

    SELECT product_name, image
    FROM cymbal_pets.products_mm`

    I risultati sono simili ai seguenti:

    +--------------------------------+--------------------------------------+-----------------------------------------------+------------------------------------------------+
    | product_name                   | image.uri                            | image.version | image.authorizer              | image.details                                  |
    +--------------------------------+--------------------------------------+-----------------------------------------------+------------------------------------------------+
    |  AquaClear Aquarium Background | gs://cloud-samples-data/bigquery/    | 1234567891011 | myproject.region.myconnection | {"gcs_metadata":{"content_type":"image/png",   |
    |                                | tutorials/cymbal-pets/images/        |               |                               | "md5_hash":"494f63b9b137975ff3e7a11b060edb1d", |
    |                                | aquaclear-aquarium-background.png    |               |                               | "size":1282805,"updated":1742492680017000}}    |
    +--------------------------------+--------------------------------------+-----------------------------------------------+------------------------------------------------+
    |  AquaClear Aquarium            | gs://cloud-samples-data/bigquery/    | 2345678910112 | myproject.region.myconnection | {"gcs_metadata":{"content_type":"image/png",   |
    |  Gravel Vacuum                 | tutorials/cymbal-pets/images/        |               |                               | "md5_hash":"b7bfc2e2641a77a402a1937bcf0003fd", |
    |                                | aquaclear-aquarium-gravel-vacuum.png |               |                               | "size":820254,"updated":1742492682411000}}     |
    +--------------------------------+--------------------------------------+-----------------------------------------------+------------------------------------------------+
    | ...                            | ...                                  | ...           |                               | ...                                            |
    +--------------------------------+--------------------------------------+-----------------------------------------------+------------------------------------------------+
    

Generare informazioni sui prodotti utilizzando un modello Gemini

Utilizza un modello Gemini per generare i seguenti dati per i prodotti del negozio di animali:

  • Aggiungi una colonna image_description alla tabella products_mm.
  • Compila le colonne animal_type, search_keywords e subcategory della tabella products_mm.
  • Esegui una query che restituisca una descrizione di ogni brand di prodotto e anche un conteggio del numero di prodotti di quel brand. La descrizione del brand viene generata analizzando le informazioni sui prodotti di tutti i prodotti di quel brand, comprese le immagini dei prodotti.
  1. Nell'editor di query della pagina BigQuery, esegui la query seguente per creare e compilare la colonna image_description:

    CREATE OR REPLACE TABLE cymbal_pets.products_mm
    AS
    SELECT
      product_id,
      product_name,
      brand,
      category,
      subcategory,
      animal_type,
      search_keywords,
      price,
      description,
      inventory_level,
      supplier_id,
      average_rating,
      image,
      image_description
    FROM
      AI.GENERATE_TABLE(
        MODEL `cymbal_pets.gemini`,
        (
          SELECT
            ('Can you describe the following image?', OBJ.GET_ACCESS_URL(image, 'r')) AS prompt,
            *
          FROM
            cymbal_pets.products_mm
        ),
        STRUCT('image_description STRING' AS output_schema));
  2. Nell'editor di query della pagina BigQuery, esegui la seguente query per aggiornare le colonne animal_type, search_keywords e subcategory con i dati generati:

    UPDATE cymbal_pets.products_mm p
    SET
      p.animal_type = s.animal_type,
      p.search_keywords = s.search_keywords,
      p.subcategory = s.subcategory
    FROM
      (
        SELECT
          animal_type,
          search_keywords,
          subcategory,
          uri
        FROM
          AI.GENERATE_TABLE(
            MODEL `cymbal_pets.gemini`,
            (
              SELECT
                (
                  'For the image of a pet product, concisely generate the following metadata.'
                    '1) animal_type and 2) 5 SEO search keywords, and 3) product subcategory',
                  OBJ.GET_ACCESS_URL(image, 'r'),
                  description) AS prompt,
                image.uri AS uri,
              FROM cymbal_pets.products_mm
            ),
            STRUCT(
              'animal_type STRING, search_keywords ARRAY<STRING>, subcategory STRING' AS output_schema,
              100 AS max_output_tokens))
      ) s
    WHERE p.image.uri = s.uri;
  3. Nell'editor di query della pagina BigQuery, esegui la seguente query per visualizzare i dati generati:

    SELECT
      product_name,
      image_description,
      animal_type,
      search_keywords,
      subcategory,
    FROM cymbal_pets.products_mm;

    I risultati sono simili ai seguenti:

    +--------------------------------+-------------------------------------+-------------+------------------------+------------------+
    | product_name                   | image.description                   | animal_type | search_keywords        | subcategory      |
    +--------------------------------+-------------------------------------+-------------+------------------------+------------------+
    |  AquaClear Aquarium Background | The image shows a colorful coral    | fish        | aquarium background    | aquarium decor   |
    |                                | reef backdrop. The background is a  |             | fish tank backdrop     |                  |
    |                                | blue ocean with a bright light...   |             | coral reef decor       |                  |
    |                                |                                     |             | underwater scenery     |                  |
    |                                |                                     |             | aquarium decoration    |                  |
    +--------------------------------+-------------------------------------+-------------+------------------------+------------------+
    |  AquaClear Aquarium            | The image shows a long, clear       | fish        | aquarium gravel vacuum | aquarium         |
    |  Gravel Vacuum                 | plastic tube with a green hose      |             | aquarium cleaning      | cleaning         |
    |                                | attached to one end. The tube...    |             | aquarium maintenance   |                  |
    |                                |                                     |             | fish tank cleaning     |                  |
    |                                |                                     |             | gravel siphon          |                  |
    +--------------------------------+-------------------------------------+-------------+------------------------+------------------+
    | ...                            | ...                                 | ...         |  ...                   | ...              |
    +--------------------------------+-------------------------------------+-------------+------------------------+------------------+
    
  4. Nell'editor di query della pagina BigQuery, esegui la query seguente per generare una descrizione di ogni brand di prodotto e anche un conteggio del numero di prodotti di quel brand:

    SELECT
      brand,
      brand_description,
      cnt
    FROM
      AI.GENERATE_TABLE(
        MODEL `cymbal_pets.gemini`,
        (
          SELECT
            brand,
            COUNT(*) AS cnt,
            (
              'Use the images and text to give one concise brand description for a website brand page.'
                'Return the description only.',
              ARRAY_AGG(OBJ.GET_ACCESS_URL(image, 'r')),
              ARRAY_AGG(description),
              ARRAY_AGG(category),
              ARRAY_AGG(subcategory)) AS prompt
          FROM cymbal_pets.products_mm
          GROUP BY brand
        ),
        STRUCT('brand_description STRING' AS output_schema))
    ORDER BY cnt DESC;

    I risultati sono simili ai seguenti:

    +--------------+-------------------------------------+-----+
    | brand        | brand.description                   | cnt |
    +--------------+-------------------------------------+-----+
    |  AquaClear   | AquaClear is a brand of aquarium    | 33  |
    |              | and pond care products that offer   |     |
    |              | a wide range of solutions for...    |     |
    +--------------+-------------------------------------+-----+
    |  Ocean       | Ocean Bites is a brand of cat food  | 28  |
    |  Bites       | that offers a variety of recipes    |     |
    |              | and formulas to meet the specific.. |     |
    +--------------+-------------------------------------+-----+
    |  ...         | ...                                 |...  |
    +--------------+-------------------------------------+-----+
    

Crea una funzione definita dall'utente Python per trasformare le immagini prodotto

Crea una UDF Python per convertire le immagini dei prodotti in scala di grigi.

La funzione definita dall'utente Python utilizza librerie open source e anche l'esecuzione parallela per trasformare più immagini contemporaneamente.

  1. Nell'editor di query della pagina BigQuery, esegui la query seguente per creare la UDF to_grayscale:

    CREATE OR REPLACE FUNCTION cymbal_pets.to_grayscale(src_json STRING, dst_json STRING)
    RETURNS STRING
    LANGUAGE python
    WITH CONNECTION `us.cymbal_conn`
    OPTIONS (entry_point='to_grayscale', runtime_version='python-3.11', packages=['numpy', 'opencv-python'])
    AS """
    
    import cv2 as cv
    import numpy as np
    from urllib.request import urlopen, Request
    import json
    
    # Transform the image to grayscale.
    def to_grayscale(src_ref, dst_ref):
      src_json = json.loads(src_ref)
      srcUrl = src_json["access_urls"]["read_url"]
    
      dst_json = json.loads(dst_ref)
      dstUrl = dst_json["access_urls"]["write_url"]
    
      req = urlopen(srcUrl)
      arr = np.asarray(bytearray(req.read()), dtype=np.uint8)
      img = cv.imdecode(arr, -1) # 'Load it as it is'
    
      # Convert the image to grayscale
      gray_image = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
    
      # Send POST request to the URL
      _, img_encoded = cv.imencode('.png', gray_image)
    
      req = Request(url=dstUrl, data=img_encoded.tobytes(), method='PUT', headers = {
          "Content-Type": "image/png",
      })
      with urlopen(req) as f:
          pass
      return dst_ref
    """;

Trasformare le immagini prodotto

Crea la tabella products_grayscale con una colonna ObjectRef che contenga i percorsi di destinazione e gli autorizzatori per le immagini in scala di grigi. Il percorso di destinazione viene ricavato dal percorso dell'immagine originale.

Dopo aver creato la tabella, esegui la funzione to_grayscale per creare le immagini in scala di grigi, scriverle in un bucket Cloud Storage e poi restituire i valori ObjectRefRuntime contenenti URL di accesso e metadati per le immagini in scala di grigi.

  1. Nell'editor di query della pagina BigQuery, esegui la query seguente per creare la tabella products_grayscale:

    CREATE OR REPLACE TABLE cymbal_pets.products_grayscale
    AS
    SELECT
      product_id,
      product_name,
      image,
      OBJ.MAKE_REF(
        CONCAT('gs://BUCKET/cymbal-pets-images/grayscale/', REGEXP_EXTRACT(image.uri, r'([^/]+)$')),
        'us.cymbal_conn') AS gray_image
    FROM cymbal_pets.products_mm;

    Sostituisci BUCKET con il nome del bucket che hai creato.

  2. Nell'editor di query della pagina BigQuery, esegui la seguente query per creare le immagini in scala di grigi, scriverle in un bucket Cloud Storage e poi restituire i valori ObjectRefRuntime contenenti URL di accesso e metadati per le immagini in scala di grigi:

    SELECT cymbal_pets.to_grayscale(
      TO_JSON_STRING(OBJ.GET_ACCESS_URL(image, 'r')),
      TO_JSON_STRING(OBJ.GET_ACCESS_URL(gray_image, 'rw')))
    FROM cymbal_pets.products_grayscale;

    I risultati sono simili ai seguenti:

    +-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
    | f0                                                                                                                                                                    |
    +-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
    | {"access_urls":{"expiry_time":"2025-04-26T03:00:48Z",                                                                                                                 |
    | "read_url":"https://storage.googleapis.com/mybucket/cymbal-pets-images%2Fgrayscale%2Focean-bites-salmon-%26-tuna-cat-food.png?additional_read URL_information",       |
    | "write_url":"https://storage.googleapis.com/myproject/cymbal-pets-images%2Fgrayscale%2Focean-bites-salmon-%26-tuna-cat-food.png?additional_write URL_information"},   |
    | "objectref":{"authorizer":"myproject.region.myconnection","uri":"gs://myproject/cymbal-pets-images/grayscale/ocean-bites-salmon-&-tuna-cat-food.png"}}                |
    +-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
    | {"access_urls":{"expiry_time":"2025-04-26T03:00:48Z",                                                                                                                 |
    | "read_url":"https://storage.googleapis.com/mybucket/cymbal-pets-images%2Fgrayscale%2Ffluffy-buns-guinea-pig-tunnel.png?additional _read URL_information",             |
    | "write_url":"https://storage.googleapis.com/myproject/cymbal-pets-images%2Fgrayscale%2Focean-bites-salmon-%26-tuna-cat-food.png?additional_write_URL_information"},   |
    | "objectref":{"authorizer":"myproject.region.myconnection","uri":"gs://myproject/cymbal-pets-images%2Fgrayscale%2Ffluffy-buns-guinea-pig-tunnel.png"}}                 |
    +-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
    |  ...                                                                                                                                                                  |
    +-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
    

Crea una funzione definita dall'utente Python per dividere i dati PDF in blocchi

Crea una UDF Python per dividere gli oggetti PDF che contengono i manuali dei prodotti per animali domestici Cymbal in più parti.

I PDF sono spesso molto grandi e potrebbero non rientrare in una singola chiamata a un modello di AI generativa. Dividendo i PDF in blocchi, puoi archiviare i dati in un formato pronto per il modello per semplificare l'analisi.

  1. Nell'editor di query della pagina BigQuery, esegui la seguente query per creare la UDF chunk_pdf:

    -- This function chunks the product manual PDF into multiple parts.
    -- The function accepts an ObjectRefRuntime value for the PDF file and the chunk size.
    -- It then parses the PDF, chunks the contents, and returns an array of chunked text.
    CREATE OR REPLACE FUNCTION cymbal_pets.chunk_pdf(src_json STRING, chunk_size INT64, overlap_size INT64)
    RETURNS ARRAY<STRING>
    LANGUAGE python
    WITH CONNECTION `us.cymbal_conn`
    OPTIONS (entry_point='chunk_pdf', runtime_version='python-3.11', packages=['pypdf'])
    AS """
    import io
    import json
    
    from pypdf import PdfReader  # type: ignore
    from urllib.request import urlopen, Request
    
    def chunk_pdf(src_ref: str, chunk_size: int, overlap_size: int) -> str:
      src_json = json.loads(src_ref)
      srcUrl = src_json["access_urls"]["read_url"]
    
      req = urlopen(srcUrl)
      pdf_file = io.BytesIO(bytearray(req.read()))
      reader = PdfReader(pdf_file, strict=False)
    
      # extract and chunk text simultaneously
      all_text_chunks = []
      curr_chunk = ""
      for page in reader.pages:
          page_text = page.extract_text()
          if page_text:
              curr_chunk += page_text
              # split the accumulated text into chunks of a specific size with overlaop
              # this loop implements a sliding window approach to create chunks
              while len(curr_chunk) >= chunk_size:
                  split_idx = curr_chunk.rfind(" ", 0, chunk_size)
                  if split_idx == -1:
                      split_idx = chunk_size
                  actual_chunk = curr_chunk[:split_idx]
                  all_text_chunks.append(actual_chunk)
                  overlap = curr_chunk[split_idx + 1 : split_idx + 1 + overlap_size]
                  curr_chunk = overlap + curr_chunk[split_idx + 1 + overlap_size :]
      if curr_chunk:
          all_text_chunks.append(curr_chunk)
    
      return all_text_chunks
    """;

Analizzare i dati PDF

Esegui la funzione chunk_pdf per dividere i dati PDF nella tabella product_manuals e poi crea una tabella product_manual_chunk_strings che contenga un blocco PDF per riga. Utilizza un modello Gemini sui dati product_manual_chunk_strings per riassumere le informazioni legali contenute nei manuali del prodotto.

  1. Nell'editor di query della pagina BigQuery, esegui la query seguente per creare la tabella product_manual_chunk_strings:

    CREATE OR REPLACE TABLE cymbal_pets.product_manual_chunk_strings
    AS
    SELECT chunked
    FROM cymbal_pets.product_manuals,
    UNNEST (cymbal_pets.chunk_pdf(
      TO_JSON_STRING(
        OBJ.GET_ACCESS_URL(OBJ.MAKE_REF(uri, 'us.cymbal_conn'), 'r')),
        1000,
        100
    )) as chunked;
  2. Nell'editor di query della pagina BigQuery, esegui la query seguente per analizzare i dati PDF utilizzando un modello Gemini:

    SELECT
      ml_generate_text_llm_result
    FROM
      ML.GENERATE_TEXT(
        MODEL `cymbal_pets.gemini`,
        (
          SELECT
            (
              'Can you summarize the product manual as bullet points? Highlight the legal clauses',
              chunked) AS prompt,
          FROM cymbal_pets.product_manual_chunk_strings
        ),
        STRUCT(
          TRUE AS FLATTEN_JSON_OUTPUT));

    I risultati sono simili ai seguenti:

    +-------------------------------------------------------------------------------------------------------------------------------------------+
    | ml_generate_text_llm_result                                                                                                               |
    +-------------------------------------------------------------------------------------------------------------------------------------------+
    | ## CritterCuisine Pro 5000 Automatic Pet Feeder Manual Summary:                                                                           |
    |                                                                                                                                           |
    | **Safety:**                                                                                                                               |
    |                                                                                                                                           |
    | * **Stability:** Place feeder on a level, stable surface to prevent tipping.                                                              |
    | * **Power Supply:** Only use the included AC adapter. Using an incompatible adapter can damage the unit and void the warranty.            |
    | * **Cord Safety:** Keep the power cord out of reach of pets to prevent chewing or entanglement.                                           |
    | * **Children:** Supervise children around the feeder. This is not a toy.                                                                  |
    | * **Pet Health:** Consult your veterinarian before using an automatic feeder if your pet has special dietary needs, health conditions, or |
    +-------------------------------------------------------------------------------------------------------------------------------------------+
    | ## Product Manual Summary:                                                                                                                |
    |                                                                                                                                           |
    | **6.3 Manual Feeding:**                                                                                                                   |
    |                                                                                                                                           |
    | * Press MANUAL button to dispense a single portion (Meal 1 size). **(Meal Enabled)**                                                      |
    |                                                                                                                                           |
    | **6.4 Recording a Voice Message:**                                                                                                        |
    |                                                                                                                                           |
    | * Press and hold VOICE button.                                                                                                            |
    | * Speak clearly into the microphone (up to 10 seconds).                                                                                   |
    | * Release VOICE button to finish recording.                                                                                               |
    | * Briefly press VOICE button to play back the recording.                                                                                  |
    | * To disable the voice message, record a blank message (hold VOICE button for 10 seconds without speaking). **(Meal Enabled)**            |
    |                                                                                                                                           |
    | **6.5 Low Food Level Indicator:**                                                                                                         |
    +-------------------------------------------------------------------------------------------------------------------------------------------+
    | ...                                                                                                                                       |
    +-------------------------------------------------------------------------------------------------------------------------------------------+
    

Genera incorporamenti dai dati immagine, quindi utilizzali per restituire immagini simili utilizzando la ricerca vettoriale.

In uno scenario di produzione, ti consigliamo di creare un indice vettoriale prima di eseguire una ricerca vettoriale. Un indice vettoriale ti consente di eseguire la ricerca vettoriale più rapidamente, a scapito della riduzione del richiamo e quindi della restituzione di risultati più approssimativi.

  1. Nell'editor di query della pagina BigQuery, esegui la seguente query per creare la tabella products_embeddings:

    CREATE OR REPLACE TABLE cymbal_pets.products_embedding
    AS
    SELECT product_id, ml_generate_embedding_result as embedding, content as image
    FROM ML.GENERATE_EMBEDDING(
    MODEL `cymbal_pets.embedding_model`,
      (
        SELECT OBJ.GET_ACCESS_URL(image, 'r') as content, image, product_id
        FROM cymbal_pets.products_mm
      ),
      STRUCT ()
    );
  2. Nell'editor di query della pagina BigQuery, esegui la query seguente per eseguire una ricerca vettoriale e restituire immagini di prodotti simili all'immagine di input fornita:

    SELECT *
    FROM
    VECTOR_SEARCH(
      TABLE cymbal_pets.products_embedding,
      'embedding',
      (SELECT ml_generate_embedding_result as embedding FROM ML.GENERATE_EMBEDDING(
        MODEL `cymbal_pets.embedding_model`,
        (SELECT OBJ.FETCH_METADATA(OBJ.MAKE_REF('gs://cloud-samples-data/bigquery/tutorials/cymbal-pets/images/cozy-naps-cat-scratching-post-with-condo.png', 'us.cymbal_conn')) as content)
      ))
    );

    I risultati sono simili ai seguenti:

    +-----------------+-----------------+----------------+----------------------------------------------+--------------------+-------------------------------+------------------------------------------------+----------------+
    | query.embedding | base.product_id | base.embedding | base.image.uri                               | base.image.version | base.image.authorizer         | base.image.details                             | distance       |
    +-----------------+-----------------+----------------+----------------------------------------------+--------------------+-------------------------------+------------------------------------------------+----------------+
    | -0.0112330541   | 181             | -0.0112330541  | gs://cloud-samples-data/bigquery/            | 12345678910        | myproject.region.myconnection | {"gcs_metadata":{"content_type":               | 0.0            |
    | 0.0142525584    |                 |  0.0142525584  | tutorials/cymbal-pets/images/                |                    |                               | "image/png","md5_hash":"21234567hst16555w60j", |                |
    | 0.0135886827    |                 |  0.0135886827  | cozy-naps-cat-scratching-post-with-condo.png |                    |                               | "size":828318,"updated":1742492688982000}}     |                |
    | 0.0149955815    |                 |  0.0149955815  |                                              |                    |                               |                                                |                |
    | ...             |                 |  ...           |                                              |                    |                               |                                                |                |
    |                 |                 |                |                                              |                    |                               |                                                |                |
    |                 |                 |                |                                              |                    |                               |                                                |                |
    +-----------------+-----------------+----------------+----------------------------------------------+--------------------+-------------------------------+------------------------------------------------+----------------+
    | -0.0112330541   | 187             | -0.0190353896  | gs://cloud-samples-data/bigquery/            | 23456789101        | myproject.region.myconnection | {"gcs_metadata":{"content_type":               | 0.4216330832.. |
    | 0.0142525584    |                 |  0.0116206668  | tutorials/cymbal-pets/images/                |                    |                               | "image/png","md5_hash":"7328728fhakd9937djo4", |                |
    | 0.0135886827    |                 |  0.0136198215  | cozy-naps-cat-scratching-post-with-bed.png   |                    |                               | "size":860113,"updated":1742492688774000}}     |                |
    | 0.0149955815    |                 |  0.0173457414  |                                              |                    |                               |                                                |                |
    | ...             |                 |  ...           |                                              |                    |                               |                                                |                |
    |                 |                 |                |                                              |                    |                               |                                                |                |
    |                 |                 |                |                                              |                    |                               |                                                |                |
    +---------C--------+-----------------+----------------+----------------------------------------------+--------------------+-------------------------------+------------------------------------------------+----------------+
    | ...             | ...             | ...            | ...                                          | ...                | ...                           | ...                                            | ...            |
    +-----------------+-----------------+----------------+----------------------------------------------+--------------------+-------------------------------+------------------------------------------------+----------------+
    

Elaborare dati multimodali ordinati utilizzando array di valori ObjectRef

Questa sezione mostra come completare le seguenti attività:

  1. Ricrea la tabella product_manuals in modo che contenga sia un file PDF per il manuale del prodotto Crittercuisine 5000 sia file PDF per ogni pagina del manuale.
  2. Crea una tabella che mappi il manuale ai suoi blocchi. Il valore ObjectRef che rappresenta il manuale completo è archiviato in una colonna STRUCT<uri STRING, version STRING, authorizer STRING, details JSON>>. I valori ObjectRef che rappresentano le pagine di manuale sono memorizzati in una colonna ARRAY<STRUCT<uri STRING, version STRING, authorizer STRING, details JSON>>.
  3. Analizza insieme una matrice di valori ObjectRef per restituire un singolo valore generato.
  4. Analizza separatamente una matrice di valori ObjectRef e restituisce un valore generato per ogni valore della matrice.

Nell'ambito delle attività di analisi, converti l'array di valori ObjectRef in un elenco ordinato di valori ObjectRefRuntime, quindi passa l'elenco a un modello Gemini, specificando i valori ObjectRefRuntime come parte del prompt. I valori ObjectRefRuntime forniscono URL firmati che il modello utilizza per accedere alle informazioni sull'oggetto in Cloud Storage.

Segui questi passaggi per elaborare dati multimodali ordinati utilizzando array di valori ObjectRef:

  1. Vai alla pagina BigQuery.

    Vai a BigQuery

  2. Nell'editor di query, esegui la query seguente per ricreare la tabella product_manuals:

    CREATE OR REPLACE EXTERNAL TABLE `cymbal_pets.product_manuals`
      WITH CONNECTION `us.cymbal_conn`
      OPTIONS (
        object_metadata = 'SIMPLE',
        uris = [
            'gs://cloud-samples-data/bigquery/tutorials/cymbal-pets/documents/*.pdf',
            'gs://cloud-samples-data/bigquery/tutorials/cymbal-pets/document_chunks/*.pdf']);
  3. Nell'editor di query, esegui la query seguente per scrivere i dati PDF nella tabella map_manual_to_chunks:

    -- Extract the file and chunks into a single table.
    -- Store the chunks in the chunks column as array of ObjectRefs (ordered by page number)
    CREATE OR REPLACE TABLE cymbal_pets.map_manual_to_chunks
    AS
    SELECT ARRAY_AGG(m1.ref)[0] manual, ARRAY_AGG(m2.ref ORDER BY m2.ref.uri) chunks
    FROM cymbal_pets.product_manuals m1
    JOIN cymbal_pets.product_manuals m2
      ON
        REGEXP_EXTRACT(m1.uri, r'.*/([^.]*).[^/]+')
        = REGEXP_EXTRACT(m2.uri, r'.*/([^.]*)_page[0-9]+.[^/]+')
    GROUP BY m1.uri;
  4. Nell'editor di query, esegui la seguente query per visualizzare i dati PDF nella tabella map_manual_to_chunks:

    SELECT *
    FROM cymbal_pets.map_manual_to_chunks;

    I risultati sono simili ai seguenti:

    +-------------------------------------+--------------------------------+-----------------------------------+------------------------------------------------------+-------------------------------------------+---------------------------------+------------------------------------+-------------------------------------------------------+
    | manual.uri                          | manual.version                 | manual.authorizer                 | manual.details                                       | chunks.uri                                | chunks.version                  | chunks.authorizer                  | chunks.details                                        |
    +-------------------------------------+--------------------------------+-----------------------------------+------------------------------------------------------+-------------------------------------------+---------------------------------+------------------------------------+-------------------------------------------------------+
    | gs://cloud-samples-data/bigquery/   | 1742492785900455               | myproject.region.myconnection     | {"gcs_metadata":{"content_type":"application/pef",   | gs://cloud-samples-data/bigquery/         | 1745875761227129                | myproject.region.myconnection      | {"gcs_metadata":{"content_type":"application/pdf",    |
    | tutorials/cymbal-pets/documents/    |                                |                                   | "md5_hash":"c9032b037693d15a33210d638c763d0e",       | tutorials/cymbal-pets/documents/          |                                 |                                    | "md5_hash":"5a1116cce4978ec1b094d8e8b49a1d7c",        |
    | crittercuisine_5000_user_manual.pdf |                                |                                   | "size":566105,"updated":1742492785941000}}           | crittercuisine_5000_user_manual_page1.pdf |                                 |                                    | "size":504583,"updated":1745875761266000}}            |
    |                                     |                                |                                   |                                                      +-------------------------------------------+---------------------------------+------------------------------------+-------------------------------------------------------+
    |                                     |                                |                                   |                                                      | crittercuisine_5000_user_manual_page1.pdf | 1745875760613874                | myproject.region.myconnection      | {"gcs_metadata":{"content_type":"application/pdf",    |
    |                                     |                                |                                   |                                                      | tutorials/cymbal-pets/documents/          |                                 |                                    | "md5_hash":"94d03ec65d28b173bc87eac7e587b325",        |
    |                                     |                                |                                   |                                                      | crittercuisine_5000_user_manual_page2.pdf |                                 |                                    | "size":94622,"updated":1745875760649000}}             |
    |                                     |                                |                                   |                                                      +-------------------------------------------+---------------------------------+------------------------------------+-------------------------------------------------------+
    |                                     |                                |                                   |                                                      | ...                                       | ...                             |  ...                               | ...                                                   |
    +-------------------------------------+--------------------------------+-----------------------------------+------------------------------------------------------+-------------------------------------------+---------------------------------+------------------------------------+-------------------------------------------------------+
    
  5. Nell'editor di query, esegui la seguente query per generare una singola risposta da un modello Gemini in base all'analisi di un array di valori ObjectRef:

    WITH
      manuals AS (
        SELECT
          OBJ.GET_ACCESS_URL(manual, 'r') AS manual,
          ARRAY(
            SELECT OBJ.GET_ACCESS_URL(chunk, 'r') AS chunk
            FROM UNNEST(m1.chunks) AS chunk WITH OFFSET AS idx
            ORDER BY idx
          ) AS chunks
        FROM cymbal_pets.map_manual_to_chunks AS m1
      )
    SELECT ml_generate_text_llm_result AS Response
    FROM
      ML.GENERATE_TEXT(
        MODEL `cymbal_pets.gemini`,
        (
          SELECT
            (
              'Can you provide a page by page summary for the first 3 pages of the attached manual? Only write one line for each page. The pages are provided in serial order',
              manuals.chunks) AS prompt,
          FROM manuals
        ),
        STRUCT(TRUE AS FLATTEN_JSON_OUTPUT));

    I risultati sono simili ai seguenti:

    +-------------------------------------------+
    | Response                                  |
    +-------------------------------------------+
    | Page 1: This manual is for the            |
    | CritterCuisine Pro 5000 automatic         |
    | pet feeder.                               |
    | Page 2: The manual covers safety          |
    | precautions, what's included,             |
    | and product overview.                     |
    | Page 3: The manual covers assembly,       |
    | initial setup, and programming the clock. |
    +-------------------------------------------+
    
  6. Nell'editor di query, esegui la seguente query per generare più risposte da un modello Gemini in base all'analisi di un array di valori ObjectRef:

    WITH
      input_chunked_objrefs AS (
        SELECT row_id, offset, chunk_ref
        FROM
          (
            SELECT ROW_NUMBER() OVER () AS row_id, * FROM `cymbal_pets.map_manual_to_chunks`
          ) AS indexed_table
        LEFT JOIN
          UNNEST(indexed_table.chunks) AS chunk_ref
          WITH OFFSET
      ),
      get_access_urls AS (
        SELECT row_id, offset, chunk_ref, OBJ.GET_ACCESS_URL(chunk_ref, 'r') AS ObjectRefRuntime
        FROM input_chunked_objrefs
      ),
      valid_get_access_urls AS (
        SELECT *
        FROM get_access_urls
        WHERE ObjectRefRuntime['runtime_errors'] IS NULL
      ),
      ordered_output_objrefruntime_array AS (
        SELECT ARRAY_AGG(ObjectRefRuntime ORDER BY offset) AS ObjectRefRuntimeArray
        FROM valid_get_access_urls
        GROUP BY row_id
      )
    SELECT
      page1_summary,
      page2_summary,
      page3_summary
    FROM
      AI.GENERATE_TABLE(
        MODEL `cymbal_pets.gemini`,
        (
          SELECT
            (
              'Can you provide a page by page summary for the first 3 pages of the attached manual? Only write one line for each page. The pages are provided in serial order',
              ObjectRefRuntimeArray) AS prompt,
          FROM ordered_output_objrefruntime_array
        ),
        STRUCT(
          'page1_summary STRING, page2_summary STRING, page3_summary STRING' AS output_schema));

    I risultati sono simili ai seguenti:

    +-----------------------------------------------+-------------------------------------------+----------------------------------------------------+
    | page1_summary                                 | page2_summary                             | page3_summary                                      |
    +-----------------------------------------------+-------------------------------------------+----------------------------------------------------+
    | This manual provides an overview of the       | This section explains how to program      | This page covers connecting the feeder to Wi-Fi    |
    | CritterCuisine Pro 5000 automatic pet feeder, | the feeder's clock, set feeding           | using the CritterCuisine Connect app,  remote      |
    | including its features, safety precautions,   | schedules, copy and delete meal settings, | feeding, managing feeding schedules, viewing       |
    | assembly instructions, and initial setup.     | manually feed your pet, record            | feeding logs, receiving low food alerts,           |
    |                                               | a voice message, and understand           | updating firmware, creating multiple pet profiles, |
    |                                               | the low food level indicator.             | sharing access with other users, and cleaning      |
    |                                               |                                           | and maintaining the feeder.                        |
    +-----------------------------------------------+-------------------------------------------+----------------------------------------------------+
    

Esegui la pulizia

  1. In the Google Cloud console, go to the Manage resources page.

    Go to Manage resources

  2. In the project list, select the project that you want to delete, and then click Delete.
  3. In the dialog, type the project ID, and then click Shut down to delete the project.