OpenAI API データベース連携（RAG）

## 例１

以下のページのプログラムを JavaScript （Node.js） で実行しました。

Question answering using embeddings-based search

https://cookbook.openai.com/examples/question_answering_using_embeddings

```console
cd working_directory 
npm install openai
export OPENAI_API_KEY=“…”

node QuestionAnswering.mjs
```

```javascript:QuestionAnswering.mjs
import OpenAI from "openai";
const openai = new OpenAI();

const wikipediaArticleOnCurling = `
(ここにウィキペディア記事の内容を挿入)
`;

const query = `
Use the below article on the 2022 Winter Olympics to answer the subsequent question. If the answer cannot be found, write "I don't know."

Article:
"""
${wikipediaArticleOnCurling}
"""

Question: Which athletes won the gold medal in curling at the 2022 Winter Olympics?
`;

const completion = await openai.chat.completions.create({
  model: "gpt-3.5-turbo", // gpt-3.5-turbo はカットオフが2021年9月
  messages: [
    { role: "system", content: "You answer questions about the 2022 Winter Olympics." },
    { role: "user", content: query },    
  ],
  temperature: 0,
});

console.log(completion.choices[0].message);

```

> システムメッセージ：あなたは2022年冬季オリンピックに関する質問に答えます。
> 
> クエリ： 以下の記事を使用して、2022年冬季オリンピックに関する次の質問に答えてください。答えが見つからない場合は、「分かりません」と書いてください。
> 　［記事］ ～
>　［質問］ 2022年冬季オリンピックでカーリングの金メダルを獲得した選手は誰ですか？


「 (ここにウィキペディア記事の内容を挿入) 」を、ウェブページの文章で置き換えます。

以下の箇所になります。

```javascript:ウィキペディア記事
const wikipediaArticleOnCurling = `
Curling at the 2022 Winter Olympics

Article
Talk
Read
Edit
View history

...

Female: Jenny Perret
Male: Martin Rios

Female: Vicky Persinger
Male: Chris Plys
`;

```

実行結果は以下のようになります。

![1217_01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3956789/d64e6f23-6c18-84ea-87a9-7d5fc768da0c.png)


> 2022年冬季オリンピックでカーリングの金メダルを獲得した選手は以下の通りです：
> 
> 　・男子カーリング：スウェーデン（ニクラス・エディン、オスカー・エリクソン、ラスムス・ヴラン、クリストファー・スンドグレン、ダニエル・マグヌソン）
> 　・女子カーリング：イギリス（イヴ・ミュアヘッド、ヴィッキー・ライト、ジェニファー・ドッズ、ヘイリー・ダフ、ミリ・スミス）
> 　・混合ダブルスカーリング：イタリア（ステファニア・コンスタンティーニ、アモス・モザナー）

 

### 説明
AI は、1人ではなく、3人の金メダリストがいることを認識しています

我々は、カーリングの質問であることを認識しているため、Wikipedia からカーリングの記事を取得して入力しました

この過程を、ベクトルデータベースサーチを使用して自動化します


## 例２

実行はできていませんが、RAG のプロンプト例を以下に示します。

Get embeddings from dataset

https://cookbook.openai.com/examples/get_embeddings_from_dataset


||Time|ProductId|UserId|Score|Summary|Text|combined|
|:--|:--|:--|:--|:--|:--|:--|:--|
|0|1351123200|B003XPF9BO|A3R7JR3FMEBXQB|5|where does one start...and stop... with a tre...|Wanted to save some to bring to my Chicago fam...|Title: where does one start...and stop... wit...|
|1|1351123200|B003JK537S|A3JBPC3WFUT5ZP|1|Arrived in pieces|Not pleased at all. When I opened the box, mos...|Title: Arrived in pieces; Content: Not pleased...|


### 説明

「data/fine_food_reviews_1k.csv」ファイルを開く
CSV データの Time, ProductId, UserId, Score, Summary, Text 列を取得する
以下の方法で combined 列を作成する
　「Title: ｛Summary｝; Content: ｛Text｝」

combined 列をベクトル化（埋め込み）する
embedding 列として格納する

ユーザーの問合せをベクトル化（埋め込み）する

文章をベクトル化（埋め込み）すると以下のようなデータが作成されます
text-embedding-3-small モデルのデフォルトでは、1536次元のベクトルデータが作成されます

![1219_01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3956789/d616b6a1-2714-a46e-6010-c63ef1c393d2.png)


※ text-embedding-3-small モデルは優れた多言語対応性能を持っています


## 例3

Azure SQL データベースのテーブルサンプル

https://learn.microsoft.com/ja-jp/azure/azure-sql/database/ai-artificial-intelligence-intelligent-applications?view=azuresql

```sql:ベクトルデータベースの例

CREATE TABLE [dbo].[wikipedia_articles_embeddings_titles_vector]
(
    [article_id] [int] NOT NULL,
    [embedding] [vector](1536) NOT NULL,    
)
GO

SELECT TOP(10) 
    * 
FROM 
    [dbo].[wikipedia_articles_embeddings_titles_vector]
ORDER BY
    VECTOR_DISTANCE('cosine', @my_reference_vector, embedding)
    
```

<table>
  <tr>
    <td>テーブル名</td> <td>wikipedia_articles_embeddings_titles_vector</td>
  </tr>
  <tr>
    <td>カラム1　（ID）</td> <td>article_id, int, NOT NULL</td>
  </tr>
  <tr>
    <td>カラム2　（ベクトルデータ）</td> <td>embedding, vector(1536), NOT NULL</td>
  </tr>
</table>


### 説明

＠my_reference_vector と類似性が高い10個を検出

'cosine'はコサイン類似度
類似度が高い順にソート

他の例では、類似度が0.4以上、かつ、4個検出している

Azure SQL や Oracle では2つのベクトルの関連性を計算する関数（vector_distance）が用意されている

article_id と「質問」が格納されたテーブルを別に作成する。前述の例にあるような「記事」と「回答例」も別テーブルに格納する
または、文章を結合して「質問；記事；回答例」をベクトル化する。「質問」のベクトルを検索することで、関連する記事が見つかる

Asure SQL での RAG サンプルプログラムは[こちら](https://learn.microsoft.com/en-us/azure/search/retrieval-augmented-generation-overview)