Subir archivos a un Almacén de Vectores
Cargar contenido de archivos en Vector Store con operaciones por lotes
Ejemplos de Solicitudes
curl -X POST \
https://api.rememberizer.ai/api/v1/vector-stores/vs_abc123/documents/upload \
-H "x-api-key: YOUR_API_KEY" \
-F "files=@/path/to/document1.pdf" \
-F "files=@/path/to/document2.docx"const uploadFiles = async (vectorStoreId, files) => {
const formData = new FormData();
// Agregar múltiples archivos a los datos del formulario
for (const file of files) {
formData.append('files', file);
}
const response = await fetch(`https://api.rememberizer.ai/api/v1/vector-stores/${vectorStoreId}/documents/upload`, {
method: 'POST',
headers: {
'x-api-key': 'YOUR_API_KEY'
// Nota: No establezca el encabezado Content-Type, se establecerá automáticamente con el límite correcto
},
body: formData
});
const data = await response.json();
console.log(data);
};
// Ejemplo de uso con el elemento de entrada de archivo
const fileInput = document.getElementById('fileInput');
uploadFiles('vs_abc123', fileInput.files);import requests
def upload_files(vector_store_id, file_paths):
headers = {
"x-api-key": "YOUR_API_KEY"
}
files = [('files', (file_path.split('/')[-1], open(file_path, 'rb'))) for file_path in file_paths]
response = requests.post(
f"https://api.rememberizer.ai/api/v1/vector-stores/{vector_store_id}/documents/upload",
headers=headers,
files=files
)
data = response.json()
print(data)
upload_files('vs_abc123', ['/path/to/document1.pdf', '/path/to/document2.docx'])```ruby require 'net/http' require 'uri' require 'json'
def upload_files(vector_store_id, file_paths) uri = URI("https://api.rememberizer.ai/api/v1/vector-stores/#{vector_store_id}/documents/upload")
Crear un nuevo objeto HTTP
http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true
Crear una solicitud de formulario multipart
request = Net::HTTP::Post.new(uri) request['x-api-key'] = 'YOUR_API_KEY'
Crear un límite multipart
boundary = "RubyFormBoundary#{rand(1000000)}" request['Content-Type'] = "multipart/form-data; boundary=#{boundary}"
Construir el cuerpo de la solicitud
body = [] file_paths.each do |file_path| file_name = File.basename(file_path) file_content = File.read(file_path, mode: 'rb')
body << "--#{boundary}\r\n"
body << "Content-Disposition: form-data; name=\"files\"; filename=\"#{file_name}\"\r\n"
body << "Content-Type: #{get_content_type(file_name)}\r\n\r\n"
body << file_content
body << "\r\n"end body << "--#{boundary}--\r\n"
request.body = body.join
Enviar la solicitud
response = http.request(request)
Analizar y devolver la respuesta
JSON.parse(response.body) end
# Método auxiliar para determinar el tipo de contenido
def get_content_type(filename)
ext = File.extname(filename).downcase
case ext
when '.pdf' then 'application/pdf'
when '.doc' then 'application/msword'
when '.docx' then 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'
when '.txt' then 'text/plain'
when '.md' then 'text/markdown'
when '.json' then 'application/json'
else 'application/octet-stream'
end
end
# Ejemplo de uso
result = upload_files('vs_abc123', ['/path/to/document1.pdf', '/path/to/document2.docx'])
puts result{% hint style="info" %} Reemplace YOUR_API_KEY con su clave API real de Vector Store, vs_abc123 con su ID de Vector Store, y proporcione las rutas a sus archivos locales. {% endhint %} {% endtab %} {% endtabs %}
Parámetros de Ruta
vector-store-id
string
Requerido. El ID de la tienda de vectores a la que subir archivos.
Cuerpo de la Solicitud
Este endpoint acepta una solicitud multipart/form-data con uno o más archivos en el campo files.
Formato de Respuesta
{
"documents": [
{
"id": 1234,
"name": "document1.pdf",
"type": "application/pdf",
"size": 250000,
"status": "processing",
"created": "2023-06-15T10:15:00Z",
"vector_store": "vs_abc123"
},
{
"id": 1235,
"name": "document2.docx",
"type": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
"size": 180000,
"status": "processing",
"created": "2023-06-15T10:15:00Z",
"vector_store": "vs_abc123"
}
],
"errors": []
}Si algunos archivos no se pueden cargar, se enumerarán en el array errors:
{
"documents": [
{
"id": 1234,
"name": "document1.pdf",
"type": "application/pdf",
"size": 250000,
"status": "processing",
"created": "2023-06-15T10:15:00Z",
"vector_store": "vs_abc123"
}
],
"errors": [
{
"file": "document2.docx",
"error": "Formato de archivo no soportado"
}
]
}Autenticación
Este endpoint requiere autenticación utilizando una clave API en el encabezado x-api-key.
Formatos de Archivo Soportados
PDF (
.pdf)Microsoft Word (
.doc,.docx)Microsoft Excel (
.xls,.xlsx)Microsoft PowerPoint (
.ppt,.pptx)Archivos de texto (
.txt)Markdown (
.md)JSON (
.json)HTML (
.html,.htm)
Límites de Tamaño de Archivo
Límite de tamaño de archivo individual: 50MB
Límite de tamaño total de solicitud: 100MB
Número máximo de archivos por solicitud: 20
Respuestas de Error
400
Solicitud Incorrecta - No se proporcionaron archivos o formato de solicitud inválido
401
No Autorizado - Clave API inválida o faltante
404
No Encontrado - Almacén de Vectores no encontrado
413
Carga Útil Demasiado Grande - Los archivos exceden el límite de tamaño
415
Tipo de Medio No Compatible - Formato de archivo no soportado
500
Error Interno del Servidor
207
Multi-Estado - Algunos archivos se subieron con éxito, pero otros fallaron
Estado del Procesamiento
Los archivos son aceptados inicialmente con un estado de processing. Puedes verificar el estado de procesamiento de los documentos utilizando el endpoint Get a List of Documents in a Vector Store. El estado final será uno de:
done: El documento fue procesado con éxitoerror: Ocurrió un error durante el procesamientoprocessing: El documento aún se está procesando
El tiempo de procesamiento depende del tamaño y la complejidad del archivo. El tiempo de procesamiento típico es de entre 30 segundos a 5 minutos por documento.
Operaciones por Lotes
Para cargar eficientemente múltiples archivos en su Almacén de Vectores, Rememberizer admite operaciones por lotes. Este enfoque ayuda a optimizar el rendimiento al tratar con grandes cantidades de documentos.
Implementación de Carga por Lotes
{% tabs %} {% tab title="Python" %}
import os
import requests
import time
import concurrent.futures
from pathlib import Path
def batch_upload_to_vector_store(vector_store_id, folder_path, batch_size=5, file_types=None):
"""
Cargar todos los archivos de un directorio a un Almacén de Vectores en lotes
Args:
vector_store_id: ID del almacén de vectores
folder_path: Ruta a la carpeta que contiene los archivos a cargar
batch_size: Número de archivos a cargar en cada lote
file_types: Lista opcional de extensiones de archivo para filtrar (por ejemplo, ['.pdf', '.docx'])
Returns:
Lista de resultados de carga
"""
api_key = "YOUR_API_KEY"
headers = {"x-api-key": api_key}
# Obtener lista de archivos en el directorio
files = []
for entry in os.scandir(folder_path):
if entry.is_file():
file_path = Path(entry.path)
# Filtrar por extensión de archivo si se especifica
if file_types is None or file_path.suffix.lower() in file_types:
files.append(file_path)
print(f"Se encontraron {len(files)} archivos para cargar")
results = []
# Procesar archivos en lotes
for i in range(0, len(files), batch_size):
batch = files[i:i+batch_size]
print(f"Procesando lote {i//batch_size + 1}/{(len(files) + batch_size - 1)//batch_size}: {len(batch)} archivos")
# Cargar lote
upload_files = []
for file_path in batch:
upload_files.append(('files', (file_path.name, open(file_path, 'rb'))))
try:
response = requests.post(
f"https://api.rememberizer.ai/api/v1/vector-stores/{vector_store_id}/documents/upload",
headers=headers,
files=upload_files
)
# Cerrar todos los manejadores de archivos
for _, (_, file_obj) in upload_files:
file_obj.close()
if response.status_code in (200, 201, 207):
batch_result = response.json()
results.append(batch_result)
print(f"Carga de lote exitosa - {len(batch_result.get('documents', []))} documentos procesados")
# Verificar errores
if batch_result.get('errors') and len(batch_result['errors']) > 0:
print(f"Errores encontrados: {len(batch_result['errors'])}")
for error in batch_result['errors']:
print(f"- {error['file']}: {error['error']}")
else:
print(f"La carga del lote falló con el código de estado {response.status_code}: {response.text}")
results.append({"error": f"La carga del lote falló: {response.text}"})
except Exception as e:
print(f"Excepción durante la carga por lotes: {str(e)}")
results.append({"error": str(e)})
# Cerrar cualquier manejador de archivo restante en caso de excepción
for _, (_, file_obj) in upload_files:
try:
file_obj.close()
except:
pass
# Limitación de tasa - pausa entre lotes
if i + batch_size < len(files):
print("Pausando antes del siguiente lote...")
time.sleep(2)
return results
# Ejemplo de uso
results = batch_upload_to_vector_store(
'vs_abc123',
'/ruta/a/la/carpeta/de/documentos',
batch_size=5,
file_types=['.pdf', '.docx', '.txt']
){% endtab %}
{% tab title="JavaScript" %}
/**
* Subir archivos a un Vector Store en lotes
*
* @param {string} vectorStoreId - ID del Vector Store
* @param {FileList|File[]} files - Archivos a subir
* @param {Object} options - Opciones de configuración
* @returns {Promise<Array>} - Lista de resultados de la subida
*/
async function batchUploadToVectorStore(vectorStoreId, files, options = {}) {
const {
batchSize = 5,
delayBetweenBatches = 2000,
onProgress = null
} = options;
const apiKey = 'YOUR_API_KEY';
const results = [];
const fileList = Array.from(files);
const totalBatches = Math.ceil(fileList.length / batchSize);
console.log(`Preparándose para subir ${fileList.length} archivos en ${totalBatches} lotes`);
// Procesar archivos en lotes
for (let i = 0; i < fileList.length; i += batchSize) {
const batch = fileList.slice(i, i + batchSize);
const batchNumber = Math.floor(i / batchSize) + 1;
console.log(`Procesando lote ${batchNumber}/${totalBatches}: ${batch.length} archivos`);
if (onProgress) {
onProgress({
currentBatch: batchNumber,
totalBatches: totalBatches,
filesInBatch: batch.length,
totalFiles: fileList.length,
completedFiles: i
});
}
// Crear FormData para este lote
const formData = new FormData();
batch.forEach(file => {
formData.append('files', file);
});
try {
const response = await fetch(
`https://api.rememberizer.ai/api/v1/vector-stores/${vectorStoreId}/documents/upload`,
{
method: 'POST',
headers: {
'x-api-key': apiKey
},
body: formData
}
);
if (response.ok) {
const batchResult = await response.json();
results.push(batchResult);
console.log(`Lote subido con éxito - ${batchResult.documents?.length || 0} documentos procesados`);
// Verificar errores
if (batchResult.errors && batchResult.errors.length > 0) {
console.warn(`Errores encontrados: ${batchResult.errors.length}`);
batchResult.errors.forEach(error => {
console.warn(`- ${error.file}: ${error.error}`);
});
}
} else {
console.error(`La subida del lote falló con estado ${response.status}: ${await response.text()}`);
results.push({ error: `Lote fallido con estado: ${response.status}` });
}
} catch (error) {
console.error(`Excepción durante la subida del lote: ${error.message}`);
results.push({ error: error.message });
}
// Agregar retraso entre lotes para evitar limitaciones de tasa
if (i + batchSize < fileList.length) {
console.log(`Pausando por ${delayBetweenBatches}ms antes del siguiente lote...`);
await new Promise(resolve => setTimeout(resolve, delayBetweenBatches));
}
}
console.log(`Subida completa. Se procesaron ${fileList.length} archivos.`);
return results;
}
// Ejemplo de uso con elemento de entrada de archivo
document.getElementById('upload-button').addEventListener('click', async () => {
const fileInput = document.getElementById('file-input');
const vectorStoreId = 'vs_abc123';
const progressBar = document.getElementById('progress-bar');
try {
const results = await batchUploadToVectorStore(vectorStoreId, fileInput.files, {
batchSize: 5,
onProgress: (progress) => {
// Actualizar la interfaz de progreso
const percentage = Math.round((progress.completedFiles / progress.totalFiles) * 100);
progressBar.style.width = `${percentage}%`;
progressBar.textContent = `${percentage}% (Lote ${progress.currentBatch}/${progress.totalBatches})`;
}
});
console.log('Resultados de la subida completa:', results);
} catch (error) {
console.error('La subida falló:', error);
}
});{% endtab %}
{% tab title="Ruby" %}
ruby
require 'net/http'
require 'uri'
require 'json'
require 'mime/types'
# Subir archivos a un Almacén de Vectores en lotes
#
# @param vector_store_id [String] ID de la tienda de vectores
# @param folder_path [String] Ruta a la carpeta que contiene los archivos a subir
# @param batch_size [Integer] Número de archivos a subir en cada lote
# @param file_types [Array<String>] Array opcional de extensiones de archivo para filtrar
# @param delay_between_batches [Float] Segundos a esperar entre lotes
# @return [Array] Lista de resultados de carga
def batch_upload_to_vector_store(vector_store_id, folder_path, batch_size: 5, file_types: nil, delay_between_batches: 2.0)
api_key = 'YOUR_API_KEY'
results = []
# Obtener lista de archivos en el directorio
files = Dir.entries(folder_path)
.select { |f| File.file?(File.join(folder_path, f)) }
.select { |f| file_types.nil? || file_types.include?(File.extname(f).downcase) }
.map { |f| File.join(folder_path, f) }
puts "Encontrados #{files.count} archivos para cargar"
total_batches = (files.count.to_f / batch_size).ceil
# Procesar archivos en lotes
files.each_slice(batch_size).with_index do |batch, batch_index|
puts "Procesando lote #{batch_index + 1}/#{total_batches}: #{batch.count} archivos"
# Preparar la solicitud HTTP
uri = URI("https://api.rememberizer.ai/api/v1/vector-stores/#{vector_store_id}/documents/upload")
request = Net::HTTP::Post.new(uri)
request['x-api-key'] = api_key
# Crear un límite de formulario multipart
boundary = "RubyBoundary#{rand(1000000)}"
request['Content-Type'] = "multipart/form-data; boundary=#{boundary}"
# Construir el cuerpo de la solicitud
body = []
batch.each do |file_path|
file_name = File.basename(file_path)
mime_type = MIME::Types.type_for(file_path).first&.content_type || 'application/octet-stream'
begin
file_content = File.binread(file_path)
body << "--#{boundary}\r\n"
body << "Content-Disposition: form-data; name=\"files\"; filename=\"#{file_name}\"\r\n"
body << "Content-Type: #{mime_type}\r\n\r\n"
body << file_content
body << "\r\n"
rescue => e
puts "Error al leer el archivo #{file_path}: #{e.message}"
end
end
body << "--#{boundary}--\r\n"
request.body = body.join
# Enviar la solicitud
begin
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
response = http.request(request)
if response.code.to_i == 200 || response.code.to_i == 201 || response.code.to_i == 207
batch_result = JSON.parse(response.body)
results << batch_result
puts "Carga del lote exitosa - #{batch_result['documents']&.count || 0} documentos procesados"
# Verificar errores
if batch_result['errors'] && !batch_result['errors'].empty?
puts "Errores encontrados: #{batch_result['errors'].count}"
batch_result['errors'].each do |error|
puts "- #{error['file']}: #{error['error']}"
end
end
else
puts "La carga del lote falló con el código de estado #{response.code}: #{response.body}"
results << { "error" => "Lote fallido: #{response.body}" }
end
rescue => e
puts "Excepción durante la carga del lote: #{e.message}"
results << { "error" => e.message }
end
# Limitación de tasa - pausa entre lotes
if batch_index < total_batches - 1
puts "Pausando durante #{delay_between_batches} segundos antes del siguiente lote..."
sleep(delay_between_batches)
end
end
puts "Carga completa. Procesados #{files.count} archivos."
results
end
# Ejemplo de uso
results = batch_upload_to_vector_store(
'vs_abc123',
'/path/to/documents/folder',
batch_size: 5,
file_types: ['.pdf', '.docx', '.txt'],
delay_between_batches: 2.0
)Mejores Prácticas para Cargas por Lotes
Para optimizar el rendimiento y la fiabilidad al cargar grandes volúmenes de archivos:
Gestionar el Tamaño del Lote: Mantenga los tamaños de lote entre 5-10 archivos para un rendimiento óptimo. Demasiados archivos en una sola solicitud aumentan el riesgo de tiempos de espera.
Implementar Limitación de Tasa: Agregue retrasos entre lotes (se recomiendan 2-3 segundos) para evitar alcanzar los límites de tasa de la API.
Agregar Lógica de Reintento de Errores: Para sistemas de producción, implemente lógica de reintento para cargas fallidas con retroceso exponencial.
Validar Tipos de Archivos: Pre-filtre los archivos para asegurarse de que sean tipos compatibles antes de intentar la carga.
Monitorear el Progreso del Lote: Para aplicaciones orientadas al usuario, proporcione retroalimentación sobre el progreso de las operaciones por lotes.
Manejar Éxitos Parciales: La API puede devolver un código de estado 207 para éxito parcial. Siempre verifique los estados de documentos individuales.
Limpiar Recursos: Asegúrese de que todos los manejadores de archivos estén cerrados correctamente, especialmente cuando ocurren errores.
Paralelizar con Sabiduría: Para cargas muy grandes (miles de archivos), considere múltiples procesos de lotes concurrentes que apunten a diferentes almacenes de vectores, luego combine los resultados más tarde si es necesario.
Implementar Sumas de Comprobación: Para datos críticos, verifique la integridad del archivo antes y después de la carga con sumas de comprobación.
Registrar Resultados Completos: Mantenga registros detallados de todas las operaciones de carga para la solución de problemas.
Siguiendo estas mejores prácticas, puede gestionar de manera eficiente la ingestión de documentos a gran escala en sus almacenes de vectores.
Last updated