Document understanding

Puoi aggiungere documenti (file PDF e TXT) alle richieste di Gemini per eseguire attività che richiedono la comprensione dei contenuti dei documenti inclusi. Questa pagina mostra come aggiungere PDF alle richieste a Gemini in Vertex AI utilizzando la console Google Cloud e l'API Vertex AI.

Modelli supportati

Nella tabella seguente sono elencati i modelli che supportano la comprensione dei documenti:

Modello Dettagli della modalità PDF

Gemini 1.5 Flash

Vai alla scheda del modello Gemini 1.5 Flash

Pagine massime per PDF: 1000

Dimensioni massime del file PDF: 50 MB

Gemini 1.5 Pro

Vai alla scheda del modello Gemini 1.5 Pro

Pagine massime per PDF: 1000

Dimensioni massime del file PDF: 50 MB

Gemini 1.0 Pro Vision

Vai alla scheda del modello Gemini 1.0 Pro Vision

Pagine massime per prompt: 16

Dimensioni massime del file PDF: 50 MB

Per un elenco delle lingue supportate dai modelli Gemini, consulta le informazioni sui modelli Google. Per scoprire di più su come progettare prompt multimodali, consulta Progettare prompt multimodali. Se stai cercando un modo per utilizzare Gemini direttamente dalle tue app web e mobile, consulta la sezione Vertex AI negli SDK Firebase per le app Android, Swift, web e Flutter.

Aggiungere documenti a una richiesta

Il seguente esempio di codice mostra come includere un PDF in una richiesta di prompt. Questo esempio PDF funziona con tutti i modelli multimodali di Gemini.

Python

Per scoprire come installare o aggiornare l'SDK Vertex AI per Python, consulta Installare l'SDK Vertex AI per Python. Per ulteriori informazioni, consulta la documentazione di riferimento dell'API Vertex AI SDK for Python.

Risposte dinamiche e non dinamiche

Puoi scegliere se il modello genera risposte in streaming o non in streaming. Per le risposte dinamiche, ricevi ogni risposta non appena viene generato il token di output. Per le risposte non dinamiche, ricevi tutte le risposte dopo la generazione di tutti i token di output.

Per una risposta dinamica, utilizza il parametro stream in generate_content.

  response = model.generate_content(contents=[...], stream = True)
  

Per una risposta non in streaming, rimuovi il parametro o impostalo su False.

Codice di esempio

import vertexai

from vertexai.generative_models import GenerativeModel, Part

# TODO(developer): Update project_id and location
vertexai.init(project=PROJECT_ID, location="us-central1")

model = GenerativeModel("gemini-1.5-flash-002")

prompt = """
You are a very professional document summarization specialist.
Please summarize the given document.
"""

pdf_file = Part.from_uri(
    uri="gs://cloud-samples-data/generative-ai/pdf/2403.05530.pdf",
    mime_type="application/pdf",
)
contents = [pdf_file, prompt]

response = model.generate_content(contents)
print(response.text)
# Example response:
# Here's a summary of the provided text, which appears to be a research paper on the Gemini 1.5 Pro
# multimodal large language model:
# **Gemini 1.5 Pro: Key Advancements and Capabilities**
# The paper introduces Gemini 1.5 Pro, a highly compute-efficient multimodal model
# significantly advancing long-context capabilities
# ...

Java

Prima di provare questo esempio, segui le istruzioni di configurazione di Java nella guida rapida di Vertex AI. Per ulteriori informazioni, consulta la documentazione di riferimento dell'SDK Java Vertex AI per Gemini.

Per autenticarti in Vertex AI, configura le credenziali predefinite dell'applicazione. Per maggiori informazioni, vedi Configurare l'ADC per un ambiente di sviluppo locale.

Risposte dinamiche e non dinamiche

Puoi scegliere se il modello genera risposte in streaming o non in streaming. Per le risposte dinamiche, ricevi ogni risposta non appena viene generato il token di output. Per le risposte non dinamiche, ricevi tutte le risposte dopo la generazione di tutti i token di output.

Per una risposta dinamica, utilizza il metodo generateContentStream.

  public ResponseStream<GenerateContentResponse> generateContentStream(Content content)
  

Per una risposta non in streaming, utilizza il metodo generateContent.

  public GenerateContentResponse generateContent(Content content)
  

