Genkit 0.9 presenta una serie de cambios rotundos junto con mejoras de funciones que mejoran la funcionalidad general. Si desarrollaste aplicaciones con Genkit 0.5, deberás actualizar el código de la aplicación cuando realices la actualización a la versión más reciente. En esta guía, se describen los cambios más significativos y se ofrecen pasos para migrar tus aplicaciones existentes sin problemas.
Guía de inicio rápido
Los siguientes pasos te ayudarán a migrar de Genkit 0.5 a Genkit 0.9 rápidamente. Obtén más información sobre estos cambios en el registro de cambios detallado que aparece a continuación.
1. Instala la nueva CLI
Desinstala la CLI anterior
npm uninstall -g genkit && npm uninstall genkit
Instala la nueva CLI
npm i -D genkit-cli
2. Cómo actualizar tus dependencias
Quita paquetes principales individuales de Genkit
npm uninstall @genkit-ai/ai @genkit-ai/core @genkit-ai/dotprompt @genkit-ai/flow
Instala el nuevo paquete consolidado de
genkit
npm i --save genkit
Actualiza todas las versiones de los complementos (consulta el ejemplo a continuación).
npm upgrade @genkit-ai/firebase
3. Cómo cambiar tus importaciones
Se quitaron las importaciones de paquetes principales individuales de Genkit.
import { … } from '@genkit-ai/ai'; import { … } from '@genkit-ai/core'; import { … } from '@genkit-ai/flow';
Quita las importaciones de zod
import * as z from 'zod';
Importa
genkit
yzod
desdegenkit
import { z, genkit } from 'genkit';
4. Actualiza tu código
Quita los bloques de configureGenkit.
La configuración de Genkit ahora se realiza por instancia. La telemetría y el registro se configuran de forma global y por separado de la instancia de Genkit.
Reemplaza
configureGenkit
por bloquesai = genkit({...})
. Conserva solo la configuración del complemento.import { genkit } from 'genkit'; const ai = genkit({ plugins: [...]});
Configura la telemetría con enableFirebaseTelemetry o enableGoogleCloudTelemetry
Para Firebase:
import { enableFirebaseTelemetry } from '@genkit-ai/firebase'; enableFirebaseTelemetry({...});
Para Google Cloud:
import { enableGoogleCloudTelemetry } from '@genkit-ai/google-cloud'; enableGoogleCloudTelemetry({...});
Establece tu nivel de registro de forma independiente ```js import { logger } from 'genkit/logging';
logger.setLogLevel('debug'); ```
Consulta la documentación de Supervisión y registro para obtener más detalles sobre cómo configurar la telemetría y el registro.
Consulta la documentación de Cómo comenzar para obtener más detalles sobre cómo configurar una instancia de Genkit.
Migra las acciones de Genkit para que se las llame desde la instancia de genkit
Las acciones (flujos, herramientas, recuperadores, indexadores, etc.) se definen por instancia. Lee el registro de cambios para conocer todas las funciones que deberás cambiar, pero aquí tienes un ejemplo de algunas comunes.
import { genkit } from 'genkit';
import { onFlow } from '@genkit-ai/firebase/functions';
const ai = genkit({ plugins: [...]});
// Flows and tools are defined on the specific genkit instance
// and are directly callable.
const sampleFlow = ai.defineFlow(...);
const sampleTool = ai.defineTool(...);
async function callMyFlow() {
// Previously, text output could accessed via .text()
// Now it is either .output() or .text
return await sampleFlow().output();
}
// onFlow now takes the Genkit instance as first argument
// This registers the flow as a callable firebase function
onFlow(ai, ...);
const flows = [ sampleFlow, ... ];
// Start the flow server to make the registered flows callable over HTTP
ai.startFlowServer({flows});
5. Ejecuta la app
# run the DevUI and your js code genkit start -- <command to run node>
# run a defined flow genkit flow:run <flowName>
Registro de cambios
1. Cambios en la CLI
La interfaz de línea de comandos (CLI) se actualizó de forma significativa en Genkit 0.9. El comando para iniciar Genkit cambió, y la CLI se separó en su propio paquete independiente, que ahora debes instalar por separado.
Para instalar la CLI, haz lo siguiente:
npm i -g genkit-cli
Se realizaron algunos cambios en el comando genkit start
:
Inicia el código de tu aplicación de Genkit y la IU para desarrolladores juntos:
genkit start -- [start command]
genkit start -- tsx src/index.ts
genkit start -- go run main.go
También se admite el modo de reproducción:
genkit start -- tsx --watch src/index.ts
Inicia SOLO el código de tu aplicación en el modo de desarrollador de Genkit:
genkit start --noui -- <start command>
genkit start --noui -- tsx src/index.ts
Inicia SOLO la IU para desarrolladores:
genkit start
Anteriormente, el comando genkit start
iniciaba la IU para desarrolladores y el código de tu aplicación juntos. Si tienes canalizaciones de CI/CD que dependen de este comando, es posible que debas actualizarlas.
La IU para desarrolladores interactuará directamente con el servidor de flujos para determinar qué flujos están registrados y te permitirá invocarlos directamente con entradas de muestra.
2. Paquetes e importaciones simplificados
Anteriormente, las bibliotecas de Genkit se separaban en varios módulos, que debías instalar e importar de forma individual. Estos módulos ahora se consolidaron en una sola importación. Además, Genkit ahora vuelve a exportar el módulo Zod.
Anterior:
npm i @genkit-ai/core @genkit-ai/ai @genkit-ai/flow @genkit-ai/dotprompt
Nuevo:
npm i genkit
Anterior:
import { … } from '@genkit-ai/ai';
import { … } from '@genkit-ai/core';
import { … } from '@genkit-ai/flow';
import * as z from 'zod';
Nuevo:
import { genkit, z } from 'genkit';
Los complementos de Genkit aún deben instalarse e importarse de forma individual.
3. Cómo configurar Genkit
Anteriormente, la inicialización de Genkit se realizaba una vez de forma global llamando a la función configureGenkit
. Los recursos de Genkit (flujos, herramientas, instrucciones, etc.) se conectarían automáticamente con esta configuración global.
Genkit 0.9 presenta instancias de Genkit
, cada una de las cuales encapsula una configuración. Consulta los ejemplos siguientes:
Anterior:
import { configureGenkit } from '@genkit-ai/core';
configureGenkit({
telemetry: {
instrumentation: ...,
logger: ...
}
});
Nuevo:
import { genkit } from 'genkit';
import { logger } from 'genkit/logging';
import { enableFirebaseTelemetry } from '@genkit-ai/firebase';
logger.setLogLevel('debug');
enableFirebaseTelemetry({...});
const ai = genkit({ ... });
Veamos esto en detalle:
configureGenkit()
se reemplazó porgenkit()
y muestra una instanciaGenkit
configurada en lugar de configurar parámetros de configuración de forma global.- La función de inicialización de Genkit ahora se encuentra en el paquete
genkit
. - El registro y la telemetría aún se configuran de forma global con sus propios métodos explícitos. Estas configuraciones se aplican de forma uniforme a todas las instancias de
Genkit
.
4. Cómo definir flujos y, luego, iniciar el servidor de flujo de forma explícita
Ahora que tienes una instancia de Genkit
configurada, deberás definir tus flujos. Todos los métodos principales de la API para desarrolladores, como defineFlow
, defineTool
y onFlow
, ahora se invocan a través de esta instancia.
Esto es diferente de la forma anterior, en la que los flujos y las herramientas se registraban de forma global.
Anterior:
import { defineFlow, defineTool, onFlow } from '@genkit-ai/core';
defineFlow(...);
defineTool(...);
onFlow(...);
Nuevo:
// Define tools and flows
const sampleFlow = ai.defineFlow(...);
const sampleTool = ai.defineTool(...);
// onFlow now takes the Genkit instance as first argument
// This registers the flow as a callable firebase function
onFlow(ai, ...);
const flows = [ sampleFlow, ... ];
// Start the flow server to make the registered flows callable over HTTP
ai.startFlowServer({flows});
A partir de ahora, todos los flujos que quieras que estén disponibles deben registrarse de forma explícita en el array flows
anterior.
5. Las herramientas y las instrucciones deben definirse de forma estática
En versiones anteriores de Genkit, podías definir herramientas y mensajes de forma dinámica durante el tiempo de ejecución, directamente desde un flujo.
En Genkit 0.9, ya no se permite este comportamiento. En su lugar, debes definir todas las acciones y los flujos fuera de la ejecución del flujo (es decir, de forma estática).
Este cambio aplica una separación más estricta de las definiciones de acciones de la ejecución.
Si alguna parte de tu código se define de forma dinámica, deberá refactorizarse. De lo contrario, se arrojará un error en el tiempo de ejecución cuando se ejecute el flujo.
❌ NO HACER LO SIGUIENTE:
const flow = defineFlow({...}, async (input) => {
const tool = defineTool({...});
await tool(...);
});
✅ HACER LO SIGUIENTE:
const tool = ai.defineTool({...});
const flow = ai.defineFlow({...}, async (input) => {
await tool(...);
});
6. Nueva API para flujos de transmisión
En Genkit 0.9, simplificamos la sintaxis para definir un flujo de transmisión y, luego, invocarlo.
En primer lugar, se separaron defineFlow
y defineStreamingFlow
. Si tienes un flujo que se debe transmitir, deberás actualizar tu código para definirlo a través de defineStreamingFlow
.
En segundo lugar, en lugar de llamar a funciones stream()
y response()
independientes, tanto la transmisión como la respuesta ahora son valores que se muestran directamente desde el flujo. Este cambio simplifica la transmisión de flujos.
Anterior:
import { defineFlow, streamFlow } from '@genkit-ai/flow';
const myStreamingFlow = defineFlow(...);
const { stream, output } = await streamFlow(myStreamingFlow, ...);
for await (const chunk of stream()) {
console.log(chunk);
}
console.log(await output());
Nuevo:
const myStreamingFlow = ai.defineStreamingFlow(...);
const { stream, response } = await myStreamingFlow(...);
for await (const chunk of stream) {
console.log(chunk);
}
console.log(await response);
7. Los métodos de la clase GenerateResponse se reemplazaron por propiedades de acceso.
Anteriormente, solías acceder al resultado estructurado o al texto de la respuesta con métodos de clase, como output()
o text()
.
En Genkit 0.9, esos métodos se reemplazaron por propiedades de acceso. Esto simplifica el trabajo con las respuestas.
Anterior:
const response = await generate({ prompt: 'hi' });
console.log(response.text());
Nuevo:
const response = await ai.generate('hi');
console.log(response.text);
Lo mismo se aplica a output
:
Anterior:
console.log(response.output());
Nuevo:
console.log(response.output);
8. Eliminación de la generación de candidatos
Genkit 0.9 simplifica el manejo de respuestas quitando el atributo candidates
. Anteriormente, las respuestas podían contener varios candidatos, que debías controlar de forma explícita. Ahora, solo se muestra el primer candidato directamente en una respuesta plana.
Ya no funcionará ningún código que acceda a los candidatos directamente.
Anterior:
const response = await generate({
messages: [ { role: 'user', content: ...} ]
});
console.log(response.candidates); // previously you could access candidates directly
Nuevo:
const response = await ai.generate({
messages: [ { role: 'user', content: ...} ]
});
console.log(response.message); // single candidate is returned directly in a flat response
9. API de Generate: Mejoras de varios turnos
En el caso de las conversaciones de varios turnos, el método toHistory()
anterior se reemplazó por messages
, lo que simplifica aún más la forma en que se maneja el historial de conversaciones.
Anterior:
const history = response.toHistory();
Nuevo:
const response = await ai.generate({
messages: [ { role: 'user', content: ...} ]
});
const history = response.messages;
10. API de Chat optimizada
En Genkit 0.9, se rediseñó la API de Chat para facilitar la administración y la interacción de las sesiones. Sigue estos pasos para aprovecharlo en las experiencias de chat síncronos y de transmisión:
import { genkit } from 'genkit';
import { gemini15Flash, googleAI } from '@genkit-ai/googleai';
const ai = genkit({
plugins: [googleAI()],
model: gemini15Flash,
});
const session = ai.createSession({ store: firestoreSessionStore() });
const chat = await session.chat({ system: 'talk like a pirate' });
let response = await chat.send('hi, my name is Pavel');
console.log(response.text()); // "hi Pavel, I'm llm"
// continue the conversation
response = await chat.send("what's my name");
console.log(response.text()); // "Pavel"
// can stream
const { response, stream } = await chat.sendStream('bye');
for await (const chunk of stream) {
console.log(chunk.text());
}
console.log((await response).text());
// can load session from the store
const prevSession = await ai.loadSession(session.id, { store });
const prevChat = await prevSession.chat();
await prevChat.send('bye');