Existen diferentes categorías de información que un desarrollador que trabaja con un LLM puede controlar de forma simultánea:
- Entrada: Es la información que es directamente relevante para guiar la respuesta del LLM para una llamada en particular. Un ejemplo de esto es el texto que se debe resumir.
- Contexto de generación: Es la información que es relevante para el LLM, pero que no es específica de la llamada. Un ejemplo de esto es la hora actual o el nombre de un usuario.
- Contexto de ejecución: Es la información que es importante para el código que rodea la llamada al LLM, pero no para el LLM en sí. Un ejemplo de esto es el token de autenticación actual de un usuario.
Genkit proporciona un objeto context
coherente que puede propagar el contexto de generación y ejecución durante todo el proceso. Este contexto está disponible para todas las acciones, incluidos los flujos, las herramientas y los mensajes.
El contexto se propaga automáticamente a todas las acciones a las que se llama dentro del alcance de la ejecución: el contexto que se pasa a un flujo está disponible para las instrucciones que se ejecutan dentro del flujo. El contexto que se pasa al método generate()
está disponible para las herramientas que se llaman dentro del bucle de generación.
¿Por qué es importante el contexto?
Como práctica recomendada, debes proporcionarle al LLM la cantidad mínima de información que necesita para completar una tarea. Esto es importante por varios motivos:
- Cuanto menos información irrelevante tenga el LLM, es más probable que realice bien su tarea.
- Si un LLM necesita pasar información, como IDs de usuario o de cuenta, a las herramientas, es posible que se engañe para que filtre información.
El contexto te brinda un canal lateral de información que puede usar cualquiera de tus códigos, pero que no necesariamente se debe enviar al LLM. Por ejemplo, puede permitirte restringir las consultas de la herramienta al alcance disponible del usuario actual.
Estructura del contexto
El contexto debe ser un objeto, pero tú decides cuáles son sus propiedades. En algunas situaciones, Genkit propaga automáticamente el contexto. Por ejemplo, cuando usas sesiones persistentes, la propiedad state
se agrega automáticamente al contexto.
Uno de los usos más comunes del contexto es almacenar información sobre el usuario actual. Te recomendamos que agregues el contexto de autenticación en el siguiente formato:
{
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
}
}
El objeto de contexto puede almacenar cualquier información que necesites saber en otro lugar del flujo de ejecución.
Cómo usar el contexto en una acción
Para usar el contexto dentro de una acción, puedes acceder al asistente de contexto que se proporciona automáticamente a la definición de tu función:
Flujo
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;
});
Herramienta
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);
});
Archivo de la instrucción
Cuando se usan plantillas de Dotprompt, el contexto está disponible con el prefijo de variable @
. Por ejemplo, se podría acceder a un objeto de contexto de {auth: {name: 'Michael'}}
en la plantilla de instrucción de la siguiente manera:
---
input:
schema:
pirateStyle?: boolean
---
{{#if pirateStyle}}
Avast, {{@auth.name}}, how be ye today?
{{else}}
Hello, {{@auth.name}}, how are you today?
{{/if}}
Proporciona contexto durante el tiempo de ejecución
Para proporcionar contexto a una acción, pasas el objeto de contexto como una opción cuando llamas a la acción.
Flows
const summarizeHistory = ai.defineFlow(/* ... */);
const summary = await summarizeHistory(friend.uid, {context: {auth: currentUser}});
Generación
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},
});
Instrucciones
const helloPrompt = ai.prompt('sayHello');
helloPrompt({pirateStyle: true}, {context: {auth: currentUser}});
Anulaciones y propagación de contexto
De forma predeterminada, cuando proporcionas contexto, este se propaga automáticamente a todas las acciones a las que se llama como resultado de tu llamada original. Si tu flujo llama a otros flujos o si tu generación llama a herramientas, se proporciona el mismo contexto.
Si deseas anular el contexto dentro de una acción, puedes pasar un objeto de contexto diferente para reemplazar el existente:
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}});
});
Cuando se reemplaza el contexto, se propaga de la misma manera. En este ejemplo, cualquier acción a la que otherFlow
llamó durante su ejecución heredaría el contexto anulado.