Codice di esempio


import com.google.cloud.vertexai.VertexAI;
import com.google.cloud.vertexai.api.GenerateContentResponse;
import com.google.cloud.vertexai.generativeai.ContentMaker;
import com.google.cloud.vertexai.generativeai.GenerativeModel;
import com.google.cloud.vertexai.generativeai.PartMaker;
import com.google.cloud.vertexai.generativeai.ResponseHandler;
import java.io.IOException;

public class PdfInput {

  public static void main(String[] args) throws IOException {
    // TODO(developer): Replace these variables before running the sample.
    String projectId = "your-google-cloud-project-id";
    String location = "us-central1";
    String modelName = "gemini-1.5-flash-001";

    pdfInput(projectId, location, modelName);
  }

  // Analyzes the given video input.
  public static String pdfInput(String projectId, String location, String modelName)
      throws IOException {
    // Initialize client that will be used to send requests. This client only needs
    // to be created once, and can be reused for multiple requests.
    try (VertexAI vertexAI = new VertexAI(projectId, location)) {
      String pdfUri = "gs://cloud-samples-data/generative-ai/pdf/2403.05530.pdf";

      GenerativeModel model = new GenerativeModel(modelName, vertexAI);
      GenerateContentResponse response = model.generateContent(
          ContentMaker.fromMultiModalData(
              "You are a very professional document summarization specialist.\n"
                  + "Please summarize the given document.",
              PartMaker.fromMimeTypeAndData("application/pdf", pdfUri)
          ));

      String output = ResponseHandler.getText(response);
      System.out.println(output);
      return output;
    }
  }
}

Node.js

Prima di provare questo esempio, segui le istruzioni di configurazione di Node.js nella guida rapida sull'IA generativa con l'SDK Node.js. Per ulteriori informazioni, consulta la documentazione di riferimento dell'SDK Node.js per Gemini.

Per autenticarti in Vertex AI, configura le credenziali predefinite dell'applicazione. Per maggiori informazioni, vedi Configurare l'ADC per un ambiente di sviluppo locale.

Risposte dinamiche e non dinamiche

Puoi scegliere se il modello genera risposte in streaming o non in streaming. Per le risposte dinamiche, ricevi ogni risposta non appena viene generato il token di output. Per le risposte non dinamiche, ricevi tutte le risposte dopo la generazione di tutti i token di output.

Per una risposta dinamica, utilizza il metodo generateContentStream.

  const streamingResp = await generativeModel.generateContentStream(request);
  

Per una risposta non in streaming, utilizza il metodo generateContent.

  const streamingResp = await generativeModel.generateContent(request);
  

Codice di esempio

const {VertexAI} = require('@google-cloud/vertexai');

/**
 * TODO(developer): Update these variables before running the sample.
 */
async function analyze_pdf(projectId = 'PROJECT_ID') {
  const vertexAI = new VertexAI({project: projectId, location: 'us-central1'});

  const generativeModel = vertexAI.getGenerativeModel({
    model: 'gemini-1.5-flash-001',
  });

  const filePart = {
    fileData: {
      fileUri: 'gs://cloud-samples-data/generative-ai/pdf/2403.05530.pdf',
      mimeType: 'application/pdf',
    },
  };
  const textPart = {
    text: `
    You are a very professional document summarization specialist.
    Please summarize the given document.`,
  };

  const request = {
    contents: [{role: 'user', parts: [filePart, textPart]}],
  };

  const resp = await generativeModel.generateContent(request);
  const contentResponse = await resp.response;
  console.log(JSON.stringify(contentResponse));
}

Go

Prima di provare questo esempio, segui le istruzioni di configurazione di Go nella guida introduttiva di Vertex AI. Per ulteriori informazioni, consulta la documentazione di riferimento dell'SDK Go di Vertex AI per Gemini.

Per autenticarti a Vertex AI, configura le Credenziali predefinite dell'applicazione. Per maggiori informazioni, vedi Configurare l'ADC per un ambiente di sviluppo locale.

Risposte dinamiche e non dinamiche

Puoi scegliere se il modello genera risposte in streaming o non in streaming. Per le risposte dinamiche, ricevi ogni risposta non appena viene generato il token di output. Per le risposte non dinamiche, ricevi tutte le risposte dopo la generazione di tutti i token di output.

