Sercem generatywnej AI są modele AI. Obecnie 2 najbardziej znane przykłady modeli generatywnych to duże modele językowe (LLM) i modele generowania obrazów. Te modele przyjmują dane wejściowe, tzw. prompt (najczęściej tekst, obraz lub ich kombinację), a na ich podstawie generują tekst, obraz, a nawet dźwięk lub film.
Wyniki działania tych modeli mogą być zaskakująco przekonujące: duże modele językowe generują tekst, który wygląda tak, jakby został napisany przez człowieka, a modele do generowania obrazów mogą tworzyć obrazy bardzo zbliżone do prawdziwych zdjęć lub dzieł sztuki stworzonych przez ludzi.
Modele LLM sprawdzają się też w zajęciach innych niż proste generowanie tekstu:
- pisanie programów komputerowych;
- planowanie podzadań, które są wymagane do wykonania większego zadania;
- porządkowanie nieuporządkowanych danych;
- Interpretowanie i wyodrębnianie danych z korpusu tekstowego
- wykonywanie automatycznych czynności na podstawie tekstu opisującego te czynności;
Dostępnych jest wiele modeli od różnych dostawców. Każdy model ma swoje mocne i słabe strony. Jeden model może się świetnie sprawdzać w jednym zadaniu, ale gorzej w innym. Aplikacje korzystające z generatywnej AI często mogą korzystać z kilku różnych modeli w zależności od wykonywanego zadania.
Jako deweloper aplikacji zwykle nie wchodzisz w bezpośrednią interakcję z modelami generatywnej AI, ale korzystasz z usług dostępnych jako interfejsy API internetowe. Chociaż te usługi często mają podobne funkcje, wszystkie udostępniają je za pomocą różnych i niezgodnych interfejsów API. Jeśli chcesz korzystać z wielu usług modelowania, musisz używać ich zastrzeżonych pakietów SDK, które mogą być ze sobą niekompatybilne. Jeśli chcesz przejść z jednego modelu na najnowszy i najbardziej wydajny, być może trzeba będzie ponownie tworzyć tę integrację.
Genkit rozwiązuje to wyzwanie, udostępniając jeden interfejs, który ukrywa szczegóły dostępu do potencjalnie dowolnej usługi modelu generatywnej AI. Dostępne są już też różne wstępnie zaimplementowane rozwiązania. Budowanie aplikacji wykorzystującej AI na podstawie Genkit upraszcza proces wykonywania pierwszego wywołania generatywnej AI i ułatwia łączenie wielu modeli lub zastępowanie jednego modelu innym w miarę pojawiania się nowych modeli.
Zanim zaczniesz
Jeśli chcesz uruchomić przykłady kodu na tej stronie, najpierw wykonaj czynności opisane w przewodniku Początki. Wszystkie przykłady zakładają, że masz już zainstalowaną bibliotekę Genkit jako zależność w projekcie.
Modele obsługiwane przez Genkit
Genkit został zaprojektowany tak, aby był na tyle elastyczny, aby można było używać go z dowolną usługą generatywnej AI. Jej podstawowe biblioteki definiują wspólny interfejs do pracy z modelami, a wtyczki modela definiują szczegóły implementacji do pracy z konkretnym modelem i jego interfejsem API.
Zespół Genkit obsługuje wtyczki do pracy z modelami udostępnianymi przez Vertex AI, generatywną AI od Google i Ollama:
- rodzinę modeli LLM Gemini za pomocą wtyczki Google Cloud Vertex AI.
- rodzinę modeli LLM Gemini za pomocą wtyczki Google AI.
- modele generowania obrazów Imagen2 i Imagen3 w Google Cloud Vertex AI;
- rodzina modeli LLM Claude 3 firmy Anthropic, dostępna w Model Garden w Vertex AI od Google Cloud;
- Gemma 2, Llama 3 i wiele innych otwartych modeli za pomocą wtyczki Ollama (serwer Ollama musisz hostować samodzielnie).
Oprócz tego istnieje kilka wtyczek obsługiwanych przez społeczność, które zapewniają interfejsy dla tych modeli:
- rodzina modeli LLM Claude 3 za pomocą wtyczki Anthropic.
- rodzina modeli GPT LLM za pomocą wtyczki OpenAI.
- rodzina modeli LLM GPT za pomocą wtyczki Azure OpenAI.
- rodzina poleceń R LLM za pomocą wtyczki Cohere.
- rodzina modeli LLM Mistral w pliku plug-ina Mistral.
- Gemma 2, Llama 3 i wiele innych otwartych modeli hostowanych w Groq za pomocą wtyczki Groq
Więcej informacji znajdziesz na stronie npmjs.org, wyszukując pakiety oznaczone tagiem genkit-model
.
Wczytywanie i konfigurowanie wtyczek modeli
Zanim zaczniesz generować treści za pomocą Genkit, musisz załadować i skonfigurować wtyczkę modelu. Jeśli korzystasz z tego przewodnika po zapoznaniu się z poprzednim, masz już to za sobą. W przeciwnym razie zapoznaj się z poradnikiem Pierwsze kroki lub dokumentacją konkretnego wtyczki i wykonaj podane w niej instrukcje.
Metoda generate()
W Genkit głównym interfejsem, za pomocą którego można wchodzić w interakcje z modelami generatywnej AI, jest metoda generate()
.
Najprostsze wywołanie generate()
określa model, którego chcesz użyć, oraz prompt tekstowy:
import { gemini20Flash, googleAI } from '@genkit-ai/googleai';
import { genkit } from 'genkit';
const ai = genkit({
plugins: [googleAI()],
model: gemini20Flash, // Changed to gemini20Flash to match import
});
async function main() {
const { text } = await ai.generate(
'Invent a menu item for a pirate themed restaurant.'
);
console.log(text);
}
main();
Po wykonaniu tego krótkiego przykładu zostanie wydrukowana pewna ilość informacji debugujących, a następnie dane wyjściowe wywołania funkcji generate()
, które zwykle będą w formacie Markdown, jak w tym przykładzie:
## The Blackheart's Bounty
**A hearty stew of slow-cooked beef, spiced with rum and molasses, served in a
hollowed-out cannonball with a side of crusty bread and a dollop of tangy
pineapple salsa.**
**Description:** This dish is a tribute to the hearty meals enjoyed by pirates
on the high seas. The beef is tender and flavorful, infused with the warm spices
of rum and molasses. The pineapple salsa adds a touch of sweetness and acidity,
balancing the richness of the stew. The cannonball serving vessel adds a fun and
thematic touch, making this dish a perfect choice for any pirate-themed
adventure.
Uruchom ponownie skrypt, aby uzyskać inny wynik.
Poprzedni przykład kodu wysłał żądanie generowania do domyślnego modelu, który został określony podczas konfigurowania instancji Genkit.
Możesz też określić model dla pojedynczego wywołania funkcji generate()
:
const { text } = await ai.generate({
model: gemini15Pro,
prompt: 'Invent a menu item for a pirate themed restaurant.',
});
W tym przykładzie użyto funkcji odwołania do modelu udostępnionej przez wtyczkę modelu. Odwołania do modelu zawierają statyczne informacje o typie modelu i jego opcjach, które mogą być przydatne podczas uzupełniania kodu w IDE i w momencie kompilacji. Wiele wtyczek używa tego wzorca, ale nie wszystkie. Jeśli Twój wtyczka nie używa tego wzorca, zapoznaj się z jej dokumentacją, aby dowiedzieć się, jak najlepiej tworzyć odwołania do funkcji.
Czasami możesz zobaczyć przykłady kodu, w których odwołania do modelu są importowane jako stałe:
import { googleAI, gemini20Flash } from "@genkit-ai/googleai";
const ai = genkit({
plugins: [googleAI()],
model: gemini20Flash,
});
Niektóre wtyczki mogą nadal używać tego wzorca. W przypadku wtyczek, które zostały przełączone na nową składnię, te stałe są nadal dostępne i działają, ale nowe stałe dla nowych przyszłych modeli mogą nie zostać dodane w przyszłości.
Inną opcją jest określenie modelu za pomocą identyfikatora ciągu znaków. Ta funkcja będzie działać we wszystkich wtyczkach niezależnie od tego, jak obsługują one odwołania do typowanych modeli. Nie będziesz jednak mieć możliwości korzystania z statycznej kontroli typów:
const { text } = await ai.generate({
model: 'googleai/gemini-1.5-pro-latest',
prompt: 'Invent a menu item for a pirate themed restaurant.',
});
Identyfikator ciągu znaków modelu ma postać providerid/modelid
, gdzie identyfikator dostawcy (w tym przypadku googleai
) identyfikuje wtyczkę, a identyfikator modelu to identyfikator ciągu znaków specyficzny dla wtyczki dla konkretnej wersji modelu.
Niektóre wtyczki modeli, takie jak wtyczka Ollama, zapewniają dostęp do potencjalnie kilkudziesięciu różnych modeli, dlatego nie eksportują poszczególnych odwołań do modelu. W takich przypadkach możesz określić model dla atrybutu generate()
tylko za pomocą jego identyfikatora ciągu znaków.
Te przykłady pokazują też ważną kwestię: gdy używasz funkcji generate()
do wywoływania modeli generatywnej AI, zmiana modelu, którego chcesz użyć, polega po prostu na przekazaniu innej wartości parametrowi model. Korzystając z pakietu generate()
zamiast pakietu SDK natywnego modelu, zyskujesz elastyczność, która ułatwi Ci używanie w aplikacji kilku różnych modeli i zmianę modeli w przyszłości.
Do tej pory pokazaliśmy Ci tylko przykłady najprostszych wywołań generate()
. Jednak generate()
udostępnia też interfejs do bardziej zaawansowanych interakcji z modelami generacyjnymi, co opiszemy w następnych sekcjach.
Prompty systemowe
Niektóre modele obsługują prompt systemowy, który zawiera instrukcje dotyczące tego, jak model ma odpowiadać na wiadomości od użytkownika. Za pomocą prompta systemowego możesz określić personę, którą model ma przyjąć, ton jego odpowiedzi, format odpowiedzi itp.
Jeśli model, którego używasz, obsługuje prompty systemowe, możesz podać taki prompt za pomocą parametru system
:
const { text } = await ai.generate({
system: 'You are a food industry marketing consultant.',
prompt: 'Invent a menu item for a pirate themed restaurant.',
});
Parametry modelu
Funkcja generate()
przyjmuje parametr config
, za pomocą którego możesz określić opcjonalne ustawienia, które kontrolują sposób generowania treści przez model:
const { text } = await ai.generate({
prompt: 'Invent a menu item for a pirate themed restaurant.',
config: {
maxOutputTokens: 400,
stopSequences: ['<end>', '<fin>'],
temperature: 1.2,
topP: 0.4,
topK: 50,
},
});
Dokładne parametry, które są obsługiwane, zależą od modelu i od API. Parametry w poprzednim przykładzie są jednak wspólne dla niemal każdego modelu. Oto wyjaśnienie tych parametrów:
Parametry kontrolujące długość danych wyjściowych
maxOutputTokens
Duże modele językowe działają na jednostkach zwanych tokenami. Token zwykle, ale niekoniecznie, jest mapowany na określoną sekwencję znaków. Gdy przekazujesz prompt do modelu, jednym z pierwszych kroków jest tokowanie promptu na sekwencję tokenów. Następnie LLM generuje sekwencję tokenów na podstawie pofragmentowanego wejścia. Na koniec sekwencja tokenów jest ponownie konwertowana na tekst, który jest wyjściem.
Parametr maksymalna liczba tokenów wyjściowych określa po prostu, ile tokenów ma wygenerować LLM. Każdy model może używać innego tokenizera, ale dobrą regułą jest stosowanie zasady, że jedno słowo angielskie składa się z 2–4 tokenów.
Jak już wspomnieliśmy, niektóre tokeny mogą nie być mapowane na sekwencje znaków. Przykładem może być token wskazujący koniec sekwencji: gdy LLM wygeneruje ten token, przestaje generować kolejne. Dlatego możliwe i częste jest, że LLM generuje mniej tokenów niż maksymalna liczba, ponieważ wygenerował token „stop”.
stopSequences
Ten parametr umożliwia ustawienie tokenów lub sekwencji tokenów, które po wygenerowaniu wskazują koniec danych wyjściowych LLM. Prawidłowe wartości, których należy tu używać, zależą od sposobu trenowania modelu i zwykle są ustawiane przez wtyczkę modelu. Jeśli jednak model wygenerował inną sekwencję znaków stop, możesz ją tutaj podać.
Pamiętaj, że określasz ciągi znaków, a nie tokeny. W większości przypadków podajesz sekwencję znaków, którą model tokenizera mapuje na pojedynczy token.
Parametry, które kontrolują „kreatywność”
Parametry temperatura, górny p i górny k razem określają, na ile „kreatywny” ma być model. Poniżej znajdziesz krótkie wyjaśnienia znaczenia tych parametrów, ale ważniejsze jest to, że służą one do dostosowywania charakteru danych wyjściowych LLM. Ich optymalne wartości zależą od Twoich celów i preferencji i najprawdopodobniej można je znaleźć tylko przez eksperymentowanie.
temperatura
LLM to maszyny do przewidywania tokenów. W przypadku danej sekwencji tokenów (np. prompta) LLM przewiduje dla każdego tokena w swoim słowniku prawdopodobieństwo, że token będzie następny w sekwencji. Temperatura to współczynnik skalowania, przez który dzieli się te prognozy przed ich znormalizowaniem do prawdopodobieństwa w zakresie od 0 do 1.
Niska wartość temperatury (od 0,0 do 1,0) zwiększa różnicę w prawdopodobieństwie między tokenami, przez co model będzie jeszcze mniej skłonny do wygenerowania tokena, który został już oceniony jako mało prawdopodobny. Jest on często postrzegany jako mniej kreatywny. Chociaż 0,0 nie jest technicznie prawidłową wartością, wiele modeli interpretuje ją jako sygnał, że model powinien działać deterministycznie i uwzględniać tylko jeden najbardziej prawdopodobny token.
Wysokie wartości temperatury (czyli większe niż 1,0) powodują kompresję różnic w prawdopodobieństwie między tokenami, przez co model częściej generuje tokeny, które wcześniej zostały ocenione jako mało prawdopodobne. Jest ono często postrzegane jako bardziej kreatywne. Niektóre interfejsy API modeli narzucają maksymalną temperaturę, często 2,0.
topP
Top-p to wartość z zakresu od 0,0 do 1,0, która określa liczbę możliwych tokenów, które model ma wziąć pod uwagę, przez określenie skumulowanego prawdopodobieństwa tokenów. Na przykład wartość 1,0 oznacza, że należy wziąć pod uwagę wszystkie możliwe tokeny (ale nadal uwzględnić prawdopodobieństwo każdego z nich). Wartość 0,4 oznacza uwzględnianie tylko najbardziej prawdopodobnych tokenów, których prawdopodobieństwa dają w sumie 0,4, oraz wykluczanie pozostałych tokenów.
topK
Top-K to wartość całkowita, która również kontroluje liczbę możliwych tokenów, które model ma wziąć pod uwagę, ale tym razem poprzez jawne określenie maksymalnej liczby tokenów. Podanie wartości 1 oznacza, że model powinien zachowywać się deterministycznie.
Eksperymentowanie z parametrami modelu
Korzystając z interfejsu dla programistów, możesz eksperymentować z wpływem tych parametrów na dane wyjściowe generowane przez różne kombinacje modeli i promptów. Uruchom interfejs programisty za pomocą polecenia genkit start
. Automatycznie wczyta on wszystkie modele zdefiniowane przez wtyczki skonfigurowane w projekcie. Możesz szybko wypróbowywać różne prompty i wartości konfiguracji bez konieczności wielokrotnego wprowadzania tych zmian w kodzie.
Uporządkowane dane wyjściowe
Gdy używasz generatywnej AI jako komponentu w aplikacji, często chcesz uzyskać dane w innym formacie niż zwykły tekst. Nawet jeśli generujesz tylko treści do wyświetlenia użytkownikowi, możesz skorzystać z wyjścia ustrukturyzowanego, aby prezentować je w bardziej atrakcyjny sposób. W przypadku bardziej zaawansowanych zastosowań generatywnej AI, takich jak programowe wykorzystanie danych wyjściowych modelu lub podawanie danych wyjściowych jednego modelu innemu, konieczne jest uporządkowanie danych wyjściowych.
W Genkit możesz poprosić o uporządkowane dane wyjściowe z modelu, określając schemat podczas wywołania funkcji generate()
:
import { z } from 'genkit'; // Import Zod, which is re-exported by Genkit.
const MenuItemSchema = z.object({
name: z.string(),
description: z.string(),
calories: z.number(),
allergens: z.array(z.string()),
});
const { output } = await ai.generate({
prompt: 'Invent a menu item for a pirate themed restaurant.',
output: { schema: MenuItemSchema },
});
Schematy danych wyjściowych modelu są określane za pomocą biblioteki Zod. Oprócz języka definiowania schematów Zod zapewnia też sprawdzanie typu w czasie wykonywania, które łączy statyczne typy TypeScript z nieprzewidywalnymi wynikami generatywnych modeli AI. Zod umożliwia pisanie kodu, który może polegać na tym, że wywołanie generate zawsze zwróci dane wyjściowe zgodne z typami TypeScript.
Gdy określisz schemat w pliku generate()
, Genkit wykona kilka czynności w tle:
- Dodaje do promptu dodatkowe wskazówki dotyczące pożądanego formatu wyjściowego. Ma to też efekt uboczny w postaci określenia dla modelu, jakie dokładnie treści chcesz generować (np. nie tylko sugerować pozycję menu, ale też generować jej opis, listę alergenów itp.).
- Parsuje dane wyjściowe modelu na obiekt JavaScript.
- Sprawdza, czy dane wyjściowe są zgodne ze schematem.
Aby uzyskać ustrukturyzowany wynik po pomyślnym wywołaniu metody generate, użyj właściwości output
obiektu odpowiedzi:
if (output) {
const { name, description, calories, allergens } = output;
}
Obsługa błędów
W poprzednim przykładzie właściwość output
może mieć wartość null
. Może się tak zdarzyć, gdy model nie wygeneruje danych wyjściowych zgodnych ze schematem.
Najlepsza strategia radzenia sobie z takimi błędami zależy od konkretnego przypadku użycia, ale oto kilka ogólnych wskazówek:
Wypróbuj inny model. Aby dane uporządkowane były generowane prawidłowo, model musi być w stanie generować dane w formacie JSON. Najpotężniejsze modele LLM, takie jak Gemini i Claude, są wystarczająco wszechstronne, aby to zrobić. Mniejsze modele, takie jak niektóre modele lokalne, których używasz z Ollama, mogą natomiast nie być w stanie niezawodnie generować danych wyjściowych w formie uporządkowanej, chyba że zostały specjalnie wytrenowane do tego celu.
Korzystanie z możliwości wymuszania: w swoich schematach możesz określić, że Zod powinien próbować wymuszać niespełniające wymagań typy na typ określony w schemacie. Jeśli Twój schemat zawiera typy proste inne niż ciągi tekstowe, użycie narzucenia typu może zmniejszyć liczbę niepowodzeń
generate()
. W tej wersji funkcjiMenuItemSchema
dopasowanie typu służy do automatycznego korygowania sytuacji, w których model generuje informacje o kalorii jako ciąg znaków zamiast liczby:const MenuItemSchema = z.object({ name: z.string(), description: z.string(), calories: z.coerce.number(), allergens: z.array(z.string()), });
Ponownie wywołaj generate(). Jeśli wybrany model tylko sporadycznie nie generuje zgodnego z standardami wyjścia, możesz traktować ten błąd jak błąd sieci i po prostu ponownie wysłać żądanie, stosując pewną strategię stopniowego wycofywania.
Streaming
Podczas generowania dużych ilości tekstu możesz ułatwić użytkownikom korzystanie z usługi, prezentując wyniki w miarę ich generowania (przesyłając je strumieniowo). Znajomy przykład strumieniowego przesyłania danych można zobaczyć w większości aplikacji do czatu z wykorzystaniem LLM: użytkownicy mogą czytać odpowiedzi modelu na ich wiadomości w miarę ich generowania, co zwiększa postrzeganą szybkość reakcji aplikacji i wzmacnia iluzję czatu z inteligentnym rozmówcą.
W Genkit możesz przesyłać dane wyjściowe strumieniowo za pomocą metody generateStream()
. Jej składnia jest podobna do metody generate()
:
const { response, stream } = await ai.generateStream(
'Suggest a complete menu for a pirate themed restaurant.'
);
Obiekt odpowiedzi ma właściwość stream
, której możesz użyć do iterowania po wyjściu strumieniowym żądania w miarę jego generowania:
for await (const chunk of stream) {
console.log(chunk.text);
}
Podobnie jak w przypadku żądania niestrumieniowego, możesz też uzyskać pełny wynik:
const completeText = (await response).text;
Transmisja strumieniowa działa też w przypadku danych uporządkowanych:
const MenuSchema = z.object({
starters: z.array(MenuItemSchema),
mains: z.array(MenuItemSchema),
desserts: z.array(MenuItemSchema),
});
const { response, stream } = await ai.generateStream({
prompt: 'Suggest a complete menu for a pirate themed restaurant.',
output: { schema: MenuSchema },
});
for await (const chunk of stream) {
// `output` is an object representing the entire output so far.
console.log(chunk.output);
}
// Get the completed output.
const { output } = await response;
Strumieniowe generowanie danych ustrukturyzowanych działa nieco inaczej niż strumieniowe generowanie tekstu: właściwość output
elementu odpowiedzi to obiekt utworzony z dotychczas wygenerowanych elementów, a nie obiekt reprezentujący pojedynczy element (który może być nieprawidłowy sam w sobie). Każdy fragment danych uporządkowanych w jakimś sensie zastępuje poprzedni fragment.
Oto przykład pierwszych 5 wyników z poprzedniego przykładu:
null
{ starters: [ {} ] }
{
starters: [ { name: "Captain's Treasure Chest", description: 'A' } ]
}
{
starters: [
{
name: "Captain's Treasure Chest",
description: 'A mix of spiced nuts, olives, and marinated cheese served in a treasure chest.',
calories: 350
}
]
}
{
starters: [
{
name: "Captain's Treasure Chest",
description: 'A mix of spiced nuts, olives, and marinated cheese served in a treasure chest.',
calories: 350,
allergens: [Array]
},
{ name: 'Shipwreck Salad', description: 'Fresh' }
]
}
Dane multimodalne
W przykładach, które do tej pory widzisz, jako prompty modelu użyto ciągów tekstowych. Chociaż jest to najczęstszy sposób inicjowania modeli generatywnej AI, wiele modeli może też akceptować inne media jako prompty. Prompty multimedialne są najczęściej używane w połączeniu z promptami tekstowymi, które instruują model do wykonania pewnych operacji na mediach, takich jak dodanie podpisu do obrazu lub transkrypcja nagrania audio.
Możliwość akceptowania danych wejściowych w formie multimediów oraz typy multimediów, których możesz używać, zależą całkowicie od modelu i jego interfejsu API. Na przykład seria modeli Gemini 1.5 może akceptować obrazy, filmy i dźwięk jako prompty.
Aby przekazać prompt multimedialny do modelu, który go obsługuje, zamiast przekazywać do generate
prosty tekstowy prompt, prześlij tablicę zawierającą część multimedialną i tekstową:
const { text } = await ai.generate([
{ media: { url: 'https://example.com/photo.jpg' } },
{ text: 'Compose a poem about this image.' },
]);
W przykładzie powyżej obraz został wskazany za pomocą publicznie dostępnego adresu URL HTTPS. Możesz też przesłać dane multimedialne bezpośrednio, kodując je jako adres URL danych. Przykład:
import { readFile } from 'node:fs/promises';
const b64Data = await readFile('photo.jpg', { encoding: 'base64url' });
const dataUrl = `data:image/jpeg;base64,${b64Data}`;
const { text } = await ai.generate([
{ media: { url: dataUrl } },
{ text: 'Compose a poem about this image.' },
]);
Wszystkie modele, które obsługują dane wejściowe, obsługują zarówno adresy URL danych, jak i adresy URL HTTPS. Niektóre wtyczki do modeli dodają obsługę innych źródeł multimediów. Na przykład wtyczka Vertex AI umożliwia też używanie adresów URL Cloud Storage (gs://
).
Generowanie multimediów
Do tej pory większość przykładów na tej stronie dotyczyła generowania tekstu za pomocą modeli LLM. Genkit może jednak służyć też do tworzenia modeli generowania obrazów. Korzystanie z modelu generowania obrazów za pomocą funkcji generate()
jest podobne do korzystania z modelu LLM. Aby na przykład wygenerować obraz za pomocą modelu Imagen2 w Vertex AI:
Genkit używa adresów URL
data:
jako standardowego formatu wyjściowego wygenerowanych multimediów. Jest to standardowy format, który obsługuje wiele bibliotek. W tym przykładzie użyto pakietudata-urls
z poziomujsdom
:npm i --save data-urls
npm i --save-dev @types/data-urls
Aby wygenerować obraz i zapisać go w pliku, wywołaj funkcję
generate()
, podając model generowania obrazu i typ multimediów w formacie wyjściowym:import { imagen3Fast, vertexAI } from '@genkit-ai/vertexai'; import parseDataURL from 'data-urls'; import { genkit } from 'genkit'; import { writeFile } from 'node:fs/promises'; const ai = genkit({ plugins: [vertexAI({ location: 'us-central1' })], }); async function main() { const { media } = await ai.generate({ model: imagen3Fast, prompt: 'photo of a meal fit for a pirate', output: { format: 'media' }, }); if (media === null) throw new Error('No media generated.'); const data = parseDataURL(media.url); if (data === null) throw new Error('Invalid "data:" URL.'); await writeFile(`output.${data.mimeType.subtype}`, data.body); } main();
Dalsze kroki
Więcej informacji o Genkit
- Jako deweloper aplikacji możesz wpływać na wyniki generatywnej AI głównie za pomocą promptów. Aby dowiedzieć się, jak Genkit pomaga tworzyć skuteczne prompty i zarządzać nimi w kodzie źródłowym, przeczytaj artykuł Zarządzanie promptami.
- Chociaż
generate()
jest jądrem każdej aplikacji korzystającej z generatywnej AI, aplikacje używane w praktyce zwykle wymagają dodatkowej pracy przed wywołaniem modelu generatywnej AI i po jego wywołaniu. W związku z tym Genkit wprowadza pojęcie przepływów, które są definiowane jak funkcje, ale zawierają dodatkowe funkcje, takie jak możliwość obserwacji i uproszczone wdrażanie. Więcej informacji znajdziesz w artykule Definiowanie przepływów pracy.
Zaawansowane korzystanie z modeli LLM
- Jedną z możliwości rozszerzenia możliwości LLM jest wyświetlenie użytkownikowi listy sposobów, w jaki LLM może poprosić o dodatkowe informacje, lub prośba o wykonanie jakiegoś działania. Jest to tzw. wywoływanie narzędzia lub wywoływanie funkcji. Modele, które zostały wytrenowane pod kątem obsługi tej funkcji, mogą odpowiadać na prompty specjalnymi odpowiedziami, które wskazują aplikacji wywołującej, że powinna wykonać określone działanie i odesłać wynik z powrotem do LLM wraz z pierwotnym promptem. Genkit zawiera funkcje biblioteki, które automatyzują generowanie promptów i elementy pętli wywołania–odpowiedzi w ramach implementacji wywołania narzędzia. Aby dowiedzieć się więcej, zapoznaj się z artykułem Wywoływanie narzędzi.
- Generowanie rozszerzone przez wyszukiwanie w zapisanych informacjach (RAG) to technika służąca do wprowadzania informacji dotyczących danej domeny do danych wyjściowych modelu. Polega to na wstawianiu odpowiednich informacji do promptu przed przekazaniem go do modelu językowego. Pełne wdrożenie RAG wymaga połączenia kilku technologii: modeli generowania wektorów dystrybucyjnych, baz danych wektorów i dużych modeli językowych. Zapoznaj się z artykułem Generowanie rozszerzone przez wyszukiwanie w zapisanych informacjach (RAG), aby dowiedzieć się, jak Genkit upraszcza proces koordynowania tych różnych elementów.
Testowanie danych wyjściowych modelu
Jako inżynier oprogramowania jesteś przyzwyczajony do systemów deterministycznych, w których ten sam rodzaj danych wejściowych zawsze daje ten sam wynik. Jednak modele AI są probabilistyczne, więc wyniki mogą się różnić w zależności od subtelnych niuansów danych wejściowych, danych treningowych modelu, a nawet losowości celowo wprowadzanej przez parametry takie jak temperatura.
Oceniacze Genkit mają strukturyzowane sposoby oceny jakości odpowiedzi LLM za pomocą różnych strategii. Więcej informacji znajdziesz na stronie Ocena.