Vai al contenuto principale

API di Gemini 2.5 Pro: Guida con progetto demo

Impara a usare l'API di Gemini 2.5 Pro per creare una web app di analisi del codice, sfruttando l'ampia finestra di contesto del modello.
· 12 min leggi

Scopri con l'IA

Costruire anche una semplice app di IA non è forse un groviglio di vector store, strumenti RAG, API e debug? Non più. Gemini 2.5 Pro offre una lunga finestra di contesto da 1 milione di token (con l'intenzione di raddoppiarla) e la possibilità di caricare file direttamente senza strumenti RAG o vector store.

Gemini 2.5 Pro è un modello di ragionamento che eccelle nel coding, e la sua enorme finestra di contesto apre la strada a un reale valore di business nelle applicazioni incentrate sul codice. Per questo, in questo blog, ti guiderò nella creazione di una vera web app che elabora il codice sorgente e ti aiuta a ottimizzare i tuoi progetti in pochi secondi.

Vado dritto al codice: se cerchi solo una panoramica del modello, dai un'occhiata a questo blog introduttivo su Gemini 2.5 Pro, e al modello più recente, Gemini 3. Se vuoi saperne di più sulla nuova funzione Computer Use, leggi la nostra guida completa a Gemini 2.5 Computer Use.

Connessione all'API di Gemini 2.5 Pro

Per accedere al modello Gemini 2.5 Pro tramite la Google API, segui questi passaggi:

1. Configurazione

Per prima cosa, installa il pacchetto Python google-genai. Esegui il seguente comando nel terminale:

pip install google-genai

2. Generazione di una chiave API

Vai su Google AI Studio e genera la tua chiave API. Poi imposta la chiave API come variabile d'ambiente nel tuo sistema.

google ai studio how to create an api key

3. Crea il client GenAI

Usa la chiave API per inizializzare il client Google GenAI. Questo client ti permetterà di interagire con il modello Gemini 2.5 Pro.

import os
from google import genai
from google.genai import types
from IPython.display import Markdown, HTML, Image, display

API_KEY = os.environ.get("GEMINI_API_KEY")

client = genai.Client(api_key=API_KEY)

4. Carica il file

Carica il file Python con cui vuoi lavorare e crea un prompt per il modello.

# Load the Python file as text

file_path = "secure_app.py"
with open(file_path, "r") as file:
    doc_data = file.read()
prompt = "Please integrate user management into the FastAPI application."

contents = [
    types.Part.from_bytes(
        data=doc_data.encode("utf-8"),
        mime_type="text/x-python",
    ),
    prompt,
]

5. Genera una risposta

Crea un'istanza di chat usando il modello Gemini 2.5 Pro (gemini-2.5-pro-exp-03-25) e fornisci i contenuti del file e il prompt. Il modello analizzerà il codice e genererà una risposta.

chat = client.aio.chats.create(
    model="gemini-2.5-pro-exp-03-25",
    config=types.GenerateContentConfig(
        tools=[types.Tool(code_execution=types.ToolCodeExecution)]
    ),
)

response = await chat.send_message(contents)
Markdown(response.text)

In pochi secondi è stata generata una risposta sensibile al contesto.

api response using gemini 2.5 pro

Nota: l'accesso gratuito al modello potrebbe non essere al momento disponibile a causa dell'elevato carico. Aspetta qualche minuto e riprova.

6. Esecuzione del codice (Sperimentale)

Puoi anche chiedere al modello di eseguire il codice.

response = await chat.send_message('Please run the code to ensure that everything is functioning properly.')
Markdown(response.text)

Nota che questa funzione è sperimentale e presenta limitazioni. Ad esempio, il modello non può eseguire server web, accedere al file system o effettuare operazioni di rete.

gemini 2.5 pro API response

Nota: il modello Gemini 2.5 Pro include capacità avanzate di "pensiero". Sebbene siano visibili in Google AI Studio, non sono incluse nell'output dell'API.

Creare un'app di analisi del codice con Gemini 2.5 Pro

Questa applicazione consente agli utenti di caricare file, inclusi più file o anche un archivio ZIP contenente un intero progetto, in un'interfaccia basata su chat. Gli utenti possono fare domande sul loro progetto, risolvere problemi o migliorare la codebase. A differenza dei tradizionali editor di codice basati su IA che faticano con contesti ampi a causa delle loro limitazioni, Gemini 2.5 Pro, con la sua lunga finestra di contesto, può analizzare e risolvere efficacemente i problemi su un intero progetto.

1. Installazione delle librerie necessarie

Installa gradio per creare l'interfaccia e zipfile36 per gestire i file ZIP.

pip install gradio==5.14.0
pip install zipfile36==0.1.3

2. Configurazione del client e dell'interfaccia

Importa i pacchetti Python necessari, definisci le variabili globali, inizializza il client GenAI, imposta le costanti dell'interfaccia e crea un elenco di estensioni di file supportate.

import os
import zipfile
from typing import Dict, List, Optional, Union

import gradio as gr
from google import genai
from google.genai import types

# Retrieve API key for Google GenAI from the environment variables.
GOOGLE_API_KEY = os.environ.get("GOOGLE_API_KEY")

# Initialize the client so that it can be reused across functions.
CLIENT = genai.Client(api_key=GOOGLE_API_KEY)


# Global variables
EXTRACTED_FILES = {}

# Store chat sessions
CHAT_SESSIONS = {}

TITLE = """<h1 align="center">✨ Gemini Code Analysis</h1>"""
AVATAR_IMAGES = (None, "https://media.roboflow.com/spaces/gemini-icon.png")


# List of supported text extensions (alphabetically sorted)
TEXT_EXTENSIONS = [
    ".bat",
    ".c",
    ".cfg",
    ".conf",
    ".cpp",
    ".cs",
    ".css",
    ".go",
    ".h",
    ".html",
    ".ini",
    ".java",
    ".js",
    ".json",
    ".jsx",
    ".md",
    ".php",
    ".ps1",
    ".py",
    ".rb",
    ".rs",
    ".sh",
    ".toml",
    ".ts",
    ".tsx",
    ".txt",
    ".xml",
    ".yaml",
    ".yml",
]

3. Funzione: extract_text_from_zip

La funzione extract_text_from_zip() estrae il contenuto testuale dai file all'interno di un archivio ZIP e lo restituisce come dizionario.

def extract_text_from_zip(zip_file_path: str) -> Dict[str, str]:

    text_contents = {}

    with zipfile.ZipFile(zip_file_path, "r") as zip_ref:
        for file_info in zip_ref.infolist():
            # Skip directories
            if file_info.filename.endswith("/"):
                continue

            # Skip binary files and focus on text files
            file_ext = os.path.splitext(file_info.filename)[1].lower()

            if file_ext in TEXT_EXTENSIONS:
                try:
                    with zip_ref.open(file_info) as file:
                        content = file.read().decode("utf-8", errors="replace")
                        text_contents[file_info.filename] = content
                except Exception as e:
                    text_contents[file_info.filename] = (
                        f"Error extracting file: {str(e)}"
                    )

    return text_contents

4. Funzione: extract_text_from_single_file

La funzione extract_text_from_single_file() estrae il contenuto testuale da un singolo file e lo restituisce come dizionario.

def extract_text_from_single_file(file_path: str) -> Dict[str, str]:

    text_contents = {}
    filename = os.path.basename(file_path)
    file_ext = os.path.splitext(filename)[1].lower()

    if file_ext in TEXT_EXTENSIONS:
        try:
            with open(file_path, "r", encoding="utf-8", errors="replace") as file:
                content = file.read()
                text_contents[filename] = content
        except Exception as e:
            text_contents[filename] = f"Error reading file: {str(e)}"

    return text_contents

5. Funzione: upload_zip

La funzione upload_zip() elabora i file caricati, in formato ZIP o come file di testo, estrae il contenuto testuale e aggiunge un messaggio alla chat.

def upload_zip(files: Optional[List[str]], chatbot: List[Union[dict, gr.ChatMessage]]):
    global EXTRACTED_FILES

    # Handle multiple file uploads
    if len(files) > 1:
        total_files_processed = 0
        total_files_extracted = 0
        file_types = set()

        # Process each file
        for file in files:
            filename = os.path.basename(file)
            file_ext = os.path.splitext(filename)[1].lower()

            # Process based on file type
            if file_ext == ".zip":
                extracted_files = extract_text_from_zip(file)
                file_types.add("zip")
            else:
                extracted_files = extract_text_from_single_file(file)
                file_types.add("text")

            if extracted_files:
                total_files_extracted += len(extracted_files)
                # Store the extracted content in the global variable
                EXTRACTED_FILES[filename] = extracted_files

            total_files_processed += 1

        # Create a summary message for multiple files
        file_types_str = (
            "files"
            if len(file_types) > 1
            else ("ZIP files" if "zip" in file_types else "text files")
        )

        # Create a list of uploaded file names
        file_list = "\n".join([f"- {os.path.basename(file)}" for file in files])

        chatbot.append(
            gr.ChatMessage(
                role="user",
                content=f"<p>📚 Multiple {file_types_str} uploaded ({total_files_processed} files)</p><p>Extracted {total_files_extracted} text file(s) in total</p><p>Uploaded files:</p><pre>{file_list}</pre>",
            )
        )

    # Handle single file upload (original behavior)
    elif len(files) == 1:
        file = files[0]
        filename = os.path.basename(file)
        file_ext = os.path.splitext(filename)[1].lower()

        # Process based on file type
        if file_ext == ".zip":
            extracted_files = extract_text_from_zip(file)
            file_type_msg = "📦 ZIP file"
        else:
            extracted_files = extract_text_from_single_file(file)
            file_type_msg = "📄 File"

        if not extracted_files:
            chatbot.append(
                gr.ChatMessage(
                    role="user",
                    content=f"<p>{file_type_msg} uploaded: {filename}, but no text content was found or the file format is not supported.</p>",
                )
            )
        else:
            file_list = "\n".join([f"- {name}" for name in extracted_files.keys()])
            chatbot.append(
                gr.ChatMessage(
                    role="user",
                    content=f"<p>{file_type_msg} uploaded: {filename}</p><p>Extracted {len(extracted_files)} text file(s):</p><pre>{file_list}</pre>",
                )
            )

            # Store the extracted content in the global variable
            EXTRACTED_FILES[filename] = extracted_files

    return chatbot

6. Funzione: user

La funzione user() aggiunge l'input testuale dell'utente alla cronologia della conversazione del chatbot.

def user(text_prompt: str, chatbot: List[gr.ChatMessage]):

    if text_prompt:
        chatbot.append(gr.ChatMessage(role="user", content=text_prompt))
    return "", chatbot

7. Funzione: get_message_content

La funzione get_message_content() recupera il contenuto di un messaggio, che può essere sia un dizionario sia un messaggio chat di Gradio.

def get_message_content(msg):
   
    if isinstance(msg, dict):
        return msg.get("content", "")
    return msg.content

8. Funzione: send_to_gemini

La funzione send_to_gemini() invia il prompt dell'utente a Gemini AI e trasmette la risposta al chatbot. Se sono stati caricati file di codice, verranno inclusi nel contesto.

def send_to_gemini(chatbot: List[Union[dict, gr.ChatMessage]]):

    global EXTRACTED_FILES, CHAT_SESSIONS

    if len(chatbot) == 0:
        chatbot.append(
            gr.ChatMessage(
                role="assistant",
                content="Please enter a message to start the conversation.",
            )
        )
        return chatbot

    # Get the last user message as the prompt
    user_messages = [
        msg
        for msg in chatbot
        if (isinstance(msg, dict) and msg.get("role") == "user")
        or (hasattr(msg, "role") and msg.role == "user")
    ]

    if not user_messages:
        chatbot.append(
            gr.ChatMessage(
                role="assistant",
                content="Please enter a message to start the conversation.",
            )
        )
        return chatbot

    last_user_msg = user_messages[-1]
    prompt = get_message_content(last_user_msg)

    # Skip if the last message was about uploading a file (ZIP, single file, or multiple files)
    if (
        "📦 ZIP file uploaded:" in prompt
        or "📄 File uploaded:" in prompt
        or "📚 Multiple files uploaded" in prompt
    ):
        chatbot.append(
            gr.ChatMessage(
                role="assistant",
                content="What would you like to know about the code in this ZIP file?",
            )
        )
        return chatbot

    # Generate a unique session ID based on the extracted files or use a default key for no files
    if EXTRACTED_FILES:
        session_key = ",".join(sorted(EXTRACTED_FILES.keys()))
    else:
        session_key = "no_files"

    # Create a new chat session if one doesn't exist for this set of files
    if session_key not in CHAT_SESSIONS:
        # Configure Gemini with code execution capability
        CHAT_SESSIONS[session_key] = CLIENT.chats.create(
            model="gemini-2.5-pro-exp-03-25",
        )

        # Send all extracted files to the chat session first
        initial_contents = []
        for zip_name, files in EXTRACTED_FILES.items():
            for filename, content in files.items():
                file_ext = os.path.splitext(filename)[1].lower()
                mime_type = "text/plain"

                # Set appropriate mime type based on file extension
                if file_ext == ".py":
                    mime_type = "text/x-python"
                elif file_ext in [".js", ".jsx"]:
                    mime_type = "text/javascript"
                elif file_ext in [".ts", ".tsx"]:
                    mime_type = "text/typescript"
                elif file_ext == ".html":
                    mime_type = "text/html"
                elif file_ext == ".css":
                    mime_type = "text/css"
                elif file_ext in [".json", ".jsonl"]:
                    mime_type = "application/json"
                elif file_ext in [".xml", ".svg"]:
                    mime_type = "application/xml"

                # Create a header with the filename to preserve original file identity
                file_header = f"File: {filename}\n\n"
                file_content = file_header + content

                initial_contents.append(
                    types.Part.from_bytes(
                        data=file_content.encode("utf-8"),
                        mime_type=mime_type,
                    )
                )

        # Initialize the chat context with files if available
        if initial_contents:
            initial_contents.append(
                "I've uploaded these code files for you to analyze. I'll ask questions about them next."
            )
            # Use synchronous API instead of async
            CHAT_SESSIONS[session_key].send_message(initial_contents)
        # For sessions without files, we don't need to send an initial message

    # Append a placeholder for the assistant's response
    chatbot.append(gr.ChatMessage(role="assistant", content=""))

    # Send the user's prompt to the existing chat session using streaming API
    response = CHAT_SESSIONS[session_key].send_message_stream(prompt)

    # Process the response stream - text only (no images)
    output_text = ""
    for chunk in response:
        if chunk.candidates and chunk.candidates[0].content.parts:
            for part in chunk.candidates[0].content.parts:
                if part.text is not None:
                    # Append the new chunk of text
                    output_text += part.text

                    # Update the last assistant message with the current accumulated response
                    if isinstance(chatbot[-1], dict):
                        chatbot[-1]["content"] = output_text
                    else:
                        chatbot[-1].content = output_text

                    # Yield the updated chatbot to show streaming updates in the UI
                    yield chatbot

    # Return the final chatbot state
    return chatbot

9. Funzione: reset_app

La funzione rest_app() ripristina l'applicazione cancellando la cronologia della chat e i file caricati.

def reset_app(chatbot):
    global EXTRACTED_FILES, CHAT_SESSIONS

    # Clear the global variables
    EXTRACTED_FILES = {}
    CHAT_SESSIONS = {}

    # Reset the chatbot with a welcome message
    return [
        gr.ChatMessage(
            role="assistant",
            content="App has been reset. You can start a new conversation or upload new files.",
        )
    ]

10. Componenti UI di Gradio

Definiamo i componenti Gradio: chatbot, input testuale, pulsante di caricamento e pulsanti di controllo.

# Define the Gradio UI components
chatbot_component = gr.Chatbot(
    label="Gemini 2.5 Pro",
    type="messages",
    bubble_full_width=False,
    avatar_images=AVATAR_IMAGES,
    scale=2,
    height=350,
)
text_prompt_component = gr.Textbox(
    placeholder="Ask a question or upload code files to analyze...",
    show_label=False,
    autofocus=True,
    scale=28,
)
upload_zip_button_component = gr.UploadButton(
    label="Upload",
    file_count="multiple",
    file_types=[".zip"] + TEXT_EXTENSIONS,
    scale=1,
    min_width=80,
)

send_button_component = gr.Button(
    value="Send", variant="primary", scale=1, min_width=80
)
reset_button_component = gr.Button(
    value="Reset", variant="stop", scale=1, min_width=80
)

# Define input lists for button chaining
user_inputs = [text_prompt_component, chatbot_component]

11. Layout dell'app Gradio

Strutturiamo l'interfaccia Gradio usando righe e colonne per un layout pulito.

with gr.Blocks(theme=gr.themes.Ocean()) as demo:
    gr.HTML(TITLE)
    with gr.Column():
        chatbot_component.render()
        with gr.Row(equal_height=True):
            text_prompt_component.render()
            send_button_component.render()
            upload_zip_button_component.render()
            reset_button_component.render()

    # When the Send button is clicked, first process the user text then send to Gemini
    send_button_component.click(
        fn=user,
        inputs=user_inputs,
        outputs=[text_prompt_component, chatbot_component],
        queue=False,
    ).then(
        fn=send_to_gemini,
        inputs=[chatbot_component],
        outputs=[chatbot_component],
        api_name="send_to_gemini",
    )

    # Allow submission using the Enter key
    text_prompt_component.submit(
        fn=user,
        inputs=user_inputs,
        outputs=[text_prompt_component, chatbot_component],
        queue=False,
    ).then(
        fn=send_to_gemini,
        inputs=[chatbot_component],
        outputs=[chatbot_component],
        api_name="send_to_gemini_submit",
    )

    # Handle ZIP file uploads
    upload_zip_button_component.upload(
        fn=upload_zip,
        inputs=[upload_zip_button_component, chatbot_component],
        outputs=[chatbot_component],
        queue=False,
    )

    # Handle Reset button clicks
    reset_button_component.click(
        fn=reset_app,
        inputs=[chatbot_component],
        outputs=[chatbot_component],
        queue=False,
    )

12. Avvio dell'app

Avviamo l'applicazione Gradio in locale con la coda abilitata per gestire più richieste.

# Launch the demo interface
demo.queue(max_size=99, api_open=False).launch(
    debug=False,
    show_error=True,
    server_port=9595,
    server_name="localhost",
)

Test dell'app di analisi del codice Gemini 2.5 Pro

Per avviare l'applicazione web, unisci tutti i sorgenti di codice sopra nel file main.py (che ho caricato su GitHub per facilitarti la copia). Eseguilo con il seguente comando:

python main.py

L'applicazione web sarà disponibile all'URL: http://localhost:9595/

Puoi copiare l'URL e incollarlo nel tuo browser.

Come possiamo vedere, l'applicazione web offre un'interfaccia tipo chatbot. Possiamo usarla proprio come ChatGPT.

gemini 2.5 pro code analysis project

Il pulsante “Upload” supporta il caricamento singolo e multiplo di file, oltre ai file zip del tuo progetto. Quindi, non preoccuparti se il tuo progetto contiene più di 20 file: l'app di analisi del codice sarà in grado di elaborarli e inviarli all'API di Gemini 2.5 Pro.

gemini 2.5 pro app supports many types of file inputs

Carichiamo più file e chiediamo a Gemini 2.5 Pro di migliorare il nostro progetto. 

Come possiamo vedere, il modello fornisce suggerimenti corretti per i miglioramenti.

gemini 2.5 pro project with gradio

Possiamo chiedergli di implementare tutti i suggerimenti nel file secure_app.py.

Se vuoi lavorare su un altro progetto, puoi cliccare sul pulsante “Reset” e iniziare a chattare sul nuovo progetto.

gemini 2.5 pro chat interface with gradio

Il codice sorgente e le configurazioni sono disponibili nel repository GitHub: kingabzpro/Gemini-2.5-Pro-Coding-App.

Conclusione

Creare una vera applicazione di IA è diventato molto più semplice. Invece di costruire applicazioni complesse con strumenti come LangChain, integrare vector store, ottimizzare i prompt o aggiungere catene di ragionamento, possiamo semplicemente inizializzare il client Gemini 2.5 Pro tramite la Google API. La Chat API di Gemini 2.5 Pro gestisce direttamente vari tipi di file, consente domande di follow-up e fornisce risposte altamente accurate.

Abid Ali Awan

Autore

Abid Ali Awan

In quanto data scientist certificato, sono appassionato di sfruttare tecnologie all’avanguardia per creare applicazioni di machine learning innovative. Con una solida esperienza in riconoscimento vocale, analisi e reportistica dei dati, MLOps, AI conversazionale e NLP, ho affinato le mie competenze nello sviluppo di sistemi intelligenti in grado di avere un impatto concreto. Oltre alla mia expertise tecnica, sono anche un comunicatore efficace, con il talento di rendere chiari e sintetici concetti complessi. Di conseguenza, sono diventato un blogger molto seguito in ambito data science, condividendo idee ed esperienze con una community in crescita di professionisti dei dati. Attualmente mi concentro sulla creazione e sull’editing di contenuti, lavorando con large language model per sviluppare contenuti potenti e coinvolgenti che possano aiutare aziende e singoli a valorizzare al meglio i propri dati.

Argomenti

Correlato