Gemini API : Tutorials : クイックスタート with Dart or Flutter (1) 日本語動作確認
翻訳 : クラスキャット セールスインフォメーション
作成日時 : 03/29/2024
* 本ページは、ai.google.dev の以下のページを参考にしてまとめ直し、適宜、補足説明したものです :
* サンプルコードの動作確認はしておりますが、必要な場合には適宜、追加改変しています。
* ご自由にリンクを張って頂いてかまいませんが、sales-info@classcat.com までご一報いただけると嬉しいです。
- 人工知能研究開発支援
- 人工知能研修サービス(経営者層向けオンサイト研修)
- テクニカルコンサルティングサービス
- 実証実験(プロトタイプ構築)
- アプリケーションへの実装
- 人工知能研修サービス
- PoC(概念実証)を失敗させないための支援
- お住まいの地域に関係なく Web ブラウザからご参加頂けます。事前登録 が必要ですのでご注意ください。
◆ お問合せ : 本件に関するお問い合わせ先は下記までお願いいたします。
- クラスキャット セールス・マーケティング本部 セールス・インフォメーション
- sales-info@classcat.com ; Website: www.classcat.com ; ClassCatJP
Gemini API : Tutorials : クイックスタート with Dart or Flutter (1) 日本語動作確認
このクイックスタートは Google AI Dart SDK を使用して Dart あるいは Flutter アプリケーションのために Gemini API にアクセスする方法を示します。アプリケーションで Gemini モデルにアクセスするために REST API で直接操作したくない場合は、この SDK を利用できます。
⭐️ Tip : この SDK を素早く試したい場合や、様々なユースケースの完全な実装を見たい場合、sample アプリケーション を確認してください。sample アプリケーションを実行するには、このガイドで説明されている要件と API キーが必要です。
要件
このクイックスタートは貴方が Dart でアプリケーションを構築するのに慣れていることを想定しています。
このクイックスタートを完了するためには、開発環境が以下の要件を満たしていることを確認してください :
- Dart 3.2.0+
プロジェクトの設定
Gemini API を呼び出す前に、プロジェクトをセットアップする必要があります、これは API キーの設定、pub 依存関係への SDK の追加、そしてモデルの初期化を含みます。
API キーの設定
Gemini API を使用するには、API キーが必要です。まだ持っていないならば、Google AI Studio でキーを作成してください。
API キーの保護
貴方の API キーを安全に保持しましょう。API キーを直接コードに含めないことや、キーを含むファイルをバージョン管理システムにチェックインしないことを強く勧めます。代わりに、API キー用にシークレットストアを使用するべきです。
このチュートリアルのすべてのスニペットは、API キーにプロセス環境変数としてアクセスしていることを仮定しています。Flutter アプリケーションを開発している場合、アプリケーション実行時にプロセス環境が異なるため、String.fromEnvironment を使用して –dart-define=API_KEY=$API_KEY を flutter build か flutter run に渡して API を使用してコンパイルすることができます。
SDK パッケージのインストール
独自アプリケーションで Gemini API を使用するためには、google_generative_ai パッケージを Dart か Flutter アプリケーションに追加する必要があります :
Dart
dart pub add google_generative_ai
Flutter
flutter pub add google_generative_ai
生成モデルの初期化
API 呼び出しを行うためには、生成モデルをインポートして初期化する必要があります。
import 'package:google_generative_ai/google_generative_ai.dart';
// Access your API key as an environment variable (see "Set up your API key" above)
final apiKey = Platform.environment['API_KEY'];
if (apiKey == null) {
print('No \$API_KEY environment variable');
exit(1);
}
final model = GenerativeModel(model: 'MODEL_NAME', apiKey: apiKey);
一般的なユースケースの実装
プロジェクトがセットアップできたら、様々なユースケースを実装するために Gemini API の利用を探求できます。
テキスト-only 入力からテキストを生成する
プロンプト入力がテキストだけを含む場合、generateContent メソッドで gemini-pro モデルを使用してテキスト出力を生成します :
import 'dart:io';
import 'package:google_generative_ai/google_generative_ai.dart';
void main() async {
// Access your API key as an environment variable (see "Set up your API key" above)
final apiKey = Platform.environment['API_KEY'];
if (apiKey == null) {
print('No \$API_KEY environment variable');
exit(1);
}
// For text-only input, use the gemini-pro model
final model = GenerativeModel(model: 'gemini-pro', apiKey: apiKey);
final content = [Content.text('Write a story about a magic backpack.')];
final response = await model.generateContent(content);
print(response.text);
}
以下は出力例です :
In the quaint little town of Willow Creek, nestled amidst rolling hills, there lived a curious young boy named Ethan. Ethan possessed an unyielding thirst for adventure and a playful imagination that often soared beyond the confines of reality. One fateful day, as Ethan rummaged through the attic of his grandmother's house, his eyes caught a weathered backpack tucked away in a dusty corner. Its leather straps were adorned with intricate carvings, and a faint shimmer seemed to emanate from its enchanted surface. Ethan couldn't resist its allure and eagerly unzipped the backpack. To his astonishment, it was filled with an assortment of extraordinary items: a glowing compass that always pointed north, a magnifying glass that could reveal hidden treasures, and a flashlight that cast beams of pure moonlight. Overjoyed with his newfound possession, Ethan slung the magic backpack over his shoulders and set out on countless escapades. With the compass guiding his path, he explored uncharted forests, discovering secret trails and hidden waterfalls. The magnifying glass allowed him to marvel at the intricate details of nature, from the veins of a leaf to the iridescent scales of a butterfly. As days turned into weeks, Ethan's adventures grew bolder and more daring. The backpack became his trusted companion, aiding him in retrieving lost toys from tall trees, rescuing injured birds from storm drains, and even uncovering a lost treasure map hidden deep within an ancient ruin. Word of the magic backpack spread throughout Willow Creek like wildfire. Children eagerly sought Ethan's company, longing for a glimpse of its wonders. But Ethan shared his backpack with only those who had a kind heart and a thirst for adventure. One stormy evening, as Ethan and his friends were huddled together in his grandmother's attic, a deafening crash shook the walls. They rushed to the window and witnessed a blinding flash of lightning illuminating the sky. To their horror, they saw a young girl standing alone in the pouring rain, lost and shivering. Without hesitation, Ethan grabbed the magic backpack and ran out into the storm. He knew that the compass would guide him to the girl, and the flashlight would provide much-needed light. Guided by the glowing compass, Ethan navigated the treacherous storm and found the girl huddled beneath a tree. He used the flashlight to keep her warm and dry, and the magnifying glass to examine her injuries. To Ethan's relief, the girl was only slightly bruised and frightened. He carefully placed her in the backpack, and with the compass leading the way, he returned to the attic, where they were greeted with cheers and embraces. From that day forward, Ethan and his magic backpack became legends in Willow Creek. The backpack never lost its enchantment, and Ethan's adventures continued, inspiring countless children to believe in the power of imagination and the kindness of the human heart.
以下は、日本語プロンプト「Dart 言語の特徴を簡潔に教えてください。」を使用した出力例です :
* **オブジェクト指向:** すべてのものがオブジェクトである。 * **シングルスレッド:** UI スレッドのみで実行する。 * **コンパイル型:** VM(仮想マシン)で実行される、Ahead-of-time コンパイルされた言語。 * **ストロング型付け:** 変数の型を明示的に宣言する必要がある。 * **オプション型:** `null` を安全に取り扱う `?` 演算子。 * **非同期的プログラミング:** `async` / `await` キーワードを使用した並行処理のサポート。 * **ガベージコレクション:** 自動メモリ管理。 * **強力なインターフェイス:** 型の契約を定義し、ポリモーフィズムを可能にする。 * **クラス拡張とミックスイン:** 既存のクラスやミクスインを継承して新しいクラスを作成する。 * **包管理:** `pub` パッケージマネージャーを使用したサードパーティライブラリの管理。
テキストと画像入力からテキストを生成する (マルチモーダル)
Gemini はマルチモーダルモデル (gemini-pro-vision) を提供していますので、テキストと画像の両方を入力できます。入力用の画像要件 を確実にレビューしてください。
プロンプト入力がテキストと画像の両方を含む場合、generateContent メソッドで gemini-pro-vision モデルを使用してテキスト出力を生成してください :
import 'dart:io';
import 'package:google_generative_ai/google_generative_ai.dart';
void main() async {
// Access your API key as an environment variable (see "Set up your API key" above)
final apiKey = Platform.environment['API_KEY'];
if (apiKey == null) {
print('No \$API_KEY environment variable');
exit(1);
}
// For text-and-image input (multimodal), use the gemini-pro-vision model
final model = GenerativeModel(model: 'gemini-pro-vision', apiKey: apiKey);
final (firstImage, secondImage) = await (
File('image0.jpg').readAsBytes(),
File('image1.jpg').readAsBytes()
).wait;
final prompt = TextPart("What's different between these pictures?");
final imageParts = [
DataPart('image/jpeg', firstImage),
DataPart('image/jpeg', secondImage),
];
final response = await model.generateContent([
Content.multi([prompt, ...imageParts])
]);
print(response.text);
}
お馴染みの子猫の画像と日本語のプロンプトで試してみました :
import 'dart:io' as io;
import 'package:google_generative_ai/google_generative_ai.dart';
final apiKey = Platform.environment['API_KEY'];
void main() async {
final prompt = TextPart("この画像の表示内容をできる限り詳しく説明して");
final img = await io.File('/Users/xxx/Downloads/cute.jpg').readAsBytes();
final imgPart = DataPart('image/jpeg', img);
final model = GenerativeModel(model: 'gemini-pro-vision', apiKey: apiKey);
final Stopwatch sw = Stopwatch();
sw.start();
final response = await model.generateContent([
Content.multi([prompt, imgPart])
]);
sw.stop();
print('Elapsed time: ${sw.elapsed}');
print(response.text);
}
回答例 1
Elapsed time: 0:00:05.564691 この画像には、緑の葉っぱを背景に、岩の上に立っているオレンジ色の毛並みの猫が写っています。 猫はカメラの方を向いており、大きな目とピンク色の鼻をしています。猫の口は閉じられており、尻尾は見えていません。
回答例 2
これは、緑の草むらを背景に、岩の上に立っているオレンジ色の毛並みの猫の画像です。猫は、こちらを向いて、カメラ目線で、驚いたような表情をしています。猫の目は青く、鼻はピンク色で、口は閉じられています。猫の体は、小さく、足は短く、尾は長いです。猫の毛並みは、オレンジ色で、胸と足先は白色です。猫の耳は、三角形で、先端が尖っています。猫の尻尾は、細長く、先端が尖っています。猫の体は、全体的に、丸みを帯びています。猫の顔は、三角形で、目は大きく、鼻は小さく、口は小さく、耳は大きいです。猫の顔の表情は、驚いたような表情をしています。猫の体は、小さく、足は短く、尾は長いです。猫の毛並みは、オレンジ色で、胸と足先は白色です。猫の耳は、三角形で、先端が尖っています。猫の尻尾は、細長く、先端が尖っています。猫の体は、全体的に、丸みを帯びています。
マルチターン会話 (チャット) の構築
Gemini を使用して、複数ターンに渡る自由形式の会話を構築することができます。SDK は会話の状態を管理することによりプロセスを単純化しますので、generateContent の使用とは異なり、会話履歴を自身でストアする必要がありません。
(チャットのような) マルチターン会話を構築するには、gemini-pro モデルを使用し、startChat() を呼び出してチャットを初期化します。それから sendMessage() を使用して新しいユーザメッセージを送信します、これはまたチャット履歴にメッセージと応答を追加します。
会話のコンテンツに関連する role 用に 2 つの可能なオプションがあります :
- user: プロンプトを提供する role です。この値は sendMessage 呼び出しのためのデフォルトで、違うロールが渡された場合m、例外が投げられます。
- model: 応答を提供する role です。このロールは既存の history を使用して startChat() を呼び出すときに使用できます。
import 'dart:io';
import 'package:google_generative_ai/google_generative_ai.dart';
Future main() async {
// Access your API key as an environment variable (see "Set up your API key" above)
final apiKey = Platform.environment['API_KEY'];
if (apiKey == null) {
print('No \$API_KEY environment variable');
exit(1);
}
// For text-only input, use the gemini-pro model
final model = GenerativeModel(
model: 'gemini-pro',
apiKey: apiKey,
generationConfig: GenerationConfig(maxOutputTokens: 100));
// Initialize the chat
final chat = model.startChat(history: [
Content.text('Hello, I have 2 dogs in my house.'),
Content.model([TextPart('Great to meet you. What would you like to know?')])
]);
var content = Content.text('How many paws are in my house?');
var response = await chat.sendMessage(content);
print(response.text);
}
以下は実行結果です :
If you have 2 dogs in your house, and each dog has 4 paws, then there are a total of **8 paws** in your house. 2 dogs x 4 paws/dog = 8 paws
日本語でも試してみましょう :
// ...
final chat = model.startChat(history: [
Content.text('こんにちは、私は家で 2 匹の犬を飼っています。'),
Content.model([TextPart('初めまして、よろしく。あなたは何を知りたいのですか?')])
]);
var content = Content.text('私の家にはいくつ動物の足があるでしょう?');
var response = await chat.sendMessage(content);
print(response.text);
あなたには4本足の犬が2匹います。したがって、合計**8**本の足があります。
Great !
より高速な相互作用のためにストリーミングを使用する
デフォルトでは、モデルは生成プロセス全体を完了した後に応答を返します。結果の全体を待つ代わりにストリーミングを使用して部分的な結果を処理することで、より高速な相互作用を実現できます。
以下の例は、テキストと画像の入力プロンプトからテキストを生成するために generateContentStream メソッドでストリーミングを実装する方法を示しています。
// ...
final response = model.generateContentStream([
Content.multi([prompt, ...imageParts])
]);
await for (final chunk in response) {
print(chunk.text);
}
// ...
日本語で試してみます :
void main() async {
final prompt = TextPart("この画像の表示内容をできる限り詳しく説明して");
final img = await io.File('/Users/xxx/Downloads/cute.jpg').readAsBytes();
final imgPart = DataPart('image/jpeg', img);
final model = GenerativeModel(model: 'gemini-pro-vision', apiKey: apiKey);
final response = model.generateContentStream([
Content.multi([prompt, imgPart])
]);
await for (final chunk in response) {
print(chunk.text);
}
}
これは、緑の草むらを背景に、岩の上に立っている子猫の画像です。子猫は、オレンジ色の毛並みで、白い 斑点があり、青い目をしていて、こちらをまっすぐ見つめています。
テキスト-only 入力とチャットのユースケースのために同様のアプローチを使用することができます。
// Use streaming with text-only input
final response = model.generateContentStream(content);
// Use streaming with multi-turn conversations (like chat)
final response = chat.sendMessageStream(content);
以上