# OpenAI

# Einführung

Das OpenAI Cookbook ist eine Sammlung praktischer Beispiele und Code-Snippets, die Entwicklern in realen Anwendungen zur Verfügung stehen. Es zeigt, wie man OpenAI's neueste Spitzenmodelle und Werkzeuge verwendet, die an vorderster Front der Künstlichen Intelligenz-Forschung stehen.

Weitere Informationen finden Sie auf der OpenAI Cookbook Website (opens new window).

# Voraussetzungen

Um dieser Anleitung folgen zu können, benötigen Sie Folgendes:

  1. Ein MyScale-Cluster, der gemäß der Schnellstartanleitung bereitgestellt wurde.
  2. Die clickhouse-connect-Bibliothek, um mit MyScale zu interagieren.
  3. Einen OpenAI API-Schlüssel (opens new window) zur Vektorisierung von Abfragen.

# Installieren der Anforderungen

Dieses Notebook erfordert die Installation von openai, clickhouse-connect sowie einigen anderen Abhängigkeiten. Verwenden Sie den folgenden Befehl, um sie zu installieren:

!pip install openai clickhouse-connect wget pandas

# Vorbereiten des OpenAI API-Schlüssels

Um die OpenAI API zu verwenden, müssen Sie einen API-Schlüssel einrichten. Wenn Sie noch keinen haben, können Sie ihn von OpenAI (opens new window) erhalten.

import openai
# API-Schlüssel von der OpenAI-Website abrufen
openai.api_key = "OPENAI_API_KEY"
# Überprüfen, ob wir authentifiziert sind
openai.Engine.list()

# Verbindung zu MyScale herstellen

Folgen Sie dem Abschnitt Verbindungsdetails, um den Cluster-Host, den Benutzernamen und das Passwort aus der MyScale-Konsole abzurufen, und verwenden Sie sie, um eine Verbindung zu Ihrem Cluster herzustellen, wie unten gezeigt:

import clickhouse_connect
# Client initialisieren
client = clickhouse_connect.get_client(host='IHR_CLUSTER_HOST', port=443, username='IHR_BENUTZERNAME', password='IHR_CLUSTER_PASSWORT')

# Daten laden

Wir müssen den Datensatz der vorberechneten Vektor-Embeddings für Wikipedia-Artikel, bereitgestellt von OpenAI, laden. Verwenden Sie das wget-Paket, um den Datensatz herunterzuladen.

import wget
embeddings_url = "https://cdn.openai.com/API/examples/data/vector_database_wikipedia_articles_embedded.zip"
# Die Datei ist ~700 MB groß, daher dauert der Download einige Zeit
wget.download(embeddings_url)

Nach Abschluss des Downloads extrahieren Sie die Datei mit dem zipfile-Paket:

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

Jetzt können wir die Daten aus vector_database_wikipedia_articles_embedded.csv in ein Pandas DataFrame laden:

import pandas as pd
from ast import literal_eval
# Daten aus CSV lesen
article_df = pd.read_csv('../data/vector_database_wikipedia_articles_embedded.csv')
article_df = article_df[['id', 'url', 'title', 'text', 'content_vector']]
# Vektoren aus Strings wieder in eine Liste umwandeln
article_df["content_vector"] = article_df.content_vector.apply(literal_eval)
article_df.head()

# Daten indizieren

Wir werden eine SQL-Tabelle namens articles in MyScale erstellen, um die Embeddings-Daten zu speichern. Die Tabelle wird einen Vektorindex mit einer Kosinus-Distanzmetrik und eine Einschränkung für die Länge der Embeddings enthalten. Verwenden Sie den folgenden Code, um die Tabelle zu erstellen und Daten in die Tabelle einzufügen:

# Tabelle "articles" mit Vektorindex erstellen
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
""")
# Daten in Batches in die Tabelle einfügen
from tqdm.auto import tqdm
batch_size = 100
total_records = len(article_df)
# Daten in Batches hochladen
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)

Bevor wir mit der Suche fortfahren, müssen wir den Build-Status des Vektorindex überprüfen, da er automatisch im Hintergrund erstellt wird.

# Anzahl der eingefügten Daten überprüfen
print(f"Anzahl der Artikel: {client.command('SELECT count(*) FROM default.articles')}")
# Den Status des Vektorindex überprüfen, sicherstellen, dass der Vektorindex mit dem Status 'Built' bereit ist
get_index_status="SELECT status FROM system.vector_indices WHERE name='article_content_index'"
print(f"Index-Build-Status: {client.command(get_index_status)}")

# Daten suchen

Sobald die Daten in MyScale indiziert sind, können wir eine Vektorsuche durchführen, um ähnliche Inhalte zu finden. Zuerst verwenden wir die OpenAI API, um Embeddings für unsere Abfrage zu generieren. Anschließend führen wir die Vektorsuche mit MyScale durch.

import openai
query = "Berühmte Schlachten in der schottischen Geschichte"
# Erzeugt Embedding-Vektor aus Benutzerabfrage
embed = openai.Embedding.create(
    input=query,
    model="text-embedding-ada-002",
)["data"][0]["embedding"]
# Datenbank nach den top K ähnlichen Inhalten zur gegebenen Abfrage durchsuchen
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}
""")
# Ergebnisse anzeigen
for i, r in enumerate(results.named_results()):
    print(i+1, r['title'])