# Conocimiento y búsqueda vectorial

Ingesta documentos, arma colecciones de conocimiento y consúltalas por significado.

URL base: `https://ai.inovacc.dev`

## Descripción general

Conocimiento y búsqueda vectorial mantiene el conocimiento de tu organización donde una aplicación puede hacerle preguntas por significado. Tiene tres partes, todas en `https://ai.inovacc.dev`:

- la **Vector Database** (base de datos vectorial): un almacén administrado de pasajes de texto que ingestas y buscas, con filtros, ámbitos y reordenamiento opcional;
- las **colecciones de conocimiento**: envía un lote de archivos mixtos (documentos, imágenes, video) y haz que se procesen en paquetes de conocimiento; luego descarga el resultado, consúltalo, chatea con él con citas, o haz que se redacte un informe sobre él;
- los **trabajos de conocimiento**: convierten una grabación larga en una base de conocimiento que descargas como un solo archivo comprimido.

El problema que resuelve es todo lo que hay entre "tenemos archivos" y "el asistente puede responder a partir de ellos": extraer texto, cortarlo en pasajes, generar embeddings, indexar, mantener el índice consistente y citar la fuente de cada respuesta. Inovacc hace esos pasos y tú llamas a un puñado de endpoints.

Úsalo cuando las respuestas deban salir de tu propio material. Si ya ejecutas tu propio índice vectorial, los [Embeddings de IA](/es/products/ai.embeddings/) te dan solo los vectores. Cuando la respuesta es texto libre sin fuentes, usa el [Chat con IA](/es/products/ai.chat/). Inovacc habilita cada parte para tu organización; una parte que no está habilitada responde `403` (`vector_database_disabled`, `collections_disabled` o `knowledge_disabled`).

## Conceptos

**Vector Database y su perfil.** Tu organización crea una base de datos con `POST /v1/vector/databases`, eligiendo un **perfil de embeddings** de `GET /v1/vector/profiles`. Un perfil indica la modalidad (`text`), los idiomas (`english` o `multilingual`), las dimensiones y la métrica de distancia; los ids se ven como `text-multilingual-1024`. Eliges un perfil, nunca un modelo. El perfil no puede cambiar: para usar otro, elimina la base de datos, crea una nueva e ingesta de nuevo.

**Documentos, ámbitos y modos.** Ingestas pasajes con tu propio `id`, su `text` y `metadata` plana opcional. Un pasaje va a un **ámbito**: `shared` (todos los servicios del espacio de trabajo de tu organización) o `local` (solo la clave de API que lo escribió). Las consultas toman un **modo**: `shared`, `local`, o `hybrid` para buscar en ambos y combinar por puntuación. Se puede filtrar por seis claves de metadatos: `kind`, `source`, `category`, `tag`, `language`, `created_at`. Los fragmentos que comparten un `document_id` forman un documento con una `generation` (tu número de versión), lo que permite eliminar o reemplazar un documento completo de una vez.

**Colecciones y su modo.** Una colección se crea en uno de tres modos, fijos durante toda su vida: `download` (procesa archivos, descarga los paquetes y luego no queda nada), `cloud` (Inovacc conserva el contenido procesado y sus vectores para que puedas ejecutar `query`, `chat` y un `analysis`) o `local_vectors` (Inovacc conserva solo vectores, nunca texto: tú haces `embed` de tus propios fragmentos y `query` devuelve ids de fragmentos y puntuaciones). Las colecciones se conservan 30 días por defecto; una organización configurada en retención `zero` las tiene eliminadas una hora después de que empieza la descarga.

**Elementos.** Un archivo se une a una colección en la solicitud (hasta 16 MiB), desde una carga completada (video de más de 16 MiB), por URL pública, o por una URL firmada sellada a una clave de un solo uso para que nunca se almacene. Cada elemento pasa por `queued`, `processing`, y luego `done` o `failed`; un elemento fallido no detiene a los demás.

