【LLM】RAGで社内QAチャットボットを作った

# RAGとは
RAGとは、**R**etrieval-**A**ugmented **G**eneration（検索拡張生成）の略称であり、**独自のドキュメントを踏まえた対話を実現する技術**です。例えば、あなたの会社にある生成AIを使ったサービスが社内独自の事柄について答えてくれている場合、RAGで実現している可能性が高いです。ChatGPTなどのLLMはインターネットに公開されているとある時点までの情報でそのモデルが構築されています。ゆえに参照データなしで非公開の社内情報はもちろん答えることができません。しかし、独自のドキュメントを最適な形でLLMの参照データにするRAGを構築することで、ドメスティックな社内QAチャットボットの作成が可能となります。「**LLM未知**」かつ「**大規模検索**」に強いわけです。また、RAG以外にもファインチューニングでLLMを追加学習する方法がありますが、高いリソース、モデルそのもの、情報更新毎に追加学習が必要といった観点から敷居が高いです。


# RAGの仕組み
![スクリーンショット 2025-02-03 2.36.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/377231/416e1e0f-a0db-3732-442e-a70839b674bf.png)

流れとしては
- 情報源となる文書集合を**チャンク**と呼ばれる固定長の文字列の長さに区切る
- 各チャンクを**ベクトル**に変換する
- 各チャンクとそれに紐づくベクトル表現を**VectorDB**に格納する
- ユーザがクエリを入力する
- クエリのベクトル表現と**ベクトル空間上の距離が近いチャンク群**を獲得
- ユーザが入力したクエリと獲得したチャンク群をLLMへの入力にする
- LLMが回答する
- ユーザに回答を表示する

です。
なんでわざわざテキストをベクトルにしておく必要があるの？って感じると思います。
それは**検索が楽**だからです。文字列のまま大規模なデータベースの中からクエリに関連する文を探すよりも、文字列をベクトルにしてその距離の計算をする方がコンピュータにとって単純で楽だからです。（コンピュータは単純な計算が得意）


# この記事で作るQAチャットボット
実際の社内ドキュメントをここに掲載する訳にはいかないので、本記事では私の経験と趣味について書いた下記文書を社内ドキュメントに見立て、それについてのQAチャットボットを作りたいと思います。

```:profile.txt
私の名前は黄猿です。1994年に東京で生まれました。幼少期のほとんどを栃木県で過ごしました。
星座はしし座、血液型はO型です。
小学校の修学旅行では鎌倉、中学校の修学旅行では奈良と京都へ行きました。
中学生まではサッカーのクラブチームに所属していて、ポジションはフォワードでした。
ガンダムが好きなので高校からは模型部に所属しました。ちなみにガンダムのシリーズの中ではガンダムSEEDとガンダム00が好きです。
高校ではロボットの制御系、大学では機械学習とAI、以前勤めていた会社ではウェブに取り組みました。
```
こんな感じのQAを期待しています。

> Q: 黄猿は西暦何年生まれですか？
> A: 西暦1994年生まれです

> Q: 黄猿が好きなガンダムのシリーズは何ですか？
> A: ガンダムSEEDとガンダム00です

> Q: 黄猿は大学で何に取り組みましたか？
> A: 機械学習とAIに取り組みました

では実装へ進みましょう。

