La semana pasada recibí malas noticias y la vida volvió a darme un duro golpe. Momentos como ese me recuerdan lo frágil que es todo, cómo un día todos nos vamos y hasta el amor puede parecer temporal.
En medio de todo esto, vi una publicación en X que decía que la herramienta de búsqueda de archivos de Gemini facilita enormemente el RAG y se ofrece a un precio realmente razonable. No sé por qué, pero algo en ella me empujó a probarla
Google anunció la herramienta de búsqueda de archivos, un sistema de generación de aumento de búsqueda (RAG) totalmente gestionado e integrado directamente en la API de Gemini.
Anteriormente, para crear un RAG, había que elegir una base de datos vectorial, desarrollar una estrategia de fragmentación, llamar a un modelo de incrustación y unir todo. La herramienta de búsqueda de archivos se encarga de todo eso automáticamente detrás de la API.
Estos eran obstáculos importantes para las empresas que querían introducir la IA, pero con la introducción de la herramienta de búsqueda de archivos, estos mecanismos ahora se pueden completar dentro de la API de Gemini.
Los desarrolladores pueden simplemente cargar archivos y utilizar llamadas API estándar para generar respuestas basadas en sus propios datos. indicando claramente a qué parte de qué archivo hizo referencia el agente de IA al generar una respuesta. Esto ayuda a prevenir las alucinaciones, un problema común con la IA generativa.
La herramienta de búsqueda de archivos ayuda a los desarrolladores a crear procesos de búsqueda e ingestión de archivos de forma sencilla, integrada y flexible para mejorar las respuestas de Gemini con sus propios datos. Almacena archivos y genera incrustaciones en el momento en que se crean de forma gratuita, con una tarifa única solo para la indexación inicial de los archivos.
Permítanme mostrarles una breve demostración de un chatbot en vivo para que vean a qué me refiero.
Durante mi desarrollo, un artículo me llamó la atención. La IA está cada vez más presente en todos los sectores, influyendo en la ciencia y más allá. Subiré el PDF de Ocean AI.
Le haré una pregunta al chatbot: «¿Qué es Ocean AI y en qué se diferencia de OpenAI?». Si observas cómo el chatbot genera la respuesta, verás que el agente primero guarda el PDF que he subido en un archivo temporal y, a continuación, crea un FileSearchStore único con un ID aleatorio.
El agente sube el PDF a este almacén y espera mientras Gemini divide el documento en fragmentos y crea un índice de búsqueda. Se trata de una función wait_operation que comprueba cada 2 segundos hasta que finaliza la indexación.
Cuando escribo mi pregunta y pulso Intro, query_file_search la envía a la API de Gemini junto con el nombre del almacén. Gemini busca automáticamente en los fragmentos de PDF indexados, encuentra las secciones relevantes sobre Ocean AI y en qué se diferencia de OpenAI, utiliza esos fragmentos como contexto y genera una respuesta utilizando el modelo seleccionado.
La respuesta incluye el texto de la respuesta más metadatos de referencia que muestran exactamente qué partes del PDF se han utilizado, de modo que cuando hago clic en «Ver fuentes», puedo ver las citas que demuestran de dónde proviene la información. Cuando termino, al hacer clic en «Borrar PDF» se elimina toda la tienda y se limpian todos los datos.
¿Qué hace la herramienta de búsqueda de archivos?
La herramienta de búsqueda de archivos de la API de Gemini consolida estos complejos procesos en una única llamada a la API totalmente automatizadagenerateContent , lo que permite a los desarrolladores aprovechar la funcionalidad de búsqueda de archivos dentro de sus API existentes, eliminando el complejo trabajo de configuración y gestión que se requería anteriormente.
A diferencia de las búsquedas tradicionales basadas en palabras clave, la herramienta de búsqueda de archivos comprende el significado y el contexto de la consulta y puede encontrar información relevante incluso si no se utilizan coincidencias exactas de palabras.
Esto se consigue mediante una potente búsqueda vectorial, que aprovecha el último modelo de incrustación de Gemini.
Aún más notable es la implementación de la autocita, que incluye automáticamente citas de los documentos específicos utilizados para generar la respuesta, lo que simplifica enormemente la verificación y la comprobación de datos y la hace mucho más útil para las empresas.
Limitaciones actuales y mejoras previstas
La herramienta de búsqueda de archivos tiene actualmente algunas limitaciones. La más importante es la capacidad limitada para ajustar el número de fragmentos recuperados. Durante las pruebas, confirmamos opciones de configuración avanzadas, como los filtros de metadatos, pero esperamos que las futuras mejoras permitan un control más detallado del número de fragmentos.
También hay margen de mejora en la precisión del reconocimiento de imágenes. Actualmente, es posible extraer texto de las imágenes, pero aún no se ha alcanzado el nivel de comprensión de la estructura y las relaciones de los diagramas. En particular, puede resultar difícil extraer información significativa de documentos escritos en formato Markdown o con diseños complejos.
Las limitaciones del tamaño de los archivos también son un factor a tener en cuenta. Cada archivo tiene un límite máximo de 100 MB, y el tamaño del almacén de búsqueda de archivos para todo el proyecto está limitado a entre 1 GB y 1 TB, dependiendo del nivel de usuario. Estas limitaciones pueden afectar a la practicidad para las grandes empresas.
Diferencias con OpenAI/Anthropic
Actualmente, la API de recuperación de OpenAI y los contextos de archivos de Anthropic son ejemplos bien conocidos de implementaciones de RAG. Estos sistemas utilizan almacenamiento externo para hacer referencia a documentos, pero requieren que los desarrolladores creen y gestionen una base de datos vectorial, lo que dificulta su implementación.
Por otro lado, la herramienta de búsqueda de archivos automatiza completamente esta parte y se realiza íntegramente dentro de la API de Gemini. La siguiente tabla compara las tres principales soluciones RAG.
Como se puede observar en esta comparación, la herramienta de búsqueda de archivos es superior tanto en términos de carga de desarrollo como de costes operativos, y es especialmente adecuada para el desarrollo de prototipos y el uso experimental por parte de desarrolladores individuales.
Además, el modelo Gemini Embedding proporcionado por Google ofrece una alta precisión de búsqueda y también resulta muy atractivo porque puede extraer con precisión información con significados similares.
Empecemos a programar:
Antes de sumergirnos en nuestra aplicación, crearemos un entorno ideal para que el código funcione. Para ello, necesitamos instalar las bibliotecas Python necesarias.
pip install requirementsEl siguiente paso es el habitual: importaremos las bibliotecas pertinentes, cuya importancia se hará evidente a medida que avancemos, y realizaremos algunas configuraciones básicas.
import streamlit as st
import os
import time
import random
import string
import tempfile
from pathlib import Path
from PyPDF2 import PdfReader
from google import genai
from google.genai import types
from dotenv import load_dotenvDiseñé estas funciones auxiliares para gestionar las tareas principales de la aplicación. En primer lugar, creé get_text(key, lang=“en”) para obtener el texto traducido: simplemente busca una palabra o frase en un diccionario de traducción, utiliza el inglés como idioma predeterminado si el idioma no existe y devuelve la clave original si no encuentra nada.
Luego creé generate_random_id(length=8) para generar ID aleatorios para nombrar tiendas: elige aleatoriamente 8 caracteres entre letras y números y los combina en una cadena.
Desarrollé wait_operation(client, op, sleep_sec=2, max_wait_sec=300) para esperar a que finalicen las operaciones en segundo plano: comprueba cada 2 segundos si la operación ha finalizado llamando a la API y, si tarda más de 5 minutos, deja de esperar y lanza un error para que la aplicación no se cuelgue indefinidamente.
A continuación, creé extract_text_from_pdf(pdf_file, lang=“en”) para extraer texto de archivos PDF: abre el PDF, revisa cada página una por una, toma el texto de cada página, lo agrega todo junto con saltos de línea y devuelve el texto completo.
Lo envolví en un manejo de errores, por lo que si el PDF está dañado o no se puede leer, muestra un mensaje de error al usuario en lugar de bloquearse.
def get_text(key, lang='en'):
"""Get translated text for the given key and language"""
return TRANSLATIONS.get(lang, TRANSLATIONS['en']).get(key, key)
# Helper Functions
def generate_random_id(length=8):
"""Generate a random ID for store naming"""
return ''.join(random.choices(string.ascii_lowercase + string.digits, k=length))
def wait_operation(client, op, sleep_sec=2, max_wait_sec=300):
"""Wait for Operations API to complete with timeout"""
start = time.time()
while not op.done:
if time.time() - start > max_wait_sec:
raise TimeoutError("Operation timed out.")
time.sleep(sleep_sec)
op = client.operations.get(op)
return op
def extract_text_from_pdf(pdf_file, lang='en'):
"""Extract text content from uploaded PDF file"""
try:
pdf_reader = PdfReader(pdf_file)
text = ""
for page in pdf_reader.pages:
text += page.extract_text() + "\n"
return text
except Exception as e:
st.error(get_text('error_pdf_extract', lang).format(e))
return NoneA partir de estas utilidades, creé tres funciones más para gestionar el almacenamiento y la gestión de archivos. La función save_uploaded_file(uploaded_file, lang=“en”) se encarga de guardar temporalmente los archivos subidos: crea un archivo temporal que no se elimina automáticamente, le añade la extensión .pdf, escribe el contenido del archivo subido en él utilizando getvalue() y devuelve la ruta del archivo para que podamos utilizarlo más tarde con las otras funciones.
A continuación, create_file_search_store(client, store_name, lang=“en”) configura un nuevo espacio de almacenamiento utilizando el ID aleatorio de generate_random_id. Llama a la API para crear un almacén de búsqueda de archivos con un nombre de visualización personalizado, devuelve el objeto de almacenamiento si tiene éxito o muestra un error get_text y devuelve None si falla.
La última función, upload_file_to_store(client, file_path, store_name, display_name, lang=“en”), sube los archivos al almacén: envía el archivo al almacén especificado utilizando la API, añade algunos metadatos como la fuente «streamlit_upload» y una marca de tiempo de cuándo se subió, luego espera a que se complete la subida utilizando mi función wait_operation anterior y devuelve la respuesta una vez que ha terminado.
def save_uploaded_file(uploaded_file, lang='en'):
"""Save uploaded file to temporary location"""
try:
with tempfile.NamedTemporaryFile(delete=False, suffix='.pdf') as tmp_file:
tmp_file.write(uploaded_file.getvalue())
return tmp_file.name
except Exception as e:
st.error(get_text('error_save_file', lang).format(e))
return None
def create_file_search_store(client, store_name, lang='en'):
"""Create a new File Search Store"""
try:
store = client.file_search_stores.create(
config={'display_name': store_name}
)
return store
except Exception as e:
st.error(get_text('error_create_store', lang).format(e))
return None
def upload_file_to_store(client, file_path, store_name, display_name, lang='en'):
"""Upload file to File Search Store"""
try:
upload_op = client.file_search_stores.upload_to_file_search_store(
file=file_path,
file_search_store_name=store_name,
config={
'display_name': display_name,
'custom_metadata': [
{"key": "source", "string_value": "streamlit_upload"},
{"key": "timestamp", "numeric_value": int(time.time())}
]
}
)
upload_op = wait_operation(client, upload_op)
return upload_op.response
except Exception as e:
st.error(get_text('error_upload_store', lang).format(e))
return None
Creé dos funciones finales que permiten a los usuarios interactuar con los archivos subidos y limpiarlos después. La función query_file_search(client, question, store_name, model, lang=“en”) es donde ocurre la magia: toma la pregunta de un usuario y busca en los archivos de la tienda llamando al modelo de IA con herramientas especiales de búsqueda de archivos configuradas.
Pasa la pregunta al modelo junto con una referencia al nombre de la tienda que hemos creado anteriormente, y el modelo busca automáticamente en todos los archivos subidos para encontrar información relevante y generar una respuesta.
Al igual que las otras funciones, utiliza get_text para los mensajes de error y devuelve None si algo sale mal. Una vez que el usuario ha terminado de trabajar con sus archivos, cleanup_store(client, store_name, lang=“en”) se encarga de la limpieza: elimina todo el almacén de búsqueda de archivos, incluidos todos los archivos cargados, llamando a la API de eliminación con el indicador force: True para asegurarse de que se elimina todo, devuelve True si tiene éxito o False si falla, y muestra un mensaje de error utilizando el ayudante de traducción si algo falla durante la eliminación.
def query_file_search(client, question, store_name, model, lang='en'):
"""Query the File Search Store with a question"""
try:
response = client.models.generate_content(
model=model,
contents=question,
config=types.GenerateContentConfig(
tools=[
types.Tool(
file_search=types.FileSearch(
file_search_store_names=[store_name]
)
)
]
)
)
return response
except Exception as e:
st.error(get_text('error_query', lang).format(e))
return None
def cleanup_store(client, store_name, lang='en'):
"""Delete the File Search Store"""
try:
client.file_search_stores.delete(
name=store_name,
config={'force': True}
)
return True
except Exception as e:
st.error(get_text('error_cleanup', lang).format(e))
return FalseConclusión:
La herramienta de búsqueda de archivos pone la tecnología avanzada de RAG al alcance de todos los desarrolladores, no solo de unos pocos expertos. Se trata, sin duda, de la «democratización de RAG».
Al liberarse de las preocupaciones relacionadas con la complejidad de la infraestructura y los costes, los desarrolladores pueden centrarse en crear aplicaciones más creativas que aborden directamente los retos de los usuarios.
La combinación de sus datos únicos con la potente inteligencia de Gemini creará un nuevo valor empresarial que antes era imposible. ¡Utilicemos esta nueva herramienta para crear las aplicaciones del futuro!
Gracias por leer Código en Casa.