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
240
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
社内チャットへRAG導入した話(Tech Talk #2)
虎の穴の社内チャットに、RAGを使ったGoogleドライブからのファイルアップロードを実装した話です。
虎の穴ラボ株式会社
November 21, 2024
More Decks by 虎の穴ラボ株式会社
See All by 虎の穴ラボ株式会社
関西Ruby登壇資料
toranoana
0
13
Tailwind CSSとAtomic Designで実現する効率的な Web 開発の事例
toranoana
1
680
Denoについて、同人誌記事を出しました+update
toranoana
0
230
【虎の穴ラボ Tech Talk #2】プロンプトエンジニアリング
toranoana
0
160
20241121_[TechTalk#2]虎の穴ラボでのLLMについて取り組み紹介
toranoana
0
170
Deno Deploy で Web Cache API を 使えるようになったので試した知見
toranoana
1
740
【虎の穴ラボ Tech Talk】虎の穴ラボTech Talk説明資料
toranoana
0
510
虎の穴ラボ Tech Talk_CDKでFargate環境構築
toranoana
1
570
虎の穴ラボスキルアップ支援制度の利用例
toranoana
0
11k
Other Decks in Technology
See All in Technology
個人開発で育てる「大規模設計の苗床」 - AI時代の1人開発から始める業務への知識接続 / The Seedbed for Large-Scale Design - From AI-Era Solo Projects to Professional Knowledge
bitkey
PRO
1
280
AI時代のYAGNI:「爆速で無駄になった機能」からの学び / 20260720 Naoki Takahashi
shift_evolve
PRO
3
330
End-to-Endで考える信頼性 —LINEアプリにおけるクライアント開発×SRE連携の実践
maruloop
4
4.7k
Oracle Exadata Database Service on Cloud@Customer X11M (ExaDB-C@C) サービス概要
oracle4engineer
PRO
2
8.4k
Gen3R: 3D Scene Generation Meets Feed-Forward Reconstruction
spatial_ai_network
0
130
Data + AI Summit 2026 イベントレポート: 「AIがビジネスで意思決定するデータ基盤」へ
nek0128
0
280
プロダクト開発組織の現在地(Ver.2026/07) / product-organization
kaonavi
0
110
AI時代のPlaywright活用(システムテストを自動化する ー 実行エンジンにPla ywrightを選んだ理由)
ynisqa1988
1
560
オブザーバビリティ、本当に活用できてる? 〜API連携×生成AIで成熟度を自動評価〜
dmmsre
1
3.6k
ZOZOTOWNの進化と信頼性を両立する負荷試験
zozotech
PRO
2
260
知らん間に、回ってる
ming_ayami
0
730
Oracle Base Database Service 技術詳細
oracle4engineer
PRO
15
110k
Featured
See All Featured
Accessibility Awareness
sabderemane
1
160
Odyssey Design
rkendrick25
PRO
2
730
Context Engineering - Making Every Token Count
addyosmani
9
1k
Navigating Weather and Climate Data
rabernat
0
370
My Coaching Mixtape
mlcsv
0
170
職位にかかわらず全員がリーダーシップを発揮するチーム作り / Building a team where everyone can demonstrate leadership regardless of position
madoxten
64
56k
Building a A Zero-Code AI SEO Workflow
portentint
PRO
0
630
Un-Boring Meetings
codingconduct
0
350
Building Applications with DynamoDB
mza
96
7.1k
Visualizing Your Data: Incorporating Mongo into Loggly Infrastructure
mongodb
49
10k
Applied NLP in the Age of Generative AI
inesmontani
PRO
4
2.4k
Build your cross-platform service in a week with App Engine
jlugia
234
18k
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}}) 検索結果の文章のみを結果として 返します これでコンテキスト検索処理は終 了です。