**Consistencia eventual y `searchable`.** El índice vectorial aplica las escrituras de forma asíncrona: un vector se puede leer unos segundos, a veces minutos, después de haberse escrito. `GET /v1/vector/databases` y toda respuesta de colección reportan `searchable`; una consulta enviada mientras es `false` puede omitir los pasajes más recientes. El `indexing.complete` de una colección `cloud` es `true` solo cuando cada fragmento está escrito **y** se puede leer.

**Trabajos, potencia y presupuesto.** Un trabajo de conocimiento toma una carga completada de una grabación, una transcripción y notas opcionales, un `power` (`light`, `medium` o `max`) y un `max_price_usd` obligatorio. Un trabajo que supera el tope de tu organización se rechaza antes de cualquier trabajo de pago.

## Cómo funciona

Toda llamada lleva `Authorization: Bearer <key>`. Tu organización se obtiene de la clave. `X-Operation-Id` es obligatorio en las llamadas `POST` de colecciones, cargas y trabajos y las hace idempotentes: un reintento con el mismo id devuelve la primera respuesta (`X-Idempotent-Replay: true`) y no agrega nada; el mismo id con un archivo distinto es `409 operation_id_reused`. En la Vector Database es opcional, porque la ingesta y la eliminación son idempotentes por construcción: ingestar un `id` existente lo reemplaza.

Una **consulta** (`POST /v1/vector/query`) toma `mode`, `query` (de 1 a 8,000 caracteres), `top_k` (de 1 a 50) y un `filter` opcional; devuelve las coincidencias de mejor a peor, cada una con `id`, `score`, `text` y `metadata`. Con `"retrieval": "vector_rerank"` y un `rerank_profile`, una lista de candidatos más amplia es reordenada por una etapa de reordenamiento; el objeto `retrieval` de la respuesta indica si el reordenamiento se aplicó o si se recurrió al orden vectorial.

Una **colección** funciona en pasos que puedes observar: créala, agrega elementos (`202`, `queued`), léela hasta que `status` sea `complete`, y luego descarga, consulta o chatea. Leer una colección `cloud` también avanza su indexación, una cantidad acotada por llamada, y cada respuesta lleva el progreso de `indexing`. `chat` responde solo a partir de las fuentes recuperadas, numera cada cita con el elemento, el paquete, el fragmento y el localizador, y dice que no puede responder cuando las fuentes no cubren la pregunta. Un `analysis` se construye a lo largo de varias solicitudes: repite `POST` o `GET` cada pocos segundos hasta que responda `200` con el informe.

Un **trabajo** es asíncrono: `POST /v1/knowledge/jobs` responde `202` con `job_id`, `status_url` y `poll_after_seconds` (también como `Retry-After`). Lee el estado cuando se te indique; la plataforma pronostica el tiempo hasta terminar e incluye `eta_seconds` mientras puede. Cuando `state` es `done`, descarga el archivo comprimido; se conserva 24 horas.

Lo que se mide: tokens de embeddings y vectores escritos por ingesta e indexación, consultas, reordenamientos como su propia unidad, llamadas de chat en tu ruta de chat, y trabajos por su precio. `POST /v1/knowledge/estimates` calcula el precio de una grabación antes de que la cargues, sin costo.

## Primeros pasos

Necesitas una clave de API y la parte que quieras habilitada para tu organización ([Autenticación](/es/guides/authentication/)).

