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
130
社内チャットへRAG導入した話(Tech Talk #2)
虎の穴の社内チャットに、RAGを使ったGoogleドライブからのファイルアップロードを実装した話です。
虎の穴ラボ株式会社
November 21, 2024
Tweet
Share
More Decks by 虎の穴ラボ株式会社
See All by 虎の穴ラボ株式会社
Tailwind CSSとAtomic Designで実現する効率的な Web 開発の事例
toranoana
1
460
Denoについて、同人誌記事を出しました+update
toranoana
0
140
【虎の穴ラボ Tech Talk #2】プロンプトエンジニアリング
toranoana
0
78
20241121_[TechTalk#2]虎の穴ラボでのLLMについて取り組み紹介
toranoana
0
76
Deno Deploy で Web Cache API を 使えるようになったので試した知見
toranoana
1
480
【虎の穴ラボ Tech Talk】虎の穴ラボTech Talk説明資料
toranoana
0
330
虎の穴ラボ Tech Talk_CDKでFargate環境構築
toranoana
1
360
虎の穴ラボスキルアップ支援制度の利用例
toranoana
0
5.9k
【虎の穴ラボ Tech Talk #1】Ansible Lintの警告への対処
toranoana
1
380
Other Decks in Technology
See All in Technology
iOS/Androidで無限循環Carousel表現を考えてみる
fumiyasac0921
0
110
TerraformとGitHub Actionsで手軽に実装するECSのCI/CD
k___tkg
0
230
CSS polyfill とその未来
ken7253
0
120
型がない世界に生まれ落ちて 〜TypeScript運用進化の歴史〜
narihara
1
190
会社紹介資料 / Sansan Company Profile
sansan33
PRO
6
360k
令和トラベルQAのAI活用
seigaitakahiro
0
380
アプリケーションの中身が見える!Mackerel APMの全貌と展望 / Mackerel APMリリースパーティ
mackerelio
0
120
Okayama WordPress Meetup #12 | そのバックアップ、本当に復元できますか? リストアやってみた!
takeshifurusato
0
100
初参加のハノーバーメッセで感じた世界最大級イベントの熱気とAI活用の未来
hamadakoji
0
210
さくらのクラウド 開発の挑戦とその舞台裏
kazeburo
0
690
VueUseから学ぶ実践TypeScript #TSKaigi #TSKaigi2025
bengo4com
3
5.3k
人とAIとの共創を夢見た2か月 #共創AIミートアップ / Co-Creation with Keito-chan
kondoyuko
0
430
Featured
See All Featured
Reflections from 52 weeks, 52 projects
jeffersonlam
349
20k
Faster Mobile Websites
deanohume
307
31k
Visualizing Your Data: Incorporating Mongo into Loggly Infrastructure
mongodb
45
9.5k
Understanding Cognitive Biases in Performance Measurement
bluesmoon
29
1.7k
Improving Core Web Vitals using Speculation Rules API
sergeychernyshev
14
880
Fashionably flexible responsive web design (full day workshop)
malarkey
407
66k
Build your cross-platform service in a week with App Engine
jlugia
231
18k
What’s in a name? Adding method to the madness
productmarketing
PRO
22
3.5k
I Don’t Have Time: Getting Over the Fear to Launch Your Podcast
jcasabona
32
2.3k
Building Adaptive Systems
keathley
41
2.6k
It's Worth the Effort
3n
184
28k
What's in a price? How to price your products and services
michaelherold
245
12k
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}}) 検索結果の文章のみを結果として 返します これでコンテキスト検索処理は終 了です。