Von 0.5 migrieren

Genkit 0.9 enthält eine Reihe von funktionsgefährdenden Änderungen sowie Funktionsverbesserungen, die die Gesamtfunktionalität verbessern. Wenn Sie Anwendungen mit Genkit 0.5 entwickelt haben, müssen Sie Ihren Anwendungscode aktualisieren, wenn Sie auf die neueste Version umstellen. In diesem Leitfaden werden die wichtigsten Änderungen beschrieben und Schritte zur reibungslosen Migration Ihrer vorhandenen Anwendungen erläutert.

Kurzanleitung

Mit den folgenden Schritten können Sie schnell von Genkit 0.5 zu Genkit 0.9 migrieren. Weitere Informationen zu diesen Änderungen findest du im detaillierten Änderungs-Log unten.

1. Neue Befehlszeile installieren

  • Alte Befehlszeile deinstallieren

    npm uninstall -g genkit && npm uninstall genkit
    
  • Neue Befehlszeile installieren

    npm i -D genkit-cli
    

2. Abhängigkeiten aktualisieren

  • Einzelne Genkit-Kernpakete entfernen

    npm uninstall @genkit-ai/ai @genkit-ai/core @genkit-ai/dotprompt @genkit-ai/flow
    
  • Neues konsolidiertes genkit-Paket installieren

    npm i --save genkit
    
  • Alle Plug-in-Versionen aktualisieren (Beispiel unten)

    npm upgrade @genkit-ai/firebase
    

3. Importe ändern

  • Importe für einzelne Genkit-Kernpakete entfernen

    import { … } from '@genkit-ai/ai';
    import { … } from '@genkit-ai/core';
    import { … } from '@genkit-ai/flow';
    
  • Zod-Importe entfernen

    import * as z from 'zod';
    
  • genkit und zod aus genkit importieren

    import { z, genkit } from 'genkit';
    

4. Code aktualisieren

Entfernen Sie die Blöcke „configureGenkit“.

Die Konfiguration für Genkit erfolgt jetzt pro Instanz. Telemetrie und Logging werden global und separat von der Genkit-Instanz konfiguriert.

  • Ersetzen Sie configureGenkit durch ai = genkit({...})-Blöcke. Behalten Sie nur die Plug-in-Konfiguration bei.

    import { genkit } from 'genkit';
    
    const ai = genkit({ plugins: [...]});
    
  • Telemetrie mit enableFirebaseTelemetry oder enableGoogleCloudTelemetry konfigurieren

    Für Firebase:

    import { enableFirebaseTelemetry } from '@genkit-ai/firebase';
    
    enableFirebaseTelemetry({...});
    

    Für Google Cloud:

    import { enableGoogleCloudTelemetry } from '@genkit-ai/google-cloud';
    
    enableGoogleCloudTelemetry({...});
    
  • Protokollierungsebene unabhängig festlegen ```js import { logger } from 'genkit/logging';

    logger.setLogLevel('debug'); ```

Weitere Informationen zum Konfigurieren von Telemetrie und Logging finden Sie in der Dokumentation unter Monitoring und Logging.

Weitere Informationen zum Konfigurieren einer Genkit-Instanz finden Sie in der Anleitung.

Genkit-Aktionen migrieren, die von der genkit-Instanz aufgerufen werden sollen

Aktionen (Abläufe, Tools, Abrufprogramme, Indexierer usw.) werden pro Instanz definiert. Im Changelog finden Sie alle Funktionen, die Sie ändern müssen. Im Folgenden sind einige häufige Beispiele aufgeführt.

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. Ausführen

# run the DevUI and your js code
genkit start -- <command to run node>
# run a defined flow
genkit flow:run <flowName>

Änderungsprotokoll

1. Änderungen an der Befehlszeile

Die Befehlszeile wurde in Genkit 0.9 erheblich aktualisiert. Der Befehl zum Starten von Genkit hat sich geändert und die Befehlszeile wurde in ein eigenes eigenständiges Paket verschoben, das Sie jetzt separat installieren müssen.

