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
83
社内チャットへRAG導入した話(Tech Talk #2)
虎の穴の社内チャットに、RAGを使ったGoogleドライブからのファイルアップロードを実装した話です。
虎の穴ラボ株式会社
November 21, 2024
Tweet
Share
More Decks by 虎の穴ラボ株式会社
See All by 虎の穴ラボ株式会社
Tailwind CSSとAtomic Designで実現する効率的な Web 開発の事例
toranoana
1
410
Denoについて、同人誌記事を出しました+update
toranoana
0
110
【虎の穴ラボ Tech Talk #2】プロンプトエンジニアリング
toranoana
0
41
20241121_[TechTalk#2]虎の穴ラボでのLLMについて取り組み紹介
toranoana
0
61
Deno Deploy で Web Cache API を 使えるようになったので試した知見
toranoana
1
380
【虎の穴ラボ Tech Talk】虎の穴ラボTech Talk説明資料
toranoana
0
250
虎の穴ラボ Tech Talk_CDKでFargate環境構築
toranoana
1
280
虎の穴ラボスキルアップ支援制度の利用例
toranoana
0
3.2k
【虎の穴ラボ Tech Talk #1】Ansible Lintの警告への対処
toranoana
1
290
Other Decks in Technology
See All in Technology
バックエンドエンジニアのためのフロントエンド入門 #devsumiC
panda_program
18
7.4k
Tech Blogを書きやすい環境づくり
lycorptech_jp
PRO
1
240
RSNA2024振り返り
nanachi
0
570
トラシューアニマルになろう ~開発者だからこそできる、安定したサービス作りの秘訣~
jacopen
2
2k
【Developers Summit 2025】プロダクトエンジニアから学ぶ、 ユーザーにより高い価値を届ける技術
niwatakeru
2
1.3k
Classmethod AI Talks(CATs) #17 司会進行スライド(2025.02.19) / classmethod-ai-talks-aka-cats_moderator-slides_vol17_2025-02-19
shinyaa31
0
110
Nekko Cloud、 これまでとこれから ~学生サークルが作る、 小さなクラウド
logica0419
2
960
N=1から解き明かすAWS ソリューションアーキテクトの魅力
kiiwami
0
120
人はなぜISUCONに夢中になるのか
kakehashi
PRO
6
1.6k
技術的負債解消の取り組みと専門チームのお話 #技術的負債_Findy
bengo4com
1
1.3k
PL900試験から学ぶ Power Platform 基礎知識講座
kumikeyy
0
130
地方拠点で エンジニアリングマネージャーってできるの? 〜地方という制約を楽しむオーナーシップとコミュニティ作り〜
1coin
1
220
Featured
See All Featured
How STYLIGHT went responsive
nonsquared
98
5.4k
[Rails World 2023 - Day 1 Closing Keynote] - The Magic of Rails
eileencodes
33
2.1k
Fontdeck: Realign not Redesign
paulrobertlloyd
83
5.4k
The MySQL Ecosystem @ GitHub 2015
samlambert
250
12k
The Myth of the Modular Monolith - Day 2 Keynote - Rails World 2024
eileencodes
21
2.5k
GitHub's CSS Performance
jonrohan
1030
460k
Fireside Chat
paigeccino
34
3.2k
Building Adaptive Systems
keathley
40
2.4k
CSS Pre-Processors: Stylus, Less & Sass
bermonpainter
356
29k
Navigating Team Friction
lara
183
15k
Dealing with People You Can't Stand - Big Design 2015
cassininazir
366
25k
Speed Design
sergeychernyshev
27
790
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}}) 検索結果の文章のみを結果として 返します これでコンテキスト検索処理は終 了です。