O'Reilly Answersは、技術的な質問に対してAI駆動の検索を提供するサービスだ。ユーザーが自然言語で質問を入力すると、O'Reillyの書籍コンテンツから関連性の高いスニペットを抽出して回答を表示する。 技術面では、Miso社がBERTやllama 3など複数のLLM技術を組み合わせたパイプラインで開発している。
ただし現状の課題として、O'Reilly Answersは英語でしか利用できない。O'Reillyには日本語の書籍も多数あるものの、検索は英語で行う必要がある。そして英語で検索すると日本語の書籍はヒットしない。コンテンツの大半が英語であることを考えれば許容できなくもないが、日本語での文章検索ができればより便利だろう。
そこで、この課題を解決するため、書籍の公開情報を取得して、日本語で質問して検索できるウェブアプリを即興で作った。さっき。以下にデプロイしてある。
使う道具はいつものようにサーバーレスなアーキテクチャで構築した。モデルとしてはGeminiを採用した。まずオライリーの書籍データをスクレイピングしてクソデカJSONファイルとして保存。このデータをJSONL形式でシステムプロンプトに組み込み、ユーザーからの質問と組み合わせることで、検索から結果の整形までをGeminiに一任している。 書籍データは静的なため、GeminiのプロンプトキャッシュAPIを活用してコスト効率を向上させた。これをする前は、当初は埋め込み形式で事前に書籍データを変換して、Firestoreを使ったベクトル検索を試していたが、途中でGeminiの100万トークン制限内に全データが収まることが判明し、現在の方式に落ち着いた。
フロントエンドの実装では、Vercelのスタックを最大限活用して自動化を図った。Vercel AI SDKを使ってGemini APIを呼び出し、ストリーミングレスポンスを返すServer Actionを構築。さらにVercel AI SDKのRSC版でストリーミング対応のUIを実装し、スタイリングはv0.devに本家サイトのスクショを送っていい感じによろしくと依頼した。
このアプリには本家と比べていくつかの制約がある。公開情報のみを参照しているため書籍の内容自体は使用しておらず、本家のような詳細な回答は生成できない。そのため、関連書籍への参照リンクを提示する仕様とした。 それにオライリーの書籍は、すべて換算すると全期間で6万件もの膨大なタイトルがある(すごい)。なのでオライリー社の日米のみとして、今回は範囲も直近2年の発売タイトルに限定した。技術書のカバー範囲としてはこれは物足りない面がある。
実際に運用して使ってみると、いくつかの技術的な制約が見えてきた。この設計は入力トークンが長くなり、それによって出力のコメントが短くなる。なので生成時のトークンパラメータを調整した。また、レスポンスをプレーンテキストではなくRSCにマッピングするために、構造化レスポンスを2段階で処理するため、ここでさらにトークンを消費してしまう。
アプリとしてはキーワードベースの検索では概ね関連するタイトルを提示できるものの、質問文を解釈してフレンドリーな解説を返すという点では本家の完成度には及ばない。本文チャプターを参照してないからしょうがない。ただし、そもそも本家O'Reilly Answersの利用状況も気になるところだ。
一方で、このプロジェクトは要素技術の学習という観点では有意義だった。特に、Vercel Deploy、v0.dev、AI SDK、Next.jsといったVercelスタック+各種SaaS(この場合Google CloudのAPI)を組み合わせた開発フローは、驚くほど時短だった。Vercel最高。ついでに個人の商用利用制限も緩和してください。
昨今は、RAGのPoCをしゃぶり尽くした人たちがAIエージェントパッケージの金脈を掘り当てるフェーズにありそうだが、LLMの「テキスト(トークン化したデータ)生成による自動化範囲の拡大」という基礎技術の部分だけでもまだより実用的なサービスとして展開できる可能性があると思っている。ただし地味だ。今回やったプロンプトキャッシュAPIの活用とかモデルプロバイダ以外がやるのはハードな上にかなりマイナーだが面白い。
AI検索サービスの実用性と採用については、まだまだ検証の余地がありそうだ。