Genkit 1.0 enthält viele Funktionsverbesserungen, die die Gesamtfunktionalität verbessern. Es gibt auch einige Änderungen, die die Kompatibilität beeinträchtigen. Wenn Sie Anwendungen mit Genkit 0.9 entwickelt haben, müssen Sie Ihren App-Code aktualisieren, wenn Sie auf die neueste Version von Genkit umstellen. In diesem Leitfaden werden die wichtigsten Änderungen beschrieben und erläutert, wie Sie Ihre vorhandenen Anwendungen reibungslos migrieren.
Beta-APIs
Wir führen einen instabilen Beta-API-Kanal ein und lassen die Session-, Chat- und Genkit-Client-APIs in der Betaphase, da wir sie weiter optimieren. Konkret sind derzeit die folgenden Funktionen im Namespace beta
verfügbar:
ai.chat
ai.createSession
ai.loadSession
ai.currentSession
ai.defineFormat
ai.defineInterrupt
Alt:
import { genkit } from 'genkit';
const ai = genkit({...})
const session = ai.createSession({ ... })
Neu:
import { genkit } from 'genkit/beta';
const ai = genkit({...})
const session = ai.createSession({ ... })
Alt:
import { runFlow, streamFlow } from 'genkit/client';
Neu:
import { runFlow, streamFlow } from 'genkit/beta/client';
Neues @genkit-ai/express
-Paket
Dieses neue Paket enthält Dienstprogramme, die das Erstellen eines Express.js-Servers mit Genkit erleichtern. Weitere Informationen dazu finden Sie auf dieser Seite.
startFlowServer
wurde aus dem Genkit-Objekt in dieses neue @genkit-ai/express
-Paket verschoben. Wenn Sie startFlowServer verwenden möchten, müssen Sie Ihre Importe aktualisieren.
Alt:
const ai = genkit({ ... });
ai.startFlowServer({
flows: [myFlow1, myFlow2],
});
Neu:
import { startFlowServer } from '@genkit-ai/express';
startFlowServer({
flows: [myFlow1, myFlow2],
});
Änderungen an Aufrufabfolgen
Bei Version 1.0 gibt es mehrere Änderungen an Abläufen:
ai.defineStreamingFlow
wurde inai.defineFlow
konsolidiert.onFlow
wurde durchonCallGenkit
ersetzt.run
wurde zuai.run
verschoben.- Es gibt Änderungen bei der Authentifizierung.
Die Funktion run
für benutzerdefinierte Trace-Blöcke wurde in das genkit
-Objekt verschoben. Verwenden Sie stattdessen ai.run
, um sie aufzurufen.
Alt:
ai.defineFlow({name: 'banana'}, async (input) => {
const step = await run('myCode', async () => {
return 'something'
});
})
Neu:
ai.defineFlow({name: 'banana'}, async (input) => {
const step = await ai.run('myCode', async () => {
return 'something'
});
})
ai.defineStreamingFlow
wurde entfernt. Verwenden Sie stattdessen ai.defineFlow
. Außerdem wurde streamingCallback
in ein Feld im zweiten Argument der Ablauffunktion verschoben und heißt jetzt sendChunk
.
Alt:
const flow = ai.defineStreamingFlow({name: 'banana'}, async (input, streamingCallback) => {
streamingCallback({chunk: 1});
})
const {stream} = await flow()
for await (const chunk of stream) {
// ...
}
Neu:
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) {
// ...
}
„FlowAuth auth“ heißt jetzt „context“. Du kannst auf „auth“ als Feld im Kontext zugreifen:
Alt:
ai.defineFlow({name: 'banana'}, async (input) => {
const auth = getFlowAuth();
// ...
})
Neu:
ai.defineFlow({name: 'banana'}, async (input, { context }) => {
const auth = context.auth;
})
onFlow
wurde in das firebase-functions/https
-Paket verschoben und in onCallGenkit
umbenannt. Das folgende Snippet zeigt ein Beispiel für die Verwendung.
Alt
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;
}
);
Neu:
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);
Authentifizierungsrichtlinien wurden aus defineFlow
entfernt. Die Verarbeitung von Authentifizierungsrichtlinien ist jetzt serverabhängig.
Alt:
export const simpleFlow = ai.defineFlow(
{
name: 'simpleFlow',
authPolicy: (auth, input) => {
// auth policy
},
},
async (input) => {
// Flow logic here...
}
);
Das folgende Snippet zeigt ein Beispiel für die Authentifizierung in Express.
Neu:
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
);
Weitere Informationen finden Sie in der Authentifizierungsdokumentation.
Das folgende Snippet zeigt ein Beispiel für die Authentifizierung in Cloud Functions for 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);
Prompts
Wir haben einige Änderungen und Verbesserungen an den Prompts vorgenommen.
Sie können separate Vorlagen für Prompts und Systemnachrichten definieren:
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'});
Alternativ können Sie im Feld „Nachrichten“ Prompts für mehrere Nachrichten definieren:
const hello = ai.definePrompt({
name: 'hello',
messages: '{{ role "system" }} talk like a pirate. {{ role "user" }} hello {{ name }}',
input: {
schema: z.object({
name: z.string()
})
}
});
Anstelle von Promptvorlagen können Sie auch eine Funktion verwenden:
ai.definePrompt({
name: 'hello',
prompt: async (input, { context }) => {
return `hello ${input.name}`
},
input: {
schema: z.object({
name: z.string()
})
}
});
Sie können über den Prompt auf den Kontext (einschließlich Authentifizierungsinformationen) zugreifen:
const hello = ai.definePrompt({
name: 'hello',
messages: 'hello {{ @auth.email }}',
});
Für Streamingfunktionen ist kein await
erforderlich.
Alt:
const { stream, response } = await ai.generateStream(`hi`);
const { stream, output } = await myflow.stream(`hi`);
Neu:
const { stream, response } = ai.generateStream(`hi`);
const { stream, output } = myflow.stream(`hi`);
„Embed“ hat einen neuen Rückgabetyp
Wir haben die Unterstützung für multimodale Einbettungen hinzugefügt. Anstatt nur einen einzelnen Einbettungsvektor zurückzugeben, gibt „Embed“ ein Array von Einbettungsobjekten zurück, die jeweils einen Einbettungsvektor und Metadaten enthalten.
Alt:
const response = await ai.embed({embedder, content, options}); // returns number[]
Neu:
const response = await ai.embed({embedder, content, options}); // returns Embedding[]
const firstEmbeddingVector = response[0].embedding; // is number[]