生成AIへの文章入力にマスキングした文章を使う

こんにちは。

本投稿では、生成AIへ文章を入力する際に、自動で個人情報を検出してマスキングを行い、その後にマスキングされた文章を生成AIへ入力として渡す例を紹介します。デモとして、Google Spreadsheet で文章のマスキングを行い、マスキングされた文章を要約する例を紹介します。顧客名などが入った議事メモを要約するような利用ケースが想定されます。また企業内の大量のナレッジを処理して RAG のソースとして利用するケースもあると思います。

マスキングの処理には、弊社で開発している製品である Insight Masking を使用しています。

## はじめに

最近はどこもかしこも生成AIが大ブーム。仮に有償契約により学習に使用されない、と謳われていたとしても、自社のテナント外のサービスに機微情報を入力として渡すことにはセキュリティ上の問題があると考えている企業は多いようです。そのあたりの利用ポリシーを現在まさに策定中であったり、マスキングすることを必須としたり、今まさに試行錯誤されているお客様が多いように感じます。
弊社が開発しているマスキング製品 Insight Masking は、文章から自動的に機微情報を検出してマスキングする「フリーテキストマスキング機能」を搭載しており、生成AIがらみのお問合せも非常に増えてきています。

本投稿では、生成AIへ文章を入力する際に、その文章から自動で個人情報を検出してマスキングし、その後に生成AIへマスキングされた文章を入力して渡す例を、Insight Masking を使ってご紹介します。

## 構成

このようなマスキングの利用を想定した場合、マスキングもSaaSのような外部で管理しているものではなく、オンプレミスまたは自テナント内で処理させたいケースがほとんどです。そのため、以下の図のように、自テナント内でマスキングしたデータに処理をしたうえで、そのデータを生成AIに渡したいと思います。そしてそのマスキングされた文章をもとに、外にある生成AIサービスを適用し、その結果を得ます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3480312/f4d2b23a-7e0d-d9fe-39ac-8b16524100f5.png)

## セキュリティを考慮した生成AI利用のデモ実装

ここでは Google Spreadsheet で文章のマスキングを行い、マスキングされた文章を要約するデモ実装を紹介します。(Google Spreadsheet を使ってるのでその時点で外のサービスを使っていますが、ここではそれは考えません。。。)
完成イメージは下図のような、A列にオリジナルの文章、B列にマスキングされた文章、C列にChatGPTで要約された文章が表示されるようにします。A列に文字列を入力すると、B列C列の値は順次更新されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3480312/4d197e68-a0d6-bf66-1131-01a392213cb7.png)

Bをマスキングする処理は、GAS で関数を作成し、そこからマスキングの処理を呼び出します。たとえば以下のような感じです。
```actionscript
/**
 * IDM APIを呼び出しマスキングを実行するMaskText関数
 * @plain_text {string} マスキング前文字列
 * @return {string} マスキング後文字列
 */
function MaskText(plain_text) {
  var url = 'xxxxxxxxxxxxxxxxxxxx';
  let options = {
    'method' : 'post',
    'payload' : Utilities.base64Encode(plain_text, Utilities.Charset.UTF_8) + '\n'
  };
  var response = UrlFetchApp.fetch(url, options).getContentText();
  Logger.log(response)
  return Utilities.newBlob(Utilities.base64Decode(response, Utilities.Charset.UTF_8)).getDataAsString()
}
```
これで、マスキングの処理が MaskText 関数で呼び出せるようになりました。

またC列のChatGPT呼び出しも、GASからAPIをコールします。以下のブログを参考にさせていただきました。

https://sterfield.co.jp/blog/18162/

すると例えば、Google Spreadsheetから呼び出し可能な要約関数は以下のように記述できます。