# 実装
## STEP1 チャンクの作成
まず情報源である`profile.txt`のテキストコーパスを**チャンク**に区切ります。
機械的に区切っているのでチャンクは文の途中から始まったり、文の途中で終わったりすることがあります。チャンクサイズとオーバーラップについては[こちら](https://hub.gflops-ai.com/rag/98/#outline__3_1)をご一読ください。

```python
from langchain.text_splitter import RecursiveCharacterTextSplitter

with open('profile.txt','r',encoding='utf-8') as f:
    text = f.read()

text_splitter = RecursiveCharacterTextSplitter(chunk_size=100, chunk_overlap=50)
texts = text_splitter.split_text(text)
print(texts)
print(len(texts))
```
```bash:実行結果
['私の名前は黄猿です。1994年に東京で生まれました。幼少期のほとんどを栃木県で過ごしました。\n星座はしし座、血液型はO型です。\n小学校の修学旅行では鎌倉、中学校の修学旅行では奈良と京都へ行きました。', '小学校の修学旅行では鎌倉、中学校の修学旅行では奈良と京都へ行きました。\n中学生まではサッカーのクラブチームに所属していて、ポジションはフォワードでした。', 'ガンダムが好きなので高校からは模型部に所属しました。ちなみにガンダムのシリーズの中ではガンダムSEEDとガンダム00が好きです。', '高校ではロボットの制御系、大学では機械学習とAI、以前勤めていた会社ではウェブに取り組みました。']
4
```
## STEP2 ベクトル化とVectorDB作成
次にチャンクを**ベクトル**にします。ここで、文字列を1024次元のベクトルに直すためのモデルを利用します。試しに適当なテキストのベクトル表現を見てみます。

```python
from langchain_community.embeddings import HuggingFaceEmbeddings

embeddings = HuggingFaceEmbeddings(model_name="intfloat/multilingual-e5-large")
print(embeddings.embed_query("私はガンダムが好きです"))
```
```:実行結果
[0.014961239881813526, -0.013438350521028042, -0.02338373102247715, -0.046732835471630096, 0.036591917276382446, -0.0314420685172081, 0.010363133624196053, 0.0526604950428009, 0.03585990145802498, -0.0021254313178360462, 0.007143037859350443, 0.009760120883584023, -0.05093642324209213, -0.022492574527859688, -0.04453587532043457, -0.029372688382864, 0.00791942048817873, 0.029772372916340828, 0.04323475807905197, -0.02580212615430355, 0.02350088208913803, -0.02859210968017578, -0.008231011219322681, -0.019815685227513313, -0.012658300809562206, 0.01473894715309143, -0.04026776924729347, -0.03728504106402397, -0.01784842647612095, -0.03154578059911728, -0.02559570223093033, 0.018046598881483078, -0.054743390530347824, -0.023097608238458633, -0.017075132578611374, 0.04239533469080925, 0.06670623272657394, 0.0393647663295269, -0.00612567737698555, 0.014776844531297684, -0.03595533221960068, 0.006567193195223808, 0.0034965560771524906, -0.054492197930812836, -0.009149786084890366, -0.0019832609687000513, 0.03376207873225212, 0.025527017191052437, 0.028105681762099266, 0.07150997966527939, 0.01242544874548912, 0.012548515573143959, 0.0053804065100848675, -0.023358387872576714, -0.015329101122915745, 0.04859049618244171, -0.04485206678509712, 0.02358246222138405, -0.005162518937140703, 0.03877830132842064, -0.013958077877759933, 0.004633623640984297, 0.06539405882358551, -0.05530891567468643, -0.033838771283626556, 0.03169017657637596, 0.023950060829520226, 0.019698485732078552, -0.04393400251865387, 0.04124794527888298, -0.025539306923747063, 0.022969987243413925, -0.02546885795891285, -0.01393309235572815, -0.015431836247444153, 0.0006134255672805011, 0.04936236888170242, -0.017534982413053513, -0.021787939593195915, -0.0012003269512206316, 0.070645771920681, 0.004021367523819208, 0.04237116128206253, -0.018033206462860107, 0.04873606562614441, 0.02478613518178463, 0.025123151019215584, 0.06223457679152489, 0.027290448546409607, 0.048527903854846954, 0.00666489964351058, 0.03820306807756424, 0.03686576336622238, -0.021651742979884148, -0.02910122647881508, 0.01663944125175476, -0.005155664402991533, 0.04968990758061409, -0.006030458956956863, -0.00012615373998414725, -0.026562964543700218, -0.002849237062036991, 0.003463418921455741, -0.04383207857608795, -0.032143134623765945, 0.0161498561501503, 0.022977260872721672, 0.004780865740031004, -0.012334780767560005, 0.013426722027361393, 0.04568832740187645, 0.053470127284526825, 0.029911594465374947, -0.02418338879942894, -0.03639993071556091, -0.0013403792399913073, -0.002198942471295595, 0.00916789099574089, -0.006598615553230047, 0.014034600928425789, 0.024208074435591698, 0.030780185014009476, -0.011789263226091862, -0.042150504887104034, 0.0354045145213604, -0.024784928187727928, 0.007657624781131744, 0.039229072630405426, -0.018773579970002174, 0.044043004512786865, 0.02985677309334278, 0.036266498267650604, -0.04551267251372337, -0.003119839821010828, -0.057745493948459625, -0.060931138694286346, -0.0017579523846507072, 0.0007465282105840743, -0.012146188877522945, -0.0017826507100835443, -0.0065483455546200275, 0.010897252708673477, 0.050162360072135925, -0.050806641578674316, -0.02139504812657833, -0.05515351891517639, -0.04604625329375267, 0.01966492086648941, 0.02148730866611004, -0.024859771132469177, -0.03703170269727707, 0.002662442857399583, 0.005424361675977707, -0.004516319837421179, -0.009283026680350304, -0.006669951137155294, 0.028904877603054047, 0.059176005423069, 0.00603108387440443, 0.013286055997014046, -0.026372024789452553, -0.07021994143724442, -0.04257135093212128, 0.005687563680112362, -0.008282496593892574, -0.009913479909300804, 0.024974407628178596, 0.030825592577457428, 0.00319453957490623, -0.029866648837924004, -0.0035094586201012135, -0.05094919353723526, 0.01975804939866066, -0.06060108542442322, 0.0033459726255387068, 0.010725985281169415, 0.007953433319926262, 0.027696356177330017, 0.048659685999155045, -0.024803154170513153, 0.005026633385568857, 0.028778256848454475, 0.06910225749015808, -0.011189105920493603, -0.0033560555893927813, 0.029954316094517708, 0.04081219434738159, 0.0068625351414084435, 0.045919131487607956, 0.005915360990911722, 0.03251267969608307, -0.016388896852731705, -0.017767054960131645, 0.016481254249811172, -0.05481494963169098, 0.03178499639034271, 0.015852658078074455, 0.029240230098366737, -0.04488131403923035, -0.03231383115053177, -0.014977261424064636, 0.0068261646665632725, -0.03599587827920914, 0.005821267608553171, 0.017642615363001823, -0.02968163788318634, -0.05912984162569046, -0.032934173941612244, 0.00465459143742919, -0.05823510140180588, -0.04215933009982109, -0.025449290871620178, 0.019521791487932205, 0.006605767644941807, -0.029389161616563797, -0.025739170610904694, -0.022756678983569145, -0.03716009482741356, 0.022691864520311356, -0.030706115067005157, 0.008466252125799656, 0.05317233130335808, 0.017519094049930573, 0.04363560304045677, -0.01333415973931551, 0.02453923225402832, 0.03196995332837105, 0.04547150060534477, 0.0450378954410553, 0.034926578402519226, 0.002581653418019414, 0.01982971653342247, -0.06339776515960693, -0.027066728100180626, -0.002351729664951563, -0.016768645495176315, -0.03092302195727825, -0.00754000386223197, 0.030637606978416443, 0.046752117574214935, -0.05355038121342659, 0.014383180066943169, 0.025319883599877357, -0.00231472821906209, 0.0031609509605914354, -0.011411917395889759, 0.017746329307556152, -0.03382455185055733, 0.02043152041733265, -0.010178707540035248, 0.027142202481627464, 0.048864103853702545, -0.026870902627706528, -0.043196603655815125, 0.02279357612133026, 0.011830984614789486, 0.017042450606822968, -0.005316172726452351, -0.005040821619331837, -0.0008813474560156465, -0.00680862320587039, 0.005966214928776026, -0.020882636308670044, 0.05373847484588623, 0.026741240173578262, 0.027910131961107254, 0.002950098365545273, -0.019913922995328903, 0.004753026645630598, -0.05077342689037323, -0.010088172741234303, -0.05187685042619705, -0.05291573330760002, -0.016992073506116867, -0.029064899310469627, 0.022446712478995323, -0.050056640058755875, -0.019570570439100266, -0.0022819528821855783, -0.020499784499406815, -0.021336659789085388, -0.04962783306837082, 0.016078796237707138, -0.0456431619822979, 0.036451954394578934, -0.008499330841004848, 0.01168335136026144, -0.013107731007039547, 0.016149505972862244, 0.001668998971581459, 0.03486863151192665, -0.03445456549525261, 0.06454066932201385, 0.003180902684107423, 0.04386097192764282, 0.038543980568647385, -0.04103032499551773, -0.09120692312717438, -0.0034302775748074055, 0.014907517470419407, 0.007111556362360716, -0.047690555453300476, 0.02362208627164364, 0.03700920194387436, -0.005422804970294237, -0.018207767978310585, -0.01003425382077694, 0.006131590344011784, -0.06063640117645264, 0.006890162825584412, 0.05375435948371887, 0.04883037507534027, 0.007284268736839294, -0.04941447824239731, -0.05681060999631882, -0.022331006824970245, -0.05466117337346077, 0.028542356565594673, -0.021182406693696976, 0.01987684890627861, -0.05077705532312393, -0.016063928604125977, -0.020763058215379715, 0.0049357423558831215, 0.008359064348042011, -0.016729263588786125, 0.0025882727932184935, -0.02446013130247593, 0.024369876831769943, -0.027427608147263527, 0.03255119174718857, -0.02278645522892475, 0.010986728593707085, 0.044663768261671066, 0.0031257225200533867, 0.02605278044939041, -0.04517955332994461, 0.029107997193932533, 0.061066292226314545, 0.0014434732729569077, 0.009820126928389072, -0.017264453694224358, -0.006275508087128401, -0.019641989842057228, 0.015032474882900715, -0.03276868537068367, -0.0006669942522421479, -0.04439051076769829, 0.01634945534169674, 0.013662120327353477, 0.009089972823858261, -0.011357257142663002, -0.004421112593263388, 0.007974402979016304, -0.02085111290216446, 0.058814238756895065, -0.004007434472441673, -0.013162147253751755, 0.023055190220475197, -0.019547484815120697, 0.013544774614274502, -0.009860963560640812, 0.03791186958551407, -0.01023047510534525, -0.025467587634921074, 0.013256966136395931, -0.010568958707153797, -0.013788629323244095, -0.023213425651192665, -0.019554488360881805, 0.022548196837306023, 0.01200068462640047, -0.008274204097688198, 0.022072946652770042, 0.005404897034168243, -0.019770514219999313, -0.09206146746873856, -0.06043284386396408, -0.004607843700796366, -0.037743717432022095, -0.015010816976428032, -0.024718990549445152, -0.02123851515352726, -0.021595094352960587, -0.02165314368903637, -0.03467915952205658, 0.1694265604019165, 0.007331719156354666, 0.07970233261585236, -0.06078623980283737, -0.018586285412311554, 0.007425188086926937, 0.051758259534835815, 0.0031918177846819162, 0.012138236314058304, 0.021350175142288208, -0.029946284368634224, -0.0005759430932812393, 0.03940124064683914, -0.025504780933260918, 0.019581269472837448, 0.059676725417375565, 0.029082033783197403, 0.017295917496085167, 0.017525946721434593, -0.006247384939342737, 0.04646379128098488, -0.05595249682664871, 0.007715665269643068, -0.0014125159941613674, -0.05057521164417267, -0.04657215252518654, -0.009756337851285934, 0.048179689794778824, -0.034784842282533646, 0.030808163806796074, -0.03077368065714836, 0.006671366281807423, -0.04267856478691101, -0.01985127292573452, 0.021407784894108772, 0.012587888166308403, 0.0013370777014642954, -0.015527242794632912, 0.025110814720392227, -0.01705789566040039, -0.01682240515947342, 0.00883137434720993, -0.026733651757240295, 0.011356273666024208, -0.010608172044157982, 0.036177121102809906, 0.057105086743831635, -0.027426807209849358, -0.00785481184720993, 0.03360361605882645, 0.025564683601260185, 0.03348669782280922, -0.034264009445905685, -0.024632306769490242, 0.017046377062797546, -0.03554363176226616, -0.021752076223492622, -0.019623111933469772, -0.015091247856616974, 0.020797936245799065, 0.03457187861204147, 0.020883461460471153, -0.022681478410959244, -0.01719244383275509, 0.03531418368220329, 0.021542105823755264, 0.012312060222029686, -0.045630622655153275, -0.014446101151406765, -0.004705104045569897, -0.05255012959241867, -0.02222096361219883, -0.03244395926594734, 0.031414881348609924, 0.033369749784469604, 0.024662354961037636, 0.010655290447175503, 0.045380450785160065, 0.0360255092382431, 0.008666944690048695, -0.007926593534648418, -0.009134470485150814, -0.02589292824268341, 0.022798214107751846, 0.04433305561542511, -0.014509521424770355, 0.0432562530040741, 0.026639416813850403, -0.03201092407107353, 0.028331082314252853, 0.006877412553876638, 0.027914034202694893, -0.03692615032196045, 0.014623159542679787, 0.03913988173007965, -0.04461773857474327, 0.0041151647455990314, 0.0016931822756305337, -0.007509627379477024, 0.008955422788858414, -0.013447397388517857, 0.01002693921327591, -0.01927376165986061, -0.015072855167090893, -0.013782203197479248, -0.04215042293071747, 0.00543644092977047, 0.013938487507402897, -0.005214078351855278, 0.009506884030997753, 0.0662228912115097, 0.019956989213824272, 0.009502781555056572, -0.006615075282752514, 0.05518760532140732, 0.026403453201055527, 0.013495313934981823, -0.029847675934433937, 0.012551847845315933, 0.010426728054881096, -0.03624517098069191, 0.058104466646909714, -0.04265497624874115, 0.07991612702608109, -0.03827574849128723, 0.039415158331394196, 0.0024558950681239367, -0.0017874074401333928, 0.03250874951481819, 0.011811787262558937, 0.02673170529305935, -0.03634865581989288, -0.031017839908599854, 0.03209036588668823, 0.013491448014974594, -0.014546040445566177, 0.07670815289020538, -0.01380995661020279, 0.0013380201999098063, 0.0493665374815464, -0.019273901358246803, 0.06313073635101318, -0.05088207125663757, 0.039608076214790344, 0.035486672073602676, 0.03705295920372009, -0.027590861544013023, -0.03363393247127533, -0.012268668040633202, -0.05134233459830284, 0.02762462943792343, -0.011631209403276443, -0.008132104761898518, 0.001277473522350192, -0.019663821905851364, -0.036434467881917953, 0.02542766183614731, 0.0010143248364329338, 0.020566217601299286, -0.050505634397268295, -0.033335693180561066, -0.02389995940029621, 0.02983464114367962, 0.11605247110128403, -0.015050644986331463, 0.054953381419181824, -0.01612328179180622, 0.009626679122447968, 0.0453374944627285, -0.005632353015244007, -0.06723123788833618, -0.027691340073943138, 0.013197261840105057, 0.03563537076115608, 0.02648225985467434, -0.01743183098733425, -0.01763659156858921, 0.026706483215093613, -0.05156918987631798, 0.030397146940231323, -0.018502065911889076, 0.013358143158257008, 0.02309376746416092, -0.025191400200128555, -0.032988425344228745, 0.020521527156233788, 0.013895438052713871, -0.028945649042725563, -0.030044540762901306, 0.01541403029114008, -0.02228309027850628, 0.05502954497933388, -0.011873597279191017, -0.0007969121215865016, -0.023624051362276077, 0.009649766609072685, 0.016294365748763084, 0.0012659222120419145, -0.05043894425034523, -0.018670683726668358, -0.0014732424169778824, -0.057994939386844635, 0.010052443481981754, -0.02446427382528782, -0.03803088515996933, -0.017925335094332695, 0.003468530485406518, -0.002746494021266699, 0.038998961448669434, 0.02364787831902504, 1.5087638530530967e-05, -0.04258761927485466, 0.0053046285174787045, 0.004138857126235962, 0.02142326347529888, 0.02097417414188385, 0.0070809354074299335, 0.0065135592594742775, 0.027413906529545784, -0.029528465121984482, 0.026416771113872528, 0.025459589436650276, 0.010275882668793201, -0.04043643921613693, -0.01815408654510975, -0.05430101230740547, 0.01832467131316662, 0.015878327190876007, -0.030394507572054863, -0.020175950601696968, 0.011641005985438824, -0.028929099440574646, -0.019649501889944077, -0.038739971816539764, -0.03868754580616951, -0.01681525446474552, 0.024538258090615273, 0.03185317665338516, -0.0019376636482775211, -0.054604608565568924, 0.039865847676992416, -0.028503701090812683, 0.039897847920656204, -0.018069716170430183, 0.009318279102444649, 0.009385554119944572, -0.03504661098122597, -0.035652562975883484, 0.040176231414079666, -0.004753677174448967, 0.00882034096866846, -0.04755471274256706, 0.06765955686569214, 0.044545553624629974, -0.0004289458738639951, -0.049122001975774765, -0.016705507412552834, -0.005647021811455488, -0.0485842265188694, -0.05368194729089737, 0.01293741725385189, 0.006197663489729166, -0.0357992947101593, 0.02471260353922844, -0.011631117202341557, 0.003696252591907978, 0.018365662544965744, -0.04842681065201759, 0.008296415209770203, -0.04090116173028946, 0.0185710359364748, -0.009896211326122284, -0.04126358404755592, -0.028678491711616516, 0.08366961032152176, 0.02301175706088543, -0.03915154188871384, -0.024161212146282196, -0.021565042436122894, -0.025121919810771942, -0.03554042801260948, 0.023015053942799568, -0.0014904448762536049, -0.021474314853549004, 0.022935492917895317, 0.021146031096577644, -0.04557059705257416, 0.010712250135838985, 0.017754653468728065, -0.009091648273169994, -0.01016726903617382, 0.026090340688824654, -0.04071613401174545, -0.04713371396064758, -0.07696029543876648, -0.03543581813573837, -0.03443523123860359, -0.03238146752119064, 0.004581408109515905, -0.02222250960767269, 0.035669755190610886, -0.002998383017256856, -0.05820569768548012, -0.05331757664680481, -0.003915947396308184, 0.009100830182433128, -0.030005838721990585, 0.022142356261610985, 0.03869315981864929, 0.053502436727285385, 0.012261574156582355, -0.03895788639783859, 0.01688660867512226, 0.027898235246539116, -0.01501299999654293, 0.01853322982788086, 0.022459357976913452, -0.011356634087860584, -0.04507286101579666, 0.06041276827454567, -0.03225374594330788, -0.003945008851587772, -0.02630513720214367, -0.0003564990183804184, 0.013071397319436073, 0.02860439568758011, 0.023750731721520424, -0.005463759880512953, 0.015155286528170109, 0.00035525596467778087, 0.030111905187368393, -0.010068419389426708, -0.042033322155475616, -0.0008528022444806993, -0.03291138634085655, -0.030441254377365112, -0.011821970343589783, -0.026720551773905754, -0.023991413414478302, -0.027217308059334755, -0.01746954396367073, 0.05290454626083374, 0.04491584748029709, -0.03588392585515976, 0.05684690549969673, 0.0054768952541053295, -0.031877707690000534, 0.025804487988352776, 0.00016700915875844657, -0.015619529411196709, -0.048141974955797195, 0.020259972661733627, -0.04046221822500229, -0.012902935035526752, 0.00647949893027544, 0.02068983018398285, -0.023122398182749748, 0.014265066012740135, -0.004190464038401842, -0.0598057396709919, -0.011496243998408318, -0.03205215930938721, 0.06132911145687103, -0.01922372728586197, -0.015071425586938858, 0.024054676294326782, 0.0010212479392066598, 0.03451882302761078, -0.042968519032001495, 0.00866744015365839, -0.0013444016221910715, 0.04496392235159874, -0.02871319279074669, -0.02535947784781456, -0.027209827676415443, 0.04501618072390556, -0.029857100918889046, 0.0037273047491908073, 0.027629347518086433, 0.035795215517282486, 0.03298480063676834, -0.04946509003639221, -0.022381577640771866, -0.00497411796823144, 0.012745998799800873, -0.05443133786320686, 0.0010187471052631736, 0.024320771917700768, -0.014627444557845592, 0.03238445520401001, -0.013202204369008541, 0.0312771201133728, 0.022892607375979424, 0.008640756830573082, -0.08985360711812973, -0.0073070465587079525, -0.013495346531271935, -0.003467483213171363, -0.00954299047589302, -0.014643482863903046, -0.03391293063759804, 0.020945996046066284, 0.015878021717071533, -0.04693037271499634, 0.022647224366664886, 0.034353990107774734, 0.02530384436249733, -0.012906919233500957, 0.0079145897179842, 0.013042053207755089, 0.045963287353515625, -0.0031650520395487547, 0.04090460389852524, 0.02350032329559326, 0.016917774453759193, -0.07635336369276047, -0.0196757223457098, 0.02278350107371807, 0.009608288295567036, 0.03845386207103729, 0.010627183131873608, 0.015125217847526073, -0.020445946604013443, -0.03383627161383629, -0.005032660439610481, -0.02700304239988327, -0.011782100424170494, 0.035544078797101974, -0.03242283686995506, 0.026748305186629295, -0.02669563516974449, -0.018883900716900826, 0.010005228221416473, 0.011790783144533634, -0.03500042110681534, 0.011210329830646515, -0.04608280211687088, 0.020402442663908005, 0.012932416051626205, 0.05797002464532852, -0.0082903066650033, -0.012422522529959679, 0.027490677312016487, -0.03190691024065018, 0.004724601749330759, -0.01711610145866871, 0.018850430846214294, 0.06779126077890396, 0.001368977827951312, 0.03808050975203514, 0.03549576550722122, -0.004404131788760424, 0.025540387257933617, 0.05344801023602486, 0.005399214569479227, -0.02612152509391308, -0.01799085922539234, -0.019772790372371674, -0.03679628670215607, -0.010225162841379642, -0.09020555019378662, -0.026353705674409866, -0.03389683738350868, 0.019897336140275, 0.0007979439105838537, -0.021898578852415085, 0.029677661135792732, -0.020302437245845795, 0.028195662423968315, 0.0021921901497989893, -0.022179391235113144, -0.001220681588165462, 0.022797737270593643, -0.024146826937794685, -0.012451875023543835, -0.027389714494347572, 0.029456237331032753, -0.001172523363493383, -0.03874116390943527, 0.024412095546722412, 0.0006244142423383892, -0.033922720700502396, -0.03539440408349037, 0.045320600271224976, -0.027905616909265518, 0.005311251152306795, 0.008954199962317944, -0.03668923303484917, -0.024035410955548286, -0.018989667296409607, -0.04314136505126953, -0.0025194778572767973, 0.002193591557443142, 0.030027752742171288, -0.006133238784968853, 0.0001453999720979482, 0.00970691628754139, -0.003228147979825735, 0.012274696491658688, 0.012653986923396587, 0.03367283195257187, 0.0038164404686540365, 0.05368487536907196, -0.03139559179544449, -0.08579523116350174, -0.010809183120727539, -0.06021055951714516, 0.0006553204148076475, -0.013429057784378529, 0.015582145191729069, 0.016136758029460907, 0.0063569131307303905, -0.04715811461210251, -0.012749183923006058, -0.015619855374097824, -0.05343244969844818, 0.04178707301616669, 0.0027807813603430986, 0.04242503643035889, -0.03518199548125267, 0.037794385105371475, -0.019231759011745453, 0.006708567030727863, -0.039621636271476746, 0.015528046526014805, -0.056051358580589294, 0.02441560849547386, 0.014801025390625, -0.014521773904561996, -0.04247550666332245, 0.008026895113289356, 0.05984623357653618, -0.02090269699692726, -0.0022575485054403543, -0.011861380189657211, -0.02072945423424244, -0.07249525189399719, -0.028486667200922966, -0.023718740791082382, 0.018264802172780037, -0.054504431784152985, -0.025597576051950455, -0.03950711339712143, -0.022337893024086952, 0.024411480873823166, 0.0005973157822154462, -0.015989018604159355, 0.012795530259609222, 0.015934277325868607, 0.017308726906776428, 0.03786246106028557, 0.006589371711015701, 0.018767759203910828, 0.011798246763646603, 0.04503186047077179, -0.020100442692637444, -0.026614218950271606, 0.028065448626875877, -0.00485546700656414, -0.03419987112283707, 0.015901213511824608, -0.0005328531260602176, -0.03347237408161163, -0.01881488971412182, 0.023669712245464325, 0.04199596866965294, -0.030339261516928673, 0.0601443350315094, 0.014768663793802261, -0.006099697668105364, 0.05009566619992256, 0.0298891831189394, 0.023866791278123856, 0.034037668257951736, 0.030770931392908096, 0.0007237487006932497, -0.01452243234962225, 0.025502407923340797, 0.030006298795342445, 0.06505756080150604, 0.045797642320394516, 0.026697278022766113, -0.05891099199652672, 0.03208981081843376, -0.06920726597309113, -0.008651752024888992, -0.0630006343126297, 0.011113225482404232, 0.03829891234636307, -0.030019141733646393, -0.032313115894794464, 0.015629861503839493, -0.055167291313409805, 0.021863019093871117, 0.015231742523610592, -0.028979601338505745, 0.04064944013953209, -0.0010817424627020955, -0.023953042924404144, -0.01003167312592268, -0.04542313143610954, -0.03123593144118786, -0.011272771283984184, 0.03121350146830082, 0.03711038827896118, -0.0015018393751233816, -0.015553836710751057, 0.009042834863066673, 0.010400217957794666, 0.011401060037314892, 0.008770978078246117, 0.007322133053094149, 0.02450593374669552, 0.04435964301228523, -0.005113513674587011, 0.03417481482028961, -0.06049993261694908, 0.006434834096580744, 0.0015760313253849745, 0.018069015815854073, -0.03700312227010727, 0.040813278406858444, -0.044429756700992584, -0.015605292282998562, 0.007060282863676548, 0.024508295580744743, 0.026957428082823753, -0.009363207966089249, 0.00338586512953043, -0.0042114160023629665, 0.04139295965433121, 0.0036454477813094854, 0.01542467251420021, 0.0022013916168361902, 0.011968715116381645, -0.016405919566750526, -0.025939472019672394, 0.0143300611525774]
```
いい感じです。
では、先ほどのチャンクのリストをベクトル化、それを**VectorDB**に格納してファイルとして保存します。**FAISS**を使えばサクッと行えます。

```python
from langchain_community.vectorstores import FAISS

db = FAISS.from_texts(texts, embeddings)
db.save_local('profile.db')
```
`texts`：チャンクのリスト
`embeddings`：ベクトル化するためのモデル

## STEP3 VectorDBへの問い合わせ
入力されたクエリのベクトル表現と**距離の近いチャンク**をVectorDBに問い合わせてみます。
```python
from langchain.embeddings import HuggingFaceEmbeddings
from langchain_community.vectorstores import FAISS

embeddings = HuggingFaceEmbeddings(
    model_name = "intfloat/multilingual-e5-large"
)

db = FAISS.load_local('profile.db',embeddings, allow_dangerous_deserialization=True)
a = db.similarity_search("私の好きなガンダム")
for i in a:
    print(i)
```

```:実行結果
page_content='ガンダムが好きなので高校からは模型部に所属しました。ちなみにガンダムのシリーズの中ではガンダムSEEDとガンダム00が好きです。'
page_content='高校ではロボットの制御系、大学では機械学習とAI、以前勤めていた会社ではウェブに取り組みました。'
page_content='私の名前は黄猿です。1994年に東京で生まれました。幼少期のほとんどを栃木県で過ごしました。星座はしし座、血液型はO型です。小学校の修学旅行では鎌倉、中学校の修学旅行では奈良と京都へ行きました。'
page_content='小学校の修学旅行では鎌倉、中学校の修学旅行では奈良と京都へ行きました。中学生まではサッカーのクラブチームに所属していて、ポジションはフォワードでした。'
```
クエリ"***私の好きなガンダム***"に関連するチャンク上位４件を獲得できました。ガンダムに関連してそうなチャンクでソートされているので信用できそうです。

試しに別のクエリで再度問い合わせてみます。

```python
a = db.similarity_search("小学校の修学旅行")
```

```:実行結果
page_content='小学校の修学旅行では鎌倉、中学校の修学旅行では奈良と京都へ行きました。中学生まではサッカーのクラブチームに所属していて、ポジションはフォワードでした。'
page_content='私の名前は黄猿です。1994年に東京で生まれました。幼少期のほとんどを栃木県で過ごしました。星座はしし座、血液型はO型です。小学校の修学旅行では鎌倉、中学校の修学旅行では奈良と京都へ行きました。'
page_content='高校ではロボットの制御系、大学では機械学習とAI、以前勤めていた会社ではウェブに取り組みました。'
page_content='ガンダムが好きなので高校からは模型部に所属しました。ちなみにガンダムのシリーズの中ではガンダムSEEDとガンダム00が好きです。'
```
上出来です。

## STEP4 LLMとの連携
最後に、**獲得したチャンク群およびユーザが入力したクエリ**をLLMに投げて、LLMがクエリに対する最適な返答文を生成します。その際、チャンクがLLMの回答文作成のための素材になるわけです。

```python
# embeddingsの生成
from langchain_community.embeddings import HuggingFaceEmbeddings
from langchain_community.vectorstores import FAISS
from langchain.chains import RetrievalQA
from langchain_openai import ChatOpenAI
import os

embeddings = HuggingFaceEmbeddings(
    model_name="intfloat/multilingual-e5-large",
    model_kwargs={'device':'cpu'},
)

db = FAISS.load_local('profile.db', embeddings, allow_dangerous_deserialization=True)
retriever = db.as_retriever()

# LLMへの接続
os.environ['OPENAI_API_KEY'] = 'OPENAI_API_KEYをここへ'
llm = ChatOpenAI(model_name="gpt-4o")
qa = RetrievalQA.from_chain_type(
    llm=llm, 
    retriever=retriever,
    return_source_documents=True,
)

q = "黄猿は西暦何年生まれですか？"

ans = qa.invoke(q)
print(ans['result'])
```
```:実行結果
黄猿は1994年に生まれました。
```

完璧です。

試しにクエリをかえて再度試してみます。
```python
q = "黄猿が好きなガンダムのシリーズは何ですか？"
```
```:実行結果
黄猿が好きなガンダムのシリーズは、ガンダムSEEDとガンダム00です。
```
完璧です。

```python
q = "黄猿は大学で何に取り組みましたか？"
```
```:実行結果
黄猿は大学で機械学習とAIに取り組みました。
```
完璧です。

以上で私に関するQAチャットボットの完成です。

# 感想
モジュールが豊富な分開発者の負担が少ないので思っていたより簡単に構築できました。自分でRAG構築できると楽しいです！ChatGPTを使ってできることの幅が３倍くらいになった感触です。今回の元文書程度の規模であればそれをそっくりそのままLLMに丸投げしてQA応答させてもいいのですが、元文書が大規模である場合はさすがにゴリ押しして全文書渡してそこからLLM自身に該当箇所探してもらうのは無理があるので、RAGやファインチューニングが必須になるかと思います。また、そもそも今回はベースとなる文書が図表のないただのテキストなので少ない事前準備で済みますが実際の場面では元の文書に図表がある前提なのでそのあたりの前処理のクオリティがRAGのクオリティを左右すると思います。昨今はLLMを利用した社内独自のQAシステムの開発案件も増えていて、益々RAGが注目されていくと思います。

次回はLLMのfunction Callingに関する記事を書こうと思います。

最後まで読んでくださりありがとうございました。