第5章(実践開発:スクレイピング・データ分析・生成AI活用)で学んだ生成AI(LLM)APIと、社内ドキュメントを高速にセマンティック検索(意味ベースの検索)できるベクトルデータベースを統合し、「社内ナレッジ検索・AI回答RAGダッシュボード」を構築します。
1. システムの設計と要件
本アプリケーションは、以下の技術要素を組み合わせて実現します。
- RAG(Retrieval-Augmented Generation): 社内マニュアルや規程などのテキストをベクトル化して保持し、ユーザーの質問に関連する情報を自動で検索・参照してハルシネーション(嘘の回答)を防ぐ仕組み。
- Chroma DB: 軽量かつローカルで動作する高速なベクトルデータベース。
- Google Gemini API / OpenAI API: 検索された文脈をベースに、ユーザーの質問に対する自然な回答を生成。
- Streamlit: 非エンジニアの社員でもブラウザから直感的に質問・検索を行えるWebダッシュボード。
2. 実装コード(rag_dashboard.py)
以下のコードを rag_dashboard.py というファイル名で保存し、手元で動かしてみましょう(事前に pip install streamlit chromadb google-generativeai が必要です)。
Python
import os
import streamlit as st
import chromadb
import google.generativeai as genai
# --- 1. ページ設定と初期化 ---
st.set_page_config(page_title="社内ナレッジAIアシスタント", layout="wide")
st.title("🤖 社内マニュアル・ナレッジ検索 AIアシスタント(RAG)")
st.markdown("社内の各種規定やマニュアル文書をAIが横断検索し、根拠となる情報と共にご質問にお答えします。")
# Chroma DB の初期化(ローカルメモリ上に作成)
@st.cache_resource
def init_vector_db():
client = chromadb.Client()
collection = client.get_or_create_collection(name="company_knowledge_base")
# 初期データの登録(実際の運用ではPDFやMarkdownファイルから読み込んで登録します)
sample_docs = [
"リモートワーク手当は、月額一律 5,000 円が給与に上乗せして支給されます。",
"有給休暇の申請は、取得希望日の 3 営業日前までに社内ワークフローシステムより申請してください。",
"社内サーバーへのアクセスには、VPN接続および二段階認証(2FA)の設定が必須となります。",
"経費精算の締め日は毎月末日であり、翌月の第 5 営業日までに申請と領収書の提出が必要です。"
]
sample_ids = ["doc_001", "doc_002", "doc_003", "doc_004"]
# 既存データがない場合のみ登録
if collection.count() == 0:
collection.add(documents=sample_docs, ids=sample_ids)
return collection
collection = init_vector_db()
# --- 2. サイドバー:新規ナレッジの追加 ---
st.sidebar.header("📝 ナレッジ(ドキュメント)の追加")
new_doc_id = st.sidebar.text_input("ドキュメントID (例: doc_005)")
new_doc_text = st.sidebar.text_area("ドキュメントの内容を入力")
if st.sidebar.button("ベクトルDBに登録"):
if new_doc_id and new_doc_text:
collection.add(documents=[new_doc_text], ids=[new_doc_id])
st.sidebar.success(f"ドキュメント '{new_doc_id}' を追加しました!")
else:
st.sidebar.error("IDと内容の両方を入力してください。")
# --- 3. メイン画面:検索・RAG質問応答 ---
st.subheader("💬 AIへの質問・検索窓")
user_query = st.text_input("質問を入力してください (例: 「有給はいつまでに申請すればいい?」)")
if user_query:
with st.spinner("AIが社内ナレッジを検索・考察中..."):
# 1. ユーザーの質問に類似する社内文書をベクトル検索(上位2件取得)
search_results = collection.query(query_texts=[user_query], n_results=2)
retrieved_docs = search_results['documents'][0] if search_results['documents'] else []
# 2. 検索された文脈(Context)を結合
context_text = "\n".join([f"- {doc}" for doc in retrieved_docs])
# 3. プロンプトの構築
prompt = f"""
以下の【社内ナレッジ(参考情報)】をもとに、質問に対して正確に回答してください。
もし参考情報の中に答えが含まれていない場合は、「社内ナレッジからは確認できませんでした」と正直に答えてください。
【社内ナレッジ(参考情報)】
{context_text}
【質問】
{user_query}
"""
# 4. 生成AI APIの呼び出し (例: Gemini 1.5 Flash)
# ※ 実際に動かす際は環境変数に GEMINI_API_KEY を設定してください
api_key = os.environ.get("GEMINI_API_KEY", "YOUR_API_KEY_HERE")
try:
if api_key != "YOUR_API_KEY_HERE":
genai.configure(api_key=api_key)
model = genai.GenerativeModel('gemini-1.5-flash')
response = model.generate_content(prompt)
ai_answer = response.text
else:
# APIキーが未設定の場合はモック回答を表示
ai_answer = f"(APIキー未設定のためプレビュー表示)\nAIが以下の参考情報をもとに回答を生成します。\n\n【参照されたナレッジ】\n{context_text}"
except Exception as e:
ai_answer = f"API呼び出しエラーが発生しました: {e}"
# 5. 結果の表示
st.markdown("### 💡 AIの回答結果")
st.info(ai_answer)
with st.expander("🔍 根拠となった社内ナレッジ(参照コンテキスト)"):
for i, doc in enumerate(retrieved_docs, 1):
st.write(f"{i}. {doc}")
3. アプリケーションの起動方法
ターミナルを開き、以下のコマンドを実行します。
Bash
streamlit run rag_dashboard.py
ブラウザが自動で立ち上がり、社内規定の検索や質問に対するAIの根拠付き回答をインタラクティブにテストできます。
まとめ
本記事では、第5章で学んだ生成AI(LLM)APIの活用法と、Chroma DBによるベクトル検索を組み合わせて、ハルシネーションを防ぎながら社内情報を正確に引き出すRAGシステムをStreamlitで構築しました。

コメント