Hiểu tài liệu

API Gemini hỗ trợ nhập PDF, bao gồm cả tài liệu dài (tối đa 3.600 trang). Các mô hình Gemini xử lý tệp PDF bằng công nghệ thị giác gốc, nhờ đó có thể hiểu được cả nội dung văn bản và hình ảnh bên trong tài liệu. Với tính năng hỗ trợ thị giác PDF gốc, các mô hình Gemini có thể:

  • Phân tích sơ đồ, biểu đồ và bảng trong tài liệu
  • Trích xuất thông tin thành các định dạng đầu ra có cấu trúc
  • Trả lời câu hỏi về nội dung hình ảnh và văn bản trong tài liệu
  • Tóm tắt tài liệu
  • Bản chép lời nội dung tài liệu (ví dụ: sang HTML) giữ nguyên bố cục và định dạng để sử dụng trong các ứng dụng tiếp theo

Hướng dẫn này minh hoạ một số cách có thể sử dụng API Gemini để xử lý tài liệu PDF.

Dữ liệu đầu vào PDF

Đối với tải trọng PDF dưới 20 MB, bạn có thể chọn tải tài liệu được mã hoá base64 lên hoặc tải trực tiếp các tệp được lưu trữ cục bộ lên.

Dưới dạng inline_data

Bạn có thể xử lý tài liệu PDF trực tiếp từ URL. Dưới đây là đoạn mã cho thấy cách thực hiện việc này:

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"

Chi tiết kỹ thuật

Gemini 1.5 Pro và 1.5 Flash hỗ trợ tối đa 3.600 trang tài liệu. Các trang tài liệu phải ở một trong các loại MIME dữ liệu văn bản sau:

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

Mỗi trang tài liệu tương đương với 258 mã thông báo.

Mặc dù không có giới hạn cụ thể về số pixel trong tài liệu ngoài cửa sổ ngữ cảnh của mô hình, nhưng các trang lớn hơn sẽ được điều chỉnh theo tỷ lệ xuống độ phân giải tối đa là 3072x3072 trong khi vẫn giữ nguyên tỷ lệ khung hình ban đầu, còn các trang nhỏ hơn sẽ được điều chỉnh theo tỷ lệ lên 768x768 pixel. Không có sự giảm chi phí nào đối với các trang có kích thước thấp hơn, ngoài băng thông hoặc cải thiện hiệu suất cho các trang có độ phân giải cao hơn.

Để có kết quả tốt nhất:

  • Xoay các trang theo đúng hướng trước khi tải lên.
  • Tránh các trang bị mờ.
  • Nếu sử dụng một trang, hãy đặt lời nhắc văn bản sau trang đó.

Tệp PDF có kích thước lớn

Bạn có thể sử dụng API Tệp để tải tài liệu có kích thước bất kỳ lên. Luôn sử dụng API tệp khi tổng kích thước yêu cầu (bao gồm cả tệp, lời nhắc văn bản, hướng dẫn hệ thống, v.v.) lớn hơn 20 MB.

Gọi media.upload để tải tệp lên bằng API Tệp. Mã sau đây sẽ tải một tệp tài liệu lên, sau đó sử dụng tệp đó trong lệnh gọi đến models.generateContent.

Tệp PDF lớn từ URL

Sử dụng API Tệp cho các tệp PDF lớn có sẵn từ URL, giúp đơn giản hoá quá trình tải lên và xử lý trực tiếp các tài liệu này thông qua URL của chúng:

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"

Tệp PDF lớn được lưu trữ cục bộ

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

Bạn có thể xác minh API đã lưu trữ thành công tệp đã tải lên và lấy siêu dữ liệu của tệp đó bằng cách gọi files.get. Chỉ name (và theo đó là uri) là duy nhất.

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

Nhiều tệp PDF

API Gemini có thể xử lý nhiều tài liệu PDF trong một yêu cầu, miễn là kích thước kết hợp của các tài liệu và lời nhắc văn bản nằm trong cửa sổ ngữ cảnh của mô hình.

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

Bước tiếp theo

Để tìm hiểu thêm, hãy xem các tài nguyên sau:

  • Chiến lược nhắc tệp: Gemini API hỗ trợ nhắc bằng dữ liệu văn bản, hình ảnh, âm thanh và video, còn gọi là nhắc đa phương thức.
  • Hướng dẫn hệ thống: Hướng dẫn hệ thống cho phép bạn điều hướng hành vi của mô hình dựa trên các nhu cầu và trường hợp sử dụng cụ thể.