L'API Gemini consente la generazione Retrieval-Augmented Generation ("RAG") tramite lo strumento di ricerca file. File Search importa, suddivide e indicizza i tuoi dati per
consentire il recupero rapido di informazioni pertinenti in base a un prompt fornito. Queste informazioni recuperate vengono poi utilizzate come contesto per il modello, consentendogli di fornire risposte più accurate e pertinenti. La ricerca nei file è anche in grado di fornire funzionalità multimodali con text embedding supportati da gemini-embedding-001 e embedding di immagini/multimodali supportati da gemini-embedding-2.
L'archiviazione dei file e la generazione di incorporamenti al momento della query sono senza costi e pagherai solo per la creazione di incorporamenti quando indicizzi per la prima volta i file e per il normale costo dei token di input / output del modello Gemini. Questo nuovo paradigma di fatturazione rende lo strumento di ricerca dei file più semplice ed economico da creare e scalare. Per i dettagli, consulta la sezione Prezzi.
Carica direttamente nello store di ricerca nei file
Questo esempio mostra come caricare direttamente un file nell'archivio di ricerca dei file:
Python
from google import genai
from google.genai import types
import time
client = genai.Client()
file_search_store = client.file_search_stores.create(
config={
'display_name': 'your-fileSearchStore-name',
'embedding_model': 'models/gemini-embedding-2'
}
)
operation = client.file_search_stores.upload_to_file_search_store(
file='sample.txt',
file_search_store_name=file_search_store.name,
config={
'display_name' : 'display-file-name',
}
)
while not operation.done:
time.sleep(5)
operation = client.operations.get(operation)
interaction = client.interactions.create(
model="gemini-3.8-flash",
input="Can you tell me about [insert question]",
tools=[{
"type": "file_search",
"file_search_store_names": [file_search_store.name]
}]
)
for step in interaction.steps:
if step.type == "model_output":
for content_block in step.content:
if content_block.type == "text":
print(content_block.text)
if content_block.annotations:
print("\nSources:")
for annotation in content_block.annotations:
if annotation.type == "file_citation":
print(f" - {annotation.file_name}: {annotation.source}")
JavaScript
import { GoogleGenAI } from '@google/genai';
const ai = new GoogleGenAI({});
async function run() {
const fileSearchStore = await ai.fileSearchStores.create({
config: {
displayName: 'your-fileSearchStore-name',
embeddingModel: 'models/gemini-embedding-2'
}
});
let operation = await ai.fileSearchStores.uploadToFileSearchStore({
file: 'file.txt',
fileSearchStoreName: fileSearchStore.name,
config: {
displayName: 'file-name',
}
});
while (!operation.done) {
await new Promise(resolve => setTimeout(resolve, 5000));
operation = await ai.operations.get({ operation });
}
const interaction = await ai.interactions.create({
model: "gemini-3.8-flash",
input: "Can you tell me about [insert question]",
tools: [{
type: "file_search",
file_search_store_names: [fileSearchStore.name]
}]
});
for (const step of interaction.steps) {
if (step.type === 'model_output') {
for (const contentBlock of step.content) {
if (contentBlock.type === 'text') {
console.log(contentBlock.text);
if (contentBlock.annotations) {
console.log("\nSources:");
for (const annotation of contentBlock.annotations) {
if (annotation.type === 'file_citation') {
console.log(` - ${annotation.file_name}: ${annotation.source}`);
}
}
}
}
}
}
}
}
run();
Java
import com.google.genai.Client;
import com.google.genai.gaos.models.interactions.Annotation;
import com.google.genai.gaos.models.interactions.Content;
import com.google.genai.gaos.models.interactions.CreateModelInteraction;
import com.google.genai.gaos.models.interactions.FileCitation;
import com.google.genai.gaos.models.interactions.FileSearch;
import com.google.genai.gaos.models.interactions.Interaction;
import com.google.genai.gaos.models.interactions.InteractionsInput;
import com.google.genai.gaos.models.interactions.Model;
import com.google.genai.gaos.models.interactions.ModelOutputStep;
import com.google.genai.gaos.models.interactions.Step;
import com.google.genai.gaos.models.interactions.TextContent;
import com.google.genai.gaos.models.operations.CreateInteractionRequestBody;
import com.google.genai.types.CreateFileSearchStoreConfig;
import com.google.genai.types.FileSearchStore;
import com.google.genai.types.UploadToFileSearchStoreConfig;
import com.google.genai.types.UploadToFileSearchStoreOperation;
import java.util.Arrays;
Client client = new Client();
FileSearchStore fileSearchStore =
client.fileSearchStores.create(
CreateFileSearchStoreConfig.builder()
.displayName("your-fileSearchStore-name")
.embeddingModel("models/gemini-embedding-2")
.build());
UploadToFileSearchStoreOperation operation =
client.fileSearchStores.uploadToFileSearchStore(
fileSearchStore.name().get(),
"sample.txt",
UploadToFileSearchStoreConfig.builder().displayName("display-file-name").build());
while (!operation.done().orElse(false)) {
Thread.sleep(5000);
operation = client.operations.get(operation, null);
}
CreateModelInteraction params =
CreateModelInteraction.builder()
.model(Model.of("gemini-3.8-flash"))
.input(InteractionsInput.of("Can you tell me about [insert question]"))
.tools(
Arrays.asList(
FileSearch.builder()
.fileSearchStoreNames(Arrays.asList(fileSearchStore.name().get()))
.build()))
.build();
Interaction interaction =
client.interactions.create(CreateInteractionRequestBody.of(params)).interaction().get();
if (interaction.steps().isPresent()) {
for (Step step : interaction.steps().get()) {
if (step instanceof ModelOutputStep) {
ModelOutputStep outputStep = (ModelOutputStep) step;
if (outputStep.content().isPresent()) {
for (Content contentBlock : outputStep.content().get()) {
if (contentBlock instanceof TextContent) {
TextContent textContent = (TextContent) contentBlock;
System.out.println(textContent.text().orElse(""));
if (textContent.annotations().isPresent()
&& !textContent.annotations().get().isEmpty()) {
System.out.println("\nSources:");
for (Annotation annotation : textContent.annotations().get()) {
if (annotation instanceof FileCitation) {
FileCitation citation = (FileCitation) annotation;
System.out.printf(
" - %s: %s%n",
citation.fileName().orElse(""), citation.source().orElse(""));
}
}
}
}
}
}
}
}
}
Go
package main
import (
"context"
"fmt"
"log"
"time"
"google.golang.org/genai"
"google.golang.org/genai/interactions/models/interactions"
"google.golang.org/genai/interactions/models/operations"
)
func main() {
ctx := context.Background()
client, err := genai.NewClient(ctx, nil)
if err != nil {
log.Fatal(err)
}
fileSearchStore, err := client.FileSearchStores.Create(ctx, &genai.CreateFileSearchStoreConfig{
DisplayName: "your-fileSearchStore-name",
EmbeddingModel: "models/gemini-embedding-2",
})
if err != nil {
log.Fatal(err)
}
operation, err := client.FileSearchStores.UploadToFileSearchStoreFromPath(
ctx,
"sample.txt",
fileSearchStore.Name,
&genai.UploadToFileSearchStoreConfig{
DisplayName: "display-file-name",
},
)
if err != nil {
log.Fatal(err)
}
for !operation.Done {
time.Sleep(5 * time.Second)
operation, err = client.Operations.GetUploadToFileSearchStoreOperation(ctx, operation, nil)
if err != nil {
log.Fatal(err)
}
}
resp, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{
Body: operations.NewCreateInteractionRequestBody(
interactions.CreateModelInteraction{
Model: interactions.Model("gemini-3.8-flash"),
Input: interactions.NewInteractionsInput("Can you tell me about [insert question]"),
Tools: []interactions.Tool{
interactions.NewTool(interactions.FileSearch{
FileSearchStoreNames: []string{fileSearchStore.Name},
}),
},
},
),
})
if err != nil {
log.Fatal(err)
}
for _, step := range resp.Interaction.Steps {
if step.ModelOutputStep != nil {
for _, content := range step.ModelOutputStep.Content {
if content.TextContent != nil {
fmt.Println(content.TextContent.Text)
if len(content.TextContent.Annotations) > 0 {
fmt.Println("\nSources:")
for _, annotation := range content.TextContent.Annotations {
if annotation.FileCitation != nil {
c := annotation.FileCitation
fileName := ""
if c.FileName != nil {
fileName = *c.FileName
}
source := ""
if c.Source != nil {
source = *c.Source
}
fmt.Printf(" - %s: %s\n", fileName, source)
}
}
}
}
}
}
}
}
REST
# 1. Create a File Search store
curl -X POST "https://generativelanguage.googleapis.com/v1beta/fileSearchStores?key=$GEMINI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"displayName": "your-file-search-store-name",
"embeddingModel": "models/gemini-embedding-2"
}' > store_res.json
FILE_SEARCH_STORE_NAME=$(jq -r ".name" store_res.json)
# 2. Upload directly to File Search store using resumable upload
NUM_BYTES=$(wc -c < "sample.txt")
curl "https://generativelanguage.googleapis.com/upload/v1beta/fileSearchStores/$FILE_SEARCH_STORE_NAME:uploadToFileSearchStore?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: text/plain" \
-H "Content-Type: application/json" \
-d '{"displayName": "sample.txt"}' 2> /dev/null
upload_url=$(grep -i "x-goog-upload-url: " upload-header.tmp | cut -d" " -f2 | tr -d "\r")
rm upload-header.tmp
curl "${upload_url}" \
-H "Content-Length: $NUM_BYTES" \
-H "X-Goog-Upload-Offset: 0" \
-H "X-Goog-Upload-Command: upload, finalize" \
--data-binary "@sample.txt" 2> /dev/null > upload_response.json
cat upload_response.json
# 3. Query using the File Search store
curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \
-H "x-goog-api-key: $GEMINI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gemini-3.8-flash",
"input": "Can you tell me about [insert question]",
"tools": [{
"type": "file_search",
"file_search_store_names": ["'"$FILE_SEARCH_STORE_NAME"'"]
}]
}'
Per ulteriori informazioni, consulta il riferimento API per uploadToFileSearchStore.
Importazione di file
In alternativa, puoi caricare un file esistente e importarlo nel tuo archivio di ricerca dei file:
Python
from google import genai
from google.genai import types
import time
client = genai.Client()
sample_file = client.files.upload(file='sample.txt', config={'display_name': 'display_file_name'})
file_search_store = client.file_search_stores.create(
config={
'display_name': 'your-fileSearchStore-name',
'embedding_model': 'models/gemini-embedding-2'
}
)
operation = client.file_search_stores.import_file(
file_search_store_name=file_search_store.name,
file_name=sample_file.name
)
while not operation.done:
time.sleep(5)
operation = client.operations.get(operation)
interaction = client.interactions.create(
model="gemini-3.8-flash",
input="Can you tell me about [insert question]",
tools=[{
"type": "file_search",
"file_search_store_names": [file_search_store.name]
}]
)
for step in interaction.steps:
if step.type == "model_output":
for content_block in step.content:
if content_block.type == "text":
print(content_block.text)
JavaScript
import { GoogleGenAI } from '@google/genai';
const ai = new GoogleGenAI({});
async function run() {
const sampleFile = await ai.files.upload({
file: 'sample.txt',
config: { displayName: 'file-name' }
});
const fileSearchStore = await ai.fileSearchStores.create({
config: {
displayName: 'your-fileSearchStore-name',
embeddingModel: 'models/gemini-embedding-2'
}
});
let operation = await ai.fileSearchStores.importFile({
fileSearchStoreName: fileSearchStore.name,
fileName: sampleFile.name
});
while (!operation.done) {
await new Promise(resolve => setTimeout(resolve, 5000));
operation = await ai.operations.get({ operation: operation });
}
const interaction = await ai.interactions.create({
model: "gemini-3.8-flash",
input: "Can you tell me about [insert question]",
tools: [{
type: "file_search",
file_search_store_names: [fileSearchStore.name]
}]
});
for (const step of interaction.steps) {
if (step.type === 'model_output') {
for (const contentBlock of step.content) {
if (contentBlock.type === 'text') {
console.log(contentBlock.text);
}
}
}
}
}
run();
Java
import com.google.genai.Client;
import com.google.genai.gaos.models.interactions.Content;
import com.google.genai.gaos.models.interactions.CreateModelInteraction;
import com.google.genai.gaos.models.interactions.FileSearch;
import com.google.genai.gaos.models.interactions.Interaction;
import com.google.genai.gaos.models.interactions.InteractionsInput;
import com.google.genai.gaos.models.interactions.Model;
import com.google.genai.gaos.models.interactions.ModelOutputStep;
import com.google.genai.gaos.models.interactions.Step;
import com.google.genai.gaos.models.interactions.TextContent;
import com.google.genai.gaos.models.operations.CreateInteractionRequestBody;
import com.google.genai.types.CreateFileSearchStoreConfig;
import com.google.genai.types.File;
import com.google.genai.types.FileSearchStore;
import com.google.genai.types.ImportFileOperation;
import com.google.genai.types.UploadFileConfig;
import java.util.Arrays;
Client client = new Client();
File sampleFile =
client.files.upload(
"sample.txt", UploadFileConfig.builder().displayName("display_file_name").build());
FileSearchStore fileSearchStore =
client.fileSearchStores.create(
CreateFileSearchStoreConfig.builder()
.displayName("your-fileSearchStore-name")
.embeddingModel("models/gemini-embedding-2")
.build());
ImportFileOperation operation =
client.fileSearchStores.importFile(
fileSearchStore.name().get(), sampleFile.name().get(), null);
while (!operation.done().orElse(false)) {
Thread.sleep(5000);
operation = client.operations.get(operation, null);
}
CreateModelInteraction params =
CreateModelInteraction.builder()
.model(Model.of("gemini-3.8-flash"))
.input(InteractionsInput.of("Can you tell me about [insert question]"))
.tools(
Arrays.asList(
FileSearch.builder()
.fileSearchStoreNames(Arrays.asList(fileSearchStore.name().get()))
.build()))
.build();
Interaction interaction =
client.interactions.create(CreateInteractionRequestBody.of(params)).interaction().get();
if (interaction.steps().isPresent()) {
for (Step step : interaction.steps().get()) {
if (step instanceof ModelOutputStep) {
ModelOutputStep outputStep = (ModelOutputStep) step;
if (outputStep.content().isPresent()) {
for (Content contentBlock : outputStep.content().get()) {
if (contentBlock instanceof TextContent) {
TextContent textContent = (TextContent) contentBlock;
System.out.println(textContent.text().orElse(""));
}
}
}
}
}
}
Go
package main
import (
"context"
"fmt"
"log"
"time"
"google.golang.org/genai"
"google.golang.org/genai/interactions/models/interactions"
"google.golang.org/genai/interactions/models/operations"
)
func main() {
ctx := context.Background()
client, err := genai.NewClient(ctx, nil)
if err != nil {
log.Fatal(err)
}
sampleFile, err := client.Files.UploadFromPath(ctx, "sample.txt", &genai.UploadFileConfig{
DisplayName: "display_file_name",
})
if err != nil {
log.Fatal(err)
}
fileSearchStore, err := client.FileSearchStores.Create(ctx, &genai.CreateFileSearchStoreConfig{
DisplayName: "your-fileSearchStore-name",
EmbeddingModel: "models/gemini-embedding-2",
})
if err != nil {
log.Fatal(err)
}
operation, err := client.FileSearchStores.ImportFile(ctx, fileSearchStore.Name, sampleFile.Name, nil)
if err != nil {
log.Fatal(err)
}
for !operation.Done {
time.Sleep(5 * time.Second)
operation, err = client.Operations.GetImportFileOperation(ctx, operation, nil)
if err != nil {
log.Fatal(err)
}
}
resp, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{
Body: operations.NewCreateInteractionRequestBody(
interactions.CreateModelInteraction{
Model: interactions.Model("gemini-3.8-flash"),
Input: interactions.NewInteractionsInput("Can you tell me about [insert question]"),
Tools: []interactions.Tool{
interactions.NewTool(interactions.FileSearch{
FileSearchStoreNames: []string{fileSearchStore.Name},
}),
},
},
),
})
if err != nil {
log.Fatal(err)
}
for _, step := range resp.Interaction.Steps {
if step.ModelOutputStep != nil {
for _, content := range step.ModelOutputStep.Content {
if content.TextContent != nil {
fmt.Println(content.TextContent.Text)
}
}
}
}
}
REST
# 1. Upload file using the Files API
NUM_BYTES=$(wc -c < "sample.txt")
curl "https://generativelanguage.googleapis.com/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: text/plain" \
-H "Content-Type: application/json" \
-d '{"file": {"displayName": "sample.txt"}}' 2> /dev/null
upload_url=$(grep -i "x-goog-upload-url: " upload-header.tmp | cut -d" " -f2 | tr -d "\r")
rm upload-header.tmp
curl "${upload_url}" \
-H "Content-Length: $NUM_BYTES" \
-H "X-Goog-Upload-Offset: 0" \
-H "X-Goog-Upload-Command: upload, finalize" \
--data-binary "@sample.txt" 2> /dev/null > file_info.json
FILE_NAME=$(jq -r ".file.name" file_info.json)
# 2. Create a File Search store
curl -X POST "https://generativelanguage.googleapis.com/v1beta/fileSearchStores?key=$GEMINI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"displayName": "your-file-search-store-name",
"embeddingModel": "models/gemini-embedding-2"
}' > store_res.json
FILE_SEARCH_STORE_NAME=$(jq -r ".name" store_res.json)
# 3. Import the file into the File Search store
curl -X POST "https://generativelanguage.googleapis.com/v1beta/fileSearchStores/$FILE_SEARCH_STORE_NAME:importFile?key=$GEMINI_API_KEY" \
-H "Content-Type: application/json" \
-d '{"fileName": "'"$FILE_NAME"'"}'
# 4. Query using the File Search store
curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \
-H "x-goog-api-key: $GEMINI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gemini-3.8-flash",
"input": "Can you tell me about [insert question]",
"tools": [{
"type": "file_search",
"file_search_store_names": ["'"$FILE_SEARCH_STORE_NAME"'"]
}]
}'
Per saperne di più, consulta il riferimento API per importFile.
Configurazione del chunking
Quando importi un file in un archivio di ricerca file, questo viene suddiviso automaticamente
in blocchi, incorporato, indicizzato e caricato nell'archivio di ricerca file. Se hai bisogno di un maggiore controllo sulla strategia di suddivisione in blocchi, puoi specificare un'impostazione chunking_config per impostare un numero massimo di token per blocco e un numero massimo di token sovrapposti.
Python
from google import genai
from google.genai import types
import time
client = genai.Client()
operation = client.file_search_stores.upload_to_file_search_store(
file_search_store_name=file_search_store.name,
file='sample.txt',
config={
'chunking_config': {
'white_space_config': {
'max_tokens_per_chunk': 200,
'max_overlap_tokens': 20
}
}
}
)
while not operation.done:
time.sleep(5)
operation = client.operations.get(operation)
print("Custom chunking complete.")
JavaScript
import { GoogleGenAI } from '@google/genai';
const ai = new GoogleGenAI({});
let operation = await ai.fileSearchStores.uploadToFileSearchStore({
file: 'file.txt',
fileSearchStoreName: fileSearchStore.name,
config: {
displayName: 'file-name',
chunkingConfig: {
whiteSpaceConfig: {
maxTokensPerChunk: 200,
maxOverlapTokens: 20
}
}
}
});
while (!operation.done) {
await new Promise(resolve => setTimeout(resolve, 5000));
operation = await ai.operations.get({ operation });
}
console.log("Custom chunking complete.");
Java
import com.google.genai.Client;
import com.google.genai.types.ChunkingConfig;
import com.google.genai.types.UploadToFileSearchStoreConfig;
import com.google.genai.types.UploadToFileSearchStoreOperation;
import com.google.genai.types.WhiteSpaceConfig;
Client client = new Client();
UploadToFileSearchStoreOperation operation =
client.fileSearchStores.uploadToFileSearchStore(
"fileSearchStores/my-file-search-store",
"sample.txt",
UploadToFileSearchStoreConfig.builder()
.displayName("file-name")
.chunkingConfig(
ChunkingConfig.builder()
.whiteSpaceConfig(
WhiteSpaceConfig.builder()
.maxTokensPerChunk(200)
.maxOverlapTokens(20)
.build())
.build())
.build());
while (!operation.done().orElse(false)) {
Thread.sleep(5000);
operation = client.operations.get(operation, null);
}
System.out.println("Custom chunking complete.");
Go
package main
import (
"context"
"fmt"
"log"
"time"
"google.golang.org/genai"
)
func main() {
ctx := context.Background()
client, err := genai.NewClient(ctx, nil)
if err != nil {
log.Fatal(err)
}
operation, err := client.FileSearchStores.UploadToFileSearchStoreFromPath(
ctx,
"sample.txt",
"fileSearchStores/my-file-search-store",
&genai.UploadToFileSearchStoreConfig{
DisplayName: "file-name",
ChunkingConfig: &genai.ChunkingConfig{
WhiteSpaceConfig: &genai.WhiteSpaceConfig{
MaxTokensPerChunk: genai.Ptr(int32(200)),
MaxOverlapTokens: genai.Ptr(int32(20)),
},
},
},
)
if err != nil {
log.Fatal(err)
}
for !operation.Done {
time.Sleep(5 * time.Second)
operation, err = client.Operations.GetUploadToFileSearchStoreOperation(ctx, operation, nil)
if err != nil {
log.Fatal(err)
}
}
fmt.Println("Custom chunking complete.")
}
REST
NUM_BYTES=$(wc -c < "sample.txt")
curl "https://generativelanguage.googleapis.com/upload/v1beta/fileSearchStores/$FILE_SEARCH_STORE_NAME:uploadToFileSearchStore?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: text/plain" \
-H "Content-Type: application/json" \
-d '{
"displayName": "sample.txt",
"chunkingConfig": {
"whiteSpaceConfig": {
"maxTokensPerChunk": 200,
"maxOverlapTokens": 20
}
}
}' 2> /dev/null
upload_url=$(grep -i "x-goog-upload-url: " upload-header.tmp | cut -d" " -f2 | tr -d "\r")
rm upload-header.tmp
curl "${upload_url}" \
-H "Content-Length: $NUM_BYTES" \
-H "X-Goog-Upload-Offset: 0" \
-H "X-Goog-Upload-Command: upload, finalize" \
--data-binary "@sample.txt" 2> /dev/null > upload_response.json
cat upload_response.json
Per utilizzare il tuo archivio di ricerca nei file, passalo come strumento al metodo interactions.create, come mostrato negli esempi di caricamento e importazione.
Come funziona
La ricerca di file utilizza una tecnica chiamata ricerca semantica per trovare informazioni pertinenti al prompt dell'utente. A differenza della ricerca standard basata su parole chiave, la ricerca semantica comprende il significato e il contesto della query.
Quando importi un file, questo viene convertito in rappresentazioni numeriche chiamate embedding, che acquisiscono il significato semantico dei contenuti caricati. Questi embedding vengono archiviati in un database di ricerca di file specializzato. Quando esegui una query, anche questa viene convertita in un embedding. Il sistema esegue quindi una ricerca di file per trovare i blocchi di documenti più simili e pertinenti nell'archivio della ricerca di file.
Non esiste un Time To Live (TTL) per gli embedding; rimangono persistenti fino a quando non vengono eliminati manualmente o quando il modello viene ritirato. I file, tuttavia, vengono eliminati dopo 48 ore.
Ecco una panoramica della procedura per l'utilizzo dell'API File Search
uploadToFileSearchStore:
Crea un contenitore archiviato per la ricerca di file: un contenitore archiviato per la ricerca di file contiene i dati elaborati dei tuoi file. È il container persistente per gli embedding su cui opererà la ricerca semantica.
Carica un file e importalo in un datastore di ricerca nei file: carica contemporaneamente un file e importa i risultati nel datastore di ricerca nei file. In questo modo viene creato un oggetto
Filetemporaneo, che è un riferimento al documento non elaborato. Questi dati vengono poi suddivisi in blocchi, convertiti in embedding di File Search e indicizzati. L'oggettoFileviene eliminato dopo 48 ore, mentre i dati importati nell'archivio di Ricerca file vengono archiviati a tempo indeterminato finché non scegli di eliminarli.Esegui una query con la ricerca nei file: infine, utilizza lo strumento
FileSearchin una chiamatagenerateContent. Nella configurazione dello strumento, specifichi unFileSearchRetrievalResource, che rimanda alFileSearchStorein cui vuoi eseguire la ricerca. In questo modo, il modello esegue una ricerca semantica in quel datastore di ricerca di file specifico per trovare informazioni pertinenti su cui basare la sua risposta.
In questo diagramma, la linea tratteggiata da Documenti a Modello di embedding
(utilizzando gemini-embedding-001)
rappresenta l'API uploadToFileSearchStore (bypassando Spazio di archiviazione file).
In caso contrario, l'utilizzo dell'API Files per creare e poi importare i file separatamente sposta il processo di indicizzazione da Documenti a Spazio di archiviazione file e poi a Modello di embedding.
Archivi di ricerca file
Un archivio di ricerca di file è un contenitore per gli incorporamenti dei documenti. Mentre i file non elaborati
caricati tramite l'API File vengono eliminati dopo 48 ore, i dati importati in
un archivio di ricerca file vengono archiviati a tempo indeterminato finché non li elimini manualmente. Puoi creare più archivi di ricerca nei file per organizzare i tuoi documenti. L'API FileSearchStore ti consente di creare, elencare, recuperare ed eliminare per gestire i tuoi datastore di ricerca di file. I nomi degli store di ricerca dei file hanno un ambito globale.
Ecco alcuni esempi di come gestire i tuoi negozi di ricerca file:
Python
file_search_store = client.file_search_stores.create(
config={
'display_name': 'myfilesearchstore123',
'embedding_model': 'models/gemini-embedding-2'
}
)
for store in client.file_search_stores.list():
print(store)
my_file_search_store = client.file_search_stores.get(name=file_search_store.name)
client.file_search_stores.delete(name=file_search_store.name, config={'force': True})
JavaScript
const fileSearchStore = await ai.fileSearchStores.create({
config: {
displayName: 'myfilesearchstore123',
embeddingModel: 'models/gemini-embedding-2'
}
});
const fileSearchStores = await ai.fileSearchStores.list();
for await (const store of fileSearchStores) {
console.log(store);
}
const myFileSearchStore = await ai.fileSearchStores.get({
name: fileSearchStore.name
});
await ai.fileSearchStores.delete({
name: fileSearchStore.name,
config: { force: true }
});
Java
import com.google.genai.Client;
import com.google.genai.types.CreateFileSearchStoreConfig;
import com.google.genai.types.DeleteFileSearchStoreConfig;
import com.google.genai.types.FileSearchStore;
Client client = new Client();
FileSearchStore fileSearchStore =
client.fileSearchStores.create(
CreateFileSearchStoreConfig.builder()
.displayName("myfilesearchstore123")
.embeddingModel("models/gemini-embedding-2")
.build());
for (FileSearchStore store : client.fileSearchStores.list(null)) {
System.out.println(store);
}
FileSearchStore myFileSearchStore =
client.fileSearchStores.get(fileSearchStore.name().get(), null);
client.fileSearchStores.delete(
fileSearchStore.name().get(), DeleteFileSearchStoreConfig.builder().force(true).build());
Go
package main
import (
"context"
"fmt"
"log"
"google.golang.org/genai"
)
func main() {
ctx := context.Background()
client, err := genai.NewClient(ctx, nil)
if err != nil {
log.Fatal(err)
}
fileSearchStore, err := client.FileSearchStores.Create(ctx, &genai.CreateFileSearchStoreConfig{
DisplayName: "myfilesearchstore123",
EmbeddingModel: "models/gemini-embedding-2",
})
if err != nil {
log.Fatal(err)
}
for store, err := range client.FileSearchStores.All(ctx) {
if err != nil {
log.Fatal(err)
}
fmt.Println(store)
}
myFileSearchStore, err := client.FileSearchStores.Get(ctx, fileSearchStore.Name, nil)
if err != nil {
log.Fatal(err)
}
_ = myFileSearchStore
err = client.FileSearchStores.Delete(ctx, fileSearchStore.Name, &genai.DeleteFileSearchStoreConfig{
Force: genai.Ptr(true),
})
if err != nil {
log.Fatal(err)
}
}
REST
curl -X POST "https://generativelanguage.googleapis.com/v1beta/fileSearchStores?key=${GEMINI_API_KEY}" \
-H "Content-Type: application/json" \
-d '{ "displayName": "My Store", "embedding_model": "models/gemini-embedding-2" }'
curl "https://generativelanguage.googleapis.com/v1beta/fileSearchStores?key=${GEMINI_API_KEY}"
curl "https://generativelanguage.googleapis.com/v1beta/fileSearchStores/myfilesearchstore123?key=${GEMINI_API_KEY}"
curl -X DELETE "https://generativelanguage.googleapis.com/v1beta/fileSearchStores/myfilesearchstore123?key=${GEMINI_API_KEY}"
Documenti di ricerca di file
Puoi gestire i singoli documenti nei tuoi datastore di file con l'API File Search Documents per list ogni documento in un datastore di ricerca di file, get informazioni su un documento e delete un documento per nome.
Python
for document_in_store in client.file_search_stores.documents.list(parent='fileSearchStores/myfilesearchstore123'):
print(document_in_store)
file_search_document = client.file_search_stores.documents.get(name='fileSearchStores/myfilesearchstore123/documents/sampletxt123')
print(file_search_document)
client.file_search_stores.documents.delete(name='fileSearchStores/myfilesearchstore123/documents/sampletxt123', config={'force': True})
JavaScript
const documents = await ai.fileSearchStores.documents.list({
parent: 'fileSearchStores/myfilesearchstore123'
});
for await (const doc of documents) {
console.log(doc);
}
const fileSearchDocument = await ai.fileSearchStores.documents.get({
name: 'fileSearchStores/myfilesearchstore123/documents/sampletxt123'
});
await ai.fileSearchStores.documents.delete({
name: 'fileSearchStores/myfilesearchstore123/documents/sampletxt123',
config: { force: true }
});
Java
import com.google.genai.Client;
import com.google.genai.types.DeleteDocumentConfig;
import com.google.genai.types.Document;
Client client = new Client();
for (Document documentInStore :
client.fileSearchStores.documents.list("fileSearchStores/myfilesearchstore123", null)) {
System.out.println(documentInStore);
}
Document fileSearchDocument =
client.fileSearchStores.documents.get(
"fileSearchStores/myfilesearchstore123/documents/sampletxt123", null);
System.out.println(fileSearchDocument);
client.fileSearchStores.documents.delete(
"fileSearchStores/myfilesearchstore123/documents/sampletxt123",
DeleteDocumentConfig.builder().force(true).build());
Go
package main
import (
"context"
"fmt"
"log"
"google.golang.org/genai"
)
func main() {
ctx := context.Background()
client, err := genai.NewClient(ctx, nil)
if err != nil {
log.Fatal(err)
}
for documentInStore, err := range client.FileSearchStores.Documents.All(ctx, "fileSearchStores/myfilesearchstore123") {
if err != nil {
log.Fatal(err)
}
fmt.Println(documentInStore)
}
fileSearchDocument, err := client.FileSearchStores.Documents.Get(ctx, "fileSearchStores/myfilesearchstore123/documents/sampletxt123", nil)
if err != nil {
log.Fatal(err)
}
fmt.Println(fileSearchDocument)
err = client.FileSearchStores.Documents.Delete(ctx, "fileSearchStores/myfilesearchstore123/documents/sampletxt123", &genai.DeleteDocumentConfig{
Force: genai.Ptr(true),
})
if err != nil {
log.Fatal(err)
}
}
REST
curl "https://generativelanguage.googleapis.com/v1beta/fileSearchStores/myfilesearchstore123/documents?key=${GEMINI_API_KEY}"
curl "https://generativelanguage.googleapis.com/v1beta/fileSearchStores/myfilesearchstore123/documents/sampletxt123?key=${GEMINI_API_KEY}"
curl -X DELETE "https://generativelanguage.googleapis.com/v1beta/fileSearchStores/myfilesearchstore123/documents/sampletxt123?key=${GEMINI_API_KEY}&force=true"
File di metadati
Puoi aggiungere metadati personalizzati ai tuoi file per filtrarli o fornire un contesto aggiuntivo. I metadati sono un insieme di coppie chiave-valore.
Python
op = client.file_search_stores.import_file(
file_search_store_name=file_search_store.name,
file_name=sample_file.name,
config={
'custom_metadata': [
{"key": "author", "string_value": "Robert Graves"},
{"key": "year", "numeric_value": 1934}
]
}
)
JavaScript
let operation = await ai.fileSearchStores.importFile({
fileSearchStoreName: fileSearchStore.name,
fileName: sampleFile.name,
config: {
customMetadata: [
{ key: "author", stringValue: "Robert Graves" },
{ key: "year", numericValue: 1934 }
]
}
});
Java
import com.google.genai.Client;
import com.google.genai.types.CustomMetadata;
import com.google.genai.types.ImportFileConfig;
import com.google.genai.types.ImportFileOperation;
import java.util.Arrays;
Client client = new Client();
ImportFileOperation op =
client.fileSearchStores.importFile(
"fileSearchStores/myfilesearchstore123",
"files/samplefile123",
ImportFileConfig.builder()
.customMetadata(
Arrays.asList(
CustomMetadata.builder().key("author").stringValue("Robert Graves").build(),
CustomMetadata.builder().key("year").numericValue(1934f).build()))
.build());
Go
package main
import (
"context"
"log"
"google.golang.org/genai"
)
func main() {
ctx := context.Background()
client, err := genai.NewClient(ctx, nil)
if err != nil {
log.Fatal(err)
}
op, err := client.FileSearchStores.ImportFile(
ctx,
"fileSearchStores/myfilesearchstore123",
"files/samplefile123",
&genai.ImportFileConfig{
CustomMetadata: []*genai.CustomMetadata{
{Key: "author", StringValue: "Robert Graves"},
{Key: "year", NumericValue: genai.Ptr(float32(1934))},
},
},
)
if err != nil {
log.Fatal(err)
}
_ = op
}
Questo è utile quando hai più documenti in un archivio di ricerca nei file e vuoi cercarne solo un sottoinsieme.
Python
interaction = client.interactions.create(
model="gemini-3.8-flash",
input="Tell me about the book 'I, Claudius'",
tools=[{
"type": "file_search",
"file_search_store_names": [file_search_store.name],
"metadata_filter": 'author="Robert Graves"',
}]
)
for step in interaction.steps:
if step.type == "model_output":
for content_block in step.content:
if content_block.type == "text":
print(content_block.text)
JavaScript
const interaction = await ai.interactions.create({
model: "gemini-3.8-flash",
input: "Tell me about the book 'I, Claudius'",
tools: [{
type: "file_search",
file_search_store_names: [fileSearchStore.name],
metadata_filter: 'author="Robert Graves"',
}]
});
for (const step of interaction.steps) {
if (step.type === 'model_output') {
for (const contentBlock of step.content) {
if (contentBlock.type === 'text') {
console.log(contentBlock.text);
}
}
}
}
Java
import com.google.genai.Client;
import com.google.genai.gaos.models.interactions.Content;
import com.google.genai.gaos.models.interactions.CreateModelInteraction;
import com.google.genai.gaos.models.interactions.FileSearch;
import com.google.genai.gaos.models.interactions.Interaction;
import com.google.genai.gaos.models.interactions.InteractionsInput;
import com.google.genai.gaos.models.interactions.Model;
import com.google.genai.gaos.models.interactions.ModelOutputStep;
import com.google.genai.gaos.models.interactions.Step;
import com.google.genai.gaos.models.interactions.TextContent;
import com.google.genai.gaos.models.operations.CreateInteractionRequestBody;
import java.util.Arrays;
Client client = new Client();
CreateModelInteraction params =
CreateModelInteraction.builder()
.model(Model.of("gemini-3.8-flash"))
.input(InteractionsInput.of("Tell me about the book 'I, Claudius'"))
.tools(
Arrays.asList(
FileSearch.builder()
.fileSearchStoreNames(Arrays.asList("fileSearchStores/myfilesearchstore123"))
.metadataFilter("author=\"Robert Graves\"")
.build()))
.build();
Interaction interaction =
client.interactions.create(CreateInteractionRequestBody.of(params)).interaction().get();
if (interaction.steps().isPresent()) {
for (Step step : interaction.steps().get()) {
if (step instanceof ModelOutputStep) {
ModelOutputStep outputStep = (ModelOutputStep) step;
if (outputStep.content().isPresent()) {
for (Content contentBlock : outputStep.content().get()) {
if (contentBlock instanceof TextContent) {
TextContent textContent = (TextContent) contentBlock;
System.out.println(textContent.text().orElse(""));
}
}
}
}
}
}
Go
package main
import (
"context"
"fmt"
"log"
"google.golang.org/genai"
"google.golang.org/genai/interactions/models/interactions"
"google.golang.org/genai/interactions/models/operations"
)
func main() {
ctx := context.Background()
client, err := genai.NewClient(ctx, nil)
if err != nil {
log.Fatal(err)
}
resp, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{
Body: operations.NewCreateInteractionRequestBody(
interactions.CreateModelInteraction{
Model: interactions.Model("gemini-3.8-flash"),
Input: interactions.NewInteractionsInput("Tell me about the book 'I, Claudius'"),
Tools: []interactions.Tool{
interactions.NewTool(interactions.FileSearch{
FileSearchStoreNames: []string{"fileSearchStores/myfilesearchstore123"},
MetadataFilter: genai.Ptr(`author="Robert Graves"`),
}),
},
},
),
})
if err != nil {
log.Fatal(err)
}
for _, step := range resp.Interaction.Steps {
if step.ModelOutputStep != nil {
for _, content := range step.ModelOutputStep.Content {
if content.TextContent != nil {
fmt.Println(content.TextContent.Text)
}
}
}
}
}
REST
curl "https://generativelanguage.googleapis.com/v1beta/interactions" \
-H "x-goog-api-key: $GEMINI_API_KEY" \
-H 'Content-Type: application/json' \
-X POST \
-d '{
"model": "gemini-3.8-flash",
"input": [{"type": "text", "text": "Tell me about the book I, Claudius"}],
"tools": [{
"type": "file_search",
"file_search_store_names": ["'$STORE_NAME'"],
"metadata_filter": "author = \"Robert Graves\""
}]
}' 2> /dev/null > response.json
cat response.json
Le indicazioni per l'implementazione della sintassi del filtro di elenco per metadata_filter sono disponibili
all'indirizzo google.aip.dev/160
Ricerca di file multimodale
La ricerca file multimodale consente di incorporare e cercare in modo nativo le immagini, consentendo applicazioni RAG multimodali avanzate.
Configura il modello di embedding
Quando crei un FileSearchStore, devi eseguire l'override del modello di embedding predefinito solo di testo per utilizzare un modello multimodale. Utilizza models/gemini-embedding-2 per elaborare sia testo che immagini.
Python
store = client.file_search_stores.create(
config={
"display_name": "Multimodal Catalog",
"embedding_model": "models/gemini-embedding-2",
}
)
JavaScript
const fileSearchStore = await ai.fileSearchStores.create({
config: {
displayName: "Multimodal Catalog",
embeddingModel: "models/gemini-embedding-2",
},
});
Java
import com.google.genai.Client;
import com.google.genai.types.CreateFileSearchStoreConfig;
import com.google.genai.types.FileSearchStore;
Client client = new Client();
FileSearchStore store =
client.fileSearchStores.create(
CreateFileSearchStoreConfig.builder()
.displayName("Multimodal Catalog")
.embeddingModel("models/gemini-embedding-2")
.build());
Go
package main
import (
"context"
"log"
"google.golang.org/genai"
)
func main() {
ctx := context.Background()
client, err := genai.NewClient(ctx, nil)
if err != nil {
log.Fatal(err)
}
store, err := client.FileSearchStores.Create(ctx, &genai.CreateFileSearchStoreConfig{
DisplayName: "Multimodal Catalog",
EmbeddingModel: "models/gemini-embedding-2",
})
if err != nil {
log.Fatal(err)
}
_ = store
}
REST
curl -X POST "https://generativelanguage.googleapis.com/v1beta/fileSearchStores?key=$GEMINI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"display_name": "Multimodal Catalog",
"embedding_model": "models/gemini-embedding-2"
}'
Carica immagini
Dopo aver creato l'archivio con un modello di incorporamento multimodale, puoi caricare i file immagine direttamente utilizzando le stesse API di caricamento descritte in Caricamento diretto nell'archivio di ricerca file o Importazione di file.
Requisiti per i file immagine:
- I file immagine devono avere una risoluzione massima di 4K x 4K pixel.
- I formati supportati sono PNG e JPEG.
Citazioni
Quando utilizzi la ricerca nei file, la risposta del modello potrebbe includere citazioni che specificano quali parti dei documenti caricati sono state utilizzate per generare la risposta. In questo modo, è più facile verificare i fatti e le informazioni.
Puoi accedere alle informazioni sulle citazioni tramite l'attributo annotations all'interno dei blocchi content del passaggio model_output della risposta.
Python
for step in interaction.steps:
if step.type == 'model_output':
for content in step.content:
if content.type == 'text' and content.annotations:
print(content.annotations)
JavaScript
for (const step of interaction.steps) {
if (step.type === 'model_output') {
for (const contentBlock of step.content) {
if (contentBlock.type === 'text' && contentBlock.annotations) {
console.log(JSON.stringify(contentBlock.annotations, null, 2));
}
}
}
}
Java
import com.google.genai.Client;
import com.google.genai.gaos.models.interactions.Content;
import com.google.genai.gaos.models.interactions.CreateModelInteraction;
import com.google.genai.gaos.models.interactions.FileSearch;
import com.google.genai.gaos.models.interactions.Interaction;
import com.google.genai.gaos.models.interactions.InteractionsInput;
import com.google.genai.gaos.models.interactions.Model;
import com.google.genai.gaos.models.interactions.ModelOutputStep;
import com.google.genai.gaos.models.interactions.Step;
import com.google.genai.gaos.models.interactions.TextContent;
import com.google.genai.gaos.models.operations.CreateInteractionRequestBody;
import java.util.Arrays;
Client client = new Client();
CreateModelInteraction params =
CreateModelInteraction.builder()
.model(Model.of("gemini-3.8-flash"))
.input(InteractionsInput.of("Can you tell me about [insert question]"))
.tools(
Arrays.asList(
FileSearch.builder()
.fileSearchStoreNames(Arrays.asList("fileSearchStores/myfilesearchstore123"))
.build()))
.build();
Interaction interaction =
client.interactions.create(CreateInteractionRequestBody.of(params)).interaction().get();
if (interaction.steps().isPresent()) {
for (Step step : interaction.steps().get()) {
if (step instanceof ModelOutputStep) {
ModelOutputStep outputStep = (ModelOutputStep) step;
if (outputStep.content().isPresent()) {
for (Content content : outputStep.content().get()) {
if (content instanceof TextContent) {
TextContent textContent = (TextContent) content;
if (textContent.annotations().isPresent()) {
System.out.println(textContent.annotations().get());
}
}
}
}
}
}
}
Go
package main
import (
"context"
"fmt"
"log"
"google.golang.org/genai"
"google.golang.org/genai/interactions/models/interactions"
"google.golang.org/genai/interactions/models/operations"
)
func main() {
ctx := context.Background()
client, err := genai.NewClient(ctx, nil)
if err != nil {
log.Fatal(err)
}
resp, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{
Body: operations.NewCreateInteractionRequestBody(
interactions.CreateModelInteraction{
Model: interactions.Model("gemini-3.8-flash"),
Input: interactions.NewInteractionsInput("Can you tell me about [insert question]"),
Tools: []interactions.Tool{
interactions.NewTool(interactions.FileSearch{
FileSearchStoreNames: []string{"fileSearchStores/myfilesearchstore123"},
}),
},
},
),
})
if err != nil {
log.Fatal(err)
}
for _, step := range resp.Interaction.Steps {
if step.ModelOutputStep != nil {
for _, content := range step.ModelOutputStep.Content {
if content.TextContent != nil && len(content.TextContent.Annotations) > 0 {
fmt.Println(content.TextContent.Annotations)
}
}
}
}
}
REST
{
"steps": [
{
"type": "model_output",
"content": [
{
"type": "text",
"text": "...",
"annotations": [
{
"type": "file_citation",
"file_name": "sample.txt",
"source": "..."
}
]
}
]
}
]
}
Per informazioni dettagliate sulla struttura delle citazioni, consulta il Riferimento API per le interazioni.
Numeri di pagina
Quando utilizzi la ricerca file con documenti che hanno pagine (come i PDF), la
risposta del modello può includere il numero di pagina in cui sono state trovate le informazioni.
Puoi accedere a queste informazioni tramite l'attributo page_number di un'annotazione file_citation.
Python
for step in interaction.steps:
if step.type == "model_output":
for content in step.content:
if content.type == "text" and content.annotations:
for annotation in content.annotations:
if annotation.type == "file_citation" and annotation.page_number:
print(f"Cited Page: {annotation.page_number}")
JavaScript
for (const step of interaction.steps) {
if (step.type === 'model_output') {
for (const block of step.content) {
if (block.type === 'text' && block.annotations) {
for (const annotation of block.annotations) {
if (annotation.type === 'file_citation' && annotation.pageNumber) {
console.log(`Cited Page: ${annotation.pageNumber}`);
}
}
}
}
}
}
Java
import com.google.genai.Client;
import com.google.genai.gaos.models.interactions.Annotation;
import com.google.genai.gaos.models.interactions.Content;
import com.google.genai.gaos.models.interactions.CreateModelInteraction;
import com.google.genai.gaos.models.interactions.FileCitation;
import com.google.genai.gaos.models.interactions.FileSearch;
import com.google.genai.gaos.models.interactions.Interaction;
import com.google.genai.gaos.models.interactions.InteractionsInput;
import com.google.genai.gaos.models.interactions.Model;
import com.google.genai.gaos.models.interactions.ModelOutputStep;
import com.google.genai.gaos.models.interactions.Step;
import com.google.genai.gaos.models.interactions.TextContent;
import com.google.genai.gaos.models.operations.CreateInteractionRequestBody;
import java.util.Arrays;
Client client = new Client();
CreateModelInteraction params =
CreateModelInteraction.builder()
.model(Model.of("gemini-3.8-flash"))
.input(InteractionsInput.of("Can you tell me about [insert question]"))
.tools(
Arrays.asList(
FileSearch.builder()
.fileSearchStoreNames(Arrays.asList("fileSearchStores/myfilesearchstore123"))
.build()))
.build();
Interaction interaction =
client.interactions.create(CreateInteractionRequestBody.of(params)).interaction().get();
if (interaction.steps().isPresent()) {
for (Step step : interaction.steps().get()) {
if (step instanceof ModelOutputStep) {
ModelOutputStep outputStep = (ModelOutputStep) step;
if (outputStep.content().isPresent()) {
for (Content content : outputStep.content().get()) {
if (content instanceof TextContent) {
TextContent textContent = (TextContent) content;
if (textContent.annotations().isPresent()) {
for (Annotation annotation : textContent.annotations().get()) {
if (annotation instanceof FileCitation) {
FileCitation citation = (FileCitation) annotation;
if (citation.pageNumber().isPresent()) {
System.out.println("Cited Page: " + citation.pageNumber().get());
}
}
}
}
}
}
}
}
}
}
Go
package main
import (
"context"
"fmt"
"log"
"google.golang.org/genai"
"google.golang.org/genai/interactions/models/interactions"
"google.golang.org/genai/interactions/models/operations"
)
func main() {
ctx := context.Background()
client, err := genai.NewClient(ctx, nil)
if err != nil {
log.Fatal(err)
}
resp, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{
Body: operations.NewCreateInteractionRequestBody(
interactions.CreateModelInteraction{
Model: interactions.Model("gemini-3.8-flash"),
Input: interactions.NewInteractionsInput("Can you tell me about [insert question]"),
Tools: []interactions.Tool{
interactions.NewTool(interactions.FileSearch{
FileSearchStoreNames: []string{"fileSearchStores/myfilesearchstore123"},
}),
},
},
),
})
if err != nil {
log.Fatal(err)
}
for _, step := range resp.Interaction.Steps {
if step.ModelOutputStep != nil {
for _, content := range step.ModelOutputStep.Content {
if content.TextContent != nil {
for _, annotation := range content.TextContent.Annotations {
if annotation.FileCitation != nil && annotation.FileCitation.PageNumber != nil {
fmt.Println("Cited Page:", *annotation.FileCitation.PageNumber)
}
}
}
}
}
}
}
REST
{
"steps": [
{
"type": "model_output",
"content": [
{
"type": "text",
"text": "...",
"annotations": [
{
"type": "file_citation",
"file_name": "document.pdf",
"page_number": 1,
"source": "..."
}
]
}
]
}
]
}
Citazioni di contenuti multimediali
Quando il modello fa riferimento a un chunk di immagine durante la generazione, l'API restituisce un'annotazione di tipo file_citation nelle annotazioni che include un media_id. Puoi utilizzare questo ID per scaricare l'esatto segmento di immagine a cui fa riferimento il modello. Questo media_id è
persistente in più chiamate di ricerca, il che ti consente di recuperare in modo affidabile
la stessa immagine o memorizzarla nella cache utilizzando l'ID.
Il seguente snippet è un esempio di passaggio di risposta REST:
{
"type": "model_output",
"content": [
{
"type": "text",
"text": "...",
"annotations": [
{
"type": "file_citation",
"file_name": "product_image",
"media_id": "fileSearchStores/my-store-123/media/BlobId-456"
}
]
}
]
}
I seguenti snippet di codice mostrano come recuperare il media_id e scaricare i contenuti multimediali:
Python
for step in interaction.steps:
if step.type == "model_output":
for content in step.content:
if content.type == "text" and content.annotations:
for annotation in content.annotations:
if annotation.type == "file_citation" and annotation.media_id:
print(f"Cited Media ID: {annotation.media_id}")
blob_content = client.file_search_stores.download_media(
media_id=annotation.media_id
)
JavaScript
for (const step of interaction.steps) {
if (step.type === 'model_output') {
for (const block of step.content) {
if (block.type === 'text' && block.annotations) {
for (const annotation of block.annotations) {
if (annotation.type === 'file_citation' && annotation.mediaId) {
console.log(`Cited Media ID: ${annotation.mediaId}`);
const blobContent = await ai.fileSearchStores.downloadMedia(annotation.mediaId);
}
}
}
}
}
}
Java
import com.google.genai.Client;
import com.google.genai.gaos.models.interactions.Annotation;
import com.google.genai.gaos.models.interactions.Content;
import com.google.genai.gaos.models.interactions.CreateModelInteraction;
import com.google.genai.gaos.models.interactions.FileCitation;
import com.google.genai.gaos.models.interactions.FileSearch;
import com.google.genai.gaos.models.interactions.Interaction;
import com.google.genai.gaos.models.interactions.InteractionsInput;
import com.google.genai.gaos.models.interactions.Model;
import com.google.genai.gaos.models.interactions.ModelOutputStep;
import com.google.genai.gaos.models.interactions.Step;
import com.google.genai.gaos.models.interactions.TextContent;
import com.google.genai.gaos.models.operations.CreateInteractionRequestBody;
import java.util.Arrays;
Client client = new Client();
CreateModelInteraction params =
CreateModelInteraction.builder()
.model(Model.of("gemini-3.8-flash"))
.input(InteractionsInput.of("Can you tell me about [insert question]"))
.tools(
Arrays.asList(
FileSearch.builder()
.fileSearchStoreNames(Arrays.asList("fileSearchStores/myfilesearchstore123"))
.build()))
.build();
Interaction interaction =
client.interactions.create(CreateInteractionRequestBody.of(params)).interaction().get();
if (interaction.steps().isPresent()) {
for (Step step : interaction.steps().get()) {
if (step instanceof ModelOutputStep) {
ModelOutputStep outputStep = (ModelOutputStep) step;
if (outputStep.content().isPresent()) {
for (Content content : outputStep.content().get()) {
if (content instanceof TextContent) {
TextContent textContent = (TextContent) content;
if (textContent.annotations().isPresent()) {
for (Annotation annotation : textContent.annotations().get()) {
if (annotation instanceof FileCitation) {
FileCitation citation = (FileCitation) annotation;
if (citation.mediaId().isPresent()) {
System.out.println("Cited Media ID: " + citation.mediaId().get());
byte[] blobContent =
client.fileSearchStores.downloadMedia(citation.mediaId().get(), null);
}
}
}
}
}
}
}
}
}
}
Go
package main
import (
"context"
"fmt"
"log"
"google.golang.org/genai"
"google.golang.org/genai/interactions/models/interactions"
"google.golang.org/genai/interactions/models/operations"
)
func main() {
ctx := context.Background()
client, err := genai.NewClient(ctx, nil)
if err != nil {
log.Fatal(err)
}
resp, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{
Body: operations.NewCreateInteractionRequestBody(
interactions.CreateModelInteraction{
Model: interactions.Model("gemini-3.8-flash"),
Input: interactions.NewInteractionsInput("Can you tell me about [insert question]"),
Tools: []interactions.Tool{
interactions.NewTool(interactions.FileSearch{
FileSearchStoreNames: []string{"fileSearchStores/myfilesearchstore123"},
}),
},
},
),
})
if err != nil {
log.Fatal(err)
}
for _, step := range resp.Interaction.Steps {
if step.ModelOutputStep != nil {
for _, content := range step.ModelOutputStep.Content {
if content.TextContent != nil {
for _, annotation := range content.TextContent.Annotations {
if annotation.FileCitation != nil && annotation.FileCitation.MediaID != nil {
fmt.Println("Cited Media ID:", *annotation.FileCitation.MediaID)
blobContent, err := client.FileSearchStores.DownloadMedia(ctx, *annotation.FileCitation.MediaID, nil)
if err != nil {
log.Fatal(err)
}
_ = blobContent
}
}
}
}
}
}
}
REST
curl -X GET "https://generativelanguage.googleapis.com/v1/fileSearchStores/my-store-123/media/BlobId-456" \
-H "x-goog-api-key: $GEMINI_API_KEY"
Metadati personalizzati
Se hai aggiunto metadati personalizzati ai tuoi file, puoi accedervi nelle annotazioni della risposta del modello. Questo è utile per passare
un contesto aggiuntivo (come URL, numeri di pagina o autori) dai documenti di origine
alla logica dell'applicazione. Ogni annotazione di citazione di tipo file_citation contiene questi metadati personalizzati.
Python
interaction = client.interactions.create(
model="gemini-3.8-flash",
input="Tell me about [insert question]",
tools=[{
"type": "file_search",
"file_search_store_names": [file_search_store.name]
}]
)
for step in interaction.steps:
if step.type == "model_output":
for content_block in step.content:
if content_block.annotations:
for annotation in content_block.annotations:
print(annotation)
JavaScript
const interaction = await ai.interactions.create({
model: "gemini-3.8-flash",
input: "Tell me about [insert question]",
tools: [{
type: "file_search",
file_search_store_names: [fileSearchStore.name]
}]
});
for (const step of interaction.steps) {
if (step.type === 'model_output') {
for (const contentBlock of step.content) {
if (contentBlock.annotations) {
contentBlock.annotations.forEach((annotation) => {
console.log(annotation);
});
}
}
}
}
Java
import com.google.genai.Client;
import com.google.genai.gaos.models.interactions.Annotation;
import com.google.genai.gaos.models.interactions.Content;
import com.google.genai.gaos.models.interactions.CreateModelInteraction;
import com.google.genai.gaos.models.interactions.FileSearch;
import com.google.genai.gaos.models.interactions.Interaction;
import com.google.genai.gaos.models.interactions.InteractionsInput;
import com.google.genai.gaos.models.interactions.Model;
import com.google.genai.gaos.models.interactions.ModelOutputStep;
import com.google.genai.gaos.models.interactions.Step;
import com.google.genai.gaos.models.interactions.TextContent;
import com.google.genai.gaos.models.operations.CreateInteractionRequestBody;
import java.util.Arrays;
Client client = new Client();
CreateModelInteraction params =
CreateModelInteraction.builder()
.model(Model.of("gemini-3.8-flash"))
.input(InteractionsInput.of("Tell me about [insert question]"))
.tools(
Arrays.asList(
FileSearch.builder()
.fileSearchStoreNames(Arrays.asList("fileSearchStores/myfilesearchstore123"))
.build()))
.build();
Interaction interaction =
client.interactions.create(CreateInteractionRequestBody.of(params)).interaction().get();
if (interaction.steps().isPresent()) {
for (Step step : interaction.steps().get()) {
if (step instanceof ModelOutputStep) {
ModelOutputStep outputStep = (ModelOutputStep) step;
if (outputStep.content().isPresent()) {
for (Content contentBlock : outputStep.content().get()) {
if (contentBlock instanceof TextContent) {
TextContent textContent = (TextContent) contentBlock;
if (textContent.annotations().isPresent()) {
for (Annotation annotation : textContent.annotations().get()) {
System.out.println(annotation);
}
}
}
}
}
}
}
}
Go
package main
import (
"context"
"fmt"
"log"
"google.golang.org/genai"
"google.golang.org/genai/interactions/models/interactions"
"google.golang.org/genai/interactions/models/operations"
)
func main() {
ctx := context.Background()
client, err := genai.NewClient(ctx, nil)
if err != nil {
log.Fatal(err)
}
resp, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{
Body: operations.NewCreateInteractionRequestBody(
interactions.CreateModelInteraction{
Model: interactions.Model("gemini-3.8-flash"),
Input: interactions.NewInteractionsInput("Tell me about [insert question]"),
Tools: []interactions.Tool{
interactions.NewTool(interactions.FileSearch{
FileSearchStoreNames: []string{"fileSearchStores/myfilesearchstore123"},
}),
},
},
),
})
if err != nil {
log.Fatal(err)
}
for _, step := range resp.Interaction.Steps {
if step.ModelOutputStep != nil {
for _, content := range step.ModelOutputStep.Content {
if content.TextContent != nil {
for _, annotation := range content.TextContent.Annotations {
fmt.Println(annotation)
}
}
}
}
}
}
REST
{
"steps": [
{
"type": "model_output",
"content": [
{
"type": "text",
"text": "...",
"annotations": [
{
"file_name": "...",
"source": "...",
"custom_metadata": [
{
"key": "author",
"string_value": "Robert Graves"
},
{
"key": "year",
"numeric_value": 1934
}
]
}
]
}
]
}
]
}
Output strutturato
A partire dai modelli Gemini 3, puoi combinare lo strumento di ricerca dei file con output strutturati.
Python
from pydantic import BaseModel, Field
class Money(BaseModel):
amount: str = Field(description="The numerical part of the amount.")
currency: str = Field(description="The currency of amount.")
interaction = client.interactions.create(
model="gemini-3.8-flash",
input="What is the minimum hourly wage in Tokyo right now?",
tools=[{
"type": "file_search",
"file_search_store_names": [file_search_store.name]
}],
response_format={
"type": "text",
"mime_type": "application/json",
"schema": Money.model_json_schema()
},
)
result = Money.model_validate_json(interaction.output_text)
print(result)
JavaScript
import { z } from "zod";
const moneyJsonSchema = {
type: "object",
properties: {
amount: { type: "string", description: "The numerical part of the amount." },
currency: { type: "string", description: "The currency of amount." }
},
required: ["amount", "currency"]
};
const moneySchema = z.fromJSONSchema(moneyJsonSchema);
async function run() {
const interaction = await ai.interactions.create({
model: "gemini-3.8-flash",
input: "What is the minimum hourly wage in Tokyo right now?",
tools: [{
type: "file_search",
file_search_store_names: [fileSearchStore.name],
}],
response_format: {
type: 'text',
mime_type: 'application/json',
schema: moneyJsonSchema
},
});
const result = moneySchema.parse(JSON.parse(interaction.output_text));
console.log(result);
}
run();
Java
import com.google.genai.Client;
import com.google.genai.gaos.models.interactions.CreateModelInteraction;
import com.google.genai.gaos.models.interactions.CreateModelInteractionResponseFormat;
import com.google.genai.gaos.models.interactions.FileSearch;
import com.google.genai.gaos.models.interactions.Interaction;
import com.google.genai.gaos.models.interactions.InteractionsInput;
import com.google.genai.gaos.models.interactions.Model;
import com.google.genai.gaos.models.interactions.ResponseFormat;
import com.google.genai.gaos.models.interactions.TextResponseFormat;
import com.google.genai.gaos.models.interactions.TextResponseFormatMimeType;
import com.google.genai.gaos.models.operations.CreateInteractionRequestBody;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
Client client = new Client();
Map<String, Object> properties = new HashMap<>();
Map<String, Object> amountProp = new HashMap<>();
amountProp.put("type", "string");
amountProp.put("description", "The numerical part of the amount.");
properties.put("amount", amountProp);
Map<String, Object> currencyProp = new HashMap<>();
currencyProp.put("type", "string");
currencyProp.put("description", "The currency of amount.");
properties.put("currency", currencyProp);
Map<String, Object> moneyJsonSchema = new HashMap<>();
moneyJsonSchema.put("type", "object");
moneyJsonSchema.put("properties", properties);
moneyJsonSchema.put("required", Arrays.asList("amount", "currency"));
CreateModelInteractionResponseFormat format =
CreateModelInteractionResponseFormat.of(
ResponseFormat.of(
TextResponseFormat.builder()
.mimeType(TextResponseFormatMimeType.APPLICATION_JSON)
.schema(moneyJsonSchema)
.build()));
CreateModelInteraction params =
CreateModelInteraction.builder()
.model(Model.of("gemini-3.8-flash"))
.input(InteractionsInput.of("What is the minimum hourly wage in Tokyo right now?"))
.tools(
Arrays.asList(
FileSearch.builder()
.fileSearchStoreNames(Arrays.asList("fileSearchStores/myfilesearchstore123"))
.build()))
.responseFormat(format)
.build();
Interaction interaction =
client.interactions.create(CreateInteractionRequestBody.of(params)).interaction().get();
System.out.println(interaction.outputText().orElse(""));
Go
package main
import (
"context"
"fmt"
"log"
"google.golang.org/genai"
"google.golang.org/genai/interactions/models/interactions"
"google.golang.org/genai/interactions/models/operations"
)
func main() {
ctx := context.Background()
client, err := genai.NewClient(ctx, nil)
if err != nil {
log.Fatal(err)
}
moneyJsonSchema := map[string]any{
"type": "object",
"properties": map[string]any{
"amount": map[string]any{
"type": "string",
"description": "The numerical part of the amount.",
},
"currency": map[string]any{
"type": "string",
"description": "The currency of amount.",
},
},
"required": []string{"amount", "currency"},
}
format := interactions.NewCreateModelInteractionResponseFormat(
interactions.NewResponseFormat(interactions.TextResponseFormat{
MimeType: interactions.TextResponseFormatMimeTypeApplicationJSON.ToPointer(),
Schema: moneyJsonSchema,
}),
)
resp, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{
Body: operations.NewCreateInteractionRequestBody(
interactions.CreateModelInteraction{
Model: interactions.Model("gemini-3.8-flash"),
Input: interactions.NewInteractionsInput("What is the minimum hourly wage in Tokyo right now?"),
Tools: []interactions.Tool{
interactions.NewTool(interactions.FileSearch{
FileSearchStoreNames: []string{"fileSearchStores/myfilesearchstore123"},
}),
},
ResponseFormat: &format,
},
),
})
if err != nil {
log.Fatal(err)
}
fmt.Println(resp.Interaction.GetOutputText())
}
REST
curl "https://generativelanguage.googleapis.com/v1beta/interactions" \
-H "x-goog-api-key: $GEMINI_API_KEY" \
-H 'Content-Type: application/json' \
-X POST \
-d '{
"model": "gemini-3.8-flash",
"input": "What is the minimum hourly wage in Tokyo right now?",
"tools": [{
"type": "file_search",
"file_search_store_names": ["$FILE_SEARCH_STORE_NAME"]
}],
"response_format": {
"type": "text",
"mime_type": "application/json",
"schema": {
"type": "object",
"properties": {
"amount": {"type": "string", "description": "The numerical part of the amount."},
"currency": {"type": "string", "description": "The currency of amount."}
},
"required": ["amount", "currency"]
}
}
}'
Modelli supportati
I seguenti modelli supportano la ricerca nei file:
| Modello | Ricerca file |
|---|---|
| Gemini 4 Argon | ✔️ |
| Gemini 3.8 Flash | ✔️ |
| Gemini 3.6 Flash | ✔️ |
| Gemini 3.5 Flash-Lite | ✔️ |
| Gemini 3.1 Pro (anteprima) | ✔️ |
| Gemini 3.1 Flash-Lite | ✔️ |
| Gemini 3 Flash (anteprima) | ✔️ |
Combinazioni di strumenti supportate
I modelli Gemini 4 e Gemini 3 supportano la combinazione di strumenti integrati (come la ricerca di file) con strumenti personalizzati (chiamata di funzione). Scopri di più nella pagina Combinazioni di strumenti.
Tipi di file supportati
La ricerca nei file supporta un'ampia gamma di formati file, elencati nelle sezioni seguenti.
Tipi di file delle applicazioni
application/dartapplication/ecmascriptapplication/jsonapplication/ms-javaapplication/mswordapplication/pdfapplication/sqlapplication/typescriptapplication/vnd.curlapplication/vnd.dartapplication/vnd.ibm.secure-containerapplication/vnd.jupyterapplication/vnd.ms-excelapplication/vnd.oasis.opendocument.textapplication/vnd.openxmlformats-officedocument.presentationml.presentationapplication/vnd.openxmlformats-officedocument.spreadsheetml.sheetapplication/vnd.openxmlformats-officedocument.wordprocessingml.documentapplication/vnd.openxmlformats-officedocument.wordprocessingml.templateapplication/x-cshapplication/x-hwpapplication/x-hwp-v5application/x-latexapplication/x-phpapplication/x-powershellapplication/x-shapplication/x-shellscriptapplication/x-texapplication/x-zshapplication/xmlapplication/zip
Tipi di file di testo
text/1d-interleaved-parityfectext/REDtext/SGMLtext/cache-manifesttext/calendartext/cqltext/cql-extensiontext/cql-identifiertext/csstext/csvtext/csv-schematext/dnstext/encaprtptext/enrichedtext/exampletext/fhirpathtext/flexfectext/fwdredtext/gff3text/grammar-ref-listtext/hl7v2text/htmltext/javascripttext/jcr-cndtext/jsxtext/markdowntext/mizartext/n3text/parameterstext/parityfectext/phptext/plaintext/provenance-notationtext/prs.fallenstein.rsttext/prs.lines.tagtext/prs.prop.logictext/raptorfectext/rfc822-headerstext/rtftext/rtp-enc-aescm128text/rtploopbacktext/rtxtext/sgmltext/shaclctext/shextext/spdxtext/stringstext/t140text/tab-separated-valuestext/texmacstext/trofftext/tsvtext/tsxtext/turtletext/ulpfectext/uri-listtext/vcardtext/vnd.DMClientScripttext/vnd.IPTC.NITFtext/vnd.IPTC.NewsMLtext/vnd.atext/vnd.abctext/vnd.ascii-arttext/vnd.curltext/vnd.debian.copyrighttext/vnd.dvb.subtitletext/vnd.esmertec.theme-descriptortext/vnd.exchangeabletext/vnd.familysearch.gedcomtext/vnd.ficlab.flttext/vnd.flytext/vnd.fmi.flexstortext/vnd.gmltext/vnd.graphviztext/vnd.hanstext/vnd.hgltext/vnd.in3d.3dmltext/vnd.in3d.spottext/vnd.latex-ztext/vnd.motorola.reflextext/vnd.ms-mediapackagetext/vnd.net2phone.commcenter.commandtext/vnd.radisys.msml-basic-layouttext/vnd.senx.warpscripttext/vnd.sositext/vnd.sun.j2me.app-descriptortext/vnd.trolltech.linguisttext/vnd.wap.sitext/vnd.wap.sltext/vnd.wap.wmltext/vnd.wap.wmlscripttext/vtttext/wgsltext/x-asmtext/x-bibtextext/x-bootext/x-ctext/x-c++hdrtext/x-c++srctext/x-cassandratext/x-chdrtext/x-coffeescripttext/x-componenttext/x-cshtext/x-csharptext/x-csrctext/x-cudatext/x-dtext/x-difftext/x-dsrctext/x-emacs-lisptext/x-erlangtext/x-gff3text/x-gotext/x-haskelltext/x-javatext/x-java-propertiestext/x-java-sourcetext/x-kotlintext/x-lilypondtext/x-lisptext/x-literate-haskelltext/x-luatext/x-moctext/x-objcsrctext/x-pascaltext/x-pcs-gcdtext/x-perltext/x-perl-scripttext/x-pythontext/x-python-scripttext/x-r-markdowntext/x-rsrctext/x-rsttext/x-ruby-scripttext/x-rusttext/x-sasstext/x-scalatext/x-schemetext/x-script.pythontext/x-scsstext/x-setexttext/x-sfvtext/x-shtext/x-siestatext/x-sostext/x-sqltext/x-swifttext/x-tcltext/x-textext/x-vbasictext/x-vcalendartext/xmltext/xml-dtdtext/xml-external-parsed-entitytext/yaml
Limitazioni
- API Live: la ricerca di file non è supportata nell'API Live.
- Incompatibilità degli strumenti:gli strumenti di grounding integrati non possono essere combinati tra loro; ad esempio, la ricerca nei file non può essere utilizzata contemporaneamente al grounding con la Ricerca Google o al contesto dell'URL nella stessa richiesta.
Limiti di frequenza
L'API File Search prevede i seguenti limiti per garantire la stabilità del servizio:
- Dimensioni massime del file / limite per documento: 100 MB
- Dimensioni totali degli spazi di archiviazione di Ricerca file di progetto (in base al livello utente):
- Senza costi: 1 GB
- Livello 1: 10 GB
- Livello 2: 100 GB
- Livello 3: 1 TB
- Consiglio: limita le dimensioni di ogni archivio di ricerca file a meno di 20 GB per garantire latenze di recupero ottimali.
Prezzi
- Ti verranno addebitati i costi per gli embedding al momento dell'indicizzazione in base ai prezzi degli embedding esistenti.
- Lo spazio di archiviazione è senza costi.
- Gli embedding temporali delle query sono senza costi.
- I token del documento recuperati vengono addebitati come token di contesto normali.
Passaggi successivi
- Consulta il riferimento API per gli archivi di ricerca nei file e i documenti di ricerca nei file.