モデル就業規則×生成AIで社内問い合わせを自動化（RAGチャットボットPoC事例）

## 1. はじめに
社内の就業規則や制度に関する質問対応に、時間を取られていませんか？

「有給休暇はいつから取れますか？」「育児休業の取得条件は？」「就業時間って何時まで？」
こうした人事労務部門への定型的な問い合わせは日常的に発生します。

本記事では、厚生労働省が公開している[モデル就業規則（PDF）](https://www.mhlw.go.jp/content/001018385.pdf)を対象に、
RAG（検索拡張生成）構成と生成AIを活用して、自然な日本語で自動応答する社内向けチャットボットのPoCを作成した事例をご紹介します。
### 🎯本記事の目的
- RAGチャットボットの構築手順を知る

- モデル就業規則をもとにした社内FAQ自動応答のイメージを掴む

- 人事領域における生成AI活用の可能性を考察する

### 📚対象読者
- 社内FAQ自動化に関心のある人事・総務部門の方

- RAG構成を用いたチャットボットの技術構成を知りたい方

- PoCから業務適用への展開を考えているAI担当者

## 2. RAGとは何か？
RAG（Retrieval-Augmented Generation）は、**「検索（Retrieve）」＋「生成（Generate）」**を組み合わせた仕組みです。

通常の生成AI（ChatGPTなど）は、質問に対して学習済み知識から回答を作りますが、
企業固有の情報や最新の社内規程には対応できないケースがあります。

そこでRAGでは以下の2段階で回答を生成します：

1. ユーザーの質問に近い社内文書をベクトル検索で抽出（検索）

2. 抽出した文書をプロンプトとして生成AIに渡し、自然な応答を生成（生成）

### ❓なぜRAGを使うのか？
| 課題                    | RAGでの解決               |
| --------------------- | --------------------- |
| 社内規程のような限定的な情報に対応できない | PDFなどの自社文書をベースに回答可能   |
| 回答の信頼性が低い             | 出典チャンクを明示することで根拠ある応答に |
| モデルが巨大すぎて再学習が難しい     | 既存LLMをそのまま使える構成で効率的   |

## 3. アプリの全体像（図解）
今回作成したPoCの全体像は以下の通りです：
![overview.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2681141/111082ff-08e9-447e-aabc-6d2ee5f49f89.png)

### 処理の流れ（簡易版）：
1. PDFをテキストに変換し、意味ごとに「チャンク（文のかたまり）」に分割

2. 各チャンクをベクトル化して、ベクトルデータベース（FAISSなど）に登録

3. ユーザーの質問もベクトル化し、類似するチャンクを検索

4. 検索結果をプロンプトとして生成AIに渡し、自然な日本語で応答

#### この構成によって、たとえば以下のような質問に自動で答えられるようになります：

>🧑‍💼「有給休暇っていつから取れますか？」
>🤖「〇〇の条件に該当する場合、〇〇日から取得可能です」

#### 🔎Streamlit上での質問-回答例の表示

![FireShot Capture 018 - 社内文書チャットボット - [localhost].png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2681141/9f12f1f3-278b-4aa9-b2d6-a333e8fdef0d.png)
少し冗長と感じたものの、自然な回答文になっていました。加えて引用された文脈も表示できるため、回答の信頼性も確認できます。

## 4. 使用技術スタック
本PoCでは、以下の技術やサービスを組み合わせてRAGチャットボットを構築しました：

| 目的           | 使用技術・ライブラリ                     | 説明                      |
| ------------ | ------------------------------ | ----------------------- |
| PDFからのテキスト抽出 | `PyMuPDF (fitz)`               | 就業規則PDFを1ページずつ文字列に変換    |
| 条文ごとのチャンク化   | `re`（正規表現）+ `pandas`           | 「第○条」「第○章」単位で文書を分割しCSV化 |
| ベクトル化        | `sentence-transformers`（E5モデル） | 各チャンクをベクトル変換（日本語対応）     |
| 類似文検索        | `FAISS`                        | ベクトル検索用インデックス作成と検索処理    |
| 応答生成         | `OpenAI API`（gpt-3.5-turbo）    | 検索結果をもとに自然言語で回答生成       |
| .env管理       | `python-dotenv`                | APIキーなどの安全な外部管理         |
| UI構築         | `Streamlit`                    | 社内向けWebチャットアプリを構築       |
| ローカル管理       | `os`, `numpy`, `pandas`        | 各種ファイル処理とデータ保存          |

## 5. 実装ステップ
### 🔹 ステップ①：PDFからテキスト抽出
```python
with fitz.open("docs/model_shugyo_kisoku.pdf") as doc:
    text = "\n".join([page.get_text() for page in doc])
```
- fitzで全ページを読み込み、全文テキストを抽出し保存(.txt)

### 🔹 ステップ②：条文単位でチャンク化
```python
chunks = re.split(r'(第[0-9０-９一二三四五六七八九十百]+[章条])', text)
```
- 正規表現で「第○条」「第○章」見出しで分割

- タイトルと本文をペアにして再構成し保存(.csv)

### 🔹 ステップ③：チャンクをベクトル化
```python
model = SentenceTransformer("intfloat/multilingual-e5-small")
embeddings = model.encode([f"passage: {t}" for t in texts])
np.save("docs/embeddings.npy", embeddings)
```
- 日本語対応のE5モデルを使用し、ベクトルを保存(.npy)

### 🔹 ステップ④：FAISSインデックス作成
```python
index = faiss.IndexFlatL2(dim)
index.add(embeddings)
faiss.write_index(index, "docs/faiss.index")
```
- ベクトル次元に応じたインデックス作成
- L2距離ベースで高速検索可能

### 🔹 ステップ⑤：質問に対して類似文を検索
```python
query_vec = model.encode(f"query: {query}")
D, I = index.search(np.array([query_vec]), top_k)
```
- ユーザーの質問をベクトル化し、上位k件を検索
- チャンク本文を表示して確認可能

### 🔹 ステップ⑥：AI応答生成
```python
prompt = f"""あなたは社内文書に詳しいAIアシスタントです。...
{context}...{question}"""
response = client.chat.completions.create(...)
```
- 類似チャンクをもとにプロンプトを構成
- OpenAIのGPT-3.5で自然な日本語応答を生成

### 🔹 ステップ⑦：StreamlitでWebチャットUI構築
```python
question = st.text_input("💬 質問を入力してください:")
context = search_context(question)
answer = generate_answer(question, context)
st.markdown(answer)
```
- 入力欄・ボタントリガー付きの対話型UI
- 回答表示とともに、使用された文脈（チャンク）も開示(※上記キャプチャイメージ)

## 6. 実際の応答例と評価
実際に本PoCで動作させたチャットボットに対する質問例とその応答結果をご紹介します。
### 🔎質問例と回答イメージ①
- Q. 育児休業はいつから取れるの？
```
 A. 育児休業は、生後満１年に達しない子を育てている女性労働者から請求があった場合に取ることができます。生後１年未満の子を育てている女性が育児休業を請求することができます。
 ```
![ragchatbotcase2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2681141/e629c629-17fc-47a5-b1b5-f711c77b335b.png)

### 🔎質問例と回答イメージ②
- Q. A社の人事部長の氏名を教えてほしい
```
申し訳ございませんが、社内文書には人事部長の氏名に関する情報は記載されておりません。人事部長の氏名については、直接A社の人事部にお問い合わせいただくか、別の情報源をご確認ください。
```
![ragchatbotcase3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2681141/a2ee5f50-c487-41a7-b420-31ebdb4f4503.png)

### ✅応答の評価ポイント
| 評価項目      | 評価内容                                 |
| --------- | ------------------------------------ |
| **自然さ**   | 回答は形式張らず自然で、社内FAQに適した文体              |
| **根拠明示性** | 回答文の裏付けがPDF内の該当条文で明確に取れる。該当する文面が見つからない質問に対しても、記載無い旨を合わせて返答できている。             |
| **網羅性**   | たまに冗長になることもあるが、概ね要点がまとまっている（プロンプトの工夫が必要）       |
| **改善点**   | ユーザーによっては「条文番号」などを明示したいというニーズも考慮余地あり |

## 7. PoCとしての位置づけと今後の展望

### 🧪 今回の取り組みはPoC（概念実証）
本記事で紹介したチャットボットは、**あくまでPoC（Proof of Concept）**として、個人環境で構築・検証したものです。

今回は以下の構成で開発しました：
| 項目     | 検証用構成（PoC）               |
| ------ | ------------------------ |
| 生成AI   | ChatGPT（個人アカウント）         |
| ベクトルDB | FAISS（ローカル環境）            |
| UI     | Streamlit（ローカル or Web公開） |

### 🔭本番運用に向けた課題と展望
PoCを通して得られた知見をもとに、今後の実運用展開では以下を検討していきます：
✅ **セキュアな生成AI環境の採用**
- ChatGPT（個人用）ではなく、**企業向け環境（例：Azure OpenAI、Claude for Work、社内LLM）**への切り替え

- APIキーのアクセス制御、監査ログの保存、社内利用規定への準拠

✅ **業務適用に向けた体制整備**
- 誰が、どの規程を、どう更新・反映するかというワークフロー設計
- AI応答へのフィードバックループ（人事担当者の確認）

## 8. おわりに
本記事では、厚生労働省が公開する「モデル就業規則（PDF）」をベースに、
生成AI × ベクトル検索（RAG構成） を活用して、社内規程に関する問い合わせ対応を自動化するPoCチャットボットを構築した事例をご紹介しました。

### 💡 RAG × 社内文書 の可能性
今回のPoCを通して、生成AIは単なる情報提供にとどまらず、「業務の効率化」や「問い合わせ業務のDX」に貢献できる強力なツールであると感じました。

本記事が、人事部門のDX推進や、RAG構成を用いた業務効率化のヒントとなれば幸いです。
質問・コメント・ご意見などありましたら、お気軽にご連絡ください！

### 🔗 GitHub公開
本PoCに関するコードは[GitHub上](https://github.com/pomeshiba29/rag-chatbot)で公開しております。
もし興味がありましたら、ご参照ください。