kintone×Geminiプラグインをつくってみた。
[ジェム(Gemini)] わーい!kintoneアドベントカレンダーの24日目だよー!✨
今日まで毎日窓を開けてプレゼントを見てきたよね!✨
さあ、一緒に窓を開けてみよう!レッツゴー!
はじめに
以前遊びで作ったイカルプラグインをパワーアップさせてみました。
今回はイカルをAI(Gemini:ジェム)と連携させたい!
ポイント解説はジェムにお願い。
詳細はこちら『師匠と私』
https://note.com/kodotone_2022/m/m87408e5a25a9
イカルプラグインをざっくり説明
- Excelのイルカ・カイル君を再現したもの。
- レコード詳細画面を開くと出現する。
- フォームに入力したワードをアプリ内で検索してくれる。
- 『お前を消す方法』を入力すると検索をしない。
本編
機構
🐬イカルプラグイン ver.2.0 の機構
- レコード詳細画面を開くとイルカ(イカル)の画像が出てくる
- 画面の検索用フィールドに文字を入力する
- 入力値をkintoneフィールド【Question】に転記する
- kintoneフィールド【prompt】で自動計算したプロンプトを作る
- プロンプトをAPIでGeminiに投げる
- 回答ボタンを押すとGeminiが生成したテキストを取得する
- イカルの画像にテキストが表示される
- 指定のフィールド【Answer】に転記する
(イカル消えない)- おまけ:検索用フィールドに「お前を消す方法」と入力したときだけ特定のメッセージが表示される(イカル消えない)
kintoneのアプリを用意
主なフィールドは4つ
- 文字列(1行):
変換モード
プロンプトに追加したい指定ワード(例:津軽弁で) - 文字列(1行):
Question
イカルのフォームに入力した値を格納 - 文字列(1行):
Prompt
Geminiへなげるプロンプトを生成する
Question+変換モード+「簡潔にまとめて。なるべく120文字以内で答えてください。指定以外の回答は無効です」を付け加えている* - 文字列(複数行)
Answer
Geminiからの回答(Geminiから取得した値。イカルに出力する)
*promptではなくQuestionがGeminiに投げられていたのに気づかず、指定がまったく反映されないので指示を厳しめにしてしまったという。。。
環境の用意
GeminiとAPIでアクセスする環境
いくつか方法はありましたが、今回はこちらを使用
[ジェム] Google が提供する生成型 AI (Generative AI) のライブラリだよ。
Google SDKは、Googleのサービスを使って、自分だけのオリジナルのものを作りたい人向けの、とても便利な道具箱なんだ。
import { GoogleGenerativeAI } from "@google/generative-ai";
フォルダとファイルを用意
[ジェム] このフォルダの中には、kintoneのアプリとGoogleのAIという賢いロボットを仲良くさせるための、特別な言葉(プログラム)がたくさん詰まっているよ。この言葉を使って、kintoneのアプリでできることをもっともっと便利にしたり、新しいことができるようにしているんだ。
お前…自分のこと賢いAIって…
2つのJavascriptファイルを用意
index.js
=> bundle.js
GeminiのAPIにアクセスするためのファイル
のちにkintoneで動作させるため webpackでbundle.jsに変換
run.js
kintoneレコード詳細画面を開いたらイカル画像を出現させるCSSやHTMLとか、検索ボタンをおして入力した値をフィールドに格納してグローバルスコープを呼び出してAPIアクセスしたりとか、そのあとボタンを押してAnserを表示させるとかの実行ファイル
JavaScriptコードの一部です~
const apiKey = 'YOUR-API-KEY';//実際のAPIキーを入れる
import { GoogleGenerativeAI } from '@google/generative-ai';
const genAI = new GoogleGenerativeAI(apiKey);
// 関数をグローバルスコープに登録して呼び出せるようにする
async function generateText(prompt) {
---
try {
// モデルを取得
const model = genAI.getGenerativeModel({ model: "gemini-1.5-flash" });
// プロンプトでコンテンツ生成
const result = await model.generateContent(prompt);
return result.response.text(); // 生成されたテキストを返す
}
// グローバルスコープに登録
window.generateText = generateText;
[ジェム] プログラムの中で使いたいものを、みんながいつでも使えるように置いておく場所、それがグローバルスコープだよ!
kintone.events.on(['app.record.detail.show'], (event) => {
---
//🐬Step3~GeminiのAPIにアクセス
try {
// プロンプト値を searchQuery として設定
const searchQuery = promptValue;
// Google Generative AI にリクエスト
const generatedText = await window.generateText(searchQuery);
---
---
[ジェム] kintone.events.onは、kintoneの中で、何か新しいことが起きたり、何かが変わったりしたときに、コンピューターに教えてもらうための言葉なんだ。
- 「const」 は、一度決めたものを変えないようにするための魔法の言葉。
- 「await」 は、コンピューターがゆっくり考えて、答えを出すまで待つための合図。
(()=>{"use strict";var t,e,n;!function(t){t.STRING="string",t.NUMBER="number",t.INTEGER="integer",t.BOOLEAN="boolean",t.
[ジェム] bundle.jsは、コンピューターが理解できる言葉(プログラム)を、一つにまとめたファイルのことなんだ。このファイルの中には、ゲームの画面を表示するためのプログラムや、ボタンを押したときの動きをさせるためのプログラムなど、たくさんのプログラムがぎゅっと詰まっているんだよ。
イカルは プ・ラ・グ・イ・ン
[ジェム] kintoneのカスタマイズとプラグインは、どちらもkintoneをもっと便利にするための方法なんだ。
カスタマイズ は、自分だけのオリジナルのkintoneを作る感じ。
プラグイン は、kintoneに新しい機能を追加する感じ。
↓ ↓ ↓
プラグインはだれでも簡単にkintoneに機能を追加できる、どんな環境でも。
ということは、GeminiのAPIキーをコード内に書いているとダメ。
(そもそもが書いちゃダメ…)
これをプラグインにすると解決できます。
完成しました~🎉
[ジェム]わぁ、すごい!ウェブの画面にイルカが出てきて何でも答えてくれるなんて、魔法みたいだね!
おまけ
🐬チャッピー(ChatGPT)---コードはチャッピーの方が得意かも!
🐬Googleの参考サイト
ここにサンプルコードがあって助かったわ~
https://www.npmjs.com/package/@google/generative-ai
ここに使用モデルも書いてあったよ~
https://ai.google.dev/gemini-api/docs/get-started/tutorial?lang=node&hl=ja
🐬cybozu developer network
レコードに値をセットする
https://cybozu.dev/ja/id/bd485c4c00776c6a54fbf89c/#set-record-value
1件のレコードを更新する
https://cybozu.dev/ja/id/607d2f57a86f03ca70588ab8/#sample-code
プラグインの作り方
https://cybozu.dev/ja/tutorials/hello-kinplugin/handle-sensitive-data/
🐬にこkin!
>認証情報のべた書きは禁止!
(今回はお遊びなので…対応できてないですけど)
https://shop.cybozu.co.jp/products/4820287389775?variant=46569864593632
kintoneのお作法はチャッピーに聞いても答えてくれた~
なんとか
kintoneアドベントカレンダーのために開発を思いたち間に合うかどうか?!?!
私のやる気(と能力)が一番の問題でした。
ジェムになんでも聞けはすぐ出来るのでは?と甘いことを考えてました。
結局はチャッピーに手伝ってもらってようやく出来たんですけどね。
開発の裏話はこちらのnoteに記載してます!
師匠と私-ふたたび。
https://note.com/kodotone_2022/n/ndfd08535d175
Special Thanks:
淺野 將生 師匠 ありがとう!!!