Sdílet prostřednictvím


Generování inzerování rozšířené AI s využitím služby Azure Cosmos DB pro virtuální jádro MongoDB

V této příručce si ukážeme, jak vytvořit dynamický reklamní obsah, který bude rezonovat s vaší cílovou skupinou pomocí našeho přizpůsobeného asistenta AI, Heelie. S využitím služby Azure Cosmos DB pro virtuální jádro MongoDB využíváme funkci vyhledávání vektorů podobnosti k sémanticky analyzovat a shodovat popisy inventáře s tématy inzerování. Proces je možný generováním vektorů pro popisy inventáře pomocí vkládání OpenAI, které výrazně zlepšují jejich sémantickou hloubku. Tyto vektory se pak ukládají a indexují v rámci prostředku virtuálního jádra Cosmos DB pro MongoDB. Při generování obsahu pro reklamy vektorizujeme téma inzerování, abychom našli nejvhodnější skladové položky. Následuje proces načítání rozšířené generace (RAG), kde se nejvyšší shody odesílají do OpenAI, aby vytvořily atraktivní reklamu. Celý základ kódu pro aplikaci je k dispozici v úložišti GitHub pro vaši referenci .

Funkce

  • Hledání vektorové podobnosti: Využívá azure Cosmos DB pro vyhledávání výkonných vektorových podobností virtuálních jader Azure Cosmos DB ke zlepšení sémantických vyhledávacích funkcí, což usnadňuje vyhledání relevantních položek inventáře na základě obsahu reklam.
  • Vkládání OpenAI: Využívá nejmodernější vkládání z OpenAI k vygenerování vektorů pro popisy inventáře. Tento přístup umožňuje více drobných a sémanticky bohatých shod mezi inventářem a inzerovaným obsahem.
  • Generování obsahu: Využívá pokročilé jazykové modely OpenAI ke generování poutavých reklam zaměřených na trend. Tato metoda zajišťuje, že obsah je nejen relevantní, ale také poutavá pro cílovou skupinu.

Požadavky

  • Azure OpenAI: Pojďme nastavit prostředek Azure OpenAI. Přístup k této službě je aktuálně k dispozici pouze aplikací. Pokud chcete získat přístup k Azure OpenAI, vyplňte formulář na adrese https://aka.ms/oai/access. Jakmile budete mít přístup, proveďte následující kroky:
    • Podle tohoto rychlého startu vytvořte prostředek Azure OpenAI.
    • Nasaďte model completions a embeddings model.
      • Další informace najdete completionstady.
      • Další informace najdete embeddingstady.
    • Poznamenejte si název koncového bodu, klíče a nasazení.
  • Prostředek virtuálních jader Služby Cosmos DB pro MongoDB: Začněme vytvořením prostředku virtuálního jádra služby Azure Cosmos DB pro MongoDB zdarma podle této úvodní příručky.
    • Poznamenejte si podrobnosti o připojení.
  • Prostředí Pythonu (>= verze 3.9) s balíčky, jako numpyjsou , openai, pymongo, python-dotenv, azure-core, azure-cosmos, tenacitya gradio.
  • Stáhněte si datový soubor a uložte ho do určené datové složky.

Spuštění skriptu

Než se ponoříme do vzrušující části generování reklam s rozšířenými technologiemi AI, musíme nastavit naše prostředí. Tato instalace zahrnuje instalaci potřebných balíčků, aby se zajistilo, že se náš skript bude bez problémů spouštět. Tady je podrobný průvodce, který vám pomůže všechno připravit.

1.1 Instalace potřebných balíčků

Nejprve musíme nainstalovat několik balíčků Pythonu. Otevřete terminál a spusťte následující příkazy:

 pip install numpy
 pip install openai==1.2.3
 pip install pymongo
 pip install python-dotenv
 pip install azure-core
 pip install azure-cosmos
 pip install tenacity
 pip install gradio
 pip show openai

1.2 Nastavení openAI a klienta Azure

Po instalaci potřebných balíčků je dalším krokem nastavení našich klientů OpenAI a Azure pro skript, což je zásadní pro ověřování požadavků na rozhraní OpenAI API a služby Azure.

import json
import time
import openai

from dotenv import dotenv_values
from openai import AzureOpenAI

# Configure the API to use Azure as the provider
openai.api_type = "azure"
openai.api_key = "<AZURE_OPENAI_API_KEY>"  # Replace with your actual Azure OpenAI API key
openai.api_base = "https://<OPENAI_ACCOUNT_NAME>.openai.azure.com/"  # Replace with your OpenAI account name
openai.api_version = "2023-06-01-preview"