So installieren Sie die Befehlszeile:

npm i -g genkit-cli

Am Befehl genkit start wurden einige Änderungen vorgenommen:

Startet den Genkit-Anwendungscode und die Dev-UI zusammen:

genkit start -- [start command]
genkit start -- tsx src/index.ts
genkit start -- go run main.go

Der Wiedergabemodus wird ebenfalls unterstützt:

genkit start -- tsx --watch src/index.ts

Lediglich der Anwendungscode wird im Genkit-Entwicklermodus gestartet:

genkit start --noui -- <start command>
genkit start --noui -- tsx src/index.ts

Startet NUR die Dev-Benutzeroberfläche:

genkit start

Bisher wurde mit dem Befehl genkit start die Dev-Benutzeroberfläche und der Anwendungscode gemeinsam gestartet. Wenn Sie CI/CD-Pipelines haben, die auf diesem Befehl basieren, müssen Sie die Pipeline möglicherweise aktualisieren.

Die Entwickleroberfläche interagiert direkt mit dem Ablaufserver, um herauszufinden, welche Abläufe registriert sind, und ermöglicht es Ihnen, sie direkt mit Beispielinputs aufzurufen.

2. Vereinfachte Pakete und Importe

Bisher waren die Genkit-Bibliotheken in mehrere Module unterteilt, die Sie einzeln installieren und importieren mussten. Diese Module wurden jetzt in einem einzigen Import zusammengefasst. Außerdem wird das Zod-Modul jetzt von Genkit noch einmal exportiert.

Alt:

npm i @genkit-ai/core @genkit-ai/ai @genkit-ai/flow @genkit-ai/dotprompt

Neu:

npm i genkit

Alt:

import { … } from '@genkit-ai/ai';
import { … } from '@genkit-ai/core';
import { … } from '@genkit-ai/flow';
import * as z from 'zod';

Neu:

import { genkit, z } from 'genkit';

Genkit-Plug-ins müssen weiterhin einzeln installiert und importiert werden.

3. Genkit konfigurieren

Bisher wurde Genkit einmal global durch Aufrufen der Funktion configureGenkit initialisiert. Genkit-Ressourcen (Abläufe, Tools, Prompts usw.) werden automatisch mit dieser globalen Konfiguration verbunden.

In Genkit 0.9 werden Genkit-Instanzen eingeführt, die jeweils eine Konfiguration umfassen. Betrachten Sie die folgenden Beispiele:

Alt:

import { configureGenkit } from '@genkit-ai/core';

configureGenkit({
  telemetry: {
    instrumentation: ...,
    logger: ...
  }
});

Neu:

import { genkit } from 'genkit';
import { logger } from 'genkit/logging';
import { enableFirebaseTelemetry } from '@genkit-ai/firebase';

logger.setLogLevel('debug');
enableFirebaseTelemetry({...});

const ai = genkit({ ... });

Sehen wir uns das genauer an:

  • configureGenkit() wurde durch genkit() ersetzt und es wird eine konfigurierte Genkit-Instanz zurückgegeben, anstatt Konfigurationen global einzurichten.
  • Die Genkit-Initialisierungsfunktion befindet sich jetzt im genkit-Paket.
  • Logging und Telemetrie werden weiterhin global mit eigenen expliziten Methoden konfiguriert. Diese Konfigurationen gelten einheitlich für alle Genkit-Instanzen.

4. Abläufe definieren und den Ablaufserver explizit starten

Nachdem Sie eine Genkit-Instanz konfiguriert haben, müssen Sie Ihre Abläufe definieren. Alle für Entwickler relevanten API-Methoden wie defineFlow, defineTool und onFlow werden jetzt über diese Instanz aufgerufen.

Das unterscheidet sich von der bisherigen Vorgehensweise, bei der Abläufe und Tools global registriert wurden.

Alt:

import { defineFlow, defineTool, onFlow } from '@genkit-ai/core';

defineFlow(...);
defineTool(...);

onFlow(...);

Neu:

// 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});

