Verständnis von Dokumenten

Die Gemini API unterstützt die PDF-Eingabe, einschließlich langer Dokumente (bis zu 3.600 Seiten). Gemini-Modelle verarbeiten PDFs mit nativer Bilderkennung und können daher sowohl Text als auch Bildinhalte in Dokumenten verstehen. Dank der nativen Unterstützung von PDF-Vision können Gemini-Modelle Folgendes tun:

  • Diagramme, Grafiken und Tabellen in Dokumenten analysieren
  • Informationen in strukturierte Ausgabeformate extrahieren
  • Fragen zu visuellem und Textinhalt in Dokumenten beantworten
  • Dokumente zusammenfassen
  • Transkribieren von Dokumentinhalten (z.B. in HTML) unter Beibehaltung von Layout und Formatierung zur Verwendung in nachfolgenden Anwendungen

In dieser Anleitung werden einige Möglichkeiten zur Verarbeitung von PDF-Dokumenten mit der Gemini API veranschaulicht.

PDF-Eingabe

Bei PDF-Nutzlast unter 20 MB können Sie zwischen dem Hochladen von Base64-codierten Dokumenten oder dem direkten Hochladen lokal gespeicherter Dateien wählen.

Als „inline_data“

Sie können PDF-Dokumente direkt über URLs verarbeiten. Hier ist ein Code-Snippet, das zeigt, wie das geht:

DOC_URL="https://discovery.ucl.ac.uk/id/eprint/10089234/1/343019_3_art_0_py4t4l_convrt.pdf"
PROMPT="Summarize this document"
DISPLAY_NAME="base64_pdf"

# Download the PDF
wget -O "${DISPLAY_NAME}.pdf" "${DOC_URL}"

# Check for FreeBSD base64 and set flags accordingly
if [[ "$(base64 --version 2>&1)" = *"FreeBSD"* ]]; then
  B64FLAGS="--input"
else
  B64FLAGS="-w0"
fi

# Base64 encode the PDF
ENCODED_PDF=$(base64 $B64FLAGS "${DISPLAY_NAME}.pdf")

# Generate content using the base64 encoded PDF
curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key=$GOOGLE_API_KEY" \
    -H 'Content-Type: application/json' \
    -X POST \
    -d '{
      "contents": [{
        "parts":[
          {"inline_data": {"mime_type": "application/pdf", "data": "'"$ENCODED_PDF"'"}},
          {"text": "'$PROMPT'"}
        ]
      }]
    }' 2> /dev/null > response.json

cat response.json
echo

jq ".candidates[].content.parts[].text" response.json

# Clean up the downloaded PDF
rm "${DISPLAY_NAME}.pdf"

Technische Details

Gemini 1.5 Pro und 1.5 Flash unterstützen maximal 3.600 Dokumentseiten. Dokumentseiten müssen einen der folgenden MIME-Typen für Textdaten haben:

  • PDF – application/pdf
  • JavaScript – application/x-javascript, text/javascript
  • Python – application/x-python, text/x-python
  • TXT – text/plain
  • HTML – text/html
  • Preisvergleichsportal – text/css
  • Markdown – text/md
  • CSV – text/csv
  • XML – text/xml
  • RTF – text/rtf

Jede Dokumentseite entspricht 258 Tokens.

Die Anzahl der Pixel in einem Dokument ist abgesehen vom Kontextfenster des Modells nicht begrenzt. Größere Seiten werden jedoch auf eine maximale Auflösung von 3.072 × 3.072 herunterskaliert, wobei ihr ursprüngliches Seitenverhältnis beibehalten wird. Kleinere Seiten werden auf 768 × 768 Pixel skaliert. Es gibt keine Kosteneinsparungen für Seiten mit niedrigerer Größe, abgesehen von der Bandbreite, und keine Leistungsverbesserung für Seiten mit höherer Auflösung.

Für optimale Ergebnisse:

  • Drehen Sie die Seiten vor dem Hochladen in die richtige Ausrichtung.
  • Vermeiden Sie unscharfe Seiten.
  • Wenn Sie eine einzelne Seite verwenden, platzieren Sie den Textprompt nach der Seite.

Große PDFs

Mit der File API können Sie Dokumente beliebiger Größe hochladen. Verwenden Sie immer die File API, wenn die Gesamtgröße der Anfrage (einschließlich der Dateien, des Textprompts, der Systemanweisungen usw.) mehr als 20 MB beträgt.

Rufe media.upload auf, um eine Datei mit der File API hochzuladen. Im folgenden Code wird eine Dokumentdatei hochgeladen und dann in einem Aufruf von models.generateContent verwendet.