# Initialize the AzureOpenAI client with your API key, version, and endpoint
client = AzureOpenAI(
    api_key=openai.api_key,
    api_version=openai.api_version,
    azure_endpoint=openai.api_base
)

Architektura řešení

architektura řešení

2. Vytváření vkládání a nastavení služby Cosmos DB

Po nastavení našeho prostředí a klienta OpenAI přejdeme do základní části projektu generování inzerování s rozšířeným AI. Následující kód vytvoří vektorové vkládání z textových popisů produktů a nastaví naši databázi ve službě Azure Cosmos DB pro virtuální jádro MongoDB pro ukládání a vyhledávání těchto vložených objektů.

2.1 Vytvoření vkládání

Abychom mohli generovat poutavé reklamy, musíme nejprve porozumět položkám v našem inventáři. Děláme to tak, že vytvoříme vektorové vkládání z popisů našich položek, což nám umožní zachytit jejich sémantický význam ve formuláři, který počítače můžou pochopit a zpracovat. Tady je postup, jak vytvořit vektorové vkládání pro popis položky pomocí Azure OpenAI:

import openai

def generate_embeddings(text):
    try:
        response = client.embeddings.create(
            input=text, model="text-embedding-ada-002")
        embeddings = response.data[0].embedding
        return embeddings
    except Exception as e:
        print(f"An error occurred: {e}")
        return None

embeddings = generate_embeddings("Shoes for San Francisco summer")

if embeddings is not None:
    print(embeddings)

Funkce přebírá textový vstup , jako je popis produktu, a používá client.embeddings.create metodu z rozhraní OpenAI API k vygenerování vektoru vloženého pro tento text. Model zde používáme text-embedding-ada-002 , ale na základě vašich požadavků si můžete vybrat jiné modely. Pokud je proces úspěšný, vytiskne vygenerované vkládání; jinak zpracovává výjimky tiskem chybové zprávy.

3. Připojení a nastavení služby Cosmos DB pro virtuální jádro MongoDB

S připravenými vkládáními je dalším krokem uložení a indexování v databázi, která podporuje vyhledávání vektorové podobnosti. Virtuální jádro Azure Cosmos DB pro MongoDB je ideální pro tuto úlohu, protože je účel vytvořený k ukládání transakčních dat a provádění vektorového vyhledávání na jednom místě.

3.1 Nastavení připojení

Pro připojení ke službě Cosmos DB používáme knihovnu pymongo, která nám umožňuje snadno komunikovat s MongoDB. Následující fragment kódu vytvoří připojení k instanci virtuálního jádra Cosmos DB pro MongoDB:

import pymongo

# Replace <USERNAME>, <PASSWORD>, and <VCORE_CLUSTER_NAME> with your actual credentials and cluster name
mongo_conn = "mongodb+srv://<USERNAME>:<PASSWORD>@<VCORE_CLUSTER_NAME>.mongocluster.cosmos.azure.com/?tls=true&authMechanism=SCRAM-SHA-256&retrywrites=false&maxIdleTimeMS=120000"
mongo_client = pymongo.MongoClient(mongo_conn)

Nahraďte <USERNAME>a <PASSWORD><VCORE_CLUSTER_NAME> zadejte skutečné uživatelské jméno, heslo a název clusteru virtuálních jader MongoDB.

4. Nastavení indexu databáze a vektoru ve službě Cosmos DB

Jakmile vytvoříte připojení ke službě Azure Cosmos DB, další kroky zahrnují nastavení databáze a kolekce a následné vytvoření vektorového indexu, který umožní efektivní vyhledávání podobnosti vektorů. Pojďme si projít tyto kroky.

4.1 Nastavení databáze a kolekce

Nejprve vytvoříme databázi a kolekci v rámci instance Cosmos DB. Postupujte následovně:

DATABASE_NAME = "AdgenDatabase"
COLLECTION_NAME = "AdgenCollection"

mongo_client.drop_database(DATABASE_NAME)
db = mongo_client[DATABASE_NAME]
collection = db[COLLECTION_NAME]

if COLLECTION_NAME not in db.list_collection_names():
    # Creates a unsharded collection that uses the DBs shared throughput
    db.create_collection(COLLECTION_NAME)
    print("Created collection '{}'.\n".format(COLLECTION_NAME))
else:
    print("Using collection: '{}'.\n".format(COLLECTION_NAME))

