Genkit 0.9 では、互換性を破る変更がいくつか導入され、全体的な機能が強化されています。Genkit 0.5 でアプリケーションを開発している場合は、最新バージョンにアップグレードするときにアプリケーション コードを更新する必要があります。このガイドでは、最も重要な変更点の概要と、既存のアプリケーションをスムーズに移行するための手順について説明します。
クイックスタート ガイド
以下の手順に沿って、Genkit 0.5 から Genkit 0.9 に簡単に移行できます。これらの変更について詳しくは、以下の変更ログをご覧ください。
1. 新しい CLI をインストールする
古い CLI をアンインストールする
npm uninstall -g genkit && npm uninstall genkit
新しい CLI をインストールする
npm i -D genkit-cli
2. 依存関係を更新する
個々の Genkit コア パッケージを削除する
npm uninstall @genkit-ai/ai @genkit-ai/core @genkit-ai/dotprompt @genkit-ai/flow
新しい統合
genkit
パッケージをインストールするnpm i --save genkit
すべてのプラグイン バージョンをアップグレードする(例を以下に示します)
npm upgrade @genkit-ai/firebase
3. インポートを変更する
個々の Genkit コア パッケージのインポートを削除
import { … } from '@genkit-ai/ai'; import { … } from '@genkit-ai/core'; import { … } from '@genkit-ai/flow';
zod のインポートを削除
import * as z from 'zod';
genkit
からgenkit
とzod
をインポートするimport { z, genkit } from 'genkit';
4. コードを更新する
configureGenkit ブロックを削除する
Genkit の構成がインスタンスごとに行われるようになりました。テレメトリーとロギングは、Genkit インスタンスとは別にグローバルに構成されます。
configureGenkit
をai = genkit({...})
ブロックに置き換えます。プラグインの構成のみを保持します。import { genkit } from 'genkit'; const ai = genkit({ plugins: [...]});
enableFirebaseTelemetry または enableGoogleCloudTelemetry を使用してテレメトリーを構成する
Firebase の場合:
import { enableFirebaseTelemetry } from '@genkit-ai/firebase'; enableFirebaseTelemetry({...});
Google Cloud の場合:
import { enableGoogleCloudTelemetry } from '@genkit-ai/google-cloud'; enableGoogleCloudTelemetry({...});
ロギングレベルを個別に設定します ```js import { logger } from 'genkit/logging';
logger.setLogLevel('debug'); ```
テレメトリーとロギングの構成方法の詳細については、モニタリングとロギングのドキュメントをご覧ください。
Genkit インスタンスを構成する方法について詳しくは、スタートガイドのドキュメントをご覧ください。
genkit
インスタンスから呼び出されるように Genkit アクションを移行する
アクション(フロー、ツール、取得ツール、インデックス エンジンなど)はインスタンスごとに定義されます。変更が必要なすべての機能については、変更履歴をご覧ください。以下に、一般的な変更の例を示します。
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. 実行
# run the DevUI and your js code genkit start -- <command to run node>
# run a defined flow genkit flow:run <flowName>
変更履歴
1. CLI の変更
コマンドライン インターフェース(CLI)は、Genkit 0.9 で大幅に更新されました。Genkit を起動するコマンドが変更され、CLI が独自のスタンドアロン パッケージに分離されました。このパッケージは別途インストールする必要があります。
CLI をインストールするには:
npm i -g genkit-cli
genkit start
コマンドが変更されました。
Genkit アプリケーション コードと Dev UI を一緒に起動します。
genkit start -- [start command]
genkit start -- tsx src/index.ts
genkit start -- go run main.go
ウォッチモードもサポートされています。
genkit start -- tsx --watch src/index.ts
Genkit デベロッパー モードでアプリケーション コードのみを起動します。
genkit start --noui -- <start command>
genkit start --noui -- tsx src/index.ts
デベロッパー UI のみを起動します。
genkit start
以前は、genkit start
コマンドで Dev UI とアプリケーション コードが同時に起動されていました。このコマンドに依存する CI/CD パイプラインがある場合は、パイプラインの更新が必要になることがあります。
デベロッパー UI はフローサーバーと直接やり取りして、登録されているフローを特定し、サンプル入力で直接呼び出すことができます。
2. パッケージとインポートの簡素化
以前は、Genkit ライブラリは複数のモジュールに分かれており、個別にインストールしてインポートする必要がありました。これらのモジュールは、単一のインポートに統合されました。また、Zod モジュールが Genkit によって再エクスポートされるようになりました。
旧:
npm i @genkit-ai/core @genkit-ai/ai @genkit-ai/flow @genkit-ai/dotprompt
新規:
npm i genkit
旧:
import { … } from '@genkit-ai/ai';
import { … } from '@genkit-ai/core';
import { … } from '@genkit-ai/flow';
import * as z from 'zod';
新規:
import { genkit, z } from 'genkit';
Genkit プラグインは引き続き個別にインストールしてインポートする必要があります。
3. Genkit の構成
以前は、Genkit の初期化は configureGenkit
関数を呼び出してグローバルに 1 回行われていました。Genkit リソース(フロー、ツール、プロンプトなど)はすべて、このグローバル構成に自動的に接続されます。
Genkit 0.9 では、それぞれが構成をカプセル化する Genkit
インスタンスが導入されています。次の例をご覧ください。
旧:
import { configureGenkit } from '@genkit-ai/core';
configureGenkit({
telemetry: {
instrumentation: ...,
logger: ...
}
});
新規:
import { genkit } from 'genkit';
import { logger } from 'genkit/logging';
import { enableFirebaseTelemetry } from '@genkit-ai/firebase';
logger.setLogLevel('debug');
enableFirebaseTelemetry({...});
const ai = genkit({ ... });
詳しく見ていきましょう。
configureGenkit()
はgenkit()
に置き換えられ、構成をグローバルに設定するのではなく、構成されたGenkit
インスタンスを返します。- Genkit 初期化関数が
genkit
パッケージに移動しました。 - ロギングとテレメトリーは、独自の明示的なメソッドを使用してグローバルに構成されます。これらの構成は、すべての
Genkit
インスタンスに均一に適用されます。
4. フローを定義してフローサーバーを明示的に起動する
Genkit
インスタンスが構成されたので、フローを定義する必要があります。デベロッパー向けのコア API メソッド(defineFlow
、defineTool
、onFlow
など)はすべて、このインスタンスから呼び出されます。
これは、フローやツールがグローバルに登録されていた以前の方法とは異なります。
旧:
import { defineFlow, defineTool, onFlow } from '@genkit-ai/core';
defineFlow(...);
defineTool(...);
onFlow(...);
新規:
// 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});
現時点では、公開するフローはすべて、上記の flows
配列に明示的に登録する必要があります。
5. ツールとプロンプトを静的に定義する必要がある
以前のバージョンの Genkit では、ツールとプロンプトを実行時に、フロー内から直接動的に定義できました。
Genkit 0.9 では、この動作は許可されなくなりました。代わりに、すべてのアクションとフローをフローの実行外で(静的に)定義する必要があります。
この変更により、アクションの定義と実行がより厳密に分離されます。
コードが動的に定義されている場合は、リファクタリングする必要があります。そうでない場合は、フローが実行されると実行時にエラーがスローされます。
❌ 行わないでください:
const flow = defineFlow({...}, async (input) => {
const tool = defineTool({...});
await tool(...);
});
✅ 行うべきこと:
const tool = ai.defineTool({...});
const flow = ai.defineFlow({...}, async (input) => {
await tool(...);
});
6. ストリーミング フロー用の新しい API
Genkit 0.9 では、ストリーミング フローの定義と呼び出しの構文を簡素化しました。
まず、defineFlow
と defineStreamingFlow
が分離されました。ストリーミングするフローがある場合は、defineStreamingFlow
で定義するようにコードを更新する必要があります。
2 つ目は、stream()
関数と response()
関数を別々に呼び出すのではなく、ストリームとレスポンスの両方がフローから直接返される値になりました。この変更により、フロー ストリーミングが簡素化されます。
旧:
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());
新規:
const myStreamingFlow = ai.defineStreamingFlow(...);
const { stream, response } = await myStreamingFlow(...);
for await (const chunk of stream) {
console.log(chunk);
}
console.log(await response);
7. GenerateResponse クラスのメソッドをゲッター プロパティに置き換え
以前は、output()
や text()
などのクラスメソッドを使用して、レスポンスの構造化出力またはテキストにアクセスしていました。
Genkit 0.9 では、これらのメソッドはゲッター プロパティに置き換えられています。これにより、レスポンスを簡単に操作できます。
旧:
const response = await generate({ prompt: 'hi' });
console.log(response.text());
新規:
const response = await ai.generate('hi');
console.log(response.text);
output
についても同様です。
旧:
console.log(response.output());
新規:
console.log(response.output);
8. 候補の生成の削除
Genkit 0.9 では、candidates
属性を削除することでレスポンスの処理を簡素化しています。以前は、レスポンスには複数の候補を含めることができ、明示的に処理する必要がありました。フラット レスポンスで直接返されるのは、最初の候補のみです。
候補に直接アクセスするコードは機能しなくなります。
旧:
const response = await generate({
messages: [ { role: 'user', content: ...} ]
});
console.log(response.candidates); // previously you could access candidates directly
新規:
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 - マルチターンの機能強化
マルチターンの会話では、古い toHistory()
メソッドが messages
に置き換えられ、会話履歴の処理方法がさらに簡素化されました。
旧:
const history = response.toHistory();
新規:
const response = await ai.generate({
messages: [ { role: 'user', content: ...} ]
});
const history = response.messages;
10. Streamlined Chat API
Genkit 0.9 では、セッションの管理と操作を容易にするために Chat API が再設計されました。同期チャットとストリーミング チャットの両方でこの機能を活用する方法は次のとおりです。
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');