はじめに
前回は、これから構築する「AI人事・研修業務支援システム」の全体像と技術スタックを整理しました。
前回の記事:Python × Dify × RAGで学ぶ業務システム開発入門【第1回 業務システム全体設計編】
第2回では、実装に入る前に行うべきフェーズである要求定義・要件定義を扱います。
「早くコードを書きたい」という気持ちはよくわかります。しかし、要件が曖昧なまま実装を始めると、次のような問題が起きます。
途中で「この機能、必要だった?」という議論が始まる
仕様変更のたびにコードを大幅に書き直す
テストで「何を確認すればよいのか」がわからない
チームメンバーごとに実装の解釈がずれる
要求定義・要件定義は、「何を作るか」を全員が同じ認識で共有するための設計図です。この設計図があることで、実装・テスト・レビューを進めやすくなります。
本記事で学ぶこと
| 項目 | 内容 |
|---|---|
| 要求定義 | 業務の現状分析、課題、利用者ニーズの整理 |
| 要件定義 | 機能要件・非機能要件の定義 |
| ユースケース | 利用者がシステムをどのように使うかの整理 |
| 制約条件 | 技術、コスト、期間などの制限 |
要求定義とは何か
まず、「要求定義」と「要件定義」の違いを整理します。
要求定義(What)
└── 業務上の課題やニーズを整理する
「何に困っているのか」「何を実現したいのか」
要件定義(What / How)
└── 要求をシステムで実現するための仕様を定める
「どのような機能が必要か」「どの程度の品質が必要か」
基本的には、要求定義 → 要件定義の順で進めます。利用者の声や業務上の課題を整理せずに要件を決めると、「作ったけれど使われないシステム」になる可能性があります。
業務の現状分析(As-Is)
最初に、**現在の業務がどのように行われているか(As-Is)**を整理します。
人事担当者の現状業務
【社員管理】
現状:Excelの社員台帳を手動で管理
課題:
- ファイルが複数存在し、最新版がどれかわからない
- 部署異動や退職の反映漏れが発生する
- 必要な社員情報をすぐに検索できない
- 複数人で情報を共有しにくい
【帳票作成】
現状:Excelで評価シートを手作業で作成
課題:
- 社員数が多いと作成に時間がかかる
- コピー&ペーストや計算式のミスが発生する
- フォーマット変更時の修正作業が多い
研修担当者の現状業務
【研修管理】
現状:研修ごとに出席率、テスト結果、課題スコアをExcelで管理
課題:
- ファイルが研修別・年度別に散在している
- 研修結果を社員単位で集計するのに手間がかかる
- 受講者ごとの研修実績を横断的に確認しにくい
【評価コメント作成】
現状:研修担当者が受講者一人ひとりにコメントを作成
課題:
- 受講者が多いと作成に時間がかかる
- コメントの品質が担当者によってばらつく
- 定型的な表現になりやすい
一般社員の現状業務
【社内文書の参照】
現状:就業規則やマニュアルをPDF・紙で参照
課題:
- どの文書に必要な情報が書かれているかわからない
- 文書を探すのに時間がかかる
- 担当者へ同じ問い合わせが繰り返し発生する
【FAQ対応(人事担当者側)】
現状:メールや口頭で問い合わせに個別対応
課題:
- 同じ質問が繰り返し寄せられる
- 問い合わせ対応に時間がかかる
- 本来の人事・研修業務が圧迫される
【自分の研修実績・評価の確認】
現状:研修担当者や人事担当者へ個別に確認
課題:
- 自分の研修履歴をすぐに確認できない
- 評価スコアや評価コメントの確認に手間がかかる
- 自分の日報と研修実績をまとめて確認できない
業務改善の方向性(To-Be)
現状の課題を整理したうえで、**システム化によって実現する姿(To-Be)**を定義します。
| 課題(As-Is) | 改善後(To-Be) | 実現手段 |
|---|---|---|
| 社員台帳がExcelファイルに散在している | Webシステムで社員情報を一元管理する | Flask + SQLite |
| 研修結果を社員単位で集計するのに手間がかかる | 出席率・理解度・課題スコアの平均値と総合スコアを自動計算する | SQLiteの集計処理 + Python |
| 評価シートを手作業で作成している | 評価一覧をExcelファイルとして出力する | openpyxl |
| 評価コメントを手作業で作成している | 研修実績をもとにAIが評価コメントを生成する | Dify API |
| 社内文書を手作業で探している | 自然言語による質問で社内文書を検索する | RAG(Dify Knowledge) |
| FAQへ個別に対応している | チャットボットが質問に回答する | Dify API |
| 社員本人が研修履歴や評価を確認しにくい | 社員番号でログインし、本人専用マイページで確認する | Flaskセッション + SQLite |
本システムでは、出席率そのものを日別の出欠データから計算するのではなく、研修履歴画面またはExcel・CSVファイルから出席率を登録します。登録された出席率・理解度・課題スコアを集計し、総合評価スコアを自動計算します。
利用者とユースケース
利用者と権限の整理
本システムには、admin、staff、userの3種類のロールがあります。また、社員番号と同じユーザー名を持つuserアカウントは、社員情報と紐づく社員本人用アカウントとして扱います。
| ロール | 想定利用者 | 利用できる主な機能 |
|---|---|---|
admin |
システム管理者・人事管理者 | 全機能の利用、社員の削除 |
staff |
人事担当者・研修担当者 | 社員の登録・編集、研修管理、評価管理、Excel入出力 |
user |
一般社員・受講者 | ダッシュボード、日報管理、社内文書検索、FAQチャット |
動作確認用の初期アカウントは次のとおりです。
| ユーザー名 | パスワード | ロール | ログイン後の画面 |
|---|---|---|---|
admin |
password |
admin |
管理者向けダッシュボード |
staff |
password |
staff |
担当者向けダッシュボード |
user |
password |
user |
一般ユーザー向けダッシュボード |
EMP001 |
password |
user |
山田太郎専用マイページ |
EMP001はロールとしてはuserですが、user.usernameとemployee.employee_noが一致するため、山田太郎の社員情報と紐づきます。
ロール別の主なアクセス範囲は次のとおりです。
admin
├── 社員一覧・検索・登録・編集・削除
├── 研修登録・研修履歴入力
├── 評価管理・AIコメント生成
├── Excel取込・出力
├── 日報管理
├── 社内文書検索
└── FAQチャット
staff
├── 社員一覧・検索・登録・編集
├── 研修登録・研修履歴入力
├── 評価管理・AIコメント生成
├── Excel取込・出力
├── 日報管理
├── 社内文書検索
└── FAQチャット
user
├── 日報管理
├── 社内文書検索
└── FAQチャット
EMP001(userロール・山田太郎)
├── 山田太郎専用マイページ
│ ├── 社員情報の確認
│ ├── 研修履歴の確認
│ ├── 最新評価・AIコメントの確認
│ └── 最近の日報の確認
├── 自分の日報の登録・確認
├── 社内文書検索
└── FAQチャット
ユースケース一覧
ユースケースとは、「利用者がシステムを使って何を達成するか」を表したものです。
admin・staffのユースケース
| No. | ユースケース名 | 概要 | 利用可能ロール |
|---|---|---|---|
| UC-01 | 社員登録 | 社員番号、氏名、部署、役職、入社日を登録する |
admin・staff
|
| UC-02 | 社員情報更新 | 登録済みの社員情報を編集する |
admin・staff
|
| UC-03 | 社員削除 |
is_activeを0にして社員情報を論理削除する |
admin |
| UC-04 | 社員検索 | 社員番号、氏名、部署をキーワードで検索する |
admin・staff
|
| UC-05 | 社員台帳取込 | Excel・CSVファイルから社員情報を一括登録する |
admin・staff
|
| UC-06 | 研修登録 | 研修名、開始日、終了日、説明を登録する |
admin・staff
|
| UC-07 | 研修履歴入力 | 社員ごとに出席率、理解度、課題スコアを入力する |
admin・staff
|
| UC-08 | 研修結果取込 | Excel・CSVファイルから研修結果を一括登録する |
admin・staff
|
| UC-09 | 評価一覧確認 | 社員ごとの平均実績と総合スコアを確認する |
admin・staff
|
| UC-10 | AI評価コメント生成 | 研修実績をDify APIへ送信し、評価コメントを生成する |
admin・staff
|
| UC-11 | 評価一覧出力 | 評価データをExcelファイルとしてダウンロードする |
admin・staff
|
| UC-12 | AI生成状況確認 | AIコメント生成中の表示を確認し、処理完了まで二重送信を防止する |
admin・staff
|
受講生のユースケース
| No. | ユースケース名 | 概要 | 利用可能ロール |
|---|---|---|---|
| UC-13 | マイページ確認 | 本人の社員情報、研修履歴、最新評価、最近の日報を確認する | 社員情報と紐づくuser
|
| UC-14 | 自分の日報登録 | ログイン中の社員IDを使用して本人の日報を登録する | 社員情報と紐づくuser
|
| UC-15 | 自分の日報確認 | 本人が登録した日報だけを一覧表示する | 社員情報と紐づくuser
|
全ロール共通のユースケース
| No. | ユースケース名 | 概要 | 利用可能ロール |
|---|---|---|---|
| UC-16 | 日報登録・確認 | 日付、作業内容、メモを登録し、日報一覧を確認する | 全ロール |
| UC-17 | 社内文書検索 | Dify Knowledgeを利用して社内文書を自然言語で検索する | 全ロール |
| UC-18 | FAQチャット | チャット形式で質問し、会話の文脈を引き継いだ回答を受け取る | 全ロール |
社員本人用アカウントでは、社員IDをURLやフォームの値から決定せず、ログイン時にセッションへ保存したemployee_idを使用します。EMP001でログインした場合、日報画面では山田太郎本人の日報だけを表示・登録します。
一方、動作確認用のuserアカウントは特定の社員番号と紐づいていないため、通常のユーザー向けダッシュボードを表示します。
機能要件
機能要件とは、「システムが何をしなければならないか」を定めたものです。
認証・認可機能
| No. | 機能 | 詳細 |
|---|---|---|
| F-01 | ログイン | ユーザー名とパスワードで認証する |
| F-02 | ログアウト | セッションを破棄してログイン画面へ移動する |
| F-03 | ログイン制御 | 未ログインの場合はログイン画面へ移動する |
| F-04 | ロール別アクセス制御 |
admin・staff・userのロールに応じて利用機能を制限する |
| F-05 | 社員情報との照合 | ログインユーザー名と社員番号が一致する社員を取得する |
| F-06 | 社員セッション保持 | 一致した社員のemployee_idと氏名をセッションへ保存する |
| F-07 | ログイン後画面の振り分け | 社員情報と紐づくユーザーは/my-pageへ、それ以外は/へ移動する |
認証処理では、user.usernameとemployee.employee_noを左外部結合して社員情報を取得します。
user.username = "EMP001"
↓ 一致確認
employee.employee_no = "EMP001"
↓
山田太郎のemployee_idをセッションへ保存
↓
/my-pageへリダイレクト
社員管理機能
| No. | 機能 | 詳細 |
|---|---|---|
| F-10 | 社員一覧表示 | 有効な社員を社員番号順に一覧表示する |
| F-11 | 社員検索 | 社員番号、氏名、部署をキーワードで部分一致検索する |
| F-12 | 社員登録 | 社員番号、氏名、部署、役職、入社日を登録する |
| F-13 | 社員情報更新 | 登録済みの社員情報を編集・保存する |
| F-14 | 社員削除 |
is_activeフラグを利用して論理削除する |
| F-15 | 社員台帳インポート |
.xlsxまたは.csvファイルから社員情報を一括登録する |
社員専用マイページ機能
| No. | 機能 | 詳細 |
|---|---|---|
| F-16 | マイページ表示 | 社員情報と紐づくユーザーに本人専用画面を表示する |
| F-17 | 社員情報表示 | 社員番号、氏名、部署、役職、入社日を表示する |
| F-18 | 研修履歴表示 | 本人の研修名、期間、出席率、理解度、課題スコアを表示する |
| F-19 | 評価・日報表示 | 本人の最新総合スコア、AI評価コメント、最近の日報5件を表示する |
departmentテーブルは作成されていますが、現在の社員登録・編集処理ではemployee.departmentに部署名を文字列として保存しています。部署マスタの登録・編集・削除画面と、department.idを利用した外部キー連携は未実装です。
研修管理機能
| No. | 機能 | 詳細 |
|---|---|---|
| F-20 | 研修一覧表示 | 登録済み研修を開始日の降順で一覧表示する |
| F-21 | 研修登録 | 研修名、開始日、終了日、説明を登録する |
| F-22 | 研修履歴表示 | 研修ごとに有効な社員と研修実績を一覧表示する |
| F-23 | 研修履歴入力 | 社員ごとに出席率、理解度、課題スコアを入力・更新する |
| F-24 | 研修結果インポート |
.xlsxまたは.csvファイルから研修結果を一括登録・更新する |
現在の実装では、日別の出欠入力、出席率の自動計算、課題ファイルの提出、研修ごとの受講者選択は行いません。研修履歴画面には有効な社員が表示され、出席率・理解度・課題スコアを数値として登録します。
評価・帳票機能
| No. | 機能 | 詳細 |
|---|---|---|
| F-30 | 研修実績集計 | 社員ごとに出席率、理解度、課題スコアの平均値をSQLiteで集計する |
| F-31 | 総合スコア計算 | 集計値をもとにPythonで総合スコアを計算する |
| F-32 | AI評価コメント生成 | 集計データをDify APIへ送信し、評価コメントを生成・保存する |
| F-33 | フォールバックコメント生成 | Dify APIキー未設定時またはAPI通信失敗時に、ローカル処理で評価コメントを生成する |
| F-34 | 評価一覧表示 | 集計値、総合スコア、最新のAIコメントを一覧表示する |
| F-35 | 評価一覧出力 | 評価データをopenpyxlでExcelファイルへ出力する |
| F-36 | AI生成中表示 | 生成ボタン押下後に「AI評価コメントを生成中...」と対象社員名を表示する |
| F-37 | 評価生成の二重送信防止 | 生成中はすべてのAI生成ボタンを無効化する |
総合スコアは、次の計算式で求めます。
総合スコア
= 出席率 × 30%
+ 理解度 × 40%
+ 課題スコア × 30%
AI生成ボタンを押すと、押したボタンの表示を「生成中...」へ切り替え、回転インジケーターと画面中央の生成中パネルを表示します。Dify APIの処理が完了すると評価一覧へ戻り、生成されたコメントを表示します。
日報機能
| No. | 機能 | 詳細 |
|---|---|---|
| F-40 | 日報登録 | 日付、作業内容、所感・メモを入力して登録する |
| F-41 | 日報一覧 | 登録済みの日報を日付の新しい順に一覧表示する |
| F-42 | 本人の日報登録 | 社員情報と紐づくユーザーでは、セッションのemployee_idを登録対象に固定する |
| F-43 | 本人の日報絞り込み | 社員情報と紐づくユーザーでは、本人の日報だけを表示する |
現在の実装では週単位の自動集計機能はなく、日報データの登録と一覧表示を行います。admin・staff・社員情報と紐づかないuserでは社員を選択できますが、EMP001では社員選択を山田太郎に固定します。
AI・RAG機能
| No. | 機能 | 詳細 |
|---|---|---|
| F-50 | RAG社内文書検索 | 自然言語の質問をDify APIへ送信し、Dify Knowledgeを利用した回答を表示する |
| F-51 | FAQチャット | チャット形式でDify APIへ質問し、回答を画面へ追加表示する |
| F-52 | 会話履歴保持 | Difyから返されたconversation_idを次の質問でも送信し、会話の文脈を保持する |
| F-53 | 送信中表示 | 回答生成中に「回答を生成中...」と表示する |
| F-54 | 二重送信防止 | 回答生成中は入力欄と送信ボタンを無効化する |
| F-55 | エラー表示 | APIキー未設定、タイムアウト、接続失敗などのエラーを表示する |
現在のRAG検索画面は、Difyから返された回答を「Dify回答」として表示します。回答の根拠となった文書名、章番号、ページ番号などの参照元表示は未実装です。また、FAQチャットはblockingモードでAPIを呼び出しており、ストリーミング応答には対応していません。
非機能要件
非機能要件とは、「システムがどのような品質で動作すべきか」を定めたものです。
パフォーマンス要件
本連載ではローカルの学習・開発環境を対象とし、次の値を目標とします。これらは環境やDify APIの応答状況によって変動するため、本番運用時には負荷試験が必要です。
| 項目 | 目標 | 補足 |
|---|---|---|
| 通常画面の応答 | 3秒以内 | 一覧表示、登録、更新など |
| AI応答 | 30秒以内 | HTTPリクエストのタイムアウトを30秒に設定 |
| Excel出力 | 100件程度を10秒以内 | ローカル開発環境での目標値 |
| 同時利用 | 少人数での利用 | 学習用のFlask開発サーバーを想定 |
セキュリティ要件
| 項目 | 要件 | 実装方法 |
|---|---|---|
| 認証 | ログインしていない利用者のアクセスを制限する | Flaskセッションとlogin_required
|
| 認可 | ロールに応じて管理機能へのアクセスを制限する | roles_required() |
| 本人データ制御 | 社員本人にはセッションで紐づいた社員の情報だけを表示する |
session["employee_id"]による絞り込み |
| パスワード | パスワードをハッシュ化して保存する | werkzeug.security |
| APIキー | APIキーをコードへ直接記述しない |
.envとpython-dotenv
|
| ファイル形式 | アップロード可能な拡張子を.xlsxと.csvに限定する |
拡張子チェック |
| ファイルサイズ | アップロードサイズを最大16MBに制限する | FlaskのMAX_CONTENT_LENGTH
|
| SQLインジェクション | SQLへ値を渡すときにプレースホルダーを使用する |
sqlite3プレースホルダー |
| セッション |
SECRET_KEYを環境変数で管理する |
Flask設定 |
APIキー、実運用のパスワード、SECRET_KEYはGitへコミットしないでください。.envファイルに記載し、.gitignoreで除外します。
サンプルコードには動作確認用アカウントが含まれています。本番環境では初期パスワードを必ず変更し、推測されにくい値を使用してください。
可用性・運用要件
| 項目 | 要件 |
|---|---|
| 対象環境 | ローカルの学習・開発環境 |
| OS | Windows、macOS、Linux |
| ブラウザ | Google Chromeなどのモダンブラウザ |
| データバックアップ |
database.dbを定期的にコピーして保管する |
| Dify障害時 | 評価コメントはローカルのフォールバック処理を使用する |
RAG検索とFAQチャットはDify APIを利用するため、APIキー、ネットワーク接続、Difyアプリの稼働状況に依存します。
保守性要件
| 項目 | 要件 |
|---|---|
| 構成分離 | ルーティング、データベース接続、業務ロジック、画面を分離する |
| バージョン管理 | Gitでソースコードを管理する |
| 環境再現性 |
requirements.txtに依存パッケージを記載する |
| 設定管理 | APIキーやFlask設定を環境変数から読み込む |
| データベース初期化 |
database.pyとcreate_admin.pyで初期化できるようにする |
制約条件
設計・実装にあたっての制約を明示します。
| 区分 | 制約 | 理由 |
|---|---|---|
| 技術 | バックエンドにはPythonとFlaskを使用する | PythonによるWebアプリケーション開発を学ぶため |
| データベース | SQLiteを使用する | セットアップが容易で学習コストが低いため |
| AI・RAG | Dify APIを使用する | 生成AIとRAGを同じプラットフォームで扱うため |
| Excel取込 | pandasを使用する | Excel・CSVデータを表形式で読み込むため |
| Excel出力 | openpyxlを使用する | セル書式を設定したExcelファイルを生成するため |
| 認証 | 外部認証サービスは使用しない | Flaskセッションによる基本的な認証・認可を学ぶため |
| 実行環境 | Flaskの開発サーバーを使用する | ローカル学習環境を対象とするため |
| 期間 | 各フェーズは1〜2週間を目安とする | 学習カリキュラムとして段階的に進めるため |
要件定義書のまとめ(サマリー)
ここまでの内容を、要件定義書として整理します。実際のプロジェクトでは、この内容をdocs/requirements.mdなどのファイルとして管理します。
# 要件定義書
## システム名
AI・RAGを活用した人事・研修業務支援システム
## 目的
人事・研修業務の効率化と品質向上を実現する。
具体的には、次の課題を解消する。
- 社員情報がExcelファイルに散在している
- 研修実績の集計に手間がかかる
- 評価コメントの作成に時間がかかる
- 社内文書を探しにくい
- 同じFAQへの回答が繰り返し発生する
## 利用者とロール
- admin:全機能と社員削除
- staff:社員管理、研修管理、評価管理、Excel入出力
- user:ダッシュボード、日報管理、社内文書検索、FAQチャット
- EMP001:userロール。山田太郎専用マイページと本人の日報を利用
## 主要な機能要件
- ログイン・ログアウト・ロール別アクセス制御
- 社員番号とログインユーザーの照合
- 社員本人用マイページ
- 社員一覧・検索・登録・編集・論理削除
- 研修登録・研修履歴入力
- 社員台帳・研修結果のExcel/CSV取込
- 研修実績の平均集計と総合スコア計算
- AI評価コメント生成
- AI評価コメントの生成中表示・二重送信防止
- 評価一覧のExcel出力
- 日報登録・一覧表示・社員本人によるデータ絞り込み
- RAG社内文書検索
- 会話履歴を保持するFAQチャット
## 主要な非機能要件
- パスワードをハッシュ化して保存する
- ロールに応じて機能へのアクセスを制限する
- 社員本人にはセッションで紐づいた本人データだけを表示する
- APIキーとSECRET_KEYを環境変数で管理する
- アップロード形式とファイルサイズを制限する
- SQLにはプレースホルダーを使用する
## 制約条件
- Python + Flask + SQLiteで構築する
- AI・RAG機能にはDify APIを使用する
- Excel・CSV取込にはpandasを使用する
- Excel出力にはopenpyxlを使用する
- ローカルの学習・開発環境を対象とする
次回の準備:要件をコードに落とす前に
要件定義が完了したら、次はER図と画面設計に進みます。
要件定義で決まった機能をもとに、次の順序で設計します。
機能要件
↓
どのようなデータが必要か? → ER図(テーブル設計)
どのような画面が必要か? → 画面設計(ワイヤーフレーム)
コードを書く前にデータ構造と画面構成を決めることで、実装時の手戻りを減らせます。
おわりに
第2回では、業務の現状分析から要求定義・要件定義までを整理しました。
ポイントを振り返ります。
- As-Is分析:人事担当者、研修担当者、一般社員の視点で現在の課題を整理した
- To-Be定義:課題をシステムでどのように改善するかを整理した
-
利用者と権限:
admin、staff、userの3ロールと社員番号による本人識別を定義した - ユースケース:実装する操作を18件のユースケースとして整理した
- 機能要件:認証、社員管理、研修管理、評価、日報、AI・RAG機能を定義した
- 非機能要件:パフォーマンス、セキュリティ、運用、保守性の要件を定義した
次回は「ER図・画面設計編」として、要件定義の内容をテーブル構造と画面に落とし込みます。「何を作るか」が決まったら、次は「どのようなデータと画面が必要か」を考えます。
次回:Python × Dify × RAGで学ぶ業務システム開発入門【第3回 ER図・画面設計編】
本連載について
本連載の各記事で実装する内容は次のとおりです。
| 回 | タイトル | 対応画面 | 主な内容 |
|---|---|---|---|
| 第1回 | 業務システム全体設計編 | ― | システム概要・技術選定・アーキテクチャ |
| 第2回 | 要求定義・要件定義編 | ― | 業務分析・機能要件・非機能要件 |
| 第3回 | ER図・画面設計編 | ― | テーブル設計・画面遷移図・ワイヤーフレーム |
| 第4回 | Flaskログイン機能編 | 🔐 ログイン | セッション・ハッシュ・ロール認可・社員番号ログイン |
| 第5回 | 社員管理CRUD編 | 👤 社員管理 | 一覧・検索・登録・更新・論理削除・入力制御 |
| 第6回 | 研修管理編 | 📚 研修管理 | 研修登録・LEFT JOIN・履歴一括入力・UPSERT |
| 第7回 | Excel業務自動化編 | 📥 取込 / 📤 出力 | pandas取込・openpyxl出力 |
| 第8回 | Dify API連携編 | 📊 評価管理 | API・フォールバック・生成中UI・二重送信防止 |
| 第9回 | RAG構築編 | 🔍 文書検索 | Dify Chat API・質問送信・回答表示・エラー処理 |
| 第10回 | FAQチャットボット編 | 💬 FAQチャット | 会話ID・Fetch API・生成中表示・二重送信防止 |
| 公開編 | Ubuntu VPS・Docker公開編 | 🌐 サービス公開 | Ubuntu VPS・Docker・Nginxを使った本番環境構築とWebアプリケーション公開 |