Wielu użytkowników po raz pierwszy będzie korzystać z dużych modeli językowych za pomocą chatbotów. Duże modele językowe mogą robić znacznie więcej niż tylko symulować rozmowy, ale nadal są to znajome i przydatne style interakcji. Nawet jeśli użytkownicy nie będą w ten sposób bezpośrednio wchodzić w interakcję z modelem, konwersacyjny styl promptów to skuteczny sposób na wpływanie na wyniki generowane przez model AI.
Aby umożliwić tego typu interakcje, Genkit udostępnia zestaw interfejsów i abstrakcji, które ułatwiają tworzenie aplikacji LLM opartych na czacie.
Zanim zaczniesz
Zanim zaczniesz czytać tę stronę, zapoznaj się z treściami na stronie Generowanie treści za pomocą modeli AI.
Jeśli chcesz uruchomić przykłady kodu na tej stronie, najpierw wykonaj czynności opisane w przewodniku Początki. We wszystkich przykładach zakładamy, że masz już zainstalowaną bibliotekę Genkit jako zależność w projekcie.
Pamiętaj, że interfejs API czatu jest obecnie w wersji beta i należy go używać z pakietu genkit/beta
.
Podstawy sesji czatu
Oto minimalna aplikacja chatbota działająca w konsoli:
import { genkit } from "genkit/beta";
import { googleAI, gemini15Flash } from "@genkit-ai/googleai";
import { createInterface } from "node:readline/promises";
const ai = genkit({
plugins: [googleAI()],
model: gemini15Flash,
});
(async () => {
const chat = ai.chat();
console.log("You're chatting with Gemini. Ctrl-C to quit.\n");
const readline = createInterface(process.stdin, process.stdout);
while (true) {
const userInput = await readline.question("> ");
const { text } = await chat.send(userInput);
console.log(text);
}
})();
Sesja czatu z tym programem wygląda mniej więcej tak:
You're chatting with Gemini. Ctrl-C to quit.
> hi
Hi there! How can I help you today?
> my name is pavel
Nice to meet you, Pavel! What can I do for you today?
> what's my name?
Your name is Pavel! I remembered it from our previous interaction.
Is there anything else I can help you with?
Jak widać na przykładzie tej krótkiej rozmowy, gdy wysyłasz wiadomość w sesji czatu, model może wykorzystać w swoich odpowiedziach informacje z dotychczasowej części sesji. Jest to możliwe, ponieważ Genkit wykonuje kilka czynności w tle:
- Pobiera historię czatu (jeśli istnieje) z miejsca na dane (więcej informacji o trwałości i miejscu na dane znajdziesz poniżej).
- Wysyła żądanie do modelu, tak jak w przypadku
generate()
, ale automatycznie uwzględnia historię czatu. - Zapisywanie odpowiedzi modelu w historii czatu
Konfiguracja modelu
Metoda chat()
akceptuje większość tych samych opcji konfiguracji co metoda generate()
. Aby przekazać opcje konfiguracji do modelu:
const chat = ai.chat({
model: gemini15Pro,
system:
"You're a pirate first mate. Address the user as Captain and assist " +
"them however you can.",
config: {
temperature: 1.3,
},
});
Sesje czatu stanowego
Oprócz trwałego przechowywania historii wiadomości z sesji czatu możesz też przechowywać dowolny obiekt JavaScript. Dzięki temu możesz zarządzać stanem w bardziej uporządkowany sposób niż tylko na podstawie informacji w historii wiadomości.
Aby uwzględnić stan w sesji, musisz jawnie utworzyć instancję sesji:
interface MyState {
userName: string;
}
const session = ai.createSession<MyState>({
initialState: {
userName: 'Pavel',
},
});
Następnie możesz rozpocząć czat w sesji:
const chat = session.chat();
Aby zmienić stan sesji na podstawie przebiegu czatu, zdefiniuj narzędzia i uwzględnij je w swoich żądaniach:
const changeUserName = ai.defineTool(
{
name: 'changeUserName',
description: 'can be used to change user name',
inputSchema: z.object({
newUserName: z.string(),
}),
},
async (input) => {
await ai.currentSession<MyState>().updateState({
userName: input.newUserName,
});
return `changed username to ${input.newUserName}`;
}
);
const chat = session.chat({
model: gemini15Pro,
tools: [changeUserName],
});
await chat.send('change user name to Kevin');
Sesje wielowątkowe
Jedna sesja może zawierać wiele wątków czatu. Każdy wątek ma własną historię wiadomości, ale wszystkie wątki mają ten sam stan sesji.
const lawyerChat = session.chat('lawyerThread', {
system: 'talk like a lawyer',
});
const pirateChat = session.chat('pirateThread', {
system: 'talk like a pirate',
});
Sesja trwała (FUNKCJA EKSPERYMENTALNA)
Gdy inicjujesz nowy czat lub sesję, sesja jest domyślnie przechowywana tylko w pamięci. Jest to odpowiednie rozwiązanie, gdy sesja musi być zachowana tylko na czas wywołania programu, tak jak w przypadku przykładowego chatbota na początku tej strony. Jednak podczas integrowania czatu LLM z aplikacją zwykle wdrażasz logikę generowania treści jako punkty końcowe interfejsu API w sieci bezstanowej. Aby trwałe czaty działały w ramach tej konfiguracji, musisz wdrożyć rodzaj pamięci sesji, który może zachować stan na różnych punktach końcowych.
Aby dodać trwałość do sesji czatu, musisz zaimplementować interfejs GenkitSessionStore
. Oto przykładowa implementacja, która zapisuje stan sesji w poszczególnych plikach JSON:
class JsonSessionStore<S = any> implements SessionStore<S> {
async get(sessionId: string): Promise<SessionData<S> | undefined> {
try {
const s = await readFile(`${sessionId}.json`, { encoding: 'utf8' });
const data = JSON.parse(s);
return data;
} catch {
return undefined;
}
}
async save(sessionId: string, sessionData: SessionData<S>): Promise<void> {
const s = JSON.stringify(sessionData);
await writeFile(`${sessionId}.json`, s, { encoding: 'utf8' });
}
}
To rozwiązanie prawdopodobnie nie nadaje się do praktycznego wdrożenia, ale pokazuje, że implementacja pamięci sesji musi realizować tylko 2 zadania:
- Pobieranie obiektu sesji z miejsca na dane za pomocą identyfikatora sesji
- Zapisz dany obiekt sesji, posortowany według identyfikatora sesji
Po zaimplementowaniu interfejsu dla backendu pamięci masowej prześlij instancję swojej implementacji do konstruktorów sesji:
// To create a new session:
const session = ai.createSession({
store: new JsonSessionStore(),
});
// Save session.id so you can restore the session the next time the
// user makes a request.
// If the user has a session ID saved, load the session instead of creating
// a new one:
const session = await ai.loadSession(sessionId, {
store: new JsonSessionStore(),
});