Upgrade to Pro — share decks privately, control downloads, hide ads and more …

LLM開発に使えるFirebaseの新機能

 LLM開発に使えるFirebaseの新機能

Firebase Genkit、 Cloud Functions for FirebaseのPythonについてお話しします。 どちらもFirebaseに新たに追加されたもので、LLM開発をしていく上で、非常に便利に使える機能になります。 実際にコードを書きながら使えるところまでの説明をしますので、気になる方はぜひご参加ください。

https://sonicgarden.connpass.com/event/324540/

Avatar for スキルアップ勉強会

スキルアップ勉強会

August 19, 2024
Tweet

More Decks by スキルアップ勉強会

Other Decks in Programming

Transcript

  1. Firebase Genkitとは? '直感的なオープンソース フレームワーク、ローカル デベロッパー ツール、統合クラウド サービスを使用し て、モバイルアプリやウェブアプリで高度な AI 機能を構築し、リリースできます'

    要は、オープンソースでLLMの機能開発が可能なフレームワーク 必要なのはNode.js(20以降推奨) 主な機能 1. 多数のモデル、1 つのインターフェース 2. 構造化出力 3. Dotprompt によるプロンプト管理 4. 作った関数をローカル実行し、履歴を保存できる 公式によると、
  2. Firebase Genkitとは? '直感的なオープンソース フレームワーク、ローカル デベロッパー ツール、統合クラウド サービスを使用し て、モバイルアプリやウェブアプリで高度な AI 機能を構築し、リリースできます'

    要は、オープンソースでLLMの機能開発が可能なフレームワーク 必要なのはNode.js(20以降推奨) 主な機能 1. 多数のモデル、1 つのインターフェース 2. 構造化出力 3. Dotprompt によるプロンプト管理 4. 作った関数をローカル実行し、履歴を保存できる 公式によると、
  3. 多数のモデル、1つのインターフェース OpenAI Google Genkitを使った場合 generate で全て書ける 参考までに引数 model: 利用するモデル prompt:

    LLMに入力する基本的なメッセージ history: 今までの会話 context: リトリーバーのドキュメント(RAGで使う やつ) LLMのAPIは、各社ほぼ同じだが、ちょっとずつ違う { "model": "gpt-4o-mini", "messages": [{"role": "user", "content": "Say this is a "temperature": 0.7 } { "contents": [ {"role":"user", "parts":[{ "text": "Write the first line of a story about a ma }] }, ] } const llmResponse = await generate({ model: gemini15Flash, prompt: 'Tell me a joke.', }); console.log(await llmResponse.text());
  4. Dotprompt によるプロンプト管理 プロンプトとは? LLMは、文字列(もしくは画像、音声など)のインプットに対して、確率的に適切なアウトプットをするもの。 このインプットがプロンプトであり、LLMの生成結果は、このプロンプトによって決まる。そのためLLMを利 用するには重要な要素になる。 プロンプトは、基本的に文章になるのでプログラムの中に内包されると見にくくなる。 プロンプトをプログラムと分離して、個別に管理できる仕組み const llmResponse

    = await generate({ model: gemini15Flash, prompt: ` LLMについてお話しする勉強会のためのスライド作成をお願いします。 参加者は、初心者から上級者まで、くることが予想されますが、比率としては初心者が多いでしょう。 以下に、人数と伝えたない内容を箇条書きするので、それで叩き台を作ってください。 ・人数: ${count} ・・・・・・ `, });
  5. Dotpromptのサンプル レストランのメニューを生成するプロンプト --- model: vertexai/gemini-1.5-flash input: schema: theme: string output:

    format: json schema: name: string price: integer ingredients(array): string --- Generate a menu item that could be found at a {{theme}} themed restaurant.
  6. Dotpromptのサンプル モデルを指定 レストランのメニューを生成するプロンプト model: vertexai/gemini-1.5-flash --- input: schema: theme: string

    output: format: json schema: name: string price: integer ingredients(array): string --- Generate a menu item that could be found at a {{theme}} themed restaurant.
  7. Dotpromptのサンプル インプットとアウトプットの形式を指定 レストランのメニューを生成するプロンプト input: schema: theme: string output: format: json

    schema: name: string price: integer ingredients(array): string --- model: vertexai/gemini-1.5-flash --- Generate a menu item that could be found at a {{theme}} themed restaurant.
  8. Dotpromptのサンプル プロンプト本体を書く レストランのメニューを生成するプロンプト Generate a menu item that could be

    found at a {{theme}} themed restaurant. --- model: vertexai/gemini-1.5-flash input: schema: theme: string output: format: json schema: name: string price: integer ingredients(array): string ---
  9. Dotpromptのサンプル レストランのメニューを生成するプロンプト Generate a menu item that could be found

    at a {{theme}} themed restaurant. --- model: vertexai/gemini-1.5-flash input: schema: theme: string output: format: json schema: name: string price: integer ingredients(array): string ---
  10. 単純な回答アプリケーション プロンプトファイルを作成して、フロー(処理のまとまり)を定義する。 --- model: vertexai/gemini-1.5-flash input: schema: question: string ---

    Firebaseに関する質問を受け答えする。質問は以下の通り。 {{ question }} Firebase以外の質問には答えない。 export const stepOneFirebaseQuestionFlow = defineFlow( { name: "stepOneFirebaseQuestionFlow", inputSchema: z.string(), outputSchema: z.string(), }, async (question: string) => { const simpleFirebaseQuestionPrompt = promptRef("simpleFirebaseQuestion"); const result = await simpleFirebaseQuestionPrompt.generate({ input: { question }, }); return result.text();
  11. RAGを使った回答アプリケーション const testableFirebaseRetriever = defineFirestoreRetriever({ name: "testableFirebaseRetriever", firestore, collection: "testableFirebases",

    contentField: "text", vectorField: "embedding", embedder: textEmbeddingGecko, distanceMeasure: "COSINE", }); const docs = await run("Retriever", () => retrieve({ retriever: testableFirebaseRetriever, query: question, options: { limit: 3 }, }) ); const firebaseRAGQuestionPrompt = promptRef("firebaseRAGQuestion"); const result = await firebaseRAGQuestionPrompt.generate({ input: { question }, context: docs, }); return result.text();
  12. RAGを使った回答アプリケーション const testableFirebaseRetriever = defineFirestoreRetriever({ name: "testableFirebaseRetriever", firestore, collection: "testableFirebases",

    contentField: "text", vectorField: "embedding", embedder: textEmbeddingGecko, distanceMeasure: "COSINE", }); const docs = await run("Retriever", () => retrieve({ retriever: testableFirebaseRetriever, query: question, options: { limit: 3 }, }) ); const firebaseRAGQuestionPrompt = promptRef("firebaseRAGQuestion"); const result = await firebaseRAGQuestionPrompt.generate({ input: { question }, context: docs, }); return result.text();
  13. RAGを使った回答アプリケーション const docs = await run("Retriever", () => retrieve({ retriever:

    testableFirebaseRetriever, query: question, options: { limit: 3 }, }) ); const testableFirebaseRetriever = defineFirestoreRetriever({ name: "testableFirebaseRetriever", firestore, collection: "testableFirebases", contentField: "text", vectorField: "embedding", embedder: textEmbeddingGecko, distanceMeasure: "COSINE", }); const firebaseRAGQuestionPrompt = promptRef("firebaseRAGQuestion"); const result = await firebaseRAGQuestionPrompt.generate({ input: { question }, context: docs, }); return result.text();
  14. RAGを使った回答アプリケーション const firebaseRAGQuestionPrompt = promptRef("firebaseRAGQuestion"); const result = await firebaseRAGQuestionPrompt.generate({

    input: { question }, context: docs, }); return result.text(); const testableFirebaseRetriever = defineFirestoreRetriever({ name: "testableFirebaseRetriever", firestore, collection: "testableFirebases", contentField: "text", vectorField: "embedding", embedder: textEmbeddingGecko, distanceMeasure: "COSINE", }); const docs = await run("Retriever", () => retrieve({ retriever: testableFirebaseRetriever, query: question, options: { limit: 3 }, }) );
  15. 場合分けを含む回答アプリケーション 常にRAGが必要ではないときは、回答内容をLLMに判断してもらい、RAGを使うか判断し動かす。 判断によって処理内容を変える場合は、jsonを使ったアウトプットが有効。 Test以外のことはLLMの知識で答えてもらい、TestのときはRAGを使う --- model: vertexai/gemini-1.5-flash input: schema: question:

    string output: format: json schema: needDocs: boolean question: string answer: string --- Firebaseに関する質問を受け答えする。質問は以下の通り。 {{ question }} Firebaseに関する質問に対して、回答を生成する。 Firebaseのテストに関わることを質問している場合は、needDocをtrueにして、検索に必要なcontentをquestionに入れ、answerは空文字列を入れる。 必要ない場合は、needDocをfalseにして、questionを空文字列にして、answerに回答を入れる。
  16. そもそもCloud Functions for Firebaseって? サービス名 対応言語 デプロイ方法 細かい設定 Cloud Functions

    Node.js, Python, Go, Java, C#, Ruby, PHP Google Cloud Console or gcloud コマンド 横に同じ Cloud Functions for Firebase Node.js, Python firebaseコマンド コードに全て 記載 制限がある分、シンプルにFirebaseコマンドとコードのみでサーバーサイドの関数を作成できる便利なサービ ス。 もともとはNode.jsのみだったが、AI関係の盛り上がりでPythonがプレビューで登場! Google CloudのCloud Functionsを、さらにシンプルにコーダブルに書けるサーバレスサービス
  17. 実際のやり方 1. npmでfirebaseコマンドを取得する 2. firebaseコマンドをログイン状態にする 3. firebase initで新しいプロジェクトの作成と必要ファイル生成 4. コードを書き換える

    5. firebaseコマンドでデプロイする 6. エラーの通り対応する 課金アカウントを設定する,venvの設定を行う,pythonのバージョン合わせ,メモリ増強,Vertex AI APIの有効化 npm i -g firebase-tools firebase login firebase init functions firebase deploy --only functions
  18. # Welcome to Cloud Functions for Firebase for Python! #

    To get started, simply uncomment the below code or create your own. # Deploy with `firebase deploy` from firebase_functions import https_fn from firebase_admin import initialize_app # initialize_app() # # # @https_fn.on_request() # def on_request_example(req: https_fn.Request) -> https_fn.Response: # return https_fn.Response("Hello world!")
  19. # Welcome to Cloud Functions for Firebase for Python! #

    To get started, simply uncomment the below code or create your own. # Deploy with `firebase deploy` from firebase_functions import https_fn from firebase_admin import initialize_app initialize_app() @https_fn.on_request() def on_request_example(req: https_fn.Request) -> https_fn.Response: return https_fn.Response("Hello world!") Pythonのバージョンが3.12じゃない場合は、firebase.jsonに`"runtime": "python311",`などを追加。 以下のコマンドでvenvを追加し、必要なpackageのインストール Cloud Functionsは無料プランでは利用できないため、有料プランへアップグレードを行う。 それが終わったらさらにデプロイ。 python -m venv venv source ./venv/bin/activate pip install -r requirements.txt
  20. from firebase_functions import https_fn from firebase_admin import initialize_app from langchain_core.messages

    import HumanMessage, SystemMessage from langchain_google_vertexai import ChatVertexAI from langchain_core.output_parsers import StrOutputParser initialize_app() @https_fn.on_request() def on_request_example(req: https_fn.Request) -> https_fn.Response: model = ChatVertexAI(model="gemini-1.5-flash") messages = [ SystemMessage(content="Translate the following from English into Italian"), HumanMessage(content="hi!"), ] result = model.invoke(messages) parser = StrOutputParser() return https_fn.Response(parser.invoke(result)) LangChainを使うためにpackageのインストールを行う pip install langchain langchain_google_vertexai pip freeze > requirements.txt
  21. from firebase_functions import https_fn, options from firebase_admin import initialize_app from

    langchain_core.messages import HumanMessage, SystemMessage from langchain_google_vertexai import ChatVertexAI from langchain_core.output_parsers import StrOutputParser initialize_app() @https_fn.on_request( memory=options.MemoryOption.GB_1, ) def on_request_example(req: https_fn.Request) -> https_fn.Response: model = ChatVertexAI(model="gemini-1.5-flash") messages = [ SystemMessage(content="Translate the following from English into Italian"), HumanMessage(content="hi!"), ] result = model.invoke(messages) parser = StrOutputParser() return https_fn.Response(parser.invoke(result)) Firebaseコンソールからエラー内容を確認。 メモリ不足であることがわかるので、メモリを増強して完成!
  22. from firebase_functions import https_fn, options from firebase_admin import initialize_app from

    langchain_core.messages import HumanMessage, SystemMessage from langchain_google_vertexai import ChatVertexAI from langchain_core.output_parsers import StrOutputParser initialize_app() @https_fn.on_request( memory=options.MemoryOption.GB_1, ) def on_request_example(req: https_fn.Request) -> https_fn.Response: model = ChatVertexAI(model="gemini-1.5-flash") messages = [ SystemMessage(content="Translate the following from English into Italian"), HumanMessage(content="hi!"), ] result = model.invoke(messages) parser = StrOutputParser() return https_fn.Response(parser.invoke(result))
  23. END