LangChain v0.3　その10 ~retrieverにメタデータをつけよう~

# 1. きっかけ
https://python.langchain.com/docs/concepts/vectorstores/#adding-documents

ちょっと気になってさ。Retrieverの項を眺めてたんですよ。
あ、metadata・・・
ここにファイル名や、ページ数などを入れたら「ここの情報を元に回答しています！」ってできそうじゃん。

ということで、メタデータを入れたretrievealデータを作ってみましょう。

## 1−1. 前回の記事
https://qiita.com/ikedachin/items/38daa23ad5dc0b9365b2

参考まで

<br><br>

# 2. 今回のモチベーション
検索すると時にメタデータで絞り込みをしたり、RAGの出力をした根拠となるファイル名やページを出力することが可能そうじゃないですか！ニヤニヤしてきたので、これが今回のモチベーション。
はい、ニヤニヤがモチベーション

<br><br>

# 3. バージョン情報
:::note
バージョン情報
Python 3.10.8
langchain==0.3.7
python-dotenv
langchain-openai==0.2.5
langgraph>0.2.27
langchain-core
langchain-community==0.3.5

※EmbeddingモデルはAzureOpenAIのtext-embedding-ada-002を使いました
:::

<br><br>


# 4. retrieverを作る
先に必要なライブラリをインポートしておきましょう。

```Python:ライブラリのインポート（環境系、retriever系）
# 環境系
import os
import glob
from dotenv import load_dotenv

# retriever構築用
# from langchain_openai import OpenAIEmbeddings # OpenAI APIの場合
from langchain_openai import AzureOpenAIEmbeddings
from langchain_community.vectorstores import FAISS
from langchain_text_splitters import CharacterTextSplitter
from langchain_core.documents import Document
```

## 4-1. データの用意

https://qiita.com/ikedachin/items/38daa23ad5dc0b9365b2#21-%E6%96%87%E7%AB%A0%E3%81%AE%E7%94%A8%E6%84%8F

文章はこちらと同じものを使います。
ファイル名は`dummy1.txt`と`dummy2.txt`
`text_files`というフォルダにこの二つを入れておきます。

<br>