4.2 Vytvoření vektorového indexu

Abychom mohli provádět efektivní hledání vektorové podobnosti v naší kolekci, musíme vytvořit vektorový index. Cosmos DB podporuje různé typy vektorových indexů a zde probereme dvě: IVF a HNSW.

IVF

IVF je zkratka pro invertovaný index souborů, je výchozí algoritmus indexování vektorů, který funguje na všech úrovních clusteru. Jedná se o přibližný přístup k nejbližším sousedům (ANN), který pomocí clusteringu urychlí hledání podobných vektorů v datové sadě. K vytvoření indexu IVF použijte následující příkaz:

db.command({
  'createIndexes': COLLECTION_NAME,
  'indexes': [
    {
      'name': 'vectorSearchIndex',
      'key': {
        "contentVector": "cosmosSearch"
      },
      'cosmosSearchOptions': {
        'kind': 'vector-ivf',
        'numLists': 1,
        'similarity': 'COS',
        'dimensions': 1536
      }
    }
  ]
});

Důležité

Pro vlastnost vektoru můžete vytvořit pouze jeden index. To znamená, že nelze vytvořit více než jeden index, který odkazuje na stejnou vektor vlastnost. Pokud chcete změnit typ indexu (např. z IVF na HNSW), musíte index před vytvořením nového indexu nejprve odstranit.

HNSW

HNSW je zkratka pro Hierarchical Navigable Small World, datovou strukturu založenou na grafech, která rozděluje vektory do clusterů a podkluzů. S HNSW můžete provádět rychlé přibližné hledání sousedů při vyšší rychlosti s větší přesností. HNSW je přibližná metoda (ANN). Tady je postup, jak ho nastavit:

db.command(
{ 
    "createIndexes": "ExampleCollection",
    "indexes": [
        {
            "name": "VectorSearchIndex",
            "key": {
                "contentVector": "cosmosSearch"
            },
            "cosmosSearchOptions": { 
                "kind": "vector-hnsw", 
                "m": 16, # default value 
                "efConstruction": 64, # default value 
                "similarity": "COS", 
                "dimensions": 1536
            } 
        } 
    ] 
}
)

Poznámka:

Indexování HNSW je k dispozici pouze na úrovních clusteru M40 a vyšších úrovních.

5. Vložení dat do kolekce

Teď vložte data inventáře, která obsahují popisy a jejich odpovídající vektorové vkládání, do nově vytvořené kolekce. K vložení dat do kolekce používáme metodu insert_many() pymongo , kterou poskytuje knihovna. Tato metoda nám umožňuje vložit více dokumentů do kolekce najednou. Naše data se ukládají do souboru JSON, který načteme a vložíme do databáze.

Stáhněte si soubor shoes_with_vectors.json z úložiště GitHub a uložte ho data do adresáře ve složce projektu.

data_file = open(file="./data/shoes_with_vectors.json", mode="r") 
data = json.load(data_file)
data_file.close()

result = collection.insert_many(data)

print(f"Number of data points added: {len(result.inserted_ids)}")

6. Vektorové vyhledávání ve službě Cosmos DB pro virtuální jádro MongoDB

Díky úspěšnému nahrání dat teď můžeme použít sílu vektorového vyhledávání a najít nejrelevavantnější položky na základě dotazu. Vektorový index, který jsme vytvořili dříve, nám umožňuje provádět sémantické vyhledávání v rámci naší datové sady.

Abychom mohli provést vektorové vyhledávání, definujeme funkci vector_search , která vezme dotaz a počet výsledků, které se mají vrátit. Funkce vygeneruje vektor dotazu pomocí generate_embeddings dříve definované funkce a pak pomocí funkcí Cosmos DB $search vyhledá nejbližší odpovídající položky na základě jejich vektorových vkládání.

# Function to assist with vector search
def vector_search(query, num_results=3):
    
    query_vector = generate_embeddings(query)

    embeddings_list = []
    pipeline = [
        {
            '$search': {
                "cosmosSearch": {
                    "vector": query_vector,
                    "numLists": 1,
                    "path": "contentVector",
                    "k": num_results
                },
                "returnStoredSource": True }},
        {'$project': { 'similarityScore': { '$meta': 'searchScore' }, 'document' : '$$ROOT' } }
    ]
    results = collection.aggregate(pipeline)
    return results

6.2 Provedení vektorových vyhledávacích dotazů

Nakonec spustíme naši funkci vektorového vyhledávání s konkrétním dotazem a výsledky zpracujeme, aby se zobrazily:

query = "Shoes for Seattle sweater weather"
results = vector_search(query, 3)

print("\nResults:\n")
for result in results: 
    print(f"Similarity Score: {result['similarityScore']}")  
    print(f"Title: {result['document']['name']}")  
    print(f"Price: {result['document']['price']}")  
    print(f"Material: {result['document']['material']}") 
    print(f"Image: {result['document']['img_url']}") 
    print(f"Purchase: {result['document']['purchase_url']}\n")

7. Generování obsahu reklamy pomocí GPT-4 a DALL. E

Kombinujeme všechny vyvinuté komponenty pro vytváření poutavých reklam, které využívají GPT-4 OpenAI pro text a DALL· E 3 pro obrázky. Společně s výsledky vektorového hledání tvoří kompletní reklamu. Představíme také Heelie, našeho inteligentního asistenta, který má za úkol vytvářet poutavé reklamní značky. V nadcházejícím kódu uvidíte Heelie v akci, což vylepšuje proces vytváření reklam.

from openai import OpenAI

def generate_ad_title(ad_topic):
    system_prompt = '''
    You are Heelie, an intelligent assistant for generating witty and cativating tagline for online advertisement.
        - The ad campaign taglines that you generate are short and typically under 100 characters.
    '''

    user_prompt = f'''Generate a catchy, witty, and short sentence (less than 100 characters) 
                    for an advertisement for selling shoes for {ad_topic}'''
    messages=[
        {"role": "system", "content": system_prompt},
        {"role": "user", "content": user_prompt},
    ]

    response = client.chat.completions.create(
        model="gpt-4",
        messages=messages
    )
    
    return response.choices[0].message.content

def generate_ad_image(ad_topic):
    daliClient = OpenAI(
        api_key="<DALI_API_KEY>"
    )

    image_prompt = f'''
        Generate a photorealistic image of an ad campaign for selling {ad_topic}. 
        The image should be clean, with the item being sold in the foreground with an easily identifiable landmark of the city in the background.
        The image should also try to depict the weather of the location for the time of the year mentioned.
        The image should not have any generated text overlay.
    '''

    response = daliClient.images.generate(
        model="dall-e-3",
        prompt= image_prompt,
        size="1024x1024",
        quality="standard",
        n=1,
        )

    return response.data[0].url

def render_html_page(ad_topic):

    # Find the matching shoes from the inventory
    results = vector_search(ad_topic, 4)
    
    ad_header = generate_ad_title(ad_topic)
    ad_image_url = generate_ad_image(ad_topic)


    with open('./data/ad-start.html', 'r', encoding='utf-8') as html_file:
        html_content = html_file.read()

    html_content += f'''<header>
            <h1>{ad_header}</h1>
        </header>'''    

    html_content += f'''
            <section class="ad">
            <img src="{ad_image_url}" alt="Base Ad Image" class="ad-image">
        </section>'''

    for result in results: 
        html_content += f''' 
        <section class="product">
            <img src="{result['document']['img_url']}" alt="{result['document']['name']}" class="product-image">
            <div class="product-details">
                <h3 class="product-title" color="gray">{result['document']['name']}</h2>
                <p class="product-price">{"$"+str(result['document']['price'])}</p>
                <p class="product-description">{result['document']['description']}</p>
                <a href="{result['document']['purchase_url']}" class="buy-now-button">Buy Now</a>
            </div>
        </section>
        '''

    html_content += '''</article>
                    </body>
                    </html>'''

    return html_content

8. Seskupování všech

K interaktivnímu generování reklam používáme Gradio, knihovnu Pythonu pro vytváření jednoduchých webových uživatelských rozhraní. Definujeme uživatelské rozhraní, které uživatelům umožňuje zadávat témata reklam a dynamicky generovat a zobrazovat výsledné reklamy.

import gradio as gr

css = """
    button { background-color: purple; color: red; }
    <style>
    </style>
"""

with gr.Blocks(css=css, theme=gr.themes.Default(spacing_size=gr.themes.sizes.spacing_sm, radius_size="none")) as demo:
    subject = gr.Textbox(placeholder="Ad Keywords", label="Prompt for Heelie!!")
    btn = gr.Button("Generate Ad")
    output_html = gr.HTML(label="Generated Ad HTML")

    btn.click(render_html_page, [subject], output_html)

    btn = gr.Button("Copy HTML")

if __name__ == "__main__":
    demo.launch()   

Výstup

Výstupní obrazovka

Další krok