Große PDFs über URLs

Verwenden Sie die File API für große PDF-Dateien, die über URLs verfügbar sind. So wird der Upload und die Verarbeitung dieser Dokumente direkt über ihre URLs vereinfacht:

PDF_PATH="https://www.nasa.gov/wp-content/uploads/static/history/alsj/a17/A17_FlightPlan.pdf"
DISPLAY_NAME="A17_FlightPlan"
PROMPT="Summarize this document"

# Download the PDF from the provided URL
wget -O "${DISPLAY_NAME}.pdf" "${PDF_PATH}"

MIME_TYPE=$(file -b --mime-type "${DISPLAY_NAME}.pdf")
NUM_BYTES=$(wc -c < "${DISPLAY_NAME}.pdf")

echo "MIME_TYPE: ${MIME_TYPE}"
echo "NUM_BYTES: ${NUM_BYTES}"

tmp_header_file=upload-header.tmp

# Initial resumable request defining metadata.
# The upload url is in the response headers dump them to a file.
curl "${BASE_URL}/upload/v1beta/files?key=${GOOGLE_API_KEY}" \
  -D upload-header.tmp \
  -H "X-Goog-Upload-Protocol: resumable" \
  -H "X-Goog-Upload-Command: start" \
  -H "X-Goog-Upload-Header-Content-Length: ${NUM_BYTES}" \
  -H "X-Goog-Upload-Header-Content-Type: ${MIME_TYPE}" \
  -H "Content-Type: application/json" \
  -d "{'file': {'display_name': '${DISPLAY_NAME}'}}" 2> /dev/null

upload_url=$(grep -i "x-goog-upload-url: " "${tmp_header_file}" | cut -d" " -f2 | tr -d "\r")
rm "${tmp_header_file}"

# Upload the actual bytes.
curl "${upload_url}" \
  -H "Content-Length: ${NUM_BYTES}" \
  -H "X-Goog-Upload-Offset: 0" \
  -H "X-Goog-Upload-Command: upload, finalize" \
  --data-binary "@${DISPLAY_NAME}.pdf" 2> /dev/null > file_info.json

file_uri=$(jq ".file.uri" file_info.json)
echo "file_uri: ${file_uri}"

# Now generate content using that file
curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key=$GOOGLE_API_KEY" \
    -H 'Content-Type: application/json' \
    -X POST \
    -d '{
      "contents": [{
        "parts":[
          {"text": "'$PROMPT'"},
          {"file_data":{"mime_type": "application/pdf", "file_uri": '$file_uri'}}]
        }]
       }' 2> /dev/null > response.json

cat response.json
echo

jq ".candidates[].content.parts[].text" response.json

# Clean up the downloaded PDF
rm "${DISPLAY_NAME}.pdf"

Lokal gespeicherte große PDFs

NUM_BYTES=$(wc -c < "${PDF_PATH}")
DISPLAY_NAME=TEXT
tmp_header_file=upload-header.tmp

# Initial resumable request defining metadata.
# The upload url is in the response headers dump them to a file.
curl "${BASE_URL}/upload/v1beta/files?key=${GEMINI_API_KEY}" \
  -D upload-header.tmp \
  -H "X-Goog-Upload-Protocol: resumable" \
  -H "X-Goog-Upload-Command: start" \
  -H "X-Goog-Upload-Header-Content-Length: ${NUM_BYTES}" \
  -H "X-Goog-Upload-Header-Content-Type: application/pdf" \
  -H "Content-Type: application/json" \
  -d "{'file': {'display_name': '${DISPLAY_NAME}'}}" 2> /dev/null

upload_url=$(grep -i "x-goog-upload-url: " "${tmp_header_file}" | cut -d" " -f2 | tr -d "\r")
rm "${tmp_header_file}"

# Upload the actual bytes.
curl "${upload_url}" \
  -H "Content-Length: ${NUM_BYTES}" \
  -H "X-Goog-Upload-Offset: 0" \
  -H "X-Goog-Upload-Command: upload, finalize" \
  --data-binary "@${PDF_PATH}" 2> /dev/null > file_info.json

file_uri=$(jq ".file.uri" file_info.json)
echo file_uri=$file_uri

# Now generate content using that file
curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash:generateContent?key=$GOOGLE_API_KEY" \
    -H 'Content-Type: application/json' \
    -X POST \
    -d '{
      "contents": [{
        "parts":[
          {"text": "Can you add a few more lines to this poem?"},
          {"file_data":{"mime_type": "application/pdf", "file_uri": '$file_uri'}}]
        }]
       }' 2> /dev/null > response.json