Per una risposta dinamica, utilizza il metodo GenerateContentStream.

  iter := model.GenerateContentStream(ctx, genai.Text("Tell me a story about a lumberjack and his giant ox. Keep it very short."))
  

Per una risposta non in streaming, utilizza il metodo GenerateContent.

  resp, err := model.GenerateContent(ctx, genai.Text("What is the average size of a swallow?"))
  

Codice di esempio

import (
	"context"
	"errors"
	"fmt"
	"io"

	"cloud.google.com/go/vertexai/genai"
)

// generateContentFromPDF generates a response into the provided io.Writer, based upon the PDF
func generateContentFromPDF(w io.Writer, projectID, location, modelName string) error {
	// location := "us-central1"
	// modelName := "gemini-1.5-flash-001"

	ctx := context.Background()

	client, err := genai.NewClient(ctx, projectID, location)
	if err != nil {
		return fmt.Errorf("unable to create client: %w", err)
	}
	defer client.Close()

	model := client.GenerativeModel(modelName)

	part := genai.FileData{
		MIMEType: "application/pdf",
		FileURI:  "gs://cloud-samples-data/generative-ai/pdf/2403.05530.pdf",
	}

	res, err := model.GenerateContent(ctx, part, genai.Text(`
			You are a very professional document summarization specialist.
    		Please summarize the given document.
	`))
	if err != nil {
		return fmt.Errorf("unable to generate contents: %w", err)
	}

	if len(res.Candidates) == 0 ||
		len(res.Candidates[0].Content.Parts) == 0 {
		return errors.New("empty response from model")
	}

	fmt.Fprintf(w, "generated response: %s\n", res.Candidates[0].Content.Parts[0])
	return nil
}

C#

Prima di provare questo esempio, segui le istruzioni di configurazione di C# nella guida rapida di Vertex AI. Per ulteriori informazioni, consulta la documentazione di riferimento C# di Vertex AI.

Per autenticarti in Vertex AI, configura le credenziali predefinite dell'applicazione. Per maggiori informazioni, vedi Configurare l'ADC per un ambiente di sviluppo locale.

Risposte dinamiche e non dinamiche

Puoi scegliere se il modello genera risposte in streaming o non in streaming. Per le risposte dinamiche, ricevi ogni risposta non appena viene generato il token di output. Per le risposte non dinamiche, ricevi tutte le risposte dopo la generazione di tutti i token di output.

Per una risposta dinamica, utilizza il metodo StreamGenerateContent.

  public virtual PredictionServiceClient.StreamGenerateContentStream StreamGenerateContent(GenerateContentRequest request)
  

Per una risposta non in streaming, utilizza il metodo GenerateContentAsync.

  public virtual Task<GenerateContentResponse> GenerateContentAsync(GenerateContentRequest request)
  

Per ulteriori informazioni su come il server può trasmettere le risposte, consulta RPC dinamiche.

Codice di esempio


using Google.Cloud.AIPlatform.V1;
using System;
using System.Threading.Tasks;

public class PdfInput
{
    public async Task<string> SummarizePdf(
        string projectId = "your-project-id",
        string location = "us-central1",
        string publisher = "google",
        string model = "gemini-1.5-flash-001")
    {

        var predictionServiceClient = new PredictionServiceClientBuilder
        {
            Endpoint = $"{location}-aiplatform.googleapis.com"
        }.Build();

        string prompt = @"You are a very professional document summarization specialist.
Please summarize the given document.";

        var generateContentRequest = new GenerateContentRequest
        {
            Model = $"projects/{projectId}/locations/{location}/publishers/{publisher}/models/{model}",
            Contents =
            {
                new Content
                {
                    Role = "USER",
                    Parts =
                    {
                        new Part { Text = prompt },
                        new Part { FileData = new() { MimeType = "application/pdf", FileUri = "gs://cloud-samples-data/generative-ai/pdf/2403.05530.pdf" }}
                    }
                }
            }
        };

        GenerateContentResponse response = await predictionServiceClient.GenerateContentAsync(generateContentRequest);

        string responseText = response.Candidates[0].Content.Parts[0].Text;
        Console.WriteLine(responseText);

        return responseText;
    }
}

REST

