Un développeur travaillant avec un LLM peut gérer simultanément différentes catégories d'informations:
- Entrée:informations directement pertinentes pour guider la réponse du LLM pour un appel particulier. Par exemple, le texte à résumer.
- Contexte de génération:informations pertinentes pour le LLM, mais non spécifiques à l'appel. Il peut s'agir, par exemple, de l'heure actuelle ou du nom d'un utilisateur.
- Contexte d'exécution:informations importantes pour le code entourant l'appel du LLM, mais pas pour le LLM lui-même. Par exemple, le jeton d'authentification actuel d'un utilisateur.
Genkit fournit un objet context
cohérent qui peut propager le contexte de génération et d'exécution tout au long du processus. Ce contexte est mis à la disposition de toutes les actions, y compris les flux, les outils et les invites.
Le contexte est automatiquement propagé à toutes les actions appelées dans le champ d'application de l'exécution: le contexte transmis à un flux est mis à la disposition des requêtes exécutées dans le flux. Le contexte transmis à la méthode generate()
est disponible pour les outils appelés dans la boucle de génération.
Pourquoi le contexte est-il important ?
Il est recommandé de fournir au LLM la quantité minimale d'informations dont il a besoin pour effectuer une tâche. Ce point est important pour plusieurs raisons:
- Moins le LLM dispose d'informations superflues, plus il est susceptible de bien accomplir sa tâche.
- Si un LLM doit transmettre des informations telles que des ID utilisateur ou de compte à des outils, il peut être piégé pour qu'il divulgue des informations.
Le contexte vous fournit un canal secondaire d'informations qui peut être utilisé par n'importe quel code, mais qui n'a pas nécessairement besoin d'être envoyé au LLM. Par exemple, il peut vous permettre de limiter les requêtes de l'outil au champ d'application disponible de l'utilisateur actuel.
Structure du contexte
Le contexte doit être un objet, mais vous pouvez choisir ses propriétés. Dans certains cas, Genkit renseigne automatiquement le contexte. Par exemple, lorsque vous utilisez des sessions persistantes, la propriété state
est automatiquement ajoutée au contexte.
L'une des utilisations les plus courantes du contexte consiste à stocker des informations sur l'utilisateur actuel. Nous vous recommandons d'ajouter le contexte d'authentification au format suivant:
{
auth: {
uid: "...", // the user's unique identifier
token: {...}, // the decoded claims of a user's id token
rawToken: "...", // the user's raw encoded id token
// ...any other fields
}
}
L'objet de contexte peut stocker toutes les informations dont vous pourriez avoir besoin ailleurs dans le flux d'exécution.
Utiliser le contexte dans une action
Pour utiliser le contexte dans une action, vous pouvez accéder à l'assistant de contexte fourni automatiquement à votre définition de fonction:
Flow
const summarizeHistory = ai.defineFlow({
name: 'summarizeMessages',
inputSchema: z.object({friendUid: z.string()}),
outputSchema: z.string();
}, async ({friendUid}, {context}) => {
if (!context.auth?.uid) throw new Error("Must supply auth context.");
const messages = await listMessagesBetween(friendUid, context.auth.uid);
const {text} = await ai.generate({
prompt:
`Summarize the content of these messages: ${JSON.stringify(messages)}`,
});
return text;
});
Outil
const searchNotes = ai.defineTool({
name: 'searchNotes',
description: "search the current user's notes for info",
inputSchema: z.object({query: z.string()}),
outputSchmea: z.array(NoteSchema);
}, async ({query}, {context}) => {
if (!context.auth?.uid) throw new Error("Must be called by a signed-in user.");
return searchUserNotes(context.auth.uid, query);
});
Fichier de requête
Lorsque vous utilisez des modèles Dotprompt, le contexte est mis à disposition avec le préfixe de variable @
. Par exemple, vous pouvez accéder à un objet de contexte {auth: {name: 'Michael'}}
dans le modèle d'invite comme suit:
---
input:
schema:
pirateStyle?: boolean
---
{{#if pirateStyle}}
Avast, {{@auth.name}}, how be ye today?
{{else}}
Hello, {{@auth.name}}, how are you today?
{{/if}}
Fournir du contexte lors de l'exécution
Pour fournir un contexte à une action, vous transmettez l'objet de contexte en tant qu'option lorsque vous appelez l'action.
Flux
const summarizeHistory = ai.defineFlow(/* ... */);
const summary = await summarizeHistory(friend.uid, {context: {auth: currentUser}});
Génération
const {text} = await ai.generate({
prompt: "Find references to ocelots in my notes.",
// the context will propagate to tool calls
tools: [searchNotes],
context: {auth: currentUser},
});
Requêtes
const helloPrompt = ai.prompt('sayHello');
helloPrompt({pirateStyle: true}, {context: {auth: currentUser}});
Propagation du contexte et forçages
Par défaut, lorsque vous fournissez un contexte, il est automatiquement propagé à toutes les actions appelées à la suite de votre appel d'origine. Si votre flux appelle d'autres flux ou vos outils d'appels de génération, le même contexte est fourni.
Si vous souhaitez remplacer le contexte dans une action, vous pouvez transmettre un objet de contexte différent pour remplacer l'objet existant:
const otherFlow = ai.defineFlow(/* ... */);
const myFlow = ai.defineFlow({
// ...
}, (input, {context}) => {
// override the existing context completely
otherFlow({/*...*/}, {context: {newContext: true}});
// or selectively override
otherFlow({/*...*/}, {context: {...context, updatedContext: true}});
});
Lorsque le contexte est remplacé, il se propage de la même manière. Dans cet exemple, toutes les actions appelées par otherFlow
lors de son exécution hériteraient du contexte ignoré.