Loading...
Loading...
Google Gemini File Search for managed RAG with 100+ file formats. Use for document Q&A, knowledge bases, or encountering immutability errors, quota issues, polling failures. Supports Gemini 3 Pro/Flash (Gemini 2.5 legacy).
npx skill4agent add secondsky/claude-skills google-gemini-file-searchbun add @google/genaiimport { GoogleGenerativeAI } from '@google/genai';
import fs from 'fs';
const ai = new GoogleGenerativeAI(process.env.GOOGLE_AI_API_KEY);
// Create store
const fileStore = await ai.fileSearchStores.create({
config: { displayName: 'my-knowledge-base' }
});
// Upload document
const operation = await ai.fileSearchStores.uploadToFileSearchStore({
name: fileStore.name,
file: fs.createReadStream('./manual.pdf'),
config: {
displayName: 'Installation Manual',
chunkingConfig: {
whiteSpaceConfig: {
maxTokensPerChunk: 500,
maxOverlapTokens: 50
}
}
}
});
// Poll until done
while (!operation.done) {
await new Promise(resolve => setTimeout(resolve, 1000));
operation = await ai.operations.get({ name: operation.name });
}
// Query documents
const model = ai.getGenerativeModel({
model: 'gemini-2.5-pro', // Only 2.5 Pro/Flash supported
tools: [{
fileSearchTool: {
fileSearchStores: [fileStore.name]
}
}]
});
const result = await model.generateContent('How do I install the product?');
console.log(result.response.text());
// Get citations
const grounding = result.response.candidates[0].groundingMetadata;
if (grounding) {
console.log('Sources:', grounding.groundingChunks);
}references/setup-guide.mddone: true// Find and delete old version
const docs = await ai.fileSearchStores.documents.list({
parent: fileStore.name
});
const oldDoc = docs.documents.find(d => d.displayName === 'manual.pdf');
if (oldDoc) {
await ai.fileSearchStores.documents.delete({
name: oldDoc.name,
force: true
});
}
// Upload new version
await ai.fileSearchStores.uploadToFileSearchStore({
name: fileStore.name,
file: fs.createReadStream('manual-v2.pdf'),
config: { displayName: 'manual.pdf' }
});const fileSize = fs.statSync('data.pdf').size;
const estimatedStorage = fileSize * 3; // Embeddings + metadata
if (estimatedStorage > 1e9) {
console.warn('⚠️ May exceed free tier 1 GB limit');
}// ✅ CORRECT
const model = ai.getGenerativeModel({
model: 'gemini-2.5-pro', // or gemini-2.5-flash
tools: [{ fileSearchTool: { fileSearchStores: [storeName] } }]
});
// ❌ WRONG
const model = ai.getGenerativeModel({
model: 'gemini-1.5-pro', // Not supported!
tools: [{ fileSearchTool: { fileSearchStores: [storeName] } }]
});references/error-catalog.md// Upload support docs with metadata
await ai.fileSearchStores.uploadToFileSearchStore({
name: fileStore.name,
file: fs.createReadStream('troubleshooting.pdf'),
config: {
displayName: 'Troubleshooting Guide',
customMetadata: {
doc_type: 'support',
category: 'troubleshooting',
language: 'en'
}
}
});const files = ['doc1.pdf', 'doc2.md', 'doc3.docx'];
const uploadPromises = files.map(file =>
ai.fileSearchStores.uploadToFileSearchStore({
name: fileStore.name,
file: fs.createReadStream(file),
config: { displayName: file }
})
);
const operations = await Promise.all(uploadPromises);
// Poll all operations
for (const op of operations) {
let operation = op;
while (!operation.done) {
await new Promise(resolve => setTimeout(resolve, 1000));
operation = await ai.operations.get({ name: operation.name });
}
console.log('✅', operation.response.displayName);
}// 1. List existing documents
const docs = await ai.fileSearchStores.documents.list({
parent: fileStore.name
});
// 2. Delete old version
const oldDoc = docs.documents.find(d => d.displayName === 'manual.pdf');
if (oldDoc) {
await ai.fileSearchStores.documents.delete({
name: oldDoc.name,
force: true
});
}
// 3. Upload new version
const operation = await ai.fileSearchStores.uploadToFileSearchStore({
name: fileStore.name,
file: fs.createReadStream('manual-v2.pdf'),
config: {
displayName: 'manual.pdf',
customMetadata: {
version: '2.0',
updated_at: new Date().toISOString()
}
}
});
// 4. Poll until done
while (!operation.done) {
await new Promise(resolve => setTimeout(resolve, 1000));
operation = await ai.operations.get({ name: operation.name });
}references/setup-guide.mdreferences/setup-guide.mdreferences/error-catalog.mdchunkingConfig: {
whiteSpaceConfig: {
maxTokensPerChunk: 500, // Smaller = more precise
maxOverlapTokens: 50 // 10% overlap recommended
}
}references/setup-guide.mderror-catalog.mdreferences/setup-guide.mdreferences/error-catalog.md