Genkit 1.0 introduit de nombreuses améliorations de fonctionnalités qui améliorent les fonctionnalités globales. Il comporte également des modifications non compatibles. Si vous avez développé des applications avec Genkit 0.9, vous devez mettre à jour le code de votre application lorsque vous passez à la dernière version de Genkit. Ce guide décrit les modifications les plus importantes et explique comment migrer vos applications existantes en douceur.
API bêta
Nous lançons un canal d'API bêta instable, et laissons les API client de session, de chat et de Genkit en version bêta pendant que nous continuons de les affiner. Plus précisément, les fonctions suivantes se trouvent actuellement dans l'espace de noms beta
:
ai.chat
ai.createSession
ai.loadSession
ai.currentSession
ai.defineFormat
ai.defineInterrupt
Anciennement:
import { genkit } from 'genkit';
const ai = genkit({...})
const session = ai.createSession({ ... })
Nouveauté:
import { genkit } from 'genkit/beta';
const ai = genkit({...})
const session = ai.createSession({ ... })
Anciennement:
import { runFlow, streamFlow } from 'genkit/client';
Nouveauté:
import { runFlow, streamFlow } from 'genkit/beta/client';
Présentation du nouveau package @genkit-ai/express
Ce nouveau package contient des utilitaires qui facilitent la création d'un serveur Express.js avec Genkit. Pour en savoir plus, consultez cette page.
startFlowServer
est passé d'une partie de l'objet genkit à ce nouveau package @genkit-ai/express
. Pour utiliser startFlowServer, vous devez mettre à jour vos importations.
Anciennement:
const ai = genkit({ ... });
ai.startFlowServer({
flows: [myFlow1, myFlow2],
});
Nouveauté:
import { startFlowServer } from '@genkit-ai/express';
startFlowServer({
flows: [myFlow1, myFlow2],
});
Modifications apportées aux flux
Plusieurs modifications ont été apportées aux flux dans la version 1.0:
ai.defineStreamingFlow
a été consolidé dansai.defineFlow
.onFlow
a été remplacé paronCallGenkit
.run
a été déplacé versai.run
.- Des modifications ont été apportées à l'utilisation de l'authentification.
La fonction run
pour les blocs de trace personnalisés a été déplacée vers une partie de l'objet genkit
. Utilisez plutôt ai.run
pour l'appeler.
Anciennement:
ai.defineFlow({name: 'banana'}, async (input) => {
const step = await run('myCode', async () => {
return 'something'
});
})
Nouveauté:
ai.defineFlow({name: 'banana'}, async (input) => {
const step = await ai.run('myCode', async () => {
return 'something'
});
})
ai.defineStreamingFlow
a été supprimé. Utilisez ai.defineFlow
à la place. De plus, streamingCallback
a été déplacé vers un champ dans le deuxième argument de la fonction de flux et est désormais appelé sendChunk
.
Anciennement:
const flow = ai.defineStreamingFlow({name: 'banana'}, async (input, streamingCallback) => {
streamingCallback({chunk: 1});
})
const {stream} = await flow()
for await (const chunk of stream) {
// ...
}
Nouveauté:
const flow = ai.defineFlow({name: 'banana'}, async (input, {context, sendChunk}) => {
sendChunk({chunk: 1});
})
const {stream, output} = flow.stream(input);
for await (const chunk of stream) {
// ...
}
L'authentification FlowAuth s'appelle désormais "context". Vous pouvez accéder à l'authentification en tant que champ dans le contexte:
Anciennement:
ai.defineFlow({name: 'banana'}, async (input) => {
const auth = getFlowAuth();
// ...
})
Nouveauté:
ai.defineFlow({name: 'banana'}, async (input, { context }) => {
const auth = context.auth;
})
onFlow
a été déplacé vers le package firebase-functions/https
et a été renommé onCallGenkit
. L'extrait de code suivant montre comment l'utiliser.
Ancienne
import { onFlow } from "@genkit-ai/firebase/functions";
export const generatePoem = onFlow(
ai,
{
name: "jokeTeller",
inputSchema: z.string().nullable(),
outputSchema: z.string(),
streamSchema: z.string(),
},
async (type, streamingCallback) => {
const { stream, response } = await ai.generateStream(
`Tell me a longish ${type ?? "dad"} joke.`
);
for await (const chunk of stream) {
streamingCallback(chunk.text);
}
return (await response).text;
}
);
Nouveauté:
import { onCallGenkit } from "firebase-functions/https";
import { defineSecret } from "firebase-functions/params";
import { genkit, z } from "genkit";
const apiKey = defineSecret("GOOGLE_GENAI_API_KEY");
const ai = genkit({
plugins: [googleAI()],
model: gemini15Flash,
});
export const jokeTeller = ai.defineFlow(
{
name: "jokeTeller",
inputSchema: z.string().nullable(),
outputSchema: z.string(),
streamSchema: z.string(),
},
async (type, { sendChunk }) => {
const { stream, response } = ai.generateStream(
`Tell me a longish ${type ?? "dad"} joke.`
);
for await (const chunk of stream) {
sendChunk(chunk.text);
}
return (await response).text;
}
);
export const tellJoke = onCallGenkit({ secrets: [apiKey] }, jokeTeller);
Les règles d'authentification ont été supprimées de defineFlow
. La gestion des règles d'authentification dépend désormais du serveur.
Anciennement:
export const simpleFlow = ai.defineFlow(
{
name: 'simpleFlow',
authPolicy: (auth, input) => {
// auth policy
},
},
async (input) => {
// Flow logic here...
}
);
L'extrait de code suivant montre un exemple de gestion de l'authentification dans Express.
Nouveauté:
import { UserFacingError } from 'genkit';
import { ContextProvider, RequestData } from 'genkit/context';
import { expressHandler, startFlowServer } from '@genkit-ai/express';
const context: ContextProvider<Context> = (req: RequestData) => {
return {
auth: parseAuthToken(req.headers['authorization']),
};
};
export const simpleFlow = ai.defineFlow(
{
name: 'simpleFlow',
},
async (input, { context }) => {
if (!context.auth) {
throw new UserFacingError("UNAUTHORIZED", "Authorization required.");
}
if (input.uid !== context.auth.uid) {
throw new UserFacingError("UNAUTHORIZED", "You may only summarize your own profile data.");
}
// Flow logic here...
}
);
const app = express();
app.use(express.json());
app.post(
'/simpleFlow',
expressHandler(simpleFlow, { context })
);
app.listen(8080);
// or
startFlowServer(
flows: [withContextProvider(simpleFlow, context)],
port: 8080
);
Pour en savoir plus, consultez la documentation sur l'authentification.
L'extrait de code suivant montre un exemple de gestion de l'authentification dans Cloud Functions pour Firebase:
import { genkit } from 'genkit';
import { onCallGenkit } from 'firebase-functions/https';
const ai = genkit({ ... });;
const simpleFlow = ai.defineFlow({
name: 'simpleFlow',
}, async (input) => {
// Flow logic here...
});
export const selfSummary = onCallGenkit({
authPolicy: (auth, data) => auth?.token?.['email_verified'] && auth?.token?.['admin'],
}, simpleFlow);
Requêtes
Nous avons apporté plusieurs modifications et améliorations aux requêtes.
Vous pouvez définir des modèles distincts pour les requêtes et les messages système:
const hello = ai.definePrompt({
name: 'hello',
system: 'talk like a pirate.',
prompt: 'hello {{ name }}',
input: {
schema: z.object({
name: z.string()
})
}
});
const { text } = await hello({name: 'Genkit'});
Vous pouvez également définir des invites multimessages dans le champ "messages" :
const hello = ai.definePrompt({
name: 'hello',
messages: '{{ role "system" }} talk like a pirate. {{ role "user" }} hello {{ name }}',
input: {
schema: z.object({
name: z.string()
})
}
});
Au lieu de modèles d'invite, vous pouvez utiliser une fonction:
ai.definePrompt({
name: 'hello',
prompt: async (input, { context }) => {
return `hello ${input.name}`
},
input: {
schema: z.object({
name: z.string()
})
}
});
Vous pouvez accéder au contexte (y compris aux informations d'authentification) depuis l'invite:
const hello = ai.definePrompt({
name: 'hello',
messages: 'hello {{ @auth.email }}',
});
Les fonctions de streaming ne nécessitent pas de await
.
Anciennement:
const { stream, response } = await ai.generateStream(`hi`);
const { stream, output } = await myflow.stream(`hi`);
Nouveauté:
const { stream, response } = ai.generateStream(`hi`);
const { stream, output } = myflow.stream(`hi`);
Nouveau type de retour pour l'intégration
Nous avons ajouté la compatibilité avec les représentations vectorielles continues multimodales. Au lieu de renvoyer un seul vecteur d'embedding, Embed renvoie un tableau d'objets d'embedding, chacun contenant un vecteur d'embedding et des métadonnées.
Anciennement:
const response = await ai.embed({embedder, content, options}); // returns number[]
Nouveauté:
const response = await ai.embed({embedder, content, options}); // returns Embedding[]
const firstEmbeddingVector = response[0].embedding; // is number[]