Dopo aver configurato l'ambiente, puoi utilizzare REST per testare un prompt di testo. Il seguente esempio invia una richiesta all'endpoint del modello del publisher.

Prima di utilizzare i dati della richiesta, apporta le seguenti sostituzioni:

  • LOCATION: la regione in cui elaborare la richiesta. Inserisci una regione supportata. Per l'elenco completo delle regioni supportate, consulta Località disponibili.

    Fai clic per espandere un elenco parziale delle regioni disponibili

    • us-central1
    • us-west4
    • northamerica-northeast1
    • us-east4
    • us-west1
    • asia-northeast3
    • asia-southeast1
    • asia-northeast1
  • PROJECT_ID: il tuo ID progetto.
  • FILE_URI: l'URI o l'URL del file da includere nel prompt. I valori accettabili sono:
    • URI del bucket Cloud Storage: l'oggetto deve essere leggibile pubblicamente o trovarsi nello stesso progetto Google Cloud che invia la richiesta. Per gemini-1.5-pro e gemini-1.5-flash, il limite di dimensioni è 2 GB. Per gemini-1.0-pro-vision, il limite di dimensioni è 20 MB.
    • URL HTTP:l'URL del file deve essere pubblicamente leggibile. Puoi specificare un file video, un file audio e fino a 10 file immagine per richiesta. I file audio, i file video e i documenti non possono superare i 15 MB.
    • URL del video di YouTube: il video di YouTube deve essere di proprietà dell'account che hai utilizzato per accedere alla console Google Cloud o essere pubblico. È supportato un solo URL video di YouTube per richiesta.

    Quando specifichi un fileURI, devi specificare anche il tipo di media (mimeType) del file. Se i Controlli di servizio VPC sono abilitati, la specifica di un URL di file multimediale per fileURI non è supportata.

    Se non hai un file PDF in Cloud Storage, puoi utilizzare il seguente file disponibile pubblicamente: gs://cloud-samples-data/generative-ai/pdf/2403.05530.pdf con un tipo MIME di application/pdf. Per visualizzare questo PDF, apri il file PDF di esempio.

  • MIME_TYPE: il tipo di media del file specificato nei campi data o fileUri. I valori accettati sono:

    Fai clic per espandere i tipi MIME

    • application/pdf
    • audio/mpeg
    • audio/mp3
    • audio/wav
    • image/png
    • image/jpeg
    • image/webp
    • text/plain
    • video/mov
    • video/mpeg
    • video/mp4
    • video/mpg
    • video/avi
    • video/wmv
    • video/mpegps
    • video/flv
  • TEXT: le istruzioni di testo da includere nel prompt. Ad esempio: You are a very professional document summarization specialist. Please summarize the given document.

Per inviare la richiesta, scegli una delle seguenti opzioni:

curl

Salva il corpo della richiesta in un file denominato request.json. Esegui questo comando nel terminale per creare o sovrascrivere questo file nella directory corrente:

cat > request.json << 'EOF'
{
  "contents": {
    "role": "USER",
    "parts": [
      {
        "fileData": {
          "fileUri": "FILE_URI",
          "mimeType": "MIME_TYPE"
        }
      },
      {
        "text": "TEXT"
      }
    ]
  }
}
EOF

Quindi, esegui il seguente comando per inviare la richiesta REST:

curl -X POST \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "Content-Type: application/json; charset=utf-8" \
-d @request.json \
"https://LOCATION-aiplatform.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/publishers/google/models/gemini-1.5-flash:generateContent"

PowerShell

Salva il corpo della richiesta in un file denominato request.json. Esegui questo comando nel terminale per creare o sovrascrivere questo file nella directory corrente:

@'
{
  "contents": {
    "role": "USER",
    "parts": [
      {
        "fileData": {
          "fileUri": "FILE_URI",
          "mimeType": "MIME_TYPE"
        }
      },
      {
        "text": "TEXT"
      }
    ]
  }
}
'@  | Out-File -FilePath request.json -Encoding utf8

Quindi, esegui il seguente comando per inviare la richiesta REST:

$cred = gcloud auth print-access-token
$headers = @{ "Authorization" = "Bearer $cred" }