cat response.json
echo

jq ".candidates[].content.parts[].text" response.json

Sie können prüfen, ob die API die hochgeladene Datei erfolgreich gespeichert hat, und die zugehörigen Metadaten abrufen, indem Sie files.get aufrufen. Nur die name (und in gewissem Maße auch die uri) sind eindeutig.

name=$(jq ".file.name" file_info.json)
# Get the file of interest to check state
curl https://generativelanguage.googleapis.com/v1beta/files/$name > file_info.json
# Print some information about the file you got
name=$(jq ".file.name" file_info.json)
echo name=$name
file_uri=$(jq ".file.uri" file_info.json)
echo file_uri=$file_uri

Mehrere PDFs

Die Gemini API kann mehrere PDF-Dokumente in einer einzigen Anfrage verarbeiten, solange die Gesamtgröße der Dokumente und des Textprompts innerhalb des Kontextfensters des Modells liegt.

DOC_URL_1="https://arxiv.org/pdf/2312.11805"
DOC_URL_2="https://arxiv.org/pdf/2403.05530"
DISPLAY_NAME_1="Gemini_paper"
DISPLAY_NAME_2="Gemini_1.5_paper"
PROMPT="What is the difference between each of the main benchmarks between these two papers? Output these in a table."

# Function to download and upload a PDF
upload_pdf() {
  local doc_url="$1"
  local display_name="$2"

  # Download the PDF
  wget -O "${display_name}.pdf" "${doc_url}"

  local MIME_TYPE=$(file -b --mime-type "${display_name}.pdf")
  local NUM_BYTES=$(wc -c < "${display_name}.pdf")

  echo "MIME_TYPE: ${MIME_TYPE}"
  echo "NUM_BYTES: ${NUM_BYTES}"

  local tmp_header_file=upload-header.tmp

  # Initial resumable request
  curl "${BASE_URL}/upload/v1beta/files?key=${GOOGLE_API_KEY}" \
    -D "${tmp_header_file}" \
    -H "X-Goog-Upload-Protocol: resumable" \
    -H "X-Goog-Upload-Command: start" \
    -H "X-Goog-Upload-Header-Content-Length: ${NUM_BYTES}" \
    -H "X-Goog-Upload-Header-Content-Type: ${MIME_TYPE}" \
    -H "Content-Type: application/json" \
    -d "{'file': {'display_name': '${display_name}'}}" 2> /dev/null

  local upload_url=$(grep -i "x-goog-upload-url: " "${tmp_header_file}" | cut -d" " -f2 | tr -d "\r")
  rm "${tmp_header_file}"

  # Upload the PDF
  curl "${upload_url}" \
    -H "Content-Length: ${NUM_BYTES}" \
    -H "X-Goog-Upload-Offset: 0" \
    -H "X-Goog-Upload-Command: upload, finalize" \
    --data-binary "@${display_name}.pdf" 2> /dev/null > "file_info_${display_name}.json"

  local file_uri=$(jq ".file.uri" "file_info_${display_name}.json")
  echo "file_uri for ${display_name}: ${file_uri}"

  # Clean up the downloaded PDF
  rm "${display_name}.pdf"

  echo "${file_uri}"
}

# Upload the first PDF
file_uri_1=$(upload_pdf "${DOC_URL_1}" "${DISPLAY_NAME_1}")

# Upload the second PDF
file_uri_2=$(upload_pdf "${DOC_URL_2}" "${DISPLAY_NAME_2}")

# Now generate content using both files
curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key=$GOOGLE_API_KEY" \
    -H 'Content-Type: application/json' \
    -X POST \
    -d '{
      "contents": [{
        "parts":[
          {"file_data": {"mime_type": "application/pdf", "file_uri": '$file_uri_1'}},
          {"file_data": {"mime_type": "application/pdf", "file_uri": '$file_uri_2'}},
          {"text": "'$PROMPT'"}
        ]
      }]
    }' 2> /dev/null > response.json

cat response.json
echo

jq ".candidates[].content.parts[].text" response.json

Nächste Schritte

Weitere Informationen finden Sie in den folgenden Ressourcen:

  • Strategien für Prompts aus Dateien: Die Gemini API unterstützt Prompts mit Text-, Bild-, Audio- und Videodaten, auch als multimodale Prompts bezeichnet.
  • Systemanweisungen: Mit Systemanweisungen können Sie das Verhalten des Modells basierend auf Ihren spezifischen Anforderungen und Anwendungsfällen steuern.