この記事は Scott Huffman, Vice President, Engineering and Josh Woodward, Senior Director, Product Management による Google Developers Blog の記事 "PaLM API & MakerSuite: an approachable way to start prototyping and building generative AI applications" を元に翻訳・加筆したものです。詳しくは元記事をご覧ください。
ゲームや対話エージェントからクリエイティブなブレインストーミングやコーディング ツールまで、人々のテクノロジーとの関わり方を変えるジェネレーティブ AI アプリケーションの新しい波が来ています。Google では、ジェネレーティブ AI を使った次世代のアプリケーションを簡単に作れる API やツールをすべてのデベロッパーに提供し、AI を身近なものにしたいと願っています。2023 年 3 月 14 日 (日本時間) 、私たちは、Google の大規模言語モデル(LLM)を簡単かつ安全に試すことができる新しいデベロッパー向けサービスである PaLM API を発表しました。この API と同時に、デベロッパーがすばやく簡単にプロトタイピングを開始できるツール、MakerSuite をリリースします。これらのツールは、プライベート プレビューを通じて一部のデベロッパーに提供される予定で、また近日中にウェイトリストも公開する予定です。
PaLM API は、Google の大規模言語モデルを簡単に利用できる API です。コンテンツ生成やチャットに最適化された対話型モデルや、要約や分類などに最適化された汎用モデルにアクセスできます。まずはサイズや機能面で効率的なモデルを 2023 年 3 月 14 日より提供し、近日中に他のモデルやサイズも追加する予定です。
私たちはここ数年、Google 検索への MUM の導入や、AI テストキッチン (英語) での LaMDA 導入のトライアルなど、大規模な言語モデルの構築と展開を推し進めてきました。その過程でジェネレーティブ AI の開発ワークフローについて多くを学び、それがすぐに断片化してしまう課題を知りました。プロンプトを組み立てては直すことの繰り返しや、合成データによるデータセットの拡張、カスタムモデルのチューニングなどのために、ばらばらのツールを組み合わせる必要があります。そこで私たちは、このワークフローを簡素化するツール、MakerSuite をリリースすることにしました。MakerSuite を使えば、イテレーティブなプロンプト作成や、合成データによるデータセットの拡張、カスタムモデルのチューニングを簡単に行えます。プロンプトをコードに移す準備ができたら、MakerSuite で Python や Node.js など、お気に入りの言語やフレームワークのコードとして書き出すことができます。
ジェネレーティブ AI モデルは、デベロッパーがすぐに使える強力な機能を備えています。さらに、個々の用途に応じてモデルのチューニングすることで、より良い性能が得られます。Maker Suite を使えば、デベロッパーがパラメータを効率的に調整する技術 (英語) を活用して、用途に合わせてチューニングされたモデルを作成できます。チューニングしたモデルをブラウザ上ですばやくテストし、繰り返し使用できます。
AI を使った開発には高品質なデータが欠かせませんが、すぐに利用できるデータだけでは学習に限界があるケースも少なくありません。MakerSuite では、少数のデータをサンプルとしてデータ拡張用のデータを合成し、新たに作成したデータセットの管理や操作が可能です。この合成データは、モデルのチューニングや評価など、さまざまなシーンで活用できます。
LLM から得られる embedding は、セマンティック検索からレコメンデーション、分類まで、幅広い応用の可能性が見いだされており、いま大きな期待が寄せられています。PaLM API で生成された embedding を使えば、既存のデータや外部のデータソースを活用したジェネレーティブ AI アプリケーションの構築が可能になります。また、TensorFlow、Keras、JAX、その他のオープンソース ライブラリで構築されたアプリケーションで embedding を使用することも可能です。
私たちは、Google の AI の基本方針 に従ってモデルを構築し、Responsible AI (責任ある AI)の基礎を提供します。デベロッパーが個々のアプリケーションにおいて責任と安全性の基準を定め遵守するには、それらをコントロールできることが重要です。Google のツールは、デベロッパーがそれぞれのアプリケーションやユースケースに応じて安全性の検証や調整するための簡単な手段を提供します。
これらのデベロッパー ツールによって、ジェネレーティブ AI アプリケーションのプロトタイピングや構築を簡単に始められるのと同時に、サービスのスケーラビリティが必要になった場合の対応も容易です。PaLM API と MakerSuite は Google のクラウド基盤で提供されており、ホスティングやサービングのスケーラビリティについて心配する必要はありません。自分のアイデアをより大きな規模で展開したり、エンタープライズグレードのサポートや、セキュリティとコンプライアンス、サービスレベル合意(SLA)などが必要なケースでは、Google Cloud Vertex AI を活用し、エンタープライズ向け検索サービスや対話型 AI などの高度な機能の数々との組み合わせで、ジェネレーティブ AI モデルの機能を活用できます。
いまとてもエキサイティングな AI の潮流の中で、Google は、デベロッパーの皆さんの開発作業をより快適にするためのツールを作り続けたいと考えています。新しいデベロッパーを受け入れ、新機能を展開し、この技術をさらに広いデベロッパー コミュニティに提供していく予定です。また同時に、フィードバックに耳を傾け、学習し、デベロッパーが今いる環境でこれらのツールを最大限活用するために改善を続けていきます。
今後の進捗状況については Google Developers のニュースレターでお知らせするので、ぜひ購読をおすすめします。
Reviewed by Kaz Sato, Staff Developer Advocate, Google Cloud & Tamao Imura, Developer Marketing Manager, Google
多くのデベロッパーはコンテンツ管理システム、プラグイン、他のソフトウェア ソリューションを使用してウェブサイトやアプリを作成します。今までは、こうしたウェブサイト エクスペリエンスへのマッピング機能の追加は分断されたプロセスであったため、多くのユーザーがプロジェクトにマップを追加する前に諦めてしまう原因となっていました。Google はこの度、Quick Start Widget を発表いたします。これによりデベロッパーは、ユーザーが Google Maps Platform を簡単に使い始められるようにし、API キーの生成やウェブサイトやアプリへのマップの埋め込みができるよう支援します。
Quick Start Widget を使用すると、ユーザーは API キーを取得し、面倒なユーザーフローを経由することなく、サイトやアプリでマップを使用できます。ユーザーが最小限の負担で開始できるようにすることが、ユーザーの導入を促すうえで重要になります。新しいウィジェットでは、ユーザーは Google から API キーを確保するためにデベロッパーの提供する環境を離れる必要がなくなります。ユーザーにはアカウントやプロジェクトを設定する簡単かつ一連の手順が提供されます。なお、キーは自動的に作成され、保護されます。
WorkManager は、非同期タスクのスケジュールを簡単に設定するための一連の API を提供します。これにより、アプリが閉じられた場合やデバイスが再起動した場合にも実行されることが期待されるタスクを即時実行または遅延実行できます。また、WorkManager は Kotlin ユーザーに最大級のコルーチンのサポートを提供します。この投稿では、WorkManager Codelab の内容に基づいて、WorkManager とコルーチンの基本について説明します。では早速始めましょう。
ユーザーが特定の画面から離れたり、アプリがバックグラウンド状態になったり、デバイスが再起動したりしても実行を続ける必要があるタスクには、WorkManager ライブラリを使うことが推奨されています。一般的には、以下のようなタスクが考えられます。
ユーザーが画面などの特定のスコープを離れたときに即時実行したタスクが終了する可能性がある場合は、直接 Kotlin コルーチンを使うことを推奨します。
WorkManager Codelab では、画像をぼかしてその結果をディスクに保存します。これを実現するために必要なことを確認しましょう。
まず、work-runtime-ktx 依存性を追加しました。
implementation "androidx.work:work-runtime-ktx:$work_version"
そして、独自の Worker クラスを実装します。ここに、バックグラウンドで実行する実際の作業に必要なコードを含めます。Worker クラスを拡張し、doWork() メソッドをオーバーライドします。これは一番重要なクラスなので、のちほど詳しく説明します。最初の実装は次のようになります。
次に、作業のリクエストを作成します。今回の場合は、作業を一度だけ行いたいので、OneTimeWorkRequest.Builder を使います。入力として、ぼかしたい画像の Uri を設定します。
Kotlin のヒント: 入力データを作成するために、workDataOf 関数を使うことができます。この関数は、データビルダーを作成し、キーと値のペアを格納してデータを作成します。
作業のスケジュールを設定して実行するには、WorkManager クラスを使います。その際に、実行するタスクと、タスクへの制約を指定できます。
Worker を使うと、WorkManager は自動的にバックグラウンド スレッドで Worker.doWork() を呼び出します。doWork() から返される Result は、WorkManager サービスに作業が成功したかどうかと、失敗した場合には作業を再試行すべきかどうかを通知します。
Worker.doWork() は同期呼び出しです。バックグラウンドの作業全体をブロックありで実行し、メソッドが終了するときには完了していることになります。doWork() で非同期 API を呼び出して Result を返すと、コールバックが正しく動作しない場合があります。
もう少し複雑な例として、ぼかしをかけたすべてのファイルの Uri をデータベースに保存する場合を考えてみましょう。
これを実現するために、以下を作成しました。
実装はこちらをご覧ください。
Kotlin でデータベースへのデータの保存やネットワーク リクエストなどの非同期作業を行う必要がある場合は、CoroutineWorker の利用を推奨します。
CoroutineWorker を使うと、Kotlin コルーチンを使って非同期作業を行えます。
doWork() メソッドは suspend メソッドです。つまり、中断を伴う dao を簡単に呼び出すことができます。
デフォルトで、doWork() は Dispatchers.Default を使います。この動作は必要な Dispatcher でオーバーライドできます。今回は、既に Room が挿入作業を別の Dispatcher に移動させているので、これを行う必要はありません。詳しくは、Room Kotlin API の投稿をご覧ください。
ぜひ CoroutineWorker を使って、ユーザーがアプリを閉じても完了しなければならない非同期作業を実行してみてください。
WorkManager についてもっと詳しく知りたい方は、今後のシリーズで詳しく解説しますので、ご期待ください。それまでの間は、Codelab やドキュメントをご覧ください。
DESTINATION_URL_REPORT
FINAL_URL_REPORT
ConversionAttributionEventType
CAMPAIGN_PERFORMANCE_REPORT
ConversionAdjustment
ConversionAdjustmentLagBucket
var report = AdsApp.report(query, { apiVersion: 'v201809' });
// json-rpc request for the list method gapi.client.rpcRequest('zoo.animals.list', 'v2', name:'giraffe'}).execute(x=>console.log(x))
// json-rest request for the list method gapi.client.zoo.animals.list({name:'giraffe'}).then(x=>console.log(x))
// Request URL (JSON-RPC) POST https://content.googleapis.com/rpc?alt=json&key=xxx
// Request Body (JSON-RPC) [{ "jsonrpc":"2.0","id":"gapiRpc", "Method":"zoo.animals.list", "apiVersion":"v2", "Params":{"name":"giraffe"} }]
// Request URL (JSON-REST) GET https://content.googleapis.com/zoo/v2/animals?name=giraffe&key=xxx
// heterogeneous batch request example. // Notice that the outer batch request contains inner API requests // for two different APIs. // Request to urlshortener API request1 = gapi.client.urlshortener.url.get({"shortUrl": "http://goo.gl/fbsS"}); // Request to zoo API request2 = gapi.client.zoo.animals.list(); // Request to urlshortener API request3 = gapi.client.urlshortener.url.get({"shortUrl": "https://goo.gl/XYFuPH"}); // Request to zoo API request4 = gapi.client.zoo.animal.get("name": "giraffe"); // Creating single heterogeneous batch request object heterogeneousBatchRequest = gapi.client.newBatch(); // adding the 4 batch requests heterogeneousBatchRequest.add(request1); heterogeneousBatchRequest.add(request2); heterogeneousBatchRequest.add(request3); heterogeneousBatchRequest.add(request4); // print the heterogeneous batch request heterogeneousBatchRequest.then(x=>console.log(x));
// Split heterogeneous batch request into two homogenous batch requests // Request to urlshortener API request1 = gapi.client.urlshortener.url.get({"shortUrl": "http://goo.gl/fbsS"}); // Request to zoo API request2 = gapi.client.zoo.animals.list(); // Request to urlshortener API request3 = gapi.client.urlshortener.url.get({"shortUrl": "http://goo.gl/fbsS"}) // Request to zoo API request4 = gapi.client.zoo.animals.list(); // Creating homogenous batch request object for urlshorterner homogenousBatchUrlshortener = gapi.client.newBatch(); // Creating homogenous batch request object for zoo homogenousBatchZoo = gapi.client.newBatch(); // adding the 2 batch requests for urlshorterner homogenousBatchUrlshortener.add(request1); homogenousBatchUrlshortener.add(request3); // adding the 2 batch requests for zoo homogenousBatchZoo.add(request2); homogenousBatchZoo.add(request4); // print the 2 homogenous batch request Promise.all([homogenousBatchUrlshortener,homogenousBatchZoo]) .then(x=>console.log(x));
addresses = GMAIL.users().settings().sendAs().list( userId='me' ).execute().get('sendAs')
{ "sendAs": [{ "sendAsEmail": string, "displayName": string, "replyToAddress": string, "signature": string, "isPrimary": boolean, "isDefault": boolean, "treatAsAlias": boolean, "smtpMsa": { "host": string, "port": integer, "username": string, "password": string, "securityMode": string }, "verificationStatus": string }, ...] }
addresses = GMAIL.users().settings().sendAs().list( userId='me', fields='sendAs(sendAsEmail,isPrimary)' ).execute().get('sendAs')
description: Dark hair, in her late thirties. Also goes by the names "Kate" or "Katie". automated-pfif-author: ScrapeMatic 0.5
icrc.org/birthdate: 1976-02-26