Derzeit müssen alle Abläufe, die Sie verfügbar machen möchten, im obigen Array flows explizit registriert werden.

5. Tools und Prompts müssen statisch definiert sein.

In früheren Versionen von Genkit konnten Sie Tools und Prompts direkt in einem Flow dynamisch definieren.

In Genkit 0.9 ist dieses Verhalten nicht mehr zulässig. Stattdessen müssen Sie alle Aktionen und Abläufe außerhalb der Ausführung des Ablaufs definieren (d.h. statisch).

Durch diese Änderung wird eine strengere Trennung von Aktionsdefinitionen von der Ausführung erzwungen.

Wenn Code dynamisch definiert ist, muss er refaktorisiert werden. Andernfalls wird bei der Ausführung des Ablaufs ein Fehler ausgegeben.

❌ NICHT:

const flow = defineFlow({...}, async (input) => {
  const tool = defineTool({...});
  await tool(...);
});

✅ EMPFOHLENE VERFAHREN

const tool = ai.defineTool({...});

const flow = ai.defineFlow({...}, async (input) => {
  await tool(...);
});

6. Neue API für Streaming-Abläufe

In Genkit 0.9 haben wir die Syntax zum Definieren und Aufrufen eines Streaming-Flows vereinfacht.

Zuerst wurden defineFlow und defineStreamingFlow getrennt. Wenn Sie einen Ablauf haben, der gestreamt werden soll, müssen Sie Ihren Code aktualisieren, um ihn über defineStreamingFlow zu definieren.

Zweitens: Anstatt separate stream()- und response()-Funktionen aufzurufen, werden jetzt sowohl Stream als auch Antwort direkt vom Fluss zurückgegeben. Diese Änderung vereinfacht das Streaming von Abläufen.

Alt:

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());

Neu:

const myStreamingFlow = ai.defineStreamingFlow(...);
const { stream, response } = await myStreamingFlow(...);

for await (const chunk of stream) {
  console.log(chunk);
}

console.log(await response);

7. Methoden der Klasse „GenerateResponse“ durch Getter-Eigenschaften ersetzt

Bisher haben Sie über Klassenmethoden wie output() oder text() auf die strukturierte Ausgabe oder den Text der Antwort zugegriffen.

In Genkit 0.9 wurden diese Methoden durch Getter-Properties ersetzt. Das vereinfacht die Arbeit mit Antworten.

Alt:

const response = await generate({ prompt: 'hi' });
console.log(response.text());

Neu:

const response = await ai.generate('hi');
console.log(response.text);

Dasselbe gilt für output:

Alt:

console.log(response.output());

Neu:

console.log(response.output);

8. Generierung von Kandidaten entfernt

In Genkit 0.9 wird die Antwortverarbeitung durch das Entfernen des Attributs candidates vereinfacht. Bisher konnten Antworten mehrere Kandidaten enthalten, die Sie explizit verarbeiten mussten. Jetzt wird nur der erste Kandidat direkt in einer flachen Antwort zurückgegeben.

Codes, die direkt auf die Kandidaten zugreifen, funktionieren nicht mehr.

Alt:

const response = await generate({
 messages: [ { role: 'user', content: ...} ]
});
console.log(response.candidates); // previously you could access candidates directly

Neu:

const response = await ai.generate({
 messages: [ { role: 'user', content: ...} ]
});
console.log(response.message); // single candidate is returned directly in a flat response

9. Generate API – Verbesserungen für mehrstufige Unterhaltungen

Bei Unterhaltungen mit mehreren Antworten wurde die alte Methode toHistory() durch messages ersetzt, was die Verarbeitung des Unterhaltungsverlaufs weiter vereinfacht.

Alt:

const history = response.toHistory();

Neu:

const response = await ai.generate({
 messages: [ { role: 'user', content: ...} ]
});
const history = response.messages;

10. Optimierte Chat API

In Genkit 0.9 wurde die Chat API für eine einfachere Sitzungsverwaltung und -interaktion neu gestaltet. So können Sie sie sowohl für synchrone als auch für Streaming-Chats nutzen:

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');