NFTを用いた生成AI出力真正性確認システムの開発

# 0. 導入
## 0-1. テーマ
「NFTを用いた生成AI出力真正性確認システム」

## 0-1. 目的
生成AIが著しく進化しており、その利便性や有用性が大きく注目されており、その一例として「Fine-tuning」や「RAG(Retrieval-Augmented Generation)」と呼ばれる技術を用いて、既存のLLM(Large Language Model)を拡張することにより、組織のデータを反映したAIを構築することが可能になっています。
しかし、これらの技術の利用には「事実とは異なる内容」や「文脈と無関係な内容」といった誤情報をAIが生成する「ハルネーション」が懸念されており、このハルネーションに対する対策が求められています。
そこで、本システム開発では発生してしまった「ハルシネーション」に対して責任の所在やその影響を明確にする手法として、ブロックチェーン上に質問とその回答をNFT化して記録することにより、AIに対する質問の出入力を保証するシステムを提案します。

# 1. 準備
## 1-1. 開発環境の準備
開発に伴い、成果報告書記入時点における以下の環境を構築しました。 
### 開発環境
IDE：IntelliJ IDEA 2024.3.3 (Ultimate Edition)
PC：MacBook Air Apple M1, 2020
OS：macOS Sequoia 15.3.1 (24D70)
ブラウザ：Google Chrome Version 133.0.6943.126 (Official Build) (arm64)

### フロントエンド
Next.jsを用いてVercel上に構築しました
Next.js(v15.1.7), Node.js(v22.12.0), HTML, CSS, TypeScript(v5.7.3), Tailwind(v3.4.1) など

### バックエンド
Express.jsとServerless Frameworkを用いてAWS Lambda上に構築しました
Node.js(v20), Serverless Framework(v4.7.0), TypeScript(v5.7.3), Express.js(v4.21.2)

### ブロックチェーン
Remixで開発をし、Sepolia Testnet上に構築しました
Metamask, Solidity(v0.8.25)

また、開発に必要なAPIなどの準備をしました。

## 1-2. 学習モデルの準備
ChatGPTのAIモデル作成のためにまずは以下のjsonl形式のデータセットを準備しました。

https://github.com/TAKAYAMAN2180/ai-dataset/blob/main/data.jsonl

このデータセットには学園祭に関する100個くらいのデータが含まれており、OpenAIの以下のドキュメントをもとに構築しています。

https://platform.openai.com/docs/guides/fine-tuning#preparing-your-dataset

#### データの例
各行が1つの学習例（ユーザーの質問とアシスタントの回答）になっており、{"messages": [...]}という構造で記述しました。
``` data.jsonl
{"messages":[{"role":"user","content":"出店料金と火器使用時の追加料金について説明してください。"},{"role":"assistant","content":"出店料金は8000円ですが、火器を使用する場合はプロパンガス代およびその他備品の費用が別途加算されます。"}]}
```


## 1-3. ブロックチェーンウォレットの準備
### ウォレットの開設
今回はウォレットとして、Metamaskを利用することにし、Chromeの拡張機能としてMetamaskをインストールしました。

<img width="300" alt="image2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2699602/ca6ca4cb-34b4-4885-a8ab-337039f9c7fd.jpeg">

### テストネットワークの選定
ブロックチェーンのテストネットワークには、Sepolia TestnetやGoerli Testnet、munbaiなどがありますが、Ethereum Mainnetのテストネットワークであり、最もモダンなSepolia Testnetを利用することにしました。

https://qiita.com/Killinneko/items/dac4a43fefa6e9281246

### Sepoliaトークンの取得
Sepolia Testnetに対してトランザクションを送信するためには、Sepoliaトークンが必要です。Sepolia Testnetworkはテストネットワークであるため、トークンの取得に費用はかからないものの、以下のようなサイトから、Sepoliaトークンを取得する必要があります。
1. Alchemy
https://www.alchemy.com/faucets/ethereum-sepolia
※ Ethereum mainnet上に0.001ETH以上が入金されている必要がある

2. Google Cloud Web3
https://cloud.google.com/application/web3/faucet/ethereum/sepolia

3. Sepolia PoW Faucet
https://sepolia-faucet.pk910.de/
※ マイニングによりトークンを取得するため、PCのリソースが必要である

今回はSepolia Testnetで利用するSepoliaトークンを取得するためには、Ethereum mainnet上に0.001ETH以上が入金されている必要があるため、少しだけ入金をしました。

Metamaskに入金した様子

<img width="300" alt="image2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2699602/1cab9e04-6c4c-46e3-896b-8fc202e48a8d.png">

# 2. 開発
## 2-1. Fine TuningされたAIモデルの構築
### Fine TuningされたAIモデルの作成
OpenAIによって提供されているシステムを利用して、以下のページから、学習データを用いてFine Tuningを実行しました。

https://platform.openai.com/finetune/

<img width="400" alt="41747b3b-03ea-40e7-9e9f-95874b8c75d8.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2699602/41747b3b-03ea-40e7-9e9f-95874b8c75d8.png">
<img width="400" alt="image2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2699602/f334e159-c7bf-4628-afaf-88f32a34e3db.png">