1. **Crea la base de datos.** `GET /v1/vector/profiles`, elige un perfil y luego `POST /v1/vector/databases` con `{"profile":"<id>"}`. La respuesta es `201` con la base de datos.
2. **Ingesta pasajes.** `POST /v1/vector/ingest` con `"scope":"shared"` y dos o tres documentos (consulta [los ejemplos](#example)). La respuesta indica cuántos se `ingested` y lista los `skipped` con un motivo.
3. **Espera a `searchable`.** `GET /v1/vector/databases` hasta que `searchable` sea `true`.
4. **Consulta.** `POST /v1/vector/query` con `"mode":"shared"` y una pregunta redactada de forma distinta a tus pasajes. El pasaje más cercano aparece primero, con su `score`.
5. **Prueba una colección.** `POST /v1/collections` con `{"mode":"cloud"}`, agrega un PDF a `/items`, lee la colección hasta que `indexing.complete` sea `true`, y luego `POST /v1/collections/{id}/chat` y revisa las `citations`.

## Casos de uso

**Un asistente basado en tu manual.** Tu intranet ingesta cada página de políticas como fragmentos bajo su `document_id`, con metadatos de `category`. El asistente consulta con un filtro de `category` y pasa los mejores pasajes a su propio prompt. Cuando una página cambia, se ingesta de nuevo con una `generation` mayor, y los fragmentos que la nueva versión ya no tiene dejan de aparecer de inmediato.

**Preguntas sobre los archivos entregados por un cliente.** Un consultor crea una colección `cloud` por proyecto, agrega los contratos y las hojas de cálculo que envió el cliente, y hace preguntas mediante `chat`. Cada respuesta cita el elemento y la página en que se apoya, de modo que cada afirmación se puede verificar antes de pasar a un informe; `analysis` produce un resumen, entidades y contradicciones entre los archivos.

**De grabaciones de reuniones a una base de conocimiento.** Después de cada reunión grabada, la aplicación estima el precio, carga el video en partes de 64 MiB con la propia transcripción de la llamada como referencia, e inicia un trabajo con `max_price_usd`. Cuando el trabajo está `done`, el archivo comprimido (audio, fotogramas clave y la base de conocimiento) se archiva junto con la reunión.

## Límites y precios

| Límite | Valor |
|---|---|
| Cuerpo de solicitud de la Vector Database | 1 MiB |
| Documentos por ingesta, ids por eliminación | 100 |
| Un documento (`id` + `text` + `metadata`) | 10 KiB |
| Texto de consulta; `top_k` | 8,000 caracteres; 50 |
| Valores de `$in` en un filtro | 20 |
| Elemento en el cuerpo de una solicitud, u obtenido por URL | 16 MiB |
| Elementos por colección | 100; 1 GiB de archivos enviados en solicitudes; 20 GiB de video por carga |
| `top_k` de consulta de colección; mensajes de chat | 20; de 1 a 20 mensajes de hasta 8,000 caracteres |
| Fragmentos por llamada `embed` | 100, cada uno de hasta 8,000 caracteres |
| Llamadas al modelo de análisis por informe | 32 |
| Tamaño de las partes de una carga | 64 MiB (todas las partes menos la última) |
| Carga que no es video (transcripción, notas) | 16 MiB |
| Carga de grabación | el tope de tu organización |
| Claves de obtención sin usar | 16, cada una válida una vez durante 60 segundos |
| Resultado del trabajo conservado | 24 horas |
| Retención de colecciones | 30 días por defecto |

**Precios:** a consultar. Una grabación procesada por un trabajo se cobra en **minutos de video**, y `POST /v1/knowledge/estimates` devuelve su precio línea por línea antes de que cargues cualquier cosa. El chat sobre una colección se mide como el [Chat con IA](/es/products/ai.chat/) en tu ruta de chat.

## Errores

| Estado | Código | Qué significa y qué hacer |
|---|---|---|
| 400 | `invalid_body`, `unsupported_field` | Un campo o valor que la ruta no acepta; revisa los campos de la ruta. |
| 400 | `invalid_profile` | Elige un perfil listado por `GET /v1/vector/profiles`. |
| 400 | `confirmation_required` | Eliminar la base de datos requiere `{"confirm":"delete-database-and-all-vectors"}`. |
| 400 | `invalid_url`, `signed_url_must_be_sealed` | Solo URL `https` públicas en el puerto 443; una URL firmada debe estar sellada. |
| 400 | `fetch_key_invalid`, `invalid_sealed_url` | Solicita una nueva clave de obtención y sella de nuevo. |
| 403 | `vector_database_disabled`, `collections_disabled`, `knowledge_disabled` | Esa parte no está habilitada para tu organización. |
| 403 | `budget_exceeded` | El `max_price_usd` del trabajo supera el tope de tu organización. |
| 404 | `collection_not_found`, `job_not_found`, `upload_not_found`, `analysis_not_found` | Revisa el id; la descarga de un trabajo también es `404` hasta que está `done`. |
| 409 | `vector_database_not_created`, `vector_database_exists`, `vector_database_deleting` | Crea primero la base de datos; una por organización; espera a que termine una eliminación. |
| 409 | `mode_not_supported` | La operación no existe en el modo de esta colección. |
| 409 | `collection_incomplete`, `collection_full` | Espera a que terminen los elementos; la colección está en su límite. |
| 409 | `upload_incomplete`, `operation_id_reused`, `operation_in_progress` | Termina la carga; usa un nuevo id de operación para un archivo distinto; espera. |
| 410 | `collection_expired`, `result_expired` | La retención terminó; procesa de nuevo. |
| 413 | `request_too_large`, `url_too_large` | Usa `POST /v1/uploads` para archivos grandes. |
| 415, 422 | `unsupported_media_type`, `input_rejected`, `archive_rejected` | El tipo de archivo no se lee, o el archivo fue rechazado (`reason` indica por qué). |
| 429 | `too_many_fetch_keys` y los códigos de cuota | Usa o deja vencer las claves que tienes; consulta [Errores](/es/guides/errors/). |
| 502, 504 | `url_fetch_failed`, `url_fetch_timeout`, `upstream_error`, `timeout_error` | Falló la URL o el procesamiento; reintenta. |
| 503 | `service_unavailable` | Reintenta más tarde; no se adivinó nada. |

## Buenas prácticas

- **Agrupa los fragmentos bajo un `document_id` y aumenta `generation`** cuando cambie la fuente; la eliminación y el reemplazo funcionan entonces por documento.
- **Envía `content_sha256` con cada fragmento** y compáralo con `GET /v1/vector/documents` para resincronizar tu copia sin volver a ingestar todo.
- **Revisa `searchable` (o `indexing.complete`) antes de confiar en los pasajes más recientes.**
- **Mantén la respuesta de un pasaje dentro de sus primeros 2,000 caracteres** cuando uses reordenamiento; el reordenador solo lee esa cantidad.
- **Compara `vector_rerank` con `vector` simple en tus propios datos**, sobre todo fuera del inglés, antes de depender de él.
- **Estima siempre antes de un trabajo y configura `max_price_usd`**; consulta el estado en `poll_after_seconds`, no más rápido.
- **Sella las URL firmadas**; nunca envíes una URL que lleve un inicio de sesión. Carga los bytes en su lugar.
- **Revisa las citas**: un modelo puede citar una fuente real para algo que esa fuente no dice.

## Relacionados

- [Embeddings de IA](/es/products/ai.embeddings/), [Chat con IA](/es/products/ai.chat/)
- [Archivos](/es/products/files/): almacena los archivos fuente en sí
- [Autenticación](/es/guides/authentication/), [Errores](/es/guides/errors/), [Límites](/es/guides/limits/)

## Endpoints

- POST /v1/vector/ingest
- POST /v1/vector/query
- POST /v1/collections
- POST /v1/collections/{id}/query
- POST /v1/knowledge/jobs

## Ejemplo

```sh
curl -X POST "https://ai.inovacc.dev/v1/vector/ingest" -H "Authorization: Bearer $INOVACC_API_KEY" -H "X-Operation-Id: $(uuidgen)" -H "Content-Type: application/json" -d '{}'
```
