# OpenAI

# Introducción

El OpenAI Cookbook es una colección de ejemplos prácticos y fragmentos de código para que los desarrolladores los utilicen en aplicaciones del mundo real. Demuestra cómo utilizar los últimos modelos y herramientas de vanguardia de OpenAI, que están a la vanguardia de la investigación en inteligencia artificial.

Para obtener más información, consulte el sitio web del OpenAI Cookbook (opens new window).

# Requisitos previos

Para seguir esta guía, necesitará tener lo siguiente:

  1. Un clúster de MyScale implementado siguiendo la guía de inicio rápido.
  2. La biblioteca clickhouse-connect para interactuar con MyScale.
  3. Una clave de API de OpenAI (opens new window) para la vectorización de consultas.

# Instalar requisitos

Este cuaderno requiere las bibliotecas openai, clickhouse-connect, así como algunas otras dependencias. Utilice el siguiente comando para instalarlas:

!pip install openai clickhouse-connect wget pandas

# Preparar su clave de API de OpenAI

Para utilizar la API de OpenAI, deberá configurar una clave de API. Si aún no tiene una, puede obtenerla en OpenAI (opens new window).

import openai
# obtener la clave de API en el sitio web de OpenAI
openai.api_key = "OPENAI_API_KEY"
# verificar que estemos autenticados
openai.Engine.list()

# Conectar a MyScale

Siga la sección de detalles de conexión para obtener la información del host del clúster, el nombre de usuario y la contraseña de la consola de MyScale, y utilícela para crear una conexión a su clúster como se muestra a continuación:

import clickhouse_connect
# inicializar el cliente
client = clickhouse_connect.get_client(host='YOUR_CLUSTER_HOST', port=443, username='YOUR_USERNAME', password='YOUR_CLUSTER_PASSWORD')

# Cargar datos

Necesitamos cargar el conjunto de datos de vectores precalculados para los artículos de Wikipedia proporcionados por OpenAI. Utilice el paquete wget para descargar el conjunto de datos.

import wget
embeddings_url = "https://cdn.openai.com/API/examples/data/vector_database_wikipedia_articles_embedded.zip"
# El archivo tiene ~700 MB, así que esto llevará un tiempo
wget.download(embeddings_url)

Después de que se complete la descarga, extraiga el archivo utilizando el paquete zipfile:

import zipfile
with zipfile.ZipFile("vector_database_wikipedia_articles_embedded.zip", "r") as zip_ref:
    zip_ref.extractall("../data")

Ahora, podemos cargar los datos de vector_database_wikipedia_articles_embedded.csv en un DataFrame de Pandas:

import pandas as pd
from ast import literal_eval
# leer los datos del archivo csv
article_df = pd.read_csv('../data/vector_database_wikipedia_articles_embedded.csv')
article_df = article_df[['id', 'url', 'title', 'text', 'content_vector']]
# leer los vectores de las cadenas y convertirlos en una lista
article_df["content_vector"] = article_df.content_vector.apply(literal_eval)
article_df.head()

# Indexar datos

Crearemos una tabla SQL llamada articles en MyScale para almacenar los datos de los vectores. La tabla incluirá un índice de vector con una métrica de distancia coseno y una restricción para la longitud de los vectores. Utilice el siguiente código para crear e insertar datos en la tabla de artículos:

# crear la tabla de artículos con el índice de vector
embedding_len=len(article_df['content_vector'][0]) # 1536
client.command(f"""
CREATE TABLE IF NOT EXISTS default.articles
(
    id UInt64,
    url String,
    title String,
    text String,
    content_vector Array(Float32),
    CONSTRAINT cons_vector_len CHECK length(content_vector) = {embedding_len},
    VECTOR INDEX article_content_index content_vector TYPE HNSWFLAT('metric_type=Cosine')
)
ENGINE = MergeTree ORDER BY id
""")
# insertar datos en la tabla en lotes
from tqdm.auto import tqdm
batch_size = 100
total_records = len(article_df)
# cargar los datos en lotes
data = article_df.to_records(index=False).tolist()
column_names = article_df.columns.tolist()
for i in tqdm(range(0, total_records, batch_size)):
    i_end = min(i + batch_size, total_records)
    client.insert("default.articles", data[i:i_end], column_names=column_names)

Necesitamos verificar el estado de construcción del índice de vectores antes de continuar con la búsqueda, ya que se construye automáticamente en segundo plano.

# verificar la cantidad de datos insertados
print(f"cantidad de artículos: {client.command('SELECT count(*) FROM default.articles')}")
# verificar el estado del índice de vectores, asegurarse de que el índice de vectores esté listo con el estado 'Built'
get_index_status="SELECT status FROM system.vector_indices WHERE name='article_content_index'"
print(f"estado de construcción del índice: {client.command(get_index_status)}")

# Buscar datos

Una vez indexados en MyScale, podemos realizar una búsqueda de vectores para encontrar contenido similar. Primero, utilizaremos la API de OpenAI para generar vectores para nuestra consulta. Luego, realizaremos la búsqueda de vectores utilizando MyScale.

import openai
query = "Batallas famosas en la historia de Escocia"
# crea un vector de incrustación a partir de la consulta del usuario
embed = openai.Embedding.create(
    input=query,
    model="text-embedding-ada-002",
)["data"][0]["embedding"]
# consulta la base de datos para encontrar los K mejores contenidos similares a la consulta dada
top_k = 10
results = client.query(f"""
SELECT id, url, title, distance(content_vector, {embed}) as dist
FROM default.articles
ORDER BY dist
LIMIT {top_k}
""")
# mostrar los resultados
for i, r in enumerate(results.named_results()):
    print(i+1, r['title'])