Skip to content

AI Základní integrace AI do VENFT App

Štefan Prokop edited this page Apr 4, 2023 · 2 revisions

Tento článek vznikl, aby ukázal, jak snadné to je, když jde člověku o využití OpenAI jen pro jeden konkrétní úkol. I když je aktuální verze integrace zatím velmi zjednodušená, stojí za to se tomu věnovat už nyní. V rámci VENFT App se totiž postupně budou funkcionality rozrůstat, což může způsobit menší přehlednost, než jako je tomu ve fázi, kdy píšu tento článek.

V rámci tohoto článku bylo popsáno, co jsou základní funkce VirtualAssistant.cs třídy a jak ji lze použít pro generování obsahu NFT. Článek, který právě čtete, na něj navazuje a ukazuje, jak tyto základní funkce integrovat do VEBlazor knihovny, tedy i do nové VENFT App.

V prvním kroku je potřeba doplnit do projektu VEBlazor referenci pro projekt VEDriversLite.AI.OpenAI.

obrazek

obrazek

Následně je potřeba přidat do AppData.cs Assistenta a ukládání + načítání klíče.

using VEDriversLite.AI.OpenAI;

public VirtualAssistant? Assistant { get; set; } = null;

public async Task<bool> InitAssistant(string apikey = "")
{
    if (!IsAccountLoaded)
        return false;

    if (string.IsNullOrEmpty(apikey))
        apikey = await GetAndDecryptOpenAIApiKey();

    if (!string.IsNullOrEmpty(apikey))
    {
        Assistant = new VirtualAssistant(apikey);
        if ((await Assistant.InitAssistant()).Item1)
        {
            if (await EncryptAndStoreOpenAIApiKey(apikey))
                return true;
        }
        else
            Assistant = null;
    }

    return false;
}

Pokud funkci pro inicializaci nezadám apikey, tak zkusí tento příkaz najít v paměti. Pokud funkci tento příkaz zadám, bere ho jako novou aktualizaci klíče, který uloží do paměti.

Funkce pro inicializaci je přidaná ve volání UnlockAccount funkce.

Následující funkce obsluhují uložení/načtení API klíče, který je potřeba před uložením zašifrovat. Klíč se v zašifrované podobě ukládá do local paměti browseru.

public async Task<bool> EncryptAndStoreOpenAIApiKey(string apikey = "")
{
    if (!IsAccountLoaded)
        return false;

    if (!string.IsNullOrEmpty(apikey))
    {
        var res = SymetricProvider.EncryptString(Account.Secret.ToString(), apikey);
        if (!string.IsNullOrEmpty(res))
        {
            await localStorage.SetItemAsStringAsync("OpenAIapiKey", res);
            return true;
        }
    }

    return false;
}

public async Task<string?> GetAndDecryptOpenAIApiKey()
{
    if (!IsAccountLoaded)
        return null;

    var OAIapikey = await localStorage.GetItemAsync<string>("OpenAIapiKey");
    if (string.IsNullOrEmpty(OAIapikey))
        return null;
    else
    {
        var res = SymetricProvider.DecryptString(Account.Secret.ToString(), OAIapikey);
        if (!string.IsNullOrEmpty(res))
            return res;
        else
            return null;
    }
}

Dalším krokem bylo vytvoření komponenty pro nastavení API klíče. Ta se nachází zde. V rámci komponenty se volají jednotlivé (výše uvedené) funkce. Po startu se zavolá GetAndDecryptOpenAIApiKey a v případě, kdy uživatel klikne na Save, se zavolá funkce pro uložení klíče.

Tuto komponentu wrapuje komponenta AccountSettings.razor, která je vložená do AccountSider.razor.

obrazek

Další komponenta slouží k vytvoření základního textu pro NFT. Jedná se o komponentu CreateTextByAIButton.razor.

V rámci této komponenty uživatel vyplní základní text, podle kterého se vygeneruje texto pro NFT.Text pole.

obrazek

Volání asistenta obsluhuje funkce CreateTextAction.

@inject AppData AppData

async Task CreateTextAction()
{
    Creating = true;
    await InvokeAsync(StateHasChanged);

    if (NotificationService != null)
        await NotificationService.Info("Createing text...", "AI working");

    var baset = "Vytvoř prosím krátký článek o " + BaseText + ". Výstup bude Markdown.";

    if (AppData.Assistant != null)
        Result = await AppData.Assistant.SendSimpleQuestion( baset , 750);

    if (NotificationService != null)
    {
        if (Result.Item1)
            await NotificationService.Success("Text creation was successfull.", "Success");
        else
            await NotificationService.Warning(Result.Item2, "Cannot create text");
    }
    await InvokeAsync(StateHasChanged);

    if (Result.Item1)
        await TextCreated.InvokeAsync(Result.Item2);

    //close automatically after 2 seconds
    await Task.Delay(2000);
    HideModal();

}

