Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
社内チャットへRAG導入した話(Tech Talk #2)
Search
虎の穴ラボ株式会社
November 21, 2024
Technology
0
32
社内チャットへRAG導入した話(Tech Talk #2)
虎の穴の社内チャットに、RAGを使ったGoogleドライブからのファイルアップロードを実装した話です。
虎の穴ラボ株式会社
November 21, 2024
Tweet
Share
More Decks by 虎の穴ラボ株式会社
See All by 虎の穴ラボ株式会社
【虎の穴ラボ Tech Talk #2】プロンプトエンジニアリング
toranoana
0
9
20241121_[TechTalk#2]虎の穴ラボでのLLMについて取り組み紹介
toranoana
0
30
Deno Deploy で Web Cache API を 使えるようになったので試した知見
toranoana
1
200
【虎の穴ラボ Tech Talk】虎の穴ラボTech Talk説明資料
toranoana
0
190
虎の穴ラボ Tech Talk_CDKでFargate環境構築
toranoana
1
220
虎の穴ラボスキルアップ支援制度の利用例
toranoana
0
670
【虎の穴ラボ Tech Talk #1】Ansible Lintの警告への対処
toranoana
1
200
【虎の穴ラボ Tech Talk #1】虎の穴ラボの利用技術紹介
toranoana
0
250
サークルポータルを支えるフロントエンドアーキテクチャの選定
toranoana
1
290
Other Decks in Technology
See All in Technology
[CV勉強会@関東 ECCV2024 読み会] オンラインマッピング x トラッキング MapTracker: Tracking with Strided Memory Fusion for Consistent Vector HD Mapping (Chen+, ECCV24)
abemii
0
230
インフラとバックエンドとフロントエンドをくまなく調べて遅いアプリを早くした件
tubone24
1
430
オープンソースAIとは何か? --「オープンソースAIの定義 v1.0」詳細解説
shujisado
10
1.1k
Terraform Stacks入門 #HashiTalks
msato
0
360
Python(PYNQ)がテーマのAMD主催のFPGAコンテストに参加してきた
iotengineer22
0
510
Security-JAWS【第35回】勉強会クラウドにおけるマルウェアやコンテンツ改ざんへの対策
4su_para
0
180
【令和最新版】AWS Direct Connectと愉快なGWたちのおさらい
minorun365
PRO
5
760
エンジニア人生の拡張性を高める 「探索型キャリア設計」の提案
tenshoku_draft
1
130
RubyのWebアプリケーションを50倍速くする方法 / How to Make a Ruby Web Application 50 Times Faster
hogelog
3
950
初心者向けAWS Securityの勉強会mini Security-JAWSを9ヶ月ぐらい実施してきての近況
cmusudakeisuke
0
130
Amazon CloudWatch Network Monitor のススメ
yuki_ink
1
210
iOS/Androidで同じUI体験をネ イティブで作成する際に気をつ けたい落とし穴
fumiyasac0921
1
110
Featured
See All Featured
Fontdeck: Realign not Redesign
paulrobertlloyd
82
5.2k
Fashionably flexible responsive web design (full day workshop)
malarkey
405
65k
The Web Performance Landscape in 2024 [PerfNow 2024]
tammyeverts
0
100
jQuery: Nuts, Bolts and Bling
dougneiner
61
7.5k
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
44
6.8k
Become a Pro
speakerdeck
PRO
25
5k
The Cult of Friendly URLs
andyhume
78
6k
Code Reviewing Like a Champion
maltzj
520
39k
Fight the Zombie Pattern Library - RWD Summit 2016
marcelosomers
232
17k
Rails Girls Zürich Keynote
gr2m
94
13k
Designing Experiences People Love
moore
138
23k
Designing Dashboards & Data Visualisations in Web Apps
destraynor
229
52k
Transcript
Copyright (C) 2024 Toranoana Lab Inc. All Rights Reserved. T
O R A N O A N A L a b 社内チャットへ RAGを導入した話 大規模言語モデル(LLM)に外部データを組み合わせる
Copyright (C) 2024 Toranoana Lab Inc. All Rights Reserved. アジェンダ
1. RAGとは何か 2. RAGの特徴と利点 3. 導入したRAGのシステム構成 4. 導入における課題と解決策 5. 結果と今後の課題、応用の検討
Copyright (C) 2024 Toranoana Lab Inc. All Rights Reserved. 1.
RAGとは何か
Copyright (C) 2024 Toranoana Lab Inc. All Rights Reserved. RAG(Retrieval
Augmented Generation): 大規模言語モデル( LLM)に外部データを組み合わせ、回答精度を向上させ る手法 関連情報を検索し、モデルのコンテキスト として回答に活用できる タイトル RAGとは何か
Copyright (C) 2024 Toranoana Lab Inc. All Rights Reserved. 2.
RAGの特徴と利点
Copyright (C) 2024 Toranoana Lab Inc. All Rights Reserved. コンテキスト情報の提供:
LLMの知識を最新かつ専門的な情報で強化。 チャットに物事を理解するための手がかり(コンテキスト)として追加情報が渡 せる。 動的な知識ベース: • データの更新や追加が容易にできる 検索エンジンとの相乗効果: • 全文検索と生成的回答を組み合わせることも可能 タイトル RAGの特徴と利点
Copyright (C) 2024 Toranoana Lab Inc. All Rights Reserved. 3.
導入したRAGのシステム構成
Copyright (C) 2024 Toranoana Lab Inc. All Rights Reserved. ファイルアップロードとベクター化
• 社内チャット (先ほど紹介があったもの)からファイルをアップロード • LangChainでファイルからテキストを出力し、メタデータを維持しつつベクター化 ベクター DBへの登録 • ベクター化したデータをベクター DBに登録 検索とコンテキスト提供 • ユーザーのメッセージ内容からベクター DBを近似検索 • 関連するコンテキストを抽出し、 ChatGPTに提供 タイトル 今回導入した RAGの処理について
Copyright (C) 2024 Toranoana Lab Inc. All Rights Reserved. タイトル
RAGのシステム構成
Copyright (C) 2024 Toranoana Lab Inc. All Rights Reserved. タイトル
チャットの画面イメージ(1)
Copyright (C) 2024 Toranoana Lab Inc. All Rights Reserved. タイトル
チャットの画面イメージ(2)
Copyright (C) 2024 Toranoana Lab Inc. All Rights Reserved. タイトル
チャットの画面イメージ(3)
Copyright (C) 2024 Toranoana Lab Inc. All Rights Reserved. 4.
導入における課題と解決策
Copyright (C) 2024 Toranoana Lab Inc. All Rights Reserved. 問題点
• Excelやスライドのセル位置やページ数などのメタデータが保持されない(したい) 解決策 • LangChainの設定を調整し、メタデータを維持するように改良 メタデータを維持するとそのままベクターデータをチャンクで分割できない。 そのため、コンテキスト情報が肥大しがちになっている。 (分割すると AIがメタデータを認識不可 ) → LangChainを使わずに分割するとか検討。今は致命的では無いので保留。 タイトル 課題 1: メタデータの維持
Copyright (C) 2024 Toranoana Lab Inc. All Rights Reserved. 問題点
• テキスト量が多い PDFでOpenAIのトークン制限によりエラー発生 解決策 • テキストをトークン制限に基づき分割して、各チャンクを個別にベクター化 • サーバ上でベクター化、 OpenAIを使わない。 処理時間が長い原因の一因になっている。 これも致命的ではないので保留。 タイトル 課題 2: ベクター化エラー
Copyright (C) 2024 Toranoana Lab Inc. All Rights Reserved. 5.
結果と今後の課題、応用の検討
Copyright (C) 2024 Toranoana Lab Inc. All Rights Reserved. 現在の成果
• RAG技術の導入に成功して、社内チャットの機能を拡張できた 課題 • 精度よりは機能的な面で要望がある ◦ 個人情報やアダルト関連の情報が入れられないこと ◦ トークン数の上限やファイル容量の上限に引っかかること • ファイルの選択後の読み込みに時間がかかること(大きいファイルは数分かかる) タイトル 結果と今後の課題
Copyright (C) 2024 Toranoana Lab Inc. All Rights Reserved. 開発時や問い合わせの調査などへの活用
内容 • GitHubのソースコードや Wiki、仕様書をベクター DBに格納 期待効果 • AIでのコードや仕様の迅速な検索・参照が可能に タイトル 他用途への応用検討(1)
Copyright (C) 2024 Toranoana Lab Inc. All Rights Reserved. さらなる
Google Driveドキュメントの活用 内容 • 全社内ドキュメント(一般社員に公開されているもの)をベクター DBに格納 期待効果 • 社内情報に即時回答する Slackボットの作成 タイトル 他用途への応用検討(2)
Copyright (C) 2024 Toranoana Lab Inc. All Rights Reserved. まとめ
Copyright (C) 2024 Toranoana Lab Inc. All Rights Reserved. RAG技術の導入により、社内版
ChatGPTにチャットに物事を理解するための手がかり(コンテキス ト)として Googleドライブのファイルを渡すことで、 社内情報を LLMが参照できるため回答の精度と機能が向上しました。 今後は要望が多い課題への取り組みや応用を実施したいな、と考えています。 (特にローカル LLMとか) タイトル まとめ
Copyright (C) 2024 Toranoana Lab Inc. All Rights Reserved. 付録:実際のコードと流れ
Copyright (C) 2024 Toranoana Lab Inc. All Rights Reserved. 実際のコードでの処理の流れ
Copyright (C) 2024 Toranoana Lab Inc. All Rights Reserved. 実際の社内版チャットで選択できるファイルは以下の形式です。
• Google ドキュメント、スプレッドシート、スライド • PDF 内部コード的には、これらのファイルを GoogleDriveでExcelやWord、 PowerPointに変換して利用しているため、各所に ExcelやWord、 PowerPoint向けの処理があります。 タイトル 注意事項
Copyright (C) 2024 Toranoana Lab Inc. All Rights Reserved. ファイルアップロード
API
Copyright (C) 2024 Toranoana Lab Inc. All Rights Reserved. ファイルアップロード
(テキスト化) def get_loader(filename: str, file_content_type: str, filepath: str): file_ext = filename.split(".")[-1].lower() known_type = True if file_ext == "pdf": loader = PyPDFLoader(filepath, extract_images=False) elif file_ext == "pptx": loader = UnstructuredPowerPointLoader(filepath, mode="elements") elif ( file_content_type == "application/vnd.openxmlformats-officedocument.wordprocessingml.document " or file_ext in ["doc", "docx"] ): loader = Docx2txtLoader(filepath) elif file_content_type in [ "application/vnd.ms-excel", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", ] or file_ext in ["xls", "xlsx"]: loader = UnstructuredExcelLoader(filepath, mode="elements") else: loader = TextLoader(filepath, autodetect_encoding=False) known_type = False return loader, known_type, file_ext LangChainのLoaderを使ってファ イル内容をファイル種別毎にテキ スト化する mode="elements"にすることでメ タデータも含めてテキスト化される
Copyright (C) 2024 Toranoana Lab Inc. All Rights Reserved. ファイルアップロード
(分割処理) # 1. データの前処理(トークナイゼーションや要約) if ( file.content_type == "application/vnd.openxmlformats-officedocument.w ordprocessingml.document" or file_ext in ["doc", "docx"] ): # ワード文書の場合は段落ごとに分割 text_splitter = RecursiveCharacterTextSplitter( chunk_size=app.config['CHUNK_SIZE'], chunk_overlap=app.config['CHUNK_OVERLAP'] ) documents = text_splitter.split_documents(documents) テキスト化したデータを段落ごとに 分割する 分割はメタデータの無いワードの み行う
Copyright (C) 2024 Toranoana Lab Inc. All Rights Reserved. ファイルアップロード
(ベクター化) # 2. エンベディング作成 # OpenAI APIを使用してテキストのベクトル化 for doc in documents: # PDFの場合はNUL文字を削除 if file_ext == "pdf": doc.page_content = clean_text(doc.page_content) # テキストをトークン制限に基づいてチャンクに分割 chunks = split_into_chunks(doc.page_content) embeddings = [] # チャンクごとにエンベディングを作成 for chunk in chunks: if not chunk.strip(): # チャンクが空でないか確認 logger.warning(f"Empty chunk, skipping... {employeeNumber} {docId} {doc.page_content}") continue retries = 3 for _ in range(retries): try: response = client.embeddings.create(input=chunk, model=model) # ベク ター化実行 embeddings.append(response.data[0].embedding) break # 成功したらループを抜ける except Exception as e: # OpenAI API エラーをここでキャッチ logger.warning(f"OpenAI API error: {e}, retrying...") time.sleep(1) # 少し待ってリトライ else: logger.warning(f"Failed to get embedding for chunk after {retries} retries.") continue if not embeddings: # エンベディングが生成されているか確認 logger.warning(f"No embeddings generated for document skipping... {employeeNumber} {docId} {doc.page_content}") continue # チャンクから得られたエンベディングを統合 doc_embedding = combine_embeddings(embeddings) テキスト化したデータをOpenAIの トークン制限に合わせて分割し最 後に統合する text-embedding-3-smallのモ デルを使って分割した単位でベク ター化する
Copyright (C) 2024 Toranoana Lab Inc. All Rights Reserved. ファイルアップロード
(ベクター DB登録) # 3. インデックス作成 # エンベディングの作成が完了した後、DBへ文書の追加 fileUploadData = FileUploadData(employeeNumber=employeeNumber, fileId=fileId, docId=docId, fileName=file.filename, contents=doc.page_content, embedding=doc_embedding) db.session.add(fileUploadData) ベクター化した統合データとテキス トデータ、ファイル名、社員番号を 登録する これでアップロード処理は完了で す。
Copyright (C) 2024 Toranoana Lab Inc. All Rights Reserved. コンテキスト検索
API
Copyright (C) 2024 Toranoana Lab Inc. All Rights Reserved. コンテキスト検索
(ベクター化&近似検 索) # 2. エンベディング作成 # OpenAI APIを使用してクエリのベクトル化 response = client.embeddings.create(input=query, model=model) query_embedding = response.data[0].embedding # 3. インデックス検索 # pgvectorを使用したベクトル検索 rows = FileUploadData.query.where(FileUploadData.fileId .in_(fileIds)).order_by(FileUploadData.embedding .l2_distance(query_embedding)).limit(app.config[ 'SEARCH_LIMIT']).all() ベクター化した問い合わせ文章(ク エリ)をベクトル化して、該当する文 章をベクトル検索する 結果は近似順に並び替えられま す。(メタデータの無い文章やPDF の時に効力を発揮)
Copyright (C) 2024 Toranoana Lab Inc. All Rights Reserved. コンテキスト検索
(検索結果取得) # 検索結果の取得 documents = [{ "id": row.id, "contents": row.contents, "fileName": row.fileName, "employeeNumber": row.employeeNumber, "docId": row.docId, "fileId": row.fileId, } for row in rows] # レスポンスを返す return jsonify({"result": {"documents": documents}}) 検索結果の文章のみを結果として 返します これでコンテキスト検索処理は終 了です。