/SKILL.md
Skill para implementar búsqueda semántica, multimodal e híbrida con Vertex AI Vector Search y Gemini.
npx skillsauth add daguonline/vertex-ai-search-skill Gemini Ultimate Procedural SkillInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Guía paso a paso para implementar flujos de búsqueda vectorial (semántica, por tokens, híbrida y multimodal) usando Gemini en Google Cloud Vertex AI.
requirements.txt.gcloud auth login).1. CONFIGURAR → Establecer PROJECT_ID, LOCATION, inicializar clientes.
2. PREPARAR DATOS → Cargar tus datos (CSV, BigQuery, etc.) en un DataFrame.
3. GENERAR EMBEDDINGS → Convertir texto a vectores (densos y/o dispersos).
4. SUBIR A GCS → Guardar como JSONL y subir a un bucket de Cloud Storage.
5. CREAR ÍNDICE → Construir un índice en Vector Search.
6. CREAR ENDPOINT → Crear un Index Endpoint público.
7. DESPLEGAR → Desplegar el índice en el endpoint.
8. CONSULTAR → Ejecutar búsquedas por similitud.
9. LIMPIAR → Eliminar recursos para evitar costos.
PROJECT_ID = "tu-proyecto-id"
LOCATION = "us-east1" # o la región que uses
# Para embeddings densos (Gemini)
from google import genai
client = genai.Client(vertexai=True, project=PROJECT_ID, location=LOCATION)
# Para Vector Search
from google.cloud import aiplatform
aiplatform.init(project=PROJECT_ID, location=LOCATION)
Usa el módulo scripts/embeddings.py:
from scripts.embeddings import get_dense_embedding, get_dense_embeddings_batch
# Un solo texto
embedding = get_dense_embedding(client, "¿Cómo leer JSON con Python?")
# En lotes (para datasets grandes)
embeddings = get_dense_embeddings_batch(client, lista_de_textos)
from scripts.embeddings import train_sparse_vectorizer, get_sparse_embedding
# Entrenar el vectorizador con tu corpus
vectorizer = train_sparse_vectorizer(lista_de_textos)
# Generar embedding disperso para un texto
sparse_emb = get_sparse_embedding(vectorizer, "Chrome Dino Pin")
from scripts.vector_search import save_embeddings_to_gcs
# Para búsqueda semántica (solo densos)
save_embeddings_to_gcs(df, BUCKET_URI, mode="dense")
# Para búsqueda híbrida (densos + dispersos)
save_embeddings_to_gcs(df, BUCKET_URI, mode="hybrid")
from scripts.vector_search import create_index, create_endpoint, deploy_index
# Crear índice
my_index = create_index(
display_name="mi-indice",
bucket_uri=BUCKET_URI,
dimensions=3072 # 3072 para gemini-embedding-001
)
# Crear endpoint
my_endpoint = create_endpoint("mi-endpoint")
# Desplegar
deploy_index(my_endpoint, my_index, "mi_indice_desplegado")
from scripts.vector_search import semantic_query
from scripts.hybrid_search import hybrid_query
# Búsqueda semántica
results = semantic_query(my_endpoint, "mi_indice_desplegado", query_embedding)
# Búsqueda híbrida
results = hybrid_query(
my_endpoint, "mi_indice_desplegado",
dense_embedding, sparse_embedding, alpha=0.5
)
from scripts.vector_search import cleanup
cleanup(my_endpoint, my_index, BUCKET_URI)
| Tipo | Caso de uso | Ejemplo | |------|------------|---------| | Semántica | Buscar por significado | "¿Cómo leer archivos?" encuentra docs sobre parsing JSON | | Por Tokens | Buscar por palabras exactas | "SKU-12345" encuentra ese producto específico | | Híbrida | Combinar ambas ventajas | "Kids sunglasses" encuentra por palabra "Kids" y por significado "Youth" |
Para búsquedas que requieren analizar lógica compleja (ej: discrepancias legales):
config = GenerateContentConfig(thinking_config={"thinking_level": "high"})
response = client.models.generate_content(
model="gemini-3.1-pro-preview",
contents=query,
config=config
)
Para documentos con contenido mixto (tablas, diagramas, imágenes):
Extracción de Metadatos — Usa get_document_metadata con sus 4 argumentos:
from utils.intro_multimodal_rag_utils import get_document_metadata
text_df, img_df = get_document_metadata(
model, # El modelo generativo (ej: GenerativeModel("gemini-2.5-flash"))
pdf_path, # Carpeta con los PDFs
save_dir, # Carpeta donde guardar imágenes extraídas
prompt # Prompt para describir cada imagen
)
Búsqueda y Generación:
# 1. Recuperar fragmentos relevantes
chunks = get_similar_text_from_query(query, text_metadata_df)
# 2. Construir contexto (unir fragmentos como string)
context = "\n".join([v['chunk_text'] for k, v in chunks.items()])
# 3. Generar respuesta con Gemini
get_gemini_response(model, model_input=prompt, stream=True)
Asegura que tu sistema de búsqueda devuelva JSON puro:
config = GenerateContentConfig(response_mime_type="application/json")
Si consultas repetidamente el mismo corpus masivo (1M+ tokens), habilita Context Caching para reducir latencia y costo drásticamente.
rrf_ranking_alpha (solo búsqueda híbrida)1.0 = Solo resultados semánticos (densos)0.0 = Solo resultados por tokens (dispersos)0.5 = Peso equilibrado entre ambos (recomendado para empezar)Estos errores fueron documentados durante la ejecución real de laboratorios de Google Cloud. Son los errores más frecuentes al trabajar con Gemini y Vertex AI.
| Error | Causa | Solución |
|-------|-------|----------|
| NameError: name 'instructions' is not defined | El kernel de Jupyter se reinició y las variables se perdieron. | Volver a ejecutar todas las celdas de configuración desde el principio. |
| NameError: name 'instruccion' is not defined | Typo: falta la 's' final. Python distingue instruccion ≠ instructions. | Copiar el nombre exacto de la variable tal como aparece en la celda donde fue definida. |
| NameError después de cambiar de tarea | Las variables de la Tarea 1.1 (prompt1) se sobreescriben en la Tarea 1.2. | Renombrar variables por tarea (ej: prompt1_sim) o redefinirlas justo antes de usarlas. |
| Error | Causa | Solución |
|-------|-------|----------|
| TypeError: get_document_metadata() missing 2 required positional arguments | La función requiere 4 argumentos, no 2. | Pasar: (modelo, folder_pdf, folder_save, prompt). |
| TypeError: 'dict' object is not subscriptable | Intentar acceder a un diccionario con índice numérico chunks[0]. | Usar for key, value in chunks.items() o list(chunks.values())[0]. |
| SyntaxError al pegar código | Comillas invisibles o indentación incorrecta copiada de un navegador. | Borrar toda la celda y reescribir manualmente. |
| Error | Causa | Solución |
|-------|-------|----------|
| FileNotFoundError: Google_Branding/ | Los archivos no se descargaron del bucket. | Ejecutar !gsutil -m rsync -r gs://spls/gsp520 . primero. |
| 403 Forbidden o 404 Not Found | El modelo no está habilitado en tu proyecto o la API no está activa. | Ir a Vertex AI > Dashboard > "Enable All Recommended APIs". |
| ResourceExhausted (429) | Se excedió la cuota de la API. | Esperar 30-60 segundos y reintentar. Considerar reducir batch_size. |
help(función) o función?.scripts/embeddings.py — Funciones para generar embeddings densos y dispersosscripts/vector_search.py — Funciones para gestionar índices, endpoints y consultasscripts/hybrid_search.py — Funciones para búsqueda híbrida con RRFexamples/ — Ejemplos ejecutables y notebooks traducidos al españolresources/ — Documentación conceptual y guías de referenciadata-ai
Example TaskFlow authoring pattern for inbox triage. Use when messages need different treatment based on intent, with some routes notifying immediately, some waiting on outside answers, and others rolling into a later summary.
data-ai
Example TaskFlow authoring pattern for inbox triage. Use when messages need different treatment based on intent, with some routes notifying immediately, some waiting on outside answers, and others rolling into a later summary.
data-ai
OpenProse VM skill pack. Activate on any `prose` command, .prose files, or OpenProse mentions; orchestrates multi-agent workflows.
data-ai
OpenProse VM skill pack. Activate on any `prose` command, .prose files, or OpenProse mentions; orchestrates multi-agent workflows.