Invoke-WebRequest `
-Method POST `
-Headers $headers `
-ContentType: "application/json; charset=utf-8" `
-InFile request.json `
-Uri "https://LOCATION-aiplatform.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/publishers/google/models/gemini-1.5-flash:generateContent" | Select-Object -Expand Content

Dovresti ricevere una risposta JSON simile alla seguente.

Tieni presente quanto segue nell'URL di questo esempio:
  • Utilizza il metodo generateContent per richiedere che la risposta venga restituita dopo essere stata completamente generata. Per ridurre la percezione della latenza da parte di un pubblico di persone, riproduci in streaming la risposta man mano che viene generata utilizzando il metodo streamGenerateContent.
  • L'ID del modello multimodale si trova alla fine dell'URL prima del metodo (ad esempio gemini-1.5-flash o gemini-1.0-pro-vision). Questo sample potrebbe supportare anche altri modelli.

Console

Per inviare un prompt multimodale utilizzando la console Google Cloud, segui questi passaggi:

  1. Nella sezione Vertex AI della console Google Cloud, vai alla pagina Vertex AI Studio.

    Vai a Vertex AI Studio

  2. Fai clic su Apri in formato libero.

  3. (Facoltativo) Configura il modello e i parametri:

    • Modello: seleziona un modello.
    • Regione: seleziona la regione che vuoi utilizzare.
    • Temperatura: utilizza il dispositivo di scorrimento o la casella di testo per inserire un valore per la temperatura.

      La temperatura viene utilizzata per il campionamento durante la generazione della risposta, che si verifica quando vengono applicati topP e topK. La temperatura controlla il grado di casualità nella selezione dei token. Le temperature più basse sono ideali per prompt che richiedono risposte meno aperte o creative, mentre le temperature più alte possono portare a risultati più diversificati o creativi. Con una temperatura pari a 0 viene sempre selezionato il token con la probabilità più alta. In questo caso, le risposte per un determinato prompt sono per lo più deterministiche, ma è comunque possibile una piccola variazione.

      Se il modello restituisce una risposta troppo generica, troppo breve o fornisce una risposta di riserva, prova ad aumentare la temperatura.

    • Limite di token di output: utilizza il cursore o la casella di testo per inserire un valore per il limite di output massimo.

      Numero massimo di token che possono essere generati nella risposta. Un token equivale a circa quattro caratteri. 100 token corrispondono a circa 60-80 parole.

      Specifica un valore più basso per risposte più brevi e un valore più alto per risposte potenzialmente più lunghe.

    • Aggiungi sequenza di interruzioni: facoltativo. Inserisci una sequenza di interruzioni, ovvero una serie di caratteri che include spazi. Se il modello rileva una sequenza di interruzione, la generazione di risposte viene interrotta. La sequenza di interruzioni non è inclusa nella risposta e puoi aggiungerne fino a cinque.

  4. (Facoltativo) Per configurare i parametri avanzati, fai clic su Avanzate e configura come segue:

    Fai clic per espandere le configurazioni avanzate

    • Top-K: utilizza il dispositivo di scorrimento o la casella di testo per inserire un valore per il top-K. (non supportato per Gemini 1.5).

      Top-K cambia il modo in cui il modello seleziona i token per l'output. Un top-K pari a 1 indica che il token successivo selezionato è il più probabile tra tutti i token nel vocabolario del modello (chiamato anche decodifica greedy). Un top-K pari a 3 indica invece che il token successivo viene selezionato tra i tre token più probabili utilizzando la temperatura.

      Per ogni fase di selezione dei token, vengono campionati i token Top-K con le probabilità più elevate. Quindi i token vengono ulteriormente filtrati in base a Top-P e il token finale viene selezionato utilizzando il campionamento con temperatura.

      Specifica un valore più basso per risposte meno casuali e un valore più alto per risposte più casuali.

    • Top-P: utilizza il dispositivo di scorrimento o la casella di testo per inserire un valore per il top-P. I token vengono selezionati dal più probabile al meno probabile finché la somma delle loro probabilità non corrisponde al valore di Top-P. Per ridurre al minimo la variabilità dei risultati, imposta Top-P su 0.
    • Risposte massime: utilizza il cursore o la casella di testo per inserire un valore per il numero di risposte da generare.
    • Risposte dinamiche: attiva questa opzione per stampare le risposte man mano che vengono generate.
    • Soglia del filtro di sicurezza: seleziona la soglia di probabilità di ricevere risposte potenzialmente dannose.
    • Abilita il grounding: il grounding non è supportato per i prompt multimodali.

  5. Fai clic su Inserisci media e seleziona un'origine per il file.

    Carica

    Seleziona il file che vuoi caricare e fai clic su Apri.

    Tramite URL

    Inserisci l'URL del file che vuoi utilizzare e fai clic su Inserisci.

    Cloud Storage

    Seleziona il bucket e poi il file al suo interno che vuoi importare e fai clic su Seleziona.

    Google Drive

    1. Scegli un account e concedi il consenso a Vertex AI Studio per accedere al tuo account la prima volta che selezioni questa opzione. Puoi caricare più file con una dimensione totale massima di 10 MB. Un singolo file non può superare 7 MB.
    2. Fai clic sul file che vuoi aggiungere.
    3. Fai clic su Seleziona.

      La miniatura del file viene visualizzata nel riquadro Prompt. Viene mostrato anche il numero totale di token. Se i dati del prompt superano il limite di token, i token vengono troncati e non sono inclusi nell'elaborazione dei dati.

  6. Inserisci il prompt di testo nel riquadro Prompt.

  7. (Facoltativo) Per visualizzare ID token in testo e ID token, fai clic sul conteggio token nel riquadro Prompt.

  8. Fai clic su Invia.

  9. (Facoltativo) Per salvare il prompt in I miei prompt, fai clic su Salva.

  10. (Facoltativo) Per ottenere il codice Python o un comando curl per il tuo prompt, fai clic su Genera codice.

Impostare i parametri facoltativi del modello

Ogni modello ha un insieme di parametri facoltativi che puoi impostare. Per ulteriori informazioni, consulta Parametri di generazione dei contenuti.

Requisiti dei documenti

I modelli multimodali Gemini supportano i seguenti tipi MIME di documenti:

Tipo MIME del documento Gemini 1.5 Flash Gemini 1.5 Pro Gemini 1.0 Pro Vision
PDF - application/pdf
Testo: text/plain

I PDF vengono trattati come immagini, quindi una singola pagina di un PDF viene considerata come un'immagine. Il numero di pagine consentite in un prompt è limitato al numero di immagini che il modello può supportare:

  • Gemini 1.0 Pro Vision: 16 pagine
  • Gemini 1.5 Pro e Gemini 1.5 Flash: 1000 pagine

Tokenizzazione PDF

I PDF vengono trattati come immagini, pertanto ogni pagina di un PDF viene tokenizzata nello stesso modo di un'immagine.

Inoltre, il costo dei PDF segue i prezzi delle immagini di Gemini. Ad esempio, se includi un PDF di due pagine in una chiamata all'API Gemini, ti viene addebitata una commissione di importo pari all'elaborazione di due immagini.

Tokenizzazione del testo normale

I documenti in testo normale vengono tokenizzati come testo. Ad esempio, se includi un documento di testo normale di 100 parole in una chiamata all'API Gemini, ti viene addebitata una tariffa di importazione per l'elaborazione di 100 parole.

Best practice per i PDF

Quando utilizzi i PDF, segui le best practice e le informazioni riportate di seguito per ottenere risultati ottimali:

  • Se il prompt contiene un singolo PDF, inseriscilo prima del prompt di testo nella richiesta.
  • Se hai un documento lungo, ti consigliamo di suddividerlo in più PDF per poterlo elaborare.
  • Utilizza i PDF creati con il testo visualizzato come testo anziché utilizzare il testo nelle immagini scansionate. Questo formato garantisce che il testo sia leggibile dalla macchina, in modo che sia più facile per il modello modificarlo, cercarlo e manipolarlo rispetto ai PDF di immagini acquisite. Questa pratica offre risultati ottimali quando si lavora con documenti con molto testo, come i contratti.

Limitazioni

Sebbene i modelli multimodali di Gemini siano efficaci in molti casi di utilizzo multimodale, è importante comprendere i loro limiti:

  • Ragionamento spaziale: i modelli non sono precisi nel localizzare testo o oggetti nei PDF. Potrebbero restituire solo i conteggi approssimativi degli oggetti.
  • Accuratezza: i modelli potrebbero avere allucinazioni durante l'interpretazione del testo scritto a mano nei documenti PDF.

Passaggi successivi