生成AIに入力フォームを補完させるボタン

# ビビッときました

BlazorでSmart Componentとやらが発表されました。
動きを見てもらえるとわかりますが、文章をコピーしておくと、入力フォームをいい感じに埋めてくれたりします。


https://github.com/dotnet-smartcomponents/smartcomponents/blob/main/docs/smart-paste.md

これを見て久方に**うおおおぉっ**、てなりまして、Blazor/Razorでこれを使えばいいだけではあるものの、自前実装(Svelte)で同じ動きを実現してみよう！というのが今回の記事の趣旨です。ちなみに、今回はSvelteで実現はしていますが、同じ方法でReactでもVueでもできるかなと。

# できたもの

クリップボードに文章をコピーしてから、AIPasteボタンを押すと、いい感じに入力フォームが補完されるものができました！これ↓ではユーザ登録フォームみたいなのでやってますけど、チケット登録とか、場合によってはこれにRAGいれたりとかすごい使いどころを感じさせますよね。

ちなみに裏側ではAzure OpenAI Serviceのgpt-35-turbo(JSON Mode)を呼んでいます。

![Animation8.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/977156/c0d4dfc7-b876-55a1-bf5d-3b879882f60b.gif)

# やったこと

本当は冒頭のSmartComponentのように、Form内部においたら自動的に入力項目を補完できたらよかったんですが、とりあえずアイディアベースの実現ということで進めました。（このあたりは時間があれば今後改善させてみたいです）
なお、今回Svelteで実現していますが、この方式であればいずれのフロントエンドでもほぼ同じ感じで実現できるかなーと思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/977156/6f2e1957-41ee-a8e6-e117-b884ab7a9641.png)

今回の動作確認では、Azure Static Web Apps を使っています。

青色矢印が入力系です。AIPasteボタンが押されてると、入力フォームとバインドされているJSON Objectと、クリップボードの内容をPOSTします。POST先ではgpt-35-turbo(JSON Mode)を呼びだし、JSON Objectの内容を埋めさせます。

赤色矢印が出力系です。そのJSONをバインドされたJSONに置き換えます。ここは、本当に使うならキー名と内容のチェックはしたいところですね。あとエラーハンドリングや異常系の処理は一切いれてませんので、そのあたりも実際のご利用の際にはご注意ください。

```javascript:AIPasteButton のボタン押下処理関数
    const fill = async () => {
        //クリップボードの内容を取得
        const text = await navigator.clipboard.readText();

        //入力フォームにバインドされているJSONのキーを取得
        const keys = Object.keys(bindObject);
        const keysString = keys.join(', '); // Joining the keys with a comma and a space

        const sendData = {
            keys: keysString,
            text: text
        }

        //キー情報とクリップボードの内容を送信
        const response = await fetch('/api/callgpt', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json'
            },
            body: JSON.stringify(sendData)
        });

        const data = await response.json();

        //返り値のJSONをバインド
        bindObject = JSON.parse(data.jsonStr);
    }
```

受け取ったFunctionsではchatgptを以下のプロンプトでJSON Mode呼び出しをします。
```javascript
        const system_prompt = `
        あなたはJSON生成器です。以下のキー情報に入力された内容をマッピングしたJSONを生成します。
        #キー情報: ${keys}
        `;

        const user_prompt = text;

        const messages = [
            {role: "system", content: system_prompt},
            {role: "user", content: user_prompt}
        ]

        const result = await client.getChatCompletions(
            model, 
            messages, 
            {responseFormat: { type: "json_object" }}
        );
```

基本的な仕組みはこれだけです。


なので入力フォームとバインドしたJSONを、AIPasteButtonに渡す必要があります。この点、冒頭のSmartComponentはうまく隠してくれていていいなぁと思いつつ、明示的にやるのも大事ですよねー。

今回検証をしたAzure Static WebApps全体を含んだソースコードはこちらです。

https://github.com/shyamagu/AIPasteButtonSample

AIPasteButton.svelteだけを見たい場合はこちらをどうぞ

https://github.com/shyamagu/AIPasteButtonSample/blob/main/src/routes/AIPasteButton.svelte

# これからのこと

久々にAIの利用シナリオとしてビビっときました。メールやドキュメントを見ながら入力フォームをいれるなんてよくあるシナリオだと思いますし、入力フォームを埋めるだけではなくRAGもつかって、さらなる補完をするなんてのもありですよね。

普段やっている（面倒くさい）ひと手間を生成AIの力をかりて、まだまだ改善できるところは多そうです。
というわけで、入力フォームを生成AIで補完させるボタンの紹介でした。

<br />