```actionscript
/**
 * ChatGPTを呼び出し要約をを実行するSummarize関数
 * @plain_text {string} 要約前文字列
 * @return {string} 要約後文字列
 */
var openaiApiKey = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';

function Summarize(plain_text) {
  var url = 'https://api.openai.com/v1/chat/completions';
  var payload = {
    'model': 'gpt-3.5-turbo',
    'messages': [{
      'role': 'system',
      'content': 'あなたはプロの編集者です。以下の制約条件に従って、入力する文章を100文字以内に要約してください。\n#制約条件\n・重要なキーワードを取りこぼさない。\n・文章の意味を変更しない。\n・架空の表現や言葉を使用しない。\n・文章中の数値には変更を加えない。\n・【法人名マスク】には変更を加えない。\n・【地名マスク】には変更を加えない。\n・【個人名マスク】には変更を加えない。'
    }, {
      'role': 'user',
      'content': plain_text
    }],
    'temperature': 0.5
  };
  var options = {
    'method' : 'post',
    'headers': {
      'Authorization': 'Bearer ' + openaiApiKey,
      'Content-Type': 'application/json'
    },
    'payload' : JSON.stringify(payload)
  };
  var response = UrlFetchApp.fetch(url, options);
  var data = JSON.parse(response.getContentText());
  return data['choices'][0]['message']['content'].trim();
}
```
そしてGoogle Spreadsheetでは、B列はA列の値を入力としてMaskText関数を呼び、C列はB列の値を入力としてSummarize関数を呼んでいます。

例えばある入力に対してのマスキング結果、要約結果は以下となります。

* 入力
```
営業日報　2024/1/30 (火)　山田 太郎

今月の目標
・受注処理の作業効率をアップさせ、3件を終えること
・ファイル共有システム導入プロジェクトのミーティングで、自分が担当する業務についてしっかりと提案すること
・インサイト社のプロジェクト定例に同行し、鈴木様にご挨拶

今日の業務内容
・製品本部定例
・議事録を作成し、上司に提出
・メール・電話対応
・インサイト社の鈴木様よりクレームの連絡があり、対応
・クライアント対応

今日の作業結果
・インサイト社の件で急なトラブルが発生したものの、上司の相談し、無事解決できた。
```

* マスキング結果
```
営業日報　2024/1/30 (火)　【個人名 マスク】

今月の目標
・受注処理の作業効率をアップさせ、3件を終えること
・ファイル共有システム導入プロジェクトのミーティングで、自分が担当する業務についてしっかりと提案すること
・【法人名 マスク】のプロジェクト定例に同行し、【個人名 マスク】様にご挨拶

今日の業務内容
・製品本部定例
・議事録を作成し、上司に提出
・メール・電話対応
・【法人名 マスク】の【個人名 マスク】様よりクレームの連絡があり、対応
・クライアント対応

今日の作業結果
・【法人名 マスク】の件で急なトラブルが発生したものの、上司の相談し、無事解決できた。
```

* 要約結果
```
営業日報　2024/1/30 (火)　【個人名 マスク】

目標：受注処理3件完了、ファイル共有システム提案、【法人名 マスク】プロジェクト定例同行
業務：本部定例、議事録作成、メール・電話対応、【法人名 マスク】の【個人名 マスク】様からのクレーム対応、クライアント対応
結果：トラブル発生も上司と相談し解決
```

なんとなくそれっぽくマスキングされ、その文章が要約されてますね！

## Insight Masking が備えるフリーテキストマスキング API について

Insight Masking は文章をマスキングする API を利用可能です。通常の利用方式としては顧客自身のテナントにマスキングのサーバーをたて、そのサーバーに API を設定します。そこから外部サービスなどへの通信は行われないため、セキュリティ要件が厳しい場合などに適しています。

一方、もっと手軽に API を利用したいというユースケースも存在するかもしれません。その場合には、弊社の環境で稼働し SaaS として提供されている環境で構築いただくことも可能です。(現在ベータ提供中)

## おわりに

本投稿では、生成AIへ文章を入力する際に、その文章から自動で個人情報を検出してマスキングし、その後に生成AIへマスキングされた文章を入力して渡す例を、Insight Masking を使ってご紹介しました。
Insight Maskingを使うと自動的に機微情報(個人情報)を検出してマスキングでき、それをAPI利用できるため、自動化のフローに組み込んで利用することが可能です。もし試してみたい方いらっしゃいましたら https://www.insight-tec.com/contact/idm/ から是非お問合せください。

## 更新情報
* 2024/4/1: Insight Data Maskingの製品名がInsight Maskingへ変更になったのでそれにあわせて更新しました