### 学習させた結果
OpenAIのPlaygroundから、学習させたモデルを実行しました。
1. 学園祭の概要 → 不正解 ❌
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2699602/1b078351-4738-4dd5-95bb-43afdce34812.png)
2. 出店責任者ガイダンスの開催日時 → 正解 ⭕️
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2699602/a11d3615-adc5-4c31-9dd1-4b2ce31113e3.png)
3. 抽選会の概要 → 不正解 ❌
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2699602/3652f997-e28b-48f2-be9f-f67fed50a35a.png)
4. 学園祭当日 → 正解 ⭕️
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2699602/1d2013d8-a45a-45a8-b909-7a19428a815b.png)
5. 書類回収の開催場所 → 正解 ⭕️ 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2699602/7ec06239-2410-4254-b886-6a2035caa7b0.png)

学習データの入力を言い換えたようなプロンプトの入力に対しては、正しく出力することができていましたが、概要を求める場合などの少し学習データから捻ったプロンプトの入力に対しては、誤った回答を出力してしまっていました。そのため、精度が不十分な点は否めませんが、今回はこのように作成したモデルを利用します。

## 2-2. スマートコントラクトの作成
### 必要な要件
今回のシステムにおいて、スマートコントラクトにおいて下のような要件が求められています。
・トランザクション引数で指定された質問内容とその回答内容がフィールドに記録される。
・NFTの規格であるERC721に準拠している。
・EVM互換のあるブロックチェーン上で動作する。

### Solidityプログラムの記述
これらの要件をもとに、Solidityというスマートコントラクトを作成する言語を用いて、Remixというブロックチェーンのための開発環境で以下のようなプログラムを記述しました。

https://github.com/TAKAYAMAN2180/challenge-ai-nft-utils/blob/main/src/contract/QnAERC721/

このプログラムでは、目的の要件を満たすべく、ERC721に準拠した形で作成しています。現在のカウントを保持する変数Counterと質問と回答をまとめて持つための構造体であるQnA構造体、変数tokenIdとQnA構造体を結びつけるマッパー_qnaDataを有しており、質問を登録するためのaskQuestion関数、質問に対する回答を登録するanswerQuestion関数、IDに紐づいた質問と回答を取得するためのgetQnA関数を実装しています。

https://remix.ethereum.org/


### 動作確認
#### ① Solidtyプログラムのデプロイ
Remixの機能を用いてブロックチェーンへデプロイしました。

デプロイを実施したトランザクション

<img width="500" alt="image2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2699602/7283bcaa-76d0-4d9a-a0f2-c78dd68fd27d.png">

#### ② askQuestion関数の実行
askQuestion関数を実行し、スマートコントラクト上に質問内容を登録し、NFTを発行(Mint)します。

askQuestion関数を実行したトランザクション

<img width="500" alt="image2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2699602/c89f148c-2a80-4efd-a6c7-1ab3f8390347.png">

トークンを発行したトランザクション

<img width="500" alt="image2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2699602/8954c427-77c0-4543-a796-a7ee7c17ba4b.png">


#### ③ answerQuestion関数の実行
answerQuestion関数を実行し、回答を記録します。

answerQuestion関数を実行したトランザクション

<img width="500" alt="image2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2699602/d35214ae-72dd-4873-b6b2-7d8df26f1d8a.png">


#### ④ getQnA関数による記録の確認
最後に実行した結果、次のようになり、質問とそれに対する回答が正しく記録されていることを確認することができました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2699602/dc96c1b0-8fa2-411b-bf1c-15809ee0f07a.png)

## 2-3. フロントエンドの作成
フロントエンドはNext.js、TypeScriptを用いて構築しました。ソースコードは下のようになっています。

https://github.com/TAKAYAMAN2180/challenge-ai-nft-page

このページは下の画像のようにお問い合わせフォームを模しており、お問い合わせを送信することができます。
このページでは、質問内容を入力し、「質問を投稿」のボタンを押すことで、一連の処理を開始することができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2699602/71013148-2e54-407f-9e7d-05c1e0f34aa7.png)

## 2-4. バックエンドの作成
バックエンドはTypeScriptとExpress.jsで構築し、Serverless Frameworkを用いて、AWS Lambda上にデプロイしました。バックエンドでのプログラムでは、リクエストで指定されたtokenIdのパラメータの質問を取得し、その質問をこれまでに作成したFine Tuningさせたモデルにより、出力を取得し、ブロックチェーン上のスマートコントラクトへ保存します。

https://github.com/TAKAYAMAN2180/challenge-ai-nft-backend

# 3. さいごに
今回は「ブロックチェーンを用いたお問い合わせフォームにおける生成AI出力真正性確認システム」を開発しました。ブロックチェーンに関しては、目的としていたNFTの発行をすることができました。しかし、AIに関しては、今回の開発で利用したOpenAIのFine Tuningでは目的の回答からは精度が低くなってしまいました。今後はOpenAIのFine Tuningに関する公式ガイドラインなどから、この精度の強化を図っていきたいと考えています。


# 参考文献

https://qiita.com/ksonoda/items/b9fd3e709aeae79629ff

https://qiita.com/sakue_103/items/c71e65808cb92356508c

https://qiita.com/sey323/items/6701b34d66a2e8c5ea17