## 4-2. ベクターストアを作成するためのデータ構造
まず、一つ目のファイルを読み取るプログラムを書いてみましょう。
metadataを作るには`Ducument'クラスを使います。

```text:データ構造のイメージ
[
    Document(
        metadata={
            'file_name': 'dummy1.txt', # ファイル名を入れようぜ
            'page': '1', # ファイルの何ページ目かを入れようぜ（あ、テキストファイルだから全部１か・・・）
            'index': '0', # チャンクした時のインデックスを入れとこうかねぇ
        },
        page_context='山田太郎は、世界最大のペンギン養殖場「ペンギンパラダイス」の CEO です。彼は南極の氷山を購入し、そこにペンギンのための超高層ビルを建設しました。このビルは氷で作られており、ペンギンたちはエレベーターで上下に移動します。'
]

```
こんな感じで行きましょうかねぇ。

<br>

## 4−3. データの読み取りとチャンク化のテスト
では一つのファイルを読み取ってみましょう。
```python:dummy1.txtの読みとり
text_file = './text_files/dummy1.txt'
with open(text_file, 'r', encoding='utf-8')as f:
    text_docs = f.read()

print(text_docs)
```

```python:splitterの作成
text_splitter = CharacterTextSplitter(
    chunk_size=200, 
    chunk_overlap=20
    )
```

```python:splitterを使ってtextをチャンク化
splits_texts = text_splitter.split_text(text_docs)
print(splits_texts)
```

<details><summary>print(splits_texts)の出力</summary>

['山田太郎は、世界最大のペンギン養殖場「ペンギンパラダイス」の CEO です。彼は南極の氷山を購入し、そこにペンギンのための超高層ビルを建設しました。このビルは氷で作られており、ペンギンたちはエレベーターで上下に移動します。',
 '鈴木花子は、月面でアボカドを栽培する会社「ルナーボカド」を創業しました。彼女の開発した特殊な肥料により、月のクレーターでアボカドが驚異的な速さで成長し、地球の10倍のサイズになります。\n\n佐藤次郎は、タイムマシンを発明しましたが、それを使って恐竜時代に行き、T-レックスをペットとして現代に連れ帰りました。彼は現在、東京都心でT-レックスの散歩に苦心しています。',
 '田中美咲は、テレパシーを使って株価を予測する能力を持っています。しかし、彼女はその能力を使わず、代わりにテレパシーでネコと会話する職業を選びました。彼女は現在、世界中のネコの悩み相談に応じています。\n\n高橋健太は、重力を無視できる靴を開発しました。彼はその靴を履いて富士山の頂上から歩いて下り、太平洋を横断して歩いてハワイに到着しました。現在は、月への徒歩旅行を計画中です。',
 '渡辺愛子は、雲を食べられる料理法を発明しました。彼女のレストラン「スカイダイナー」では、様々な種類の雲料理が提供されており、特に積乱雲のステーキが人気メニューです。\n\n中村勇太は、植物と会話できる能力を持っています。彼は森の木々と交渉し、CO2を半分しか吸収しないかわりに、動いて街の掃除をするよう説得することに成功しました。現在、東京の街路樹が自ら動いてゴミ拾いをしています。',
 '小林雄二は、夢の中でプログラミングを行い、起きたらそのコードが現実のコンピュータ上に存在している能力を持っています。彼は睡眠中に世界最高のAIを開発しましたが、それが目覚めるとすぐに消えてしまうという問題に悩んでいます。\n\n加藤美樹は、クラゲを飼育して生きた傘を作る会社「ジェリーブレラ」のCEOです。彼女の開発したクラゲ傘は、雨を吸収して成長し、晴れの日には縮小するという画期的な商品です。',
 '木村隆は、恐竜の DNA を使って現代の動物をハイブリッド化する研究を行っています。彼の最新作は、ティラノサウルスとウサギを掛け合わせた「ティラノウサギ」で、現在ペットとして人気急上昇中です。',
 '伊藤さくらは、音楽を視覚化する眼鏡を発明しました。この眼鏡をかけると、音楽が色とりどりの幾何学模様として空中に浮かんで見えます。彼女はこの技術を使って、「視聴覚オーケストラ」というユニークなパフォーマンス集団を結成しました。',
 '斎藤健一は、自身の影と交換できる能力を持っています。彼は影と交代で仕事に行くことで、24時間働き続けることができます。しかし、影の給料をどう処理するかで税務署と揉めているそうです。\n\n岡田真理は、水中で呼吸できる植物の種を開発しました。彼女は東京湾全体を巨大な水中庭園に変える計画を進めており、既に水中チューリップの栽培に成功しています。',
 '山本太一は、重力を操る能力を持っています。彼は週末にお菓子の袋を宙に浮かべ、まるでプラネタリウムのように菓子を回転させながら食べるのが趣味だそうです。\n\n中島弘美は、雲を編んで服を作るファッションデザイナーです。彼女の作る雲のドレスは、着る人の気分によって色や形が変化するという画期的なものです。ただし、晴れの日に消えてしまう欠点があります。',
 '吉田花子は、植物の成長を音楽でコントロールする「メロディガーデン」を発明しました。クラシック音楽を聴かせると高級野菜に、ロックを聴かせると凶暴な食虫植物に成長するそうです。',
 '井上修二は、●×△企業で働いていましたが、社長から突如平社員に転落しました。その理由は、彼が会社の廊下で逆立ちしながら歩くことを提案し、実行したためです。しかし、この奇抜なアイデアが従業員のストレス解消に効果的だと判明し、1週間後に再び社長に復帰しました。',
 'Alexさんは、コーヒーショップでパートタイムジョブを始めてわずか3か月で社長になりました。彼の秘密は、コーヒー豆と話せる特殊能力を持っていたことでした。各豆の個性を活かしたブレンドが評判を呼び、ライバル企業の役員たちを買収するほどの利益を上げたのです。',
 '橋本雄大は、雨粒を操る能力を持っています。彼は雨の日に雨粒を操って空中に文字を書き、天気予報を表示するサービスを始めました。ただし、晴れの日のサービスに課題が残っています。\n\n田村みどりは、夢の中で食べた料理を現実世界に持ち帰ることができます。彼女のレストラン「ドリームダイニング」では、毎晩彼女が見た夢の料理が提供されます。ユニコーンのステーキが人気メニューだそうです。',
 '佐々木健太は、量子力学を応用して、同時に複数の場所に存在できる技術を開発しました。彼は現在、東京、ニューヨーク、パリで同時に講演を行いながら、南極で休暇を楽しんでいます。\n\n岡本さくらは、植物と融合する能力を持っています。彼女は春になると桜の木と一体化し、満開の桜の姿で公園に立っています。冬は常緑樹と融合して過ごすそうです。',
 '中村太郎は、重力を反転させる靴を発明しました。彼はその靴を履いて天井を歩き回り、家具を天井に設置する新しいインテリアデザインを提案しています。\n\n高橋美香は、雲を固形化する技術を開発しました。彼女は雲で作った家具を販売していますが、晴れた日に商品が消えてしまうというクレームに対応するのに苦心しています。',
 '渡辺健一は、動物と人間の言語を相互翻訳できるアプリを開発しました。このアプリの人気No.1機能は、「猫の気まぐれ翻訳」だそうです。\n\n木村愛子は、時間を瓶詰めにする技術を発明しました。彼女の販売する「週末の瓶」は、平日に開けると48時間の週末を楽しめるという画期的な商品です。',
 '斎藤裕太は、影絵を実体化させる能力を持っています。彼の影絵パフォーマンスでは、観客の目の前で影が立体化し、現実世界を歩き回ります。\n\n山本美咲は、海底に巨大な空気ドームを作り、そこで通常の陸上生活ができる「アクアシティ」を建設しました。魚が窓の外を泳ぐ光景を眺めながらのオフィスワークが人気です。',
 '田中博士は、人工的に作った小さな宇宙を瓶の中で育てることに成功しました。彼のラボでは、様々な物理法則を持つミニ宇宙のコレクションが展示されています。\n\n佐藤花子は、夢の中でオンラインショッピングをすると、起きた後に実際に商品が届く能力を持っています。彼女は「ドリームモール」という夢専用のECサイトを運営していますが、在庫管理に頭を悩ませているそうです。',
 '加藤健太は、思考をクラウドにアップロードし、複数の人と共有できる技術を開発しました。この技術により、チームメンバー全員が同じ夢を見ながら会議をするという新しいビジネススタイルが生まれています。\n\n伊藤さとみは、過去の自分と会話する能力を持っています。彼女は過去の自分にアドバイスをすることで、リアルタイムで自身の人生を書き換えていますが、思わぬ副作用に悩まされることもあるそうです。',
 '野口太郎は、植物の気持ちを視覚化するメガネを発明しました。このメガネをかけると、植物の周りにオーラのような感情の色が見えます。彼は現在、植物のメンタルヘルスケア事業を展開しています。',
 '鈴木一郎は、重力を自在に操る能力を持っています。彼は東京タワーを持ち上げて掃除をしたり、スカイツリーを傾けて観光客に斜塔体験を提供したりしています。ただし、うっかり富士山を浮かせてしまい、国際問題になりかけたこともあるそうです。',
 '山田花子は、植物と交渉して好きな形に成長させる能力を持っています。彼女のガーデニング会社「シェイプリーフ」では、顧客の顔を模した観葉植物や、企業ロゴ型の巨大な生垣が人気商品です。\n\n佐藤雄二は、雲を操る能力を持ち、「スカイライティング」という新しい広告媒体を開発しました。しかし、競合他社の広告を消すために晴天にしてしまい、農家から苦情が殺到する問題に直面しています。',
 '田中みどりは、人間の影を実体化させる発明をしました。影だけで働く「シャドウワーカー」を雇用する企業が増えていますが、労働法の適用をめぐって議論が起きています。\n\n高橋健太は、夢の中で習得したスキルを現実世界で使える能力を持っています。彼は毎晩異なる職業の夢を見ることで、医師、弁護士、シェフなど、10以上の資格を取得しました。現在は、夢の中での宇宙飛行士訓練に挑戦中です。',
 '渡辺愛子は、食べ物の味を音楽に変換するフォークを発明しました。彼女のレストラン「メロディ・キッチン」では、シンフォニーのようなフルコースを楽しめます。ただし、カレーを食べると重金属の音楽になってしまう問題が指摘されています。',
 '中村太郎は、言葉を可視化する技術を開発しました。彼の作ったゴーグルをかけると、人々の話す言葉が空中に文字として現れます。これにより、世界中の図書館が「静寂」から「色とりどりの文字が飛び交う空間」に変貌しました。']
</details>

これで、一つ目のファイルの読み込みとchunk化ができました。

<br>

```Python:4.2で定義したデータ構造に合わせる処理（１ファイル分だけ）
docs = []
page = 1 # 今回はテキストファイルのなので全て１とします。💦

for i, text in enumerate(splits_texts):
    # メタデータを作る
    meta_data = {
        'file_name': text_file,
        'page': page,
        'index': i
    }

    # メタデータと、チャンク化されたテキストをDocumentにしてdocsクラスに入れていく。
    docs.append(
        Document(
            page_content=text,
            metadata=meta_data
        )
    )

print(docs)
```

<details><summary>docsの中身</summary>

[Document(metadata={'file_name': 'dummy.txt', 'page': '1', 'index': 0}, page_content='山田太郎は、世界最大のペンギン養殖場「ペンギンパラダイス」の CEO です。彼は南極の氷山を購入し、そこにペンギンのための超高層ビルを建設しました。このビルは氷で作られており、ペンギンたちはエレベーターで上下に移動します。'),
 Document(metadata={'file_name': 'dummy.txt', 'page': '1', 'index': 1}, page_content='鈴木花子は、月面でアボカドを栽培する会社「ルナーボカド」を創業しました。彼女の開発した特殊な肥料により、月のクレーターでアボカドが驚異的な速さで成長し、地球の10倍のサイズになります。\n\n佐藤次郎は、タイムマシンを発明しましたが、それを使って恐竜時代に行き、T-レックスをペットとして現代に連れ帰りました。彼は現在、東京都心でT-レックスの散歩に苦心しています。'),
 Document(metadata={'file_name': 'dummy.txt', 'page': '1', 'index': 2}, page_content='田中美咲は、テレパシーを使って株価を予測する能力を持っています。しかし、彼女はその能力を使わず、代わりにテレパシーでネコと会話する職業を選びました。彼女は現在、世界中のネコの悩み相談に応じています。\n\n高橋健太は、重力を無視できる靴を開発しました。彼はその靴を履いて富士山の頂上から歩いて下り、太平洋を横断して歩いてハワイに到着しました。現在は、月への徒歩旅行を計画中です。'),
 Document(metadata={'file_name': 'dummy.txt', 'page': '1', 'index': 3}, page_content='渡辺愛子は、雲を食べられる料理法を発明しました。彼女のレストラン「スカイダイナー」では、様々な種類の雲料理が提供されており、特に積乱雲のステーキが人気メニューです。\n\n中村勇太は、植物と会話できる能力を持っています。彼は森の木々と交渉し、CO2を半分しか吸収しないかわりに、動いて街の掃除をするよう説得することに成功しました。現在、東京の街路樹が自ら動いてゴミ拾いをしています。'),
 Document(metadata={'file_name': 'dummy.txt', 'page': '1', 'index': 4}, page_content='小林雄二は、夢の中でプログラミングを行い、起きたらそのコードが現実のコンピュータ上に存在している能力を持っています。彼は睡眠中に世界最高のAIを開発しましたが、それが目覚めるとすぐに消えてしまうという問題に悩んでいます。\n\n加藤美樹は、クラゲを飼育して生きた傘を作る会社「ジェリーブレラ」のCEOです。彼女の開発したクラゲ傘は、雨を吸収して成長し、晴れの日には縮小するという画期的な商品です。'),
 Document(metadata={'file_name': 'dummy.txt', 'page': '1', 'index': 5}, page_content='木村隆は、恐竜の DNA を使って現代の動物をハイブリッド化する研究を行っています。彼の最新作は、ティラノサウルスとウサギを掛け合わせた「ティラノウサギ」で、現在ペットとして人気急上昇中です。'),
 Document(metadata={'file_name': 'dummy.txt', 'page': '1', 'index': 6}, page_content='伊藤さくらは、音楽を視覚化する眼鏡を発明しました。この眼鏡をかけると、音楽が色とりどりの幾何学模様として空中に浮かんで見えます。彼女はこの技術を使って、「視聴覚オーケストラ」というユニークなパフォーマンス集団を結成しました。'),
 Document(metadata={'file_name': 'dummy.txt', 'page': '1', 'index': 7}, page_content='斎藤健一は、自身の影と交換できる能力を持っています。彼は影と交代で仕事に行くことで、24時間働き続けることができます。しかし、影の給料をどう処理するかで税務署と揉めているそうです。\n\n岡田真理は、水中で呼吸できる植物の種を開発しました。彼女は東京湾全体を巨大な水中庭園に変える計画を進めており、既に水中チューリップの栽培に成功しています。'),
 Document(metadata={'file_name': 'dummy.txt', 'page': '1', 'index': 8}, page_content='山本太一は、重力を操る能力を持っています。彼は週末にお菓子の袋を宙に浮かべ、まるでプラネタリウムのように菓子を回転させながら食べるのが趣味だそうです。\n\n中島弘美は、雲を編んで服を作るファッションデザイナーです。彼女の作る雲のドレスは、着る人の気分によって色や形が変化するという画期的なものです。ただし、晴れの日に消えてしまう欠点があります。'),
 Document(metadata={'file_name': 'dummy.txt', 'page': '1', 'index': 9}, page_content='吉田花子は、植物の成長を音楽でコントロールする「メロディガーデン」を発明しました。クラシック音楽を聴かせると高級野菜に、ロックを聴かせると凶暴な食虫植物に成長するそうです。'),
 Document(metadata={'file_name': 'dummy.txt', 'page': '1', 'index': 10}, page_content='井上修二は、●×△企業で働いていましたが、社長から突如平社員に転落しました。その理由は、彼が会社の廊下で逆立ちしながら歩くことを提案し、実行したためです。しかし、この奇抜なアイデアが従業員のストレス解消に効果的だと判明し、1週間後に再び社長に復帰しました。'),
 Document(metadata={'file_name': 'dummy.txt', 'page': '1', 'index': 11}, page_content='Alexさんは、コーヒーショップでパートタイムジョブを始めてわずか3か月で社長になりました。彼の秘密は、コーヒー豆と話せる特殊能力を持っていたことでした。各豆の個性を活かしたブレンドが評判を呼び、ライバル企業の役員たちを買収するほどの利益を上げたのです。'),
 Document(metadata={'file_name': 'dummy.txt', 'page': '1', 'index': 12}, page_content='橋本雄大は、雨粒を操る能力を持っています。彼は雨の日に雨粒を操って空中に文字を書き、天気予報を表示するサービスを始めました。ただし、晴れの日のサービスに課題が残っています。\n\n田村みどりは、夢の中で食べた料理を現実世界に持ち帰ることができます。彼女のレストラン「ドリームダイニング」では、毎晩彼女が見た夢の料理が提供されます。ユニコーンのステーキが人気メニューだそうです。'),
 Document(metadata={'file_name': 'dummy.txt', 'page': '1', 'index': 13}, page_content='佐々木健太は、量子力学を応用して、同時に複数の場所に存在できる技術を開発しました。彼は現在、東京、ニューヨーク、パリで同時に講演を行いながら、南極で休暇を楽しんでいます。\n\n岡本さくらは、植物と融合する能力を持っています。彼女は春になると桜の木と一体化し、満開の桜の姿で公園に立っています。冬は常緑樹と融合して過ごすそうです。'),
 Document(metadata={'file_name': 'dummy.txt', 'page': '1', 'index': 14}, page_content='中村太郎は、重力を反転させる靴を発明しました。彼はその靴を履いて天井を歩き回り、家具を天井に設置する新しいインテリアデザインを提案しています。\n\n高橋美香は、雲を固形化する技術を開発しました。彼女は雲で作った家具を販売していますが、晴れた日に商品が消えてしまうというクレームに対応するのに苦心しています。'),
 Document(metadata={'file_name': 'dummy.txt', 'page': '1', 'index': 15}, page_content='渡辺健一は、動物と人間の言語を相互翻訳できるアプリを開発しました。このアプリの人気No.1機能は、「猫の気まぐれ翻訳」だそうです。\n\n木村愛子は、時間を瓶詰めにする技術を発明しました。彼女の販売する「週末の瓶」は、平日に開けると48時間の週末を楽しめるという画期的な商品です。'),
 Document(metadata={'file_name': 'dummy.txt', 'page': '1', 'index': 16}, page_content='斎藤裕太は、影絵を実体化させる能力を持っています。彼の影絵パフォーマンスでは、観客の目の前で影が立体化し、現実世界を歩き回ります。\n\n山本美咲は、海底に巨大な空気ドームを作り、そこで通常の陸上生活ができる「アクアシティ」を建設しました。魚が窓の外を泳ぐ光景を眺めながらのオフィスワークが人気です。'),
 Document(metadata={'file_name': 'dummy.txt', 'page': '1', 'index': 17}, page_content='田中博士は、人工的に作った小さな宇宙を瓶の中で育てることに成功しました。彼のラボでは、様々な物理法則を持つミニ宇宙のコレクションが展示されています。\n\n佐藤花子は、夢の中でオンラインショッピングをすると、起きた後に実際に商品が届く能力を持っています。彼女は「ドリームモール」という夢専用のECサイトを運営していますが、在庫管理に頭を悩ませているそうです。'),
 Document(metadata={'file_name': 'dummy.txt', 'page': '1', 'index': 18}, page_content='加藤健太は、思考をクラウドにアップロードし、複数の人と共有できる技術を開発しました。この技術により、チームメンバー全員が同じ夢を見ながら会議をするという新しいビジネススタイルが生まれています。\n\n伊藤さとみは、過去の自分と会話する能力を持っています。彼女は過去の自分にアドバイスをすることで、リアルタイムで自身の人生を書き換えていますが、思わぬ副作用に悩まされることもあるそうです。'),
 Document(metadata={'file_name': 'dummy.txt', 'page': '1', 'index': 19}, page_content='野口太郎は、植物の気持ちを視覚化するメガネを発明しました。このメガネをかけると、植物の周りにオーラのような感情の色が見えます。彼は現在、植物のメンタルヘルスケア事業を展開しています。'),
 Document(metadata={'file_name': 'dummy.txt', 'page': '1', 'index': 20}, page_content='鈴木一郎は、重力を自在に操る能力を持っています。彼は東京タワーを持ち上げて掃除をしたり、スカイツリーを傾けて観光客に斜塔体験を提供したりしています。ただし、うっかり富士山を浮かせてしまい、国際問題になりかけたこともあるそうです。'),
 Document(metadata={'file_name': 'dummy.txt', 'page': '1', 'index': 21}, page_content='山田花子は、植物と交渉して好きな形に成長させる能力を持っています。彼女のガーデニング会社「シェイプリーフ」では、顧客の顔を模した観葉植物や、企業ロゴ型の巨大な生垣が人気商品です。\n\n佐藤雄二は、雲を操る能力を持ち、「スカイライティング」という新しい広告媒体を開発しました。しかし、競合他社の広告を消すために晴天にしてしまい、農家から苦情が殺到する問題に直面しています。'),
 Document(metadata={'file_name': 'dummy.txt', 'page': '1', 'index': 22}, page_content='田中みどりは、人間の影を実体化させる発明をしました。影だけで働く「シャドウワーカー」を雇用する企業が増えていますが、労働法の適用をめぐって議論が起きています。\n\n高橋健太は、夢の中で習得したスキルを現実世界で使える能力を持っています。彼は毎晩異なる職業の夢を見ることで、医師、弁護士、シェフなど、10以上の資格を取得しました。現在は、夢の中での宇宙飛行士訓練に挑戦中です。'),
 Document(metadata={'file_name': 'dummy.txt', 'page': '1', 'index': 23}, page_content='渡辺愛子は、食べ物の味を音楽に変換するフォークを発明しました。彼女のレストラン「メロディ・キッチン」では、シンフォニーのようなフルコースを楽しめます。ただし、カレーを食べると重金属の音楽になってしまう問題が指摘されています。'),
 Document(metadata={'file_name': 'dummy.txt', 'page': '1', 'index': 24}, page_content='中村太郎は、言葉を可視化する技術を開発しました。彼の作ったゴーグルをかけると、人々の話す言葉が空中に文字として現れます。これにより、世界中の図書館が「静寂」から「色とりどりの文字が飛び交う空間」に変貌しました。')]
</details>

これで、目的の構造のファイルができそうです。



<br>

## 4-4. 4−3をまとめて関数化しよう
このままプログラムを作ってもいいのですが、可読性を上げるために関数しましょう。

```Python:ベクターストアに渡すデータ構造を作る関数
def get_document_list(file_path: str) -> list[Document]:
    docs = []

    with open(file_path, 'r', encoding='utf-8')as f:
        text_docs = f.read()
    
    splits_texts = text_splitter.split_text(text_docs)
    file_name = os.path.basename(file_path)
    page = 1
    
    for i, text in enumerate(splits_texts):
        meta_data = {
            'file_name': file_name,
            'page': page,
            'index': i
        }
        docs.append(
            Document(
                page_content=text,
                metadata=meta_data
            )
        )
    return docs
```
最近、型提案を覚えました。
`def get_document_list(file_path: str) -> list[Document]:`の`: str`とか、` ->list[Document:`みたいなやつです。
入力、出力の型を書いておくとミスが減るんです。おすすめです。

そこじゃなくて、関数の解説。
1. ファイルパスを受け取り、
1. ファイルを読み取って
1. チャンク化して
1. metadataに入れる情報を作って
1. チャンク化したテキスト毎にDocumentを作る
1. Documentができたらdocsリストに格納して
1. docsを返り値として返す

そんな関数です。そんなに難しくないですね。

<br>


```Python:複数のファイルを一括処理する
docs_list = []

for text_file in text_files:
    docs_list += get_document_list(text_file) # listにlistの要素を付け加えるので、`+=`で。

print(docs_list)
```

<details><summary>出力</summary>

[Document(metadata={'file_name': 'dummy1.txt', 'page': 1, 'index': 0}, page_content='山田太郎は、世界最大のペンギン養殖場「ペンギンパラダイス」の CEO です。彼は南極の氷山を購入し、そこにペンギンのための超高層ビルを建設しました。このビルは氷で作られており、ペンギンたちはエレベーターで上下に移動します。'),
 Document(metadata={'file_name': 'dummy1.txt', 'page': 1, 'index': 1}, page_content='鈴木花子は、月面でアボカドを栽培する会社「ルナーボカド」を創業しました。彼女の開発した特殊な肥料により、月のクレーターでアボカドが驚異的な速さで成長し、地球の10倍のサイズになります。\n\n佐藤次郎は、タイムマシンを発明しましたが、それを使って恐竜時代に行き、T-レックスをペットとして現代に連れ帰りました。彼は現在、東京都心でT-レックスの散歩に苦心しています。'),
 Document(metadata={'file_name': 'dummy1.txt', 'page': 1, 'index': 2}, page_content='田中美咲は、テレパシーを使って株価を予測する能力を持っています。しかし、彼女はその能力を使わず、代わりにテレパシーでネコと会話する職業を選びました。彼女は現在、世界中のネコの悩み相談に応じています。\n\n高橋健太は、重力を無視できる靴を開発しました。彼はその靴を履いて富士山の頂上から歩いて下り、太平洋を横断して歩いてハワイに到着しました。現在は、月への徒歩旅行を計画中です。'),
 Document(metadata={'file_name': 'dummy1.txt', 'page': 1, 'index': 3}, page_content='渡辺愛子は、雲を食べられる料理法を発明しました。彼女のレストラン「スカイダイナー」では、様々な種類の雲料理が提供されており、特に積乱雲のステーキが人気メニューです。\n\n中村勇太は、植物と会話できる能力を持っています。彼は森の木々と交渉し、CO2を半分しか吸収しないかわりに、動いて街の掃除をするよう説得することに成功しました。現在、東京の街路樹が自ら動いてゴミ拾いをしています。'),
 Document(metadata={'file_name': 'dummy1.txt', 'page': 1, 'index': 4}, page_content='小林雄二は、夢の中でプログラミングを行い、起きたらそのコードが現実のコンピュータ上に存在している能力を持っています。彼は睡眠中に世界最高のAIを開発しましたが、それが目覚めるとすぐに消えてしまうという問題に悩んでいます。\n\n加藤美樹は、クラゲを飼育して生きた傘を作る会社「ジェリーブレラ」のCEOです。彼女の開発したクラゲ傘は、雨を吸収して成長し、晴れの日には縮小するという画期的な商品です。'),
 Document(metadata={'file_name': 'dummy1.txt', 'page': 1, 'index': 5}, page_content='木村隆は、恐竜の DNA を使って現代の動物をハイブリッド化する研究を行っています。彼の最新作は、ティラノサウルスとウサギを掛け合わせた「ティラノウサギ」で、現在ペットとして人気急上昇中です。'),
 Document(metadata={'file_name': 'dummy1.txt', 'page': 1, 'index': 6}, page_content='伊藤さくらは、音楽を視覚化する眼鏡を発明しました。この眼鏡をかけると、音楽が色とりどりの幾何学模様として空中に浮かんで見えます。彼女はこの技術を使って、「視聴覚オーケストラ」というユニークなパフォーマンス集団を結成しました。'),
 Document(metadata={'file_name': 'dummy1.txt', 'page': 1, 'index': 7}, page_content='斎藤健一は、自身の影と交換できる能力を持っています。彼は影と交代で仕事に行くことで、24時間働き続けることができます。しかし、影の給料をどう処理するかで税務署と揉めているそうです。\n\n岡田真理は、水中で呼吸できる植物の種を開発しました。彼女は東京湾全体を巨大な水中庭園に変える計画を進めており、既に水中チューリップの栽培に成功しています。'),
 Document(metadata={'file_name': 'dummy1.txt', 'page': 1, 'index': 8}, page_content='山本太一は、重力を操る能力を持っています。彼は週末にお菓子の袋を宙に浮かべ、まるでプラネタリウムのように菓子を回転させながら食べるのが趣味だそうです。\n\n中島弘美は、雲を編んで服を作るファッションデザイナーです。彼女の作る雲のドレスは、着る人の気分によって色や形が変化するという画期的なものです。ただし、晴れの日に消えてしまう欠点があります。'),
 Document(metadata={'file_name': 'dummy1.txt', 'page': 1, 'index': 9}, page_content='吉田花子は、植物の成長を音楽でコントロールする「メロディガーデン」を発明しました。クラシック音楽を聴かせると高級野菜に、ロックを聴かせると凶暴な食虫植物に成長するそうです。'),
 Document(metadata={'file_name': 'dummy1.txt', 'page': 1, 'index': 10}, page_content='井上修二は、●×△企業で働いていましたが、社長から突如平社員に転落しました。その理由は、彼が会社の廊下で逆立ちしながら歩くことを提案し、実行したためです。しかし、この奇抜なアイデアが従業員のストレス解消に効果的だと判明し、1週間後に再び社長に復帰しました。'),
 Document(metadata={'file_name': 'dummy1.txt', 'page': 1, 'index': 11}, page_content='Alexさんは、コーヒーショップでパートタイムジョブを始めてわずか3か月で社長になりました。彼の秘密は、コーヒー豆と話せる特殊能力を持っていたことでした。各豆の個性を活かしたブレンドが評判を呼び、ライバル企業の役員たちを買収するほどの利益を上げたのです。'),
 Document(metadata={'file_name': 'dummy1.txt', 'page': 1, 'index': 12}, page_content='橋本雄大は、雨粒を操る能力を持っています。彼は雨の日に雨粒を操って空中に文字を書き、天気予報を表示するサービスを始めました。ただし、晴れの日のサービスに課題が残っています。\n\n田村みどりは、夢の中で食べた料理を現実世界に持ち帰ることができます。彼女のレストラン「ドリームダイニング」では、毎晩彼女が見た夢の料理が提供されます。ユニコーンのステーキが人気メニューだそうです。'),
 Document(metadata={'file_name': 'dummy1.txt', 'page': 1, 'index': 13}, page_content='佐々木健太は、量子力学を応用して、同時に複数の場所に存在できる技術を開発しました。彼は現在、東京、ニューヨーク、パリで同時に講演を行いながら、南極で休暇を楽しんでいます。\n\n岡本さくらは、植物と融合する能力を持っています。彼女は春になると桜の木と一体化し、満開の桜の姿で公園に立っています。冬は常緑樹と融合して過ごすそうです。'),
 Document(metadata={'file_name': 'dummy1.txt', 'page': 1, 'index': 14}, page_content='中村太郎は、重力を反転させる靴を発明しました。彼はその靴を履いて天井を歩き回り、家具を天井に設置する新しいインテリアデザインを提案しています。\n\n高橋美香は、雲を固形化する技術を開発しました。彼女は雲で作った家具を販売していますが、晴れた日に商品が消えてしまうというクレームに対応するのに苦心しています。'),
 Document(metadata={'file_name': 'dummy1.txt', 'page': 1, 'index': 15}, page_content='渡辺健一は、動物と人間の言語を相互翻訳できるアプリを開発しました。このアプリの人気No.1機能は、「猫の気まぐれ翻訳」だそうです。\n\n木村愛子は、時間を瓶詰めにする技術を発明しました。彼女の販売する「週末の瓶」は、平日に開けると48時間の週末を楽しめるという画期的な商品です。'),
 Document(metadata={'file_name': 'dummy1.txt', 'page': 1, 'index': 16}, page_content='斎藤裕太は、影絵を実体化させる能力を持っています。彼の影絵パフォーマンスでは、観客の目の前で影が立体化し、現実世界を歩き回ります。\n\n山本美咲は、海底に巨大な空気ドームを作り、そこで通常の陸上生活ができる「アクアシティ」を建設しました。魚が窓の外を泳ぐ光景を眺めながらのオフィスワークが人気です。'),
 Document(metadata={'file_name': 'dummy1.txt', 'page': 1, 'index': 17}, page_content='田中博士は、人工的に作った小さな宇宙を瓶の中で育てることに成功しました。彼のラボでは、様々な物理法則を持つミニ宇宙のコレクションが展示されています。\n\n佐藤花子は、夢の中でオンラインショッピングをすると、起きた後に実際に商品が届く能力を持っています。彼女は「ドリームモール」という夢専用のECサイトを運営していますが、在庫管理に頭を悩ませているそうです。'),
 Document(metadata={'file_name': 'dummy1.txt', 'page': 1, 'index': 18}, page_content='加藤健太は、思考をクラウドにアップロードし、複数の人と共有できる技術を開発しました。この技術により、チームメンバー全員が同じ夢を見ながら会議をするという新しいビジネススタイルが生まれています。\n\n伊藤さとみは、過去の自分と会話する能力を持っています。彼女は過去の自分にアドバイスをすることで、リアルタイムで自身の人生を書き換えていますが、思わぬ副作用に悩まされることもあるそうです。'),
 Document(metadata={'file_name': 'dummy1.txt', 'page': 1, 'index': 19}, page_content='野口太郎は、植物の気持ちを視覚化するメガネを発明しました。このメガネをかけると、植物の周りにオーラのような感情の色が見えます。彼は現在、植物のメンタルヘルスケア事業を展開しています。'),
 Document(metadata={'file_name': 'dummy1.txt', 'page': 1, 'index': 20}, page_content='鈴木一郎は、重力を自在に操る能力を持っています。彼は東京タワーを持ち上げて掃除をしたり、スカイツリーを傾けて観光客に斜塔体験を提供したりしています。ただし、うっかり富士山を浮かせてしまい、国際問題になりかけたこともあるそうです。'),
 Document(metadata={'file_name': 'dummy1.txt', 'page': 1, 'index': 21}, page_content='山田花子は、植物と交渉して好きな形に成長させる能力を持っています。彼女のガーデニング会社「シェイプリーフ」では、顧客の顔を模した観葉植物や、企業ロゴ型の巨大な生垣が人気商品です。\n\n佐藤雄二は、雲を操る能力を持ち、「スカイライティング」という新しい広告媒体を開発しました。しかし、競合他社の広告を消すために晴天にしてしまい、農家から苦情が殺到する問題に直面しています。'),
 Document(metadata={'file_name': 'dummy1.txt', 'page': 1, 'index': 22}, page_content='田中みどりは、人間の影を実体化させる発明をしました。影だけで働く「シャドウワーカー」を雇用する企業が増えていますが、労働法の適用をめぐって議論が起きています。\n\n高橋健太は、夢の中で習得したスキルを現実世界で使える能力を持っています。彼は毎晩異なる職業の夢を見ることで、医師、弁護士、シェフなど、10以上の資格を取得しました。現在は、夢の中での宇宙飛行士訓練に挑戦中です。'),
 Document(metadata={'file_name': 'dummy1.txt', 'page': 1, 'index': 23}, page_content='渡辺愛子は、食べ物の味を音楽に変換するフォークを発明しました。彼女のレストラン「メロディ・キッチン」では、シンフォニーのようなフルコースを楽しめます。ただし、カレーを食べると重金属の音楽になってしまう問題が指摘されています。'),
 Document(metadata={'file_name': 'dummy1.txt', 'page': 1, 'index': 24}, page_content='中村太郎は、言葉を可視化する技術を開発しました。彼の作ったゴーグルをかけると、人々の話す言葉が空中に文字として現れます。これにより、世界中の図書館が「静寂」から「色とりどりの文字が飛び交う空間」に変貌しました。'),
 Document(metadata={'file_name': 'dummy2.txt', 'page': 1, 'index': 0}, page_content='小林美香は、動物と人間の心を入れ替えることができます。彼女は動物園で週に一度、来場者と動物の心を入れ替えるイベントを行っていますが、人間の体で木の上に残されたお客さんの救出に頭を悩ませているそうです。\n\n加藤健一は、音楽を立体物として具現化する能力を持っています。彼のコンサートでは、クラシック音楽が巨大な彫刻となって会場に出現し、フィナーレでは観客がその彫刻を持ち帰ることができます。'),
 Document(metadata={'file_name': 'dummy2.txt', 'page': 1, 'index': 1}, page_content='伊藤さくらは、人々の寿命を視覚化できる特殊な眼鏡を発明しました。彼女は医療機関と提携していますが、知りたくない情報を目にしてしまう人々へのカウンセリングサービスの需要が急増しています。\n\n木村隆太は、遺伝子操作により、光合成できる人間を作り出すことに成功しました。彼の研究所では、日光浴をするだけで栄養補給ができる人々が暮らしていますが、雨の日の対策が課題となっています。'),
 Document(metadata={'file_name': 'dummy2.txt', 'page': 1, 'index': 2}, page_content='斎藤美咲は、過去にタイムスリップできますが、その際に現在の自分の年齢と体型が維持されるという特殊な能力を持っています。彼女は自分の幼稚園時代に行って先生として働いていますが、園児たちからは「巨人先生」と呼ばれているそうです。'),
 Document(metadata={'file_name': 'dummy2.txt', 'page': 1, 'index': 3}, page_content='岡田健太は、人々の夢をキャプチャーして映画化する技術を開発しました。彼の「ドリームシネマ」は大ヒットしていますが、著作権の問題や、あまりにも奇抜な夢のレーティング付けに苦心しています。'),
 Document(metadata={'file_name': 'dummy2.txt', 'page': 1, 'index': 4}, page_content='山本良子は、思考を料理として具現化できる能力を持っています。彼女のレストラン「マインド・デリシャス」では、シェフの創造性そのものを食べることができます。ただし、たまに悪い考えが混じると料理が不味くなる問題があります。'),
 Document(metadata={'file_name': 'dummy2.txt', 'page': 1, 'index': 5}, page_content='中島大輔は、自分の分身を作り出せますが、分身の性格が毎回ランダムになってしまいます。彼は分身たちを雇って多角経営を行っていますが、過激派の分身が起こした問題の処理に追われることもあるそうです。\n\n吉田美穂は、植物と会話する能力を持っています。彼女は植物の気持ちを代弁する「グリーンコンシェルジュ」として活躍していますが、サボテンの持つ痛烈な皮肉に悩まされることもあるそうです。'),
 Document(metadata={'file_name': 'dummy2.txt', 'page': 1, 'index': 6}, page_content='藤田一郎は、空気から物体を作り出す能力を持っています。彼は大気中の分子を再構成して、家具や建物を即座に作り出すことができます。しかし、くしゃみをするたびに周囲のものが空気に戻ってしまうという問題に悩んでいます。'),
 Document(metadata={'file_name': 'dummy2.txt', 'page': 1, 'index': 7}, page_content='村上智子は、絵画の中に入り込める能力を持っています。彼女は美術館で「ライブアートツアー」を主催し、モナ・リザと一緒に自撮りをしたり、ゴッホの「星月夜」で星空浴を楽しんだりするツアーを行っています。ただし、抽象画に入るとしばらく出てこられなくなる問題があるそうです。'),
 Document(metadata={'file_name': 'dummy2.txt', 'page': 1, 'index': 8}, page_content='佐々木健太は、時間を素材として扱える能力を持っています。彼は「タイムファクトリー」という工場を経営し、若返りクリームや未来予知メガネなどを製造しています。ただし、従業員の勤務時間管理が非常に複雑になっているそうです。'),
 Document(metadata={'file_name': 'dummy2.txt', 'page': 1, 'index': 9}, page_content='近藤美咲は、人々の悩みを物理的に小さくする能力を持っています。彼女のカウンセリングオフィスでは、巨大な悩みが玉砂利サイズまで縮小され、クライアントはそれをお守りとして持ち帰ります。しかし、時々悩みが膨張して街中が大パニックになることもあるそうです。'),
 Document(metadata={'file_name': 'dummy2.txt', 'page': 1, 'index': 10}, page_content='田辺隆太は、重力を反転させる靴を発明しました。彼の会社「アップサイドダウン」では、天井を歩けるアトラクションパークを運営していますが、お客様の落下物対策に頭を悩ませています。'),
 Document(metadata={'file_name': 'dummy2.txt', 'page': 1, 'index': 11}, page_content='山岸花子は、動物と人間のコミュニケーションを円滑にする「アニマルトーク」アプリを開発しました。このアプリは大ヒットしましたが、飼い主の言葉を理解したペットたちの要求が高度になりすぎて、飼育放棄が増加するという予想外の問題が発生しています。'),
 Document(metadata={'file_name': 'dummy2.txt', 'page': 1, 'index': 12}, page_content='岡本太郎は、夢の中で描いた絵画を現実世界に持ち込める能力を持っています。彼のギャラリー「ドリームキャンバス」には、物理法則を無視したシュールな作品が展示されていますが、時々絵の中の生き物が抜け出してくるトラブルも起きているそうです。'),
 Document(metadata={'file_name': 'dummy2.txt', 'page': 1, 'index': 13}, page_content='高木美香は、植物を瞬時に成長させる能力を持っています。彼女は砂漠に数秒で森林を作り出すことができますが、うっかりくしゃみをして東京ドームを巨大な森に変えてしまい、プロ野球の試合が中止になったこともあるそうです。\n\n渡辺健一は、雲を固形化して建築材料として使用する技術を開発しました。彼の会社「スカイビルダー」では、雲で作られた超高層ビルを建設していますが、晴れの日の対策に苦心しているそうです。'),
 Document(metadata={'file_name': 'dummy2.txt', 'page': 1, 'index': 14}, page_content='中村さゆりは、人々の記憶を料理として再現できる能力を持っています。彼女のレストラン「メモリーダイニング」では、幼少期の思い出や初恋の味を楽しめますが、時々悪い記憶が混ざってしまい、苦い料理になることもあるそうです。'),
 Document(metadata={'file_name': 'dummy2.txt', 'page': 1, 'index': 15}, page_content='木下雄太は、瞬間移動できるポータルを作り出す能力を持っています。彼は「テレポート交通」という会社を設立し、世界中の主要都市を結ぶ新しい交通網を構築しました。ただし、時差ボケ対策やポータル渋滞の問題に直面しているそうです。'),
 Document(metadata={'file_name': 'dummy2.txt', 'page': 1, 'index': 16}, page_content='藤原美樹は、人々の感情を色として視覚化できる能力を持っています。彼女は「エモーショナルデザイン」という新しいファッションブランドを立ち上げ、着る人の感情に合わせて色が変わる服を販売しています。ただし、感情の起伏が激しい人が着ると虹色に輝きすぎて周囲の目がくらむという問題があります。'),
 Document(metadata={'file_name': 'dummy2.txt', 'page': 1, 'index': 17}, page_content='石田隆は、重力を自在に操る能力を持っています。彼は「フローティングファーム」という宙に浮かぶ農場を経営し、空中で野菜や果物を栽培しています。しかし、強風時の農作物の飛散防止に頭を悩ませているそうです。'),
 Document(metadata={'file_name': 'dummy2.txt', 'page': 1, 'index': 18}, page_content='宮本桃子は、人々の夢をキャプチャーして香水に変換する技術を開発しました。彼女のブランド「ドリームフレグランス」では、冒険や恋愛、成功の香りを楽しめます。ただし、悪夢の香りが予想以上に人気で、品薄状態が続いているそうです。'),
 Document(metadata={'file_name': 'dummy2.txt', 'page': 1, 'index': 19}, page_content='小野寺健太は、時間を止める能力を持っていますが、その間に彼の髭だけが伸び続けるという奇妙な副作用があります。彼は世界記録更新のために時間を24時間止めたことがありますが、1メートル以上に伸びた髭の処理に困ったそうです。'),
 Document(metadata={'file_name': 'dummy2.txt', 'page': 1, 'index': 20}, page_content='坂本美咲は、人々の才能を抽出して、飲み物として提供できる能力を持っています。彼女のカフェ「タレントブリュー」では、アインシュタインの知性やピカソの創造性を一杯の飲み物で味わえます。ただし、副作用で一時的に奇抜な髪型になってしまうことがあるそうです。'),
 Document(metadata={'file_name': 'dummy2.txt', 'page': 1, 'index': 21}, page_content='川島真理は、人々の悩みを食べ物に変換する能力を持っています。彼女の経営する「ワーリーイーツ」では、ストレスがチョコレートに、不安がアイスクリームに変わります。しかし、幸せな人が食べると太るという副作用があるため、ダイエット中の人には不評だそうです。'),
 Document(metadata={'file_name': 'dummy2.txt', 'page': 1, 'index': 22}, page_content='西田健太郎は、音楽を立体物として具現化できます。彼のコンサート「ソリッドサウンド」では、クラシック音楽が巨大な彫刻となって会場に現れます。ただし、ヘビーメタルのコンサートで生まれた尖った彫刻の処理に困っているそうです。'),
 Document(metadata={'file_name': 'dummy2.txt', 'page': 1, 'index': 23}, page_content='遠藤さくらは、植物と融合して新しい生命体になれる能力を持っています。彼女は「ヒューマンプラント」として、光合成による環境浄化活動を行っていますが、冬場の寒さ対策に苦心しているそうです。'),
 Document(metadata={'file_name': 'dummy2.txt', 'page': 1, 'index': 24}, page_content='橋本龍太郎は、潜在意識をプログラミング言語に変換する能力を持っています。彼の会社「ドリームコード」では、寝ている間に天才プログラマーになれるサービスを提供していますが、たまに悪夢がバグを生み出すという問題に直面しています。'),
 Document(metadata={'file_name': 'dummy2.txt', 'page': 1, 'index': 25}, page_content='菊地美香は、人々の記憶を書籍化できる能力を持っています。彼女の「メモリーライブラリー」では、自分の人生を本として読むことができます。ただし、忘れたはずの恥ずかしい記憶が突然ベストセラーになってしまうこともあるそうです。'),
 Document(metadata={'file_name': 'dummy2.txt', 'page': 1, 'index': 26}, page_content='野村太一は、感情を料理として具現化できます。彼のレストラン「エモーショナル・ダイニング」では、喜びのパスタや悲しみのスープが人気メニューです。しかし、怒りのステーキがあまりにも辛くて食べられないという苦情も寄せられているそうです。'),
 Document(metadata={'file_name': 'dummy2.txt', 'page': 1, 'index': 27}, page_content='松田涼子は、夢の中で学習した内容を現実世界でも使えるようになる能力を持っています。彼女は「スリープラーニング・アカデミー」を設立し、寝ながら資格を取得できるコースを提供しています。ただし、悪夢を見ると変な技能を習得してしまう副作用があるそうです。'),
 Document(metadata={'file_name': 'dummy2.txt', 'page': 1, 'index': 28}, page_content='金子隆太は、思考をホログラムとして投影できる能力を持っています。彼の「マインドシアター」では、観客の頭の中をスクリーンに映し出すユニークな映画館を運営していますが、あまりにもカオスな内容に検閲の問題が発生しているそうです。'),
 Document(metadata={'file_name': 'dummy2.txt', 'page': 1, 'index': 29}, page_content='浜田美咲は、人々の運勢を視覚化し、カラフルなオーラとして表示できます。彼女の占い館「フォーチュンレインボー」は大人気ですが、不運な人があまりにも暗いオーラを放つため、店内の照明を増設する必要が出てきたそうです。'),
 Document(metadata={'file_name': 'dummy2.txt', 'page': 1, 'index': 30}, page_content='岸本健太は、動物と人間の知能を交換できる能力を持っています。彼の「アニマルスワップ」では、ペットと飼い主の知能を交換するサービスを提供していますが、人間の体で魚の知能になってしまった客の対応に苦慮しているそうです。'),
 Document(metadata={'file_name': 'dummy2.txt', 'page': 1, 'index': 31}, page_content='上田花子は、絵画の中の出来事を現実世界に引き出せる能力を持っています。彼女のギャラリー「リビングアート」では、モネの睡蓮の池で泳いだり、ゴッホのひまわりを持ち帰ったりできます。ただし、ピカソの作品から出てきた人物の処遇に困っているそうです。'),
 Document(metadata={'file_name': 'dummy2.txt', 'page': 1, 'index': 32}, page_content='後藤一郎は、人々の夢を録画し、映画として上映できる技術を開発しました。彼の「ドリームシネマ」は大ヒットしていますが、あまりにもシュールな夢のレーティング付けに頭を悩ませているそうです。'),
 Document(metadata={'file_name': 'dummy2.txt', 'page': 1, 'index': 33}, page_content='中野さつきは、料理に込められた感情を可視化できる能力を持っています。彼女のレストランレビューサイト「テイストフィール」は料理の味だけでなく、シェフの感情も評価の対象としています。ただし、怒りに満ちた料理を食べて胸やけする人が続出し、医療費が問題になっているそうです。'),
 Document(metadata={'file_name': 'dummy2.txt', 'page': 1, 'index': 34}, page_content='横山拓也は、植物と交渉して好きな形に成長させられる能力を持っています。彼の「リビングアーキテクチャー」では、木で作られた家具や建物をデザインしていますが、時々植物が反抗して予想外の形に成長してしまうこともあるそうです。'),
 Document(metadata={'file_name': 'dummy2.txt', 'page': 1, 'index': 35}, page_content='田島美香は、人々の才能を抽出して、他の人に一時的に転送できる能力を持っています。彼女の「タレントシェアリング」サービスは大人気ですが、ロックスターの才能を受け取った主婦が家出してしまうなどのトラブルも発生しているそうです。'),
 Document(metadata={'file_name': 'dummy2.txt', 'page': 1, 'index': 36}, page_content='森下健太は、重力を自在に操る能力を持っています。彼の「アンチグラビティ・フィットネス」では、空中でのワークアウトが人気ですが、たまに参加者が宙に浮いたまま帰れなくなるというトラブルが起きているそうです。')]
 
</details>

これでretriever（検索機）に入れるデータの準備ができました。



## 4-4. retriever(検索機)の作成
さて、今回はFAISSという方法を使って、ベクターストアを作ります。
`Document`を使っているので、ここは`from_documents`関数を使います。前は単に一つのテキストデータのretrieverを作ったので、`from_texts`でしたね。使い分けに注意。

<br>

```python:先にembeddingモデルを作っておきます。
load_env(".env") # .envファイルを環境変数に読み込み

embeddings = AzureOpenAIEmbeddings(
    model="text-embedding-ada-002",
    azure_endpoint=os.getenv("END_POINT"),
    api_version=os.getenv("API_VERSION"),
    api_key=os.getenv("API_KEY"),
)
```
embeddingモデルの定義をして、

<br>


```python:FAISSを使ってベクターストアを作成
vector_store_docs = FAISS.from_documents(
    documents=docs,
    embedding=embeddings,
)
print(vector_store)
# <langchain_community.vectorstores.faiss.FAISS at ***********>
```
ベクターストアを作成。プリントするとFAISSクラスができたことがわかります。

<br>


```python:retriever（検索機）の作成
retriever_docs = vector_store.as_retriever(
    search_type='mmr', 
    search_kwargs={'k': 2}
    )
```
さらに、ベクターストアを検索機として定義します。
ここの`search_type`についてはこちらが詳しい。

<br>


https://zenn.dev/pipon_tech_blog/articles/8cdb27830236c5

ここではmmrという手法で、二つだけ検索するという方法を設定してみました。


<br>


## 4-5. 検索テスト
```python
retrieved_docs = retriever_docs.invoke('プラネタリウム')
print(retrieved_docs)
# [Document(id='77fafee7-30fd-4417-9f1c-51b02c8a9de6', metadata={'file_name': './text_files/dummy1.txt', 'page': '1', 'index': 8}, page_content='山本太一は、重力を操る能力を持っています。彼は週末にお菓子の袋を宙に浮かべ、まるでプラネタリウムのように菓子を回転させながら食べるのが趣味だそうです。\n\n中島弘美は、雲を編んで服を作るファッションデザイナーです。彼女の作る雲のドレスは、着る人の気分によって色や形が変化するという画期的なものです。ただし、晴れの日に消えてしまう欠点があります。'),
#  Document(id='97448c1f-5c9b-4734-af3c-c962155a21a0', metadata={'file_name': './text_files/dummy1.txt', 'page': '1', 'index': 5}, page_content='木村隆は、恐竜の DNA を使って現代の動物をハイブリッド化する研究を行っています。彼の最新作は、ティラノサウルスとウサギを掛け合わせた「ティラノウサギ」で、現在ペットとして人気急上昇中です。')]
```
でけたでけた。にやにや、わくわく。
ちゃんとメタデータが入ってるのがわかります。


<br>

## 4-6. ベクターストアのローカル保存と呼び出しもついでにやっときましょう。
```python:ベクターストアのローカル保存
local_vectorstore_path = './vector_store/' # 保存先フォルダの指定
vector_store_docs.save_local(local_vectorstore_path)
```
保存できた。

<br>

```python:ベクターストアの読み込み
local_vectorstore = FAISS.load_local(
    folder_path=local_vectorstore_path,
    embeddings=embeddings,
    index_name='index',
    allow_dangerous_deserialization=True
)
```
再度読み込みができた！といってもドキュメントのコピペだが何か？（引数調べよう。汗）

<br>


```python:retrieverの設定
local_retriever = local_vectorstore.as_retriever(
    search_type='mmr', # 類似性による選択、デフォルト設定
    search_kwargs={'k': 2} # 2個だけ検出する（デフォルトは4個）
    )
```
ちょっと色気を出して、検索方法やら、検索数を指定してみたたりして・・・。

<br>


```python:検索テスト
print(local_retriever.invoke('プラネタリウム'))
# [Document(id='617d4ad8-6bd6-4269-83a9-ae250d1008ac', metadata={'file_name': 'dummy1.txt', 'page': 1, 'index': 8}, page_content='山本太一は、重力を操る能力を持っています。彼は週末にお菓子の袋を宙に浮かべ、まるでプラネタリウムのように菓子を回転させながら食べるのが趣味だそうです。\n\n中島弘美は、雲を編んで服を作るファッションデザイナーです。彼女の作る雲のドレスは、着る人の気分によって色や形が変化するという画期的なものです。ただし、晴れの日に消えてしまう欠点があります。'),
#  Document(id='38fed566-7093-42ba-b56f-9fe01db51d3f', metadata={'file_name': 'dummy1.txt', 'page': 1, 'index': 5}, page_content='木村隆は、恐竜の DNA を使って現代の動物をハイブリッド化する研究を行っています。彼の最新作は、ティラノサウルスとウサギを掛け合わせた「ティラノウサギ」で、現在ペットとして人気急上昇中です。')]
```

無事検索できた。さらに欲張ってみようと思う。

<br>


## 4-7. metadataを使った絞り込み
metadataを使った絞り込み。
ま、ドキュメントを眺めていたら見つけてしまったんです。ここ↓

https://python.langchain.com/docs/concepts/vectorstores/#metadata-filtering

**おおお！！** って思いましたよ。
やってみましょう。

注意：`langchain-core`が`0.3.21`だと`filter`が機能しませんでした。filterが機能しない場合は`langchain-core`をアップデートしてください。（`0.3.35`にアップデートしたら機能しました.
2025/2/17追記）

<br>


```python:medadataを使った絞り込み
print(local_retriever.invoke('プラネタリウム', filter={'file_name': 'dummy2.txt'}))
# [Document(id='31ca87a6-757e-4d3a-a6cf-4d43070eedc7', metadata={'file_name': 'dummy2.txt', 'page': 1, 'index': 23}, page_content='遠藤さくらは、植物と融合して新しい生命体になれる能力を持っています。彼女は「ヒューマンプラント」として、光合成による環境浄化活動を行っていますが、冬場の寒さ対策に苦心しているそうです。'),
#  Document(id='3a4b3ba3-7043-4726-8e30-d4167f1edb73', metadata={'file_name': 'dummy2.txt', 'page': 1, 'index': 15}, page_content='木下雄太は、瞬間移動できるポータルを作り出す能力を持っています。彼は「テレポート交通」という会社を設立し、世界中の主要都市を結ぶ新しい交通網を構築しました。ただし、時差ボケ対策やポータル渋滞の問題に直面しているそうです。')]
```
なんと、fillterを引数として渡せばいいだけ。フィルタなしでプラネタリウムで検索した時は`file_name`が`dummy1.txt`だったので、あえて、`dummy2.txt`を指定してみました。
ね、dummy2.txtだけを検索してるでしょ。

これ、たとえば、metadataにプロジェクト名やテキスト作成日時を入れておけば、これらで絞り込みができるってことですよね。いや、これはテンションあがるぞ。
**これは~~きっと~~便利だぁ〜！！！**
~~（まだ実用するものは作っていない）~~

<br>
<br>


# 5. 検索した結果を使ってLLMから出力させる
ここでも追加で必要なライブラリをインポートしてから始めましょう。

```python:ライブラリのインポート（RAG構築関係）
from langchain_openai import AzureChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.runnables import RunnablePassthrough
from langchain_core.output_parsers import StrOutputParser
```

おっと、API等も用意しなきゃね。
```Python
load_dotenv('.env')

API_KEY = os.getenv("API_KEY")
END_POINT = os.getenv("END_POINT")
API_VERSION = os.getenv("API_VERSION")
```

<br>

## 5-1. ChatModelの用意
```python
model = AzureChatOpenAI(
    azure_deployment='gpt-4o-mini',
    azure_endpoint=END_POINT,
    api_version=API_VERSION,
    api_key=API_KEY,
    max_tokens=150
)
```
もういうことはあるまい。

<br>


## 5-1. プロンプトの用意
```python:プロンプトの用意
prompt = ChatPromptTemplate.from_template('''
以下の文脈の内容を踏まえて質問に回答してください。

文脈："""
{context}
"""

質問： {question}
'''
)
```
contextのところにretrieverの出力を、質問のところに質問文が入る仕組み。
ま、これも復習だからサッと行きます。

<br>



## 5-2. Chainの準備
```python:Chainの準備
chain = {
    "context": local_retriever, 
    "question": RunnablePassthrough()
    } | prompt | model | StrOutputParser()
```
`{}`の中身はパラレルで動きます。質問文を元に`local_retriever`のところで検索を行い、`RunnablePassthrough`のところで、質問文をそのまま次に渡します。
その次ってのが`prompt`その後、モデルに入れて出力のテキスト部分だけを`StrOutputParser`で出力します。

では次に出力してみましょう。

<br>


## 5-3. 出力１~普通の出力~
```python:普通の出力
result = chain.invoke("渡辺愛子は何を作りましたか？")
print(result)
# 渡辺愛子は、食べ物の味を音楽に変換するフォークを発明しました。
```
お、できましたねー。
きっと、dummy1.txtの23番目の文章、「渡辺愛子は、食べ物の味を音楽に変換するフォークを発明しました。彼女のレストラン「メロディ・キッチン」では・・・」という文章を参照したんだと思いますが、わかりませんね。
ということで、工夫をしてみましょう。

<br>


## 5-4. 出力２~引用したテキストを含めて出力~
```python:引用テキストを含めて出力するChain
chain_assign = {
    "context": local_retriever, 
    "question": RunnablePassthrough()
    } | RunnablePassthrough.assign(answer = prompt | model | StrOutputParser())
```
僕の理解では、最初の辞書の出力をそのまま出力し、そこにanswerとして割り当て（assign）されたものが追加されて出力されるというイメージ。

さて、出力してみましょう。

<br>

```python:引用テキストを含めて出力するChain
result_assign = chain_assign.invoke("渡辺愛子は何を作りましたか？")
print(result_assign.keys())
# dict_keys(['context', 'question', 'answer'])
```
辞書形式で、出力されます。そして、そのkeyは`context`, `question`, `answer`です。
それぞれを見ていきます。

<br>

```python:contextの出力
print(result_assign['context'])
# [Document(id='49969438-8e89-4382-8a93-bb83e8fc7ed4', metadata={'file_name': 'dummy.txt', 'page': 1, 'index': 23}, page_content='渡辺愛子は、食べ物の味を音楽に変換するフォークを発明しました。彼女のレストラン「メロディ・キッチン」では、シンフォニーのようなフルコースを楽しめます。ただし、カレーを食べると重金属の音楽になってしまう問題が指摘されています。'),
#  Document(id='0d8ba05b-02ca-4cd5-8598-4bff7d19e9fc', metadata={'file_name': 'dummy.txt', 'page': 1, 'index': 21}, page_content='山田花子は、植物と交渉して好きな形に成長させる能力を持っています。彼女のガーデニング会社「シェイプリーフ」では、顧客の顔を模した観葉植物や、企業ロゴ型の巨大な生垣が人気商品です。\n\n佐藤雄二は、雲を操る能力を持ち、「スカイライティング」という新しい広告媒体を開発しました。しかし、競合他社の広告を消すために晴天にしてしまい、農家から苦情が殺到する問題に直面しています。')]
```
contextは検索結果のようですね。

<br>

```python:questionの出力
print(result_assign['question'])
# '渡辺愛子は何を作りましたか？'
```
questionは質問そのもの

<br>

```python:answerの出力
print(result_assign['answer'])
# '渡辺愛子は、食べ物の味を音楽に変換するフォークを発明しました。'
```
answerは回答そのものの出力です。

<br>


## 5-5. 出力３~指定した内容を出力~
今回みたいに３っつだけならこのままでいいんですが、出力のkeyがたくさんあったりすると出力も **うっとうしい** ですよね。
ということで以下で絞り込みができます。
```python:出力の絞り込み
chain_assign_2 = {
    "context": local_retriever, 
    "question": RunnablePassthrough()
    } | RunnablePassthrough.assign(answer= prompt | model | StrOutputParser()).pick(['answer', 'context'])
```
`pick`関数で出力を指定します。ここでは、質問文はそもそもいらないので、`answer`と`context`だけにしておきます。このChainの出力をしてみましょう。


<br>


```python:answerとcontextだけの出力
result_assign_2 = chain_assign_2.invoke("渡辺愛子は何を作りましたか？")
print(result_assign_2)
# {
#     'answer': '渡辺愛子は、食べ物の味を音楽に変換するフォークを発明しました。', 
#     'context': [
#          Document(id='49969438-8e89-4382-8a93-bb83e8fc7ed4', metadata={'file_name': 'dummy.txt', 'page': 1, 'index': 23}, page_content='渡辺愛子は、食べ物の味を音楽に変換するフォークを発明しました。彼女のレストラン「メロディ・キッチン」では、シンフォニーのようなフルコースを楽しめます。ただし、カレーを食べると重金属の音楽になってしまう問題が指摘されています。'), 
#          Document(id='0d8ba05b-02ca-4cd5-8598-4bff7d19e9fc', metadata={'file_name': 'dummy.txt', 'page': 1, 'index': 21}, page_content='山田花子は、植物と交渉して好きな形に成長させる能力を持っています。彼女のガーデニング会社「シェイプリーフ」では、顧客の顔を模した観葉植物や、企業ロゴ型の巨大な生垣が人気商品です。\n\n佐藤雄二は、雲を操る能力を持ち、「スカイライティング」という新しい広告媒体を開発しました。しかし、競合他社の広告を消すために晴天にしてしまい、農家から苦情が殺到する問題に直面しています。')
#      ]
# }
```
これで、出力を絞り込むことができます。途中に入るデータが多くなるとこうやって絞り込めばいいんですね。

<br>

# 6. まとめ
- retrieverにmetadataを付与することができました。
- 付与したmetadataを元に絞り込みをしつつ、検索（retrieve）することができました。
- RAGのChainの工夫で、最終出力だけでなく、metadataや検索結果などを出力することができました。

あとは作りたいもの次第！？
いや、作りたいものはあるのよ。でもね、色々調べてるとまだ作り始められなくて、知識の習得が必要なんだわさ。💦

何かに続く・・・