Zennを例に Gen App Builder の Enterprise Search 活用方法を考察する
2023年6月、Generative AI App Builder の Enterprise Search(以下、Enterprise Search)に関するブログが投稿されました。
その後、Wait list への登録が始まったので、Zennの検証プロジェクトも登録、待機していたところ、先日使えるようになりました。最初に使用感を紹介します。
まずは使ってみる
Google Cloud の Gen App Builder 管理画面を開きます。 https://console.cloud.google.com/gen-app-builder/engines
その後、新しいアプリを作成できるので、ウィザードへ遷移します。このような画面が表示されるので入力を進めます。
- アプリのタイプ: 検索
- エンジン名の設定: 任意です。
zenn-test-app-search
としました。 - 高度なLLM機能: 有効
続いてデータストアの作成は、ウェブサイト
としました。
作成します。最後にデータストアのウェブサイト、つまり検索させたいURLを指定します。
今回はZenn全体を検索してみたいので、zenn.dev/*
と指定しました。以下のような状態になるので、プレビューへ進みます。
プレビューでは実際に検索が実行できます。Next.js app router
と入力した結果です。
なかなかいい感じですね!ここまでの数ステップでサイト内検索が実行できました。アプリケーションへの組み込みは、ウィジェットを埋め込んだり、HTTP経由でJSONを取得することもできるため、それらが利用できそうです。
ユースケース
ひととおり触ってみたところで、ユースケースについて考えてみます。そもそもの話、Google Cloud の Gen App Builder は何者なのでしょうか。
ブログによると、生成AIサービスの一部
とあり、
- 基盤モデルの作成
- 基盤モデルに対する検索インタフェース
- 基盤モデルに対する会話型インタフェース
これらをすばやく提供するサービスとあります。一番シンプルなのは、上記で設定したような、すでに公開しているサイトに対するGoogleライクな検索です。この場合、公開されているWebサイトのデータからGoogleが勝手にモデルを生成してくれるため、開発者体験としては1はないに等しいです。あまりにもすぐに利用できるため、すでにGoogle検索で利用しているモデルをそのまま利用しているのではないかと疑っています🤔
いずれにせよ、Gen App Builder は情報を探すことに特化した生成AI組み込みキットといえます。公開ウェブサイトであるZennに絞って、ユースケースを考えてみます。
サイト内検索
最初に思いつくのはサイト内検索です。Zennでも検索ページを用意していますが、本文の検索には対応していません。Enterprise Searchを使えば、シンプルかつ強力なサイト内検索機能が実装できそうです。Googleカスタム検索とは異なり、Google Cloud のサービスとして提供されるため、アプリケーションの一部として組み込みやすいメリットがあります。一方、プレビューで表示したように、結果として得られる情報はあくまでGoogleがインデックスしたものになりそうなので、体験がGoogle検索に近くなってしまいそうです。Zennで全文検索の変わりに利用できるかもと考えましたが、そのまま使うのは違和感があるかもしれません。
Book内の検索
Zennには多種多様のBookが公開されており、中には50チャプター超えのものもあります。たいていの場合、チャプター1から順番に読んでいくことを想定していると思いますが、後から読み返すときなどBook全体の検索が欲しくなるかもしれません。ためしに私のBook内で検索してみます。
この本でGraphQLのメリットについて書かれてた気がするけど、どこだっけ… というシーンを想定。
なかなかいい精度ですね!NestJSやCloud Runのメリットではなく、GraphQLそのもののメリットについて述べている部分が上位に表示されているのもポイントが高いです。当該チャプターに直接飛べるため、Googleライクな検索が割り切れるのならばアリだと思いました。
Publication内の検索
これはどちらいかというとPublicationをご利用中の皆様に提供する機能という位置づけになりそうです。切り貼りですがこのようにPublicationのトップページで検索できるイメージ。
さすがにUI的にはもう一声ほしいところですが、機能的には十分かもしれません。
API での利用
ここまではプレビューで利用しましたが、API経由での利用も可能です。Google Cloud のコンソールからコマンドを取得できます。
curl -X POST -H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "Content-Type: application/json" \
"https://discoveryengine.googleapis.com/v1alpha/projects/xxxxxxxxxx/locations/global/collections/default_collection/dataStores/zenn-test-app-search/servingConfigs/default_search:search" \
-d '{"query":"GraphQL メリット","pageSize":10,"queryExpansionSpec":{"condition":"AUTO"},"spellCorrectionSpec":{"mode":"AUTO"}}'
{
"results": [
{
"id": "0",
"document": {
"id": "0",
"derivedStructData": {
"htmlFormattedUrl": "https://zenn.dev/waddy/books/\u003cb\u003egraphql\u003c/b\u003e-nestjs.../overview_from_frontend",
"htmlTitle": "フロントエンドから見た\u003cb\u003eGraphQL\u003c/b\u003e|\u003cb\u003eGraphQL\u003c/b\u003e スターターパック ...",
"pagemap": {
"cse_image": [
{
"src": "https://res.cloudinary.com/zenn/image/upload/s--fBV2XRoH--/g_center%2Ch_280%2Cl_fetch:aHR0cHM6Ly9zdG9yYWdlLmdvb2dsZWFwaXMuY29tL3plbm4tdXNlci11cGxvYWQvYm9va19jb3Zlci9mM2RjMTNmZDkwLnBuZw==%2Cw_200/v1627283836/default/og-base-book_yz4z02.jpg"
}
],
"cse_thumbnail": [
{
"width": "310",
"src": "https://encrypted-tbn1.gstatic.com/images?q=tbn:ANd9GcTXNXwhcb9cQ4lxVdCMEEqVUioGZ3J2j8W7h53tfqc6v_t3jHekfH6AmLk",
"height": "162"
}
],
"metatags": [
{
"og:type": "article",
"og:url": "https://zenn.dev/waddy/books/graphql-nestjs-nextjs-bootcamp/viewer/overview_from_frontend",
"zenn:description": "waddy_uさんによる本",
"og:image": "https://res.cloudinary.com/zenn/image/upload/s--fBV2XRoH--/g_center%2Ch_280%2Cl_fetch:aHR0cHM6Ly9zdG9yYWdlLmdvb2dsZWFwaXMuY29tL3plbm4tdXNlci11cGxvYWQvYm9va19jb3Zlci9mM2RjMTNmZDkwLnBuZw==%2Cw_200/v1627283836/default/og-base-book_yz4z02.jpg",
"viewport": "width=device-width, initial-scale=1",
"og:site_name": "Zenn",
"next-head-count": "12",
"apple-mobile-web-app-title": "Zenn",
"twitter:card": "summary_large_image",
"og:title": "フロントエンドから見たGraphQL|GraphQL スターターパック | Prisma + NestJS + Next.JS製 個人ブログサイトをCloud Runで運用しよう"
}
]
},
"title": "フロントエンドから見たGraphQL|GraphQL スターターパック ...",
"link": "https://zenn.dev/waddy/books/graphql-nestjs-nextjs-bootcamp/viewer/overview_from_frontend",
"formattedUrl": "https://zenn.dev/waddy/books/graphql-nestjs.../overview_from_frontend",
"displayLink": "zenn.dev",
"snippets": [
{
"htmlSnippet": "May 9, 2022 \u003cb\u003e...\u003c/b\u003e インストール; Apollo Client の初期化; バックエンド側:\u003cb\u003eGraphQL\u003c/b\u003e ... フロントエンドで\u003cb\u003eGraphQL\u003c/b\u003eを使う\u003cb\u003eメリット\u003c/b\u003eはわ かりやすく、バックエンドとの通信 ...",
"snippet": "May 9, 2022 ... インストール; Apollo Client の初期化; バックエンド側:GraphQL ... フロントエンドでGraphQLを使うメリットはわかりやすく、バックエンドとの通信 ..."
}
]
}
}
}
]
}
検索結果に表示するためのURL、タイトル、スニペットが取得できることがわかります。API経由でデータを取得し、うまくUIに統合できると違和感を減らせそうです。
料金
記事執筆時点では、非公開情報でした。
まとめ
公開されたウェブサイトのEnterprise Searchに絞って、Zennならどう使うかを考えてみました。活用できそうなケースはいくつかあるものの、以下の点を継続的に考えていきます:
UIの統合
Enterprise Search で得られる結果は公開されたHTMLに依る部分が大きく、結果として検索の体験がGoogle検索に近くなります。より自然にアプリケーションに溶け込ませるためには、公開されたHTMLではなく検索用の構造化データをインポートして利用することも検討するべきかもしれません。
検索時のパス指定
いまはApps単位で検索対象のパスを指定する仕様ですが、本やPublicationごとにEnterprise Searchを用意する場合、都度Appsを用意するのは大変です。実現可能性がどの程度が微妙ですが、Appsの設定としてではなく、検索クエリにサイトやパスを組み込めると活用の幅が広がりそうです。
Enterprise Search の使用感がイメージできれば幸いです。
Webサイトのデータ
以外のことはじめ
本稿では公開ずみのWebサイトのデータを使ってEnterprise Searchを使ってみました。DevelopersIOで山本さんがPDFファイルをインポートして検索する例を実装しているので、こちらもご参照ください。
参考
Discussion