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
120
社内チャットへRAG導入した話(Tech Talk #2)
虎の穴の社内チャットに、RAGを使ったGoogleドライブからのファイルアップロードを実装した話です。
虎の穴ラボ株式会社
November 21, 2024
Tweet
Share
More Decks by 虎の穴ラボ株式会社
See All by 虎の穴ラボ株式会社
Tailwind CSSとAtomic Designで実現する効率的な Web 開発の事例
toranoana
1
440
Denoについて、同人誌記事を出しました+update
toranoana
0
130
【虎の穴ラボ Tech Talk #2】プロンプトエンジニアリング
toranoana
0
59
20241121_[TechTalk#2]虎の穴ラボでのLLMについて取り組み紹介
toranoana
0
69
Deno Deploy で Web Cache API を 使えるようになったので試した知見
toranoana
1
460
【虎の穴ラボ Tech Talk】虎の穴ラボTech Talk説明資料
toranoana
0
300
虎の穴ラボ Tech Talk_CDKでFargate環境構築
toranoana
1
330
虎の穴ラボスキルアップ支援制度の利用例
toranoana
0
5.2k
【虎の穴ラボ Tech Talk #1】Ansible Lintの警告への対処
toranoana
1
350
Other Decks in Technology
See All in Technology
Classmethod AI Talks(CATs) #21 司会進行スライド(2025.04.17) / classmethod-ai-talks-aka-cats_moderator-slides_vol21_2025-04-17
shinyaa31
0
550
Amazon S3 Tables + Amazon Athena / Apache Iceberg
okaru
0
260
アセスメントで紐解く、10Xのデータマネジメントの軌跡
10xinc
1
410
20250413_湘南kaggler会_音声認識で使うのってメルス・・・なんだっけ?
sugupoko
1
460
Cursor AgentによるパーソナルAIアシスタント育成入門―業務のプロンプト化・MCPの活用
os1ma
12
4.4k
Automatically generating types by running tests
sinsoku
2
1.9k
20250408 AI Agent workshop
sakana_ai
PRO
15
3.8k
Lightdashの利活用状況 ー導入から2年経った現在地_20250409
hirokiigeta
2
280
7,000名規模の 人材サービス企業における プロダクト戦略・戦術と課題 / Product strategy, tactics and challenges for a 7,000-employee staffing company
techtekt
0
290
Amazon CloudWatchで始める エンドユーザー体験のモニタリング
o11yfes2023
0
160
MCPを活用した検索システムの作り方/How to implement search systems with MCP #catalks
quiver
11
6.2k
いつも初心者向けの記事に助けられているので得意分野では初心者向けの記事を書きます
toru_kubota
2
300
Featured
See All Featured
Improving Core Web Vitals using Speculation Rules API
sergeychernyshev
13
670
Practical Orchestrator
shlominoach
186
10k
Building Flexible Design Systems
yeseniaperezcruz
329
38k
Why Our Code Smells
bkeepers
PRO
336
57k
Mobile First: as difficult as doing things right
swwweet
223
9.6k
Six Lessons from altMBA
skipperchong
27
3.7k
Put a Button on it: Removing Barriers to Going Fast.
kastner
60
3.8k
Refactoring Trust on Your Teams (GOTO; Chicago 2020)
rmw
34
2.9k
What’s in a name? Adding method to the madness
productmarketing
PRO
22
3.4k
Rails Girls Zürich Keynote
gr2m
94
13k
Sharpening the Axe: The Primacy of Toolmaking
bcantrill
41
2.2k
The Invisible Side of Design
smashingmag
299
50k
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}}) 検索結果の文章のみを結果として 返します これでコンテキスト検索処理は終 了です。