Funkce pro vygenerování názvu, popisu a tagů NFT je umístěna v rámci komponenty DataInfoForm.razor a to formou jednoduchého tlačítka s obslužnou funkcí CreateDescriptionForNFT:

obrazek

AI potřebuje chvíli na zpracování, nicméně po stisku tohoto tlačítka přijde odpověď a automaticky se vyplní pole pro Name, Tags a Description:

obrazek

Funkce CreateDescriptionForNFT je zde:

public async Task CreateDescriptionForNFT()
{
    if (string.IsNullOrEmpty(NFT.Text))
    {
        if (NotificationService != null)
            await NotificationService.Error("Cannot create NFT Info without filled Text field.", "Fill the Text field");

        return;
    }

    if (AppData.Assistant != null)
    {
        creatingDescription = true;
        await InvokeAsync(StateHasChanged);

        if (NotificationService != null)
            await NotificationService.Info("Createing NFT Name, Description and Tags...", "AI working");

        var res = await AppData.Assistant.GetNewDataForNFT(NFT.Text);
        if (res.Item1)
        {
            if (NotificationService != null)
                await NotificationService.Success("NFT info created...", "Done");

            NFT.Name = res.Item2.Name;
            NFT.Description = res.Item2.Description;
            NFT.Tags = res.Item2.Tags;
            await InvokeAsync(StateHasChanged);
        }
        else
        {
            if (NotificationService != null)
                await NotificationService.Error("Cannot create NFT Info.", "Error");
        }

        creatingDescription = false;
        await InvokeAsync(StateHasChanged);

    }
    else
    {
        if (NotificationService != null)
            await NotificationService.Warning("Cannot use AI without setup of OpenAI API Key. Please fill it in the profile tab in settings.", "OpenAI API Key missing");
    }
}

Funkce zkontroluje, jestli je v NFT.Text nějaký obsah - pokud ano, pošle ho do AI Assistenta, aby se vytvořil pro NFT název, popis a tagy. Ty pak vloží do NFT. Doporučuji prozkoumat i to, jakým způsobem se VirtualAssistant.cs baví s ChatGPT. V případě generování info pro NFT je totiž poslán i požadavek na to, aby ChatGPT vrátil zpět přímo JSON, který se pak celkem jednoduše rozparsuje.

Poslední část integrace se odehrává v sekci obrázků. OpenAI má k dispozici přes API DALL-E-2 modul. Tato AI je využita pro automatické generování obrázků pro NFT. Integrace proběhla do komponenty UploadData.razor. Zde přibylo nové tlačítko a obslužná funkce CreateImageForNFT. Protože je tato funkce je celkem dlouhá a obsáhlá, v tomto článku ji zkopírovanou nenajdete. Její hlubší popis je ale již v tomto článku, který si určitě také přečtěte, pokud vás funkce, jako je tato, zajímají.

Generování obrázků potřebuje vyplněný Název, Tagy a nebo Description. Ideálně by mělo být vyplněné vše. Výsledek vypadá následovně:

obrazek

Vygenerovaný obrázek se po chvíli čekání objeví v galerii:

obrazek

Možná si při generování obrázků všimnete, že má AI trochu smysl pro černý humor. :D Nicméně v případech, kdy se Vám obrázek nelíbí, je možné nechat si vygenerovat více variant a ostatní poté smazat (nebo si můžete nechat všechny). Jen je potřeba zvolit, která varianta bude hlavní. Takto to vypadá, když se vygeneruje víc návrhů obrázků. (Je vidět i celkem dobrý progres.):

obrazek

Celé vygenerované NFT pomocí AI vypadá následovně:

obrazek

Pomocí tlačítka "Finish" můžete NFT vymintovat:

obrazek

Po vymintování je již vidět v galerii:

obrazek

Je možné si prohlédnout i detail včetně všech obrázků:

obrazek

Zde je odkaz na Blockchain transakci. Nelekejte se zobrazní textu - Neblio explorer nepodporuje češtinu. Nicméně jak je vidět výše, v aplikacích kolem VEFramework je možné využívat češtinu bez (známých) problémů.

Postupně budou funkce AI rozšiřovány. :)

Clone this wiki locally