音声対応AI医薬品アシスタント
薬のパッケージを読み取るか添付文書をアップロードし、音声またはテキストで資料に基づく回答を得られます。
English · 简体中文 · 繁體中文 · 한국어 · Español · Português · Русский · Français · Deutsch
MedVision-RAGは、視覚障がい者や高齢者がお薬の情報を理解できるよう支援するシステムです。薬のパッケージにカメラを向けるか、PDF・Word文書をアップロードすると、以下の処理が自動で行われます。
- テキスト抽出 — OCR(macOS Vision / Tesseractフォールバック)
- OCRテキストの正規化 — 有用な段落構造を保持
- ナレッジベース構築 — テキストをベクトル化してChromaDBに格納
- 質問応答 — アダプティブRAG(短文はコンテキストスタッキング、長文はベクトル類似検索)
- 音声読み上げ — edge-ttsによる回答読み上げ
システムはWebブラウザ、微信ミニプログラム、管理ダッシュボード(チャットログと分析の監視)に対応しています。
- 写真:薬のパッケージ、箱、PTPシートをカメラで直接撮影
- PDF:テキストベースとスキャン画像の両方に対応(自動判定し画像OCRを実行)
- Word:テキストと表を抽出。テキストが不十分な場合は埋め込み画像のOCRにフォールバック
- HEIC/HEIF:iPhone写真はOCR前に自動的にJPEGへ変換
- 短文(1500文字未満):コンテキストスタッキング — 文書全体をLLMプロンプトに注入
- 長文(1500文字以上):ベクトル検索 — テキストをチャンクに分割しChromaDBに格納、上位K件の関連パスagesを取得
- 薬の切り替え対応:ユーザーが別の薬の名前を言及した場合、コンテキストを自動的に切り替え
- Web:ブラウザ標準のSpeech Recognition API(レイテンシなし、APIコストゼロ)
- ミニプログラム:Groq Whisper Large-V3で音声認識、edge-ttsで音声合成
- 医療用語補正:LLMがASR出力を後処理し、誤認識された薬名を修正
- 割り込み再生対応:読み上げボタンを押すとTTS再生を即座に停止
- キーワード検出:
risk_keywords.jsonで設定可能なリスクキーワード - チャットログ監査:すべての会話をMySQLに保存しレビュー可能
- メールアラート:リスクキーワード検出時に自動メール通知(設定可能)
- 管理ダッシュボード:Streamlitによるリアルタイム監視、IPホワイトリストで保護
- ハイコントラストUI(WCAG AA準拠)
- 大きなタッチターゲット(48px以上)
- 視覚障がい者向けの完全音声駆動ワークフロー
- 中国語・英語の言語切替対応(AI応答とTTS音声の選択を同期)
┌─────────────┐ ┌──────────────────┐ ┌──────────────────┐
│ Web Front │────▶│ Java Backend │────▶│ Python AI │
│ :5174 │ │ Spring Boot │ │ FastAPI │
│ Vue 3 CDN │ │ :8080 │ │ :8001 │
└─────────────┘ │ │ │ │
│ - REST API │ │ - OCR (ocrmac) │
┌─────────────┐ │ - JPA / MySQL │ │ - ASR (Groq) │
│ WeChat │────▶│ - Auth / CORS │ │ - RAG (LangChain)│
│ Mini App │ │ - IP Whitelist │ │ - TTS (edge-tts) │
└─────────────┘ └────────┬─────────┘ │ - Risk Detection │
│ └────────┬──────────┘
▼ ▼
┌──────────────┐ ┌──────────────┐
│ MySQL 8 │ │ ChromaDB │
│ :3306 │ │ (local) │
└──────────────┘ └──────────────┘
| 依存関係 | バージョン | 備考 |
|---|---|---|
| Python | 3.10+ | AIサービスランタイム |
| Java | 17+ | ビジネスバックエンドランタイム |
| Maven | 3.8+ | Javaビルドツール |
| MySQL | 8.0+ | リレーショナルデータストレージ |
| macOS(推奨) | 13+ | ocrmacはApple Visionフレームワークを使用してOCRを実行 |
Linux:動作可能ですが、OCRにTesseractが必要です。
apt install tesseract-ocr tesseract-ocr-chi-simでインストールし、backend-ai/services/ocr.pyを修正してください。
DeepSeek APIキー(必須)と、オプションでGroq APIキー(微信ミニプログラムの音声認識用)が必要です。
DeepSeek APIキーの取得方法(必須)
DeepSeekは質問応答用のLLMを提供しています。
- platform.deepseek.comにアクセス
- アカウント登録またはログイン
- 左サイドバーのAPI Keysを選択
- Create API Keyをクリックし、名前を入力(例:「MedVision」)
- キーをすぐにコピー(
sk-で始まり、再表示されません)
コスト:デフォルトモデルdeepseek-v4-flashは非常に安価です。1日中の開発テストでも通常$0.01未満です。
Groq APIキーの取得方法(オプション — ミニプログラム専用)
GroqはLPUハードウェア上でWhisper Large-V3による高速な音声認識を提供しています。
- console.groq.comにアクセス
- GitHubまたはGoogleアカウントで登録
- 左サイドバーのAPI Keysを選択
- Create API Keyをクリック
- キーをコピー(
gsk-で始まる)
コスト:無料プランにはWhisperの利用が十分に含まれています。Webフロントエンドはブラウザ標準の音声APIを使用するためGroqのクレジットは消費されません。微信ミニプログラムのみがGroqを使用します。
git clone https://github.com/Ha1baraA11/MedVision_RAG.git
cd MedVision_RAGcp .env.example .env任意のテキストエディタで.envを開き、値を入力してください。
# macOS
open -e .env
# VS Code
code .env| 変数名 | 必須 | 説明 |
|---|---|---|
MYSQL_PASSWORD |
必須 | MySQLのrootパスワード |
DEEPSEEK_API_KEY |
必須 | platform.deepseek.comから取得 |
DEEPSEEK_BASE_URL |
任意 | デフォルト:https://api.deepseek.com |
GROQ_API_KEY |
ミニプログラム用 | console.groq.comから取得 |
SMTP_SERVER |
任意 | リスクアラート用SMTPサーバー(例:smtp.qq.com) |
SMTP_PORT |
任意 | SMTPポート(QQメール:465) |
SMTP_USER |
任意 | 送信元メールアドレス |
SMTP_PASSWORD |
任意 | SMTP認証コード(メールパスワードではありません) |
SMTP_RECEIVER |
任意 | 送信先メールアドレス |
INTERNAL_TOKEN |
任意 | Java ↔ Python間の認証トークン |
注意:
MYSQL_PASSWORDはシステム起動に本当に必要な唯一の資格情報です。それ以外はすべて安全なデフォルト値を持つか、グレースフルデグラデーションに対応しています。
QQメールのSMTP認証コード取得方法
- mail.qq.comにログイン → 設定 → アカウント
- POP3/IMAP/SMTP/Exchange/CardDAV/CalDAVサービスを見つける
- IMAP/SMTPサービスを有効にする
- SMS認証の指示に従って認証コードを取得
- このコード(QQパスワードではありません)を
SMTP_PASSWORDとして使用
cd backend-ai
# 仮想環境の作成
python3 -m venv venv
# 有効化
source venv/bin/activate
# 依存関係のインストール(初回のみ、約2分)
pip install -r requirements.txt初回起動時にHuggingFaceからbge-small-zh-v1.5埋め込みモデル(約90MB)がダウンロードされます。
cd backend-java
# 依存関係のダウンロードとコンパイル(初回のみ、約3分)
mvn clean install -DskipTestsmysql -u root -p < sql/init.sql以下のリソースが作成されます:
- データベース
medvision(UTF8MB4) - テーブル
medicines— 医薬品情報と全文テキスト - テーブル
chat_logs— 会話履歴と分析データ - テーブル
admin_users— 管理者アカウント
デフォルトの管理者アカウント(admin / admin)は、Javaバックエンドの初回起動時に自動作成されます。
代替方法:この手順をスキップすると、Spring Bootの
hibernate.ddl-auto=updateにより起動時にテーブルが自動作成されます。SQLスクリプトは明示的なスキーマ管理および本番環境デプロイ用に用意されています。
./start_all.shこのスクリプトはすべてのサービスを依存関係順に起動し、各サービスの準備完了を待ってからステータスを表示します。ログはbackend-ai/service.log、backend-java/backend.log、dashboard.logに出力されます。
ターミナル1 — Python AIサービス(最初に起動、最も時間がかかる)
cd backend-ai
source venv/bin/activate
python main.py次のメッセージを待ちます:Uvicorn running on http://0.0.0.0:8001
初回起動時に埋め込みモデル(
bge-small-zh-v1.5)がダウンロード・キャッシュされます。2回目以降は約3秒で起動します。
ターミナル2 — Javaバックエンド
cd backend-java
mvn spring-boot:run次のメッセージを待ちます:Started MedVisionApplication in X.XXX seconds
初回実行時にMavenが依存関係をダウンロードします。バックエンドはデータベーステーブルとデフォルトの管理者アカウントを自動作成します。
ターミナル3 — Webフロントエンド
cd frontend
python3 -m http.server 5174ブラウザでhttp://localhost:5174を開きます。
オプション — 管理ダッシュボード
streamlit run admin_dashboard.py --server.port 8502http://localhost:8502を開きます。ログイン:`admin` / admin。
./stop_all.shまたは手動で:
lsof -t -i:5174 -i:8080 -i:8001 -i:8502 | xargs kill -9- 微信開発者ツールをダウンロードしてインストール
- ツールを開き、プロジェクトのインポートをクリック
frontend-wechat/ディレクトリを選択- テストAppIDまたはゲストモードを選択
frontend-wechat/config.jsを編集:
const API_CANDIDATES = [
'http://192.168.x.x:8080', // お使いのPCのLAN IPに置き換えてください
];# macOS
ifconfig | grep "inet " | grep -v 127.0.0.1
# Windows
ipconfig | findstr "IPv4"- スマートフォンとPCが同じWi-Fiネットワークに接続されていることを確認
- 微信開発者ツールでデバイスでデバッグをクリック
- スマートフォンでQRコードをスキャン
- 接続に失敗した場合、以下を確認:
- PCのファイアウォールがポート
8080の受信を許可していること config.jsに正しいLAN IPが設定されていること(localhostではなく)- Javaバックエンドが実行中であること
- PCのファイアウォールがポート
backend-ai/core/config.pyを編集:
llm = ChatOpenAI(
model="deepseek-v4-flash", # ここでモデルを変更
api_key=API_KEY,
base_url=BASE_URL,
temperature=0.3 # 0.0 = 決定論的、1.0 = 創造的
)利用可能なDeepSeekモデル:
| モデル | 速度 | コスト | 推奨用途 |
|---|---|---|---|
deepseek-v4-flash |
高速 | 非常に低い | 開発・デモ(デフォルト) |
deepseek-v4 |
中程度 | 低 | より高品質な回答 |
デフォルトではocrmac(macOS Vision)を使用します。LinuxでTesseractに切り替える場合:
# 中国語対応Tesseractのインストール
sudo apt install tesseract-ocr tesseract-ocr-chi-sim
# Pythonラッパーのインストール
pip install pytesseractその後、backend-ai/services/ocr.pyを修正してocrmacの代わりにpytesseractを使用してください。
デフォルトモデルはBAAI/bge-small-zh-v1.5(中国語医療テキスト向けに最適化、約90MB)です。ローカルのCPUで実行され、API呼び出しは不要です。変更する場合:
# backend-ai/core/config.py
embedding_model = HuggingFaceEmbeddings(
model_name="BAAI/bge-small-zh-v1.5", # ここでモデルを変更
model_kwargs={"local_files_only": True, "device": "cpu"}
)初回使用時は
local_files_onlyをFalseに変更してHuggingFaceからダウンロードしてください。
risk_keywords.jsonを編集してトリガーワードを追加・削除:
{
"keywords": ["overdose", "poisoning", "allergy", "contraindication", "side effect", "..."]
}設定済みのキーワードがユーザーの質問に含まれると、システムはリスクイベントを記録し、メールアラートを送信できます。
管理ダッシュボードはIPホワイトリストによるアクセス制限を行います。backend-java/src/main/resources/application.propertiesで設定:
admin.security.enabled=true
admin.security.ip-whitelist=127.0.0.1,::1リモートアクセスする場合は、IPをホワイトリストに追加してください。
埋め込みモデルは初回ダウンロード後にローカルにキャッシュされます。再ダウンロードが必要な場合:
cd backend-ai
source venv/bin/activate
python -c "from langchain_huggingface import HuggingFaceEmbeddings; HuggingFaceEmbeddings(model_name='BAAI/bge-small-zh-v1.5')"| メソッド | パス | 説明 |
|---|---|---|
GET |
/health |
ヘルスチェック |
POST |
/ocr |
画像・PDF・Word → テキスト抽出 |
POST |
/chat |
RAG質問応答 |
POST |
/transcribe |
音声認識(Groq経由Whisper) |
POST |
/analyze |
手動テキスト分析 |
GET |
/tts |
音声合成(edge-tts) |
GET |
/search |
薬の履歴検索 |
| メソッド | パス | 説明 |
|---|---|---|
GET |
/api/medicine/health |
ヘルスチェック |
POST |
/api/medicine/recognize |
添付文書のアップロードと認識 |
POST |
/api/medicine/chat |
AIサービスへのチャットプロキシ |
GET |
/api/medicine/list |
保存済み薬の一覧 |
GET |
/api/medicine/chat-logs |
チャットログ履歴(管理者用) |
GET |
/api/medicine/analytics |
利用分析(管理者用) |
POST |
/api/medicine/admin/login |
管理者ログイン |
# Pythonユニットテスト(17テスト、約0.2秒)
cd backend-ai
source venv/bin/activate
python -m pytest tests/ -v
# Javaユニットテスト(6テスト)
cd backend-java
mvn test| モジュール | テスト数 | カバレッジ |
|---|---|---|
check_risk_keywords |
6 | ヒット、キャッシュ、期限切れ、空入力 |
smart_rag_search |
4 | 短文、長文、エラーフォールバック、エッジケース |
correct_medical_terms |
7 | ハルシネーションフィルタ、ブラックリスト、LLM補正、エラーフォールバック |
MedicineController |
6 | RESTエンドポイントMockMvcテスト |
MedVision-RAG/
├── frontend/ # Vue 3 CDNの単一ページWebアプリ
│ └── index.html # フロントエンド全体(848行)
├── frontend-wechat/ # 微信ミニプログラム
│ ├── pages/index/ # メインページ(WXML + JS + WXSS)
│ ├── app.js # アプリエントリ
│ └── config.js # APIエンドポイント設定
├── backend-java/ # Spring Bootビジネスバックエンド
│ ├── src/main/java/com/medvision/
│ │ ├── controller/ # RESTエンドポイント
│ │ ├── service/ # ビジネスロジック
│ │ ├── entity/ # JPAエンティティ(Medicine、ChatLog、AdminUser)
│ │ ├── repository/ # Spring Data JPAリポジトリ
│ │ └── config/ # セキュリティ、CORS、IPホワイトリスト、データ初期化
│ ├── src/test/ # MockMvcテスト
│ └── pom.xml # Maven依存関係
├── backend-ai/ # FastAPI AIサービス
│ ├── main.py # ルートエントリ(約250行)
│ ├── core/
│ │ ├── config.py # グローバルシングルトン(LLM、埋め込み、Groqクライアント)
│ │ ├── logging_config.py # 構造化ロギング+トレースミドルウェア
│ │ └── security.py # 内部トークン検証
│ ├── services/
│ │ ├── ocr.py # OCR(ocrmac + Tesseractフォールバック)
│ │ ├── asr.py # 音声認識(Groq Whisper)
│ │ ├── rag.py # アダプティブRAG(コンテキストスタッキング+ベクトル検索)
│ │ ├── tts.py # 音声合成(edge-tts)
│ │ ├── risk.py # リスクキーワード検出+TTLキャッシュ
│ │ ├── email.py # リスクアラートメール(非同期スレッドプール)
│ │ ├── intent.py # 意図分析(現在 vs 過去の薬)
│ │ ├── search.py # 薬の履歴検索
│ │ └── chat_model.py # チャットモデル切替
│ ├── models/
│ │ └── schemas.py # Pydanticリクエストモデル
│ └── tests/ # pytestユニットテスト
├── admin_dashboard.py # Streamlit管理ダッシュボード
├── risk_keywords.json # リスクキーワード辞書
├── sql/
│ └── init.sql # データベース初期化スクリプト
├── Package-Insert_Test/ # テスト用サンプル添付文書
├── .env.example # 環境変数テンプレート
├── .gitignore # Git除外ルール
├── start_all.sh # 全サービス一括起動スクリプト
└── stop_all.sh # 全サービス一括停止スクリプト
No module named 'ocrmac'
ocrmacはmacOS Visionフレームワークを使用するため、macOSでのみ動作します。Linuxの場合はTesseractをインストールしてください:
sudo apt install tesseract-ocr tesseract-ocr-chi-sim
pip install pytesseractその後、backend-ai/services/ocr.pyを修正してpytesseractを使用してください。
Javaバックエンド起動時にConnection refused
MySQLが実行されていないか、パスワードが間違っています。
# MySQLステータスの確認
mysql -u root -p -e "SELECT 1"
# .envのパスワードがMySQL rootパスワードと一致しているか確認
cat .env | grep MYSQL_PASSWORDPython起動時にtorchaudioの警告が表示される
VAD(音声活動検出)に関する非致命的な警告です。システムはVADなしモードにフォールバックし、正常に動作します。修正するには:pip install torchaudio。
Mavenのダウンロードが遅い
~/.m2/settings.xmlにミラーを追加:
<mirrors>
<mirror>
<id>aliyun</id>
<mirrorOf>central</mirrorOf>
<url>https://maven.aliyun.com/repository/central</url>
</mirror>
</mirrors>ブラウザで白い画面が表示される
DevTools(F12)→ コンソールタブを開いてください。よくある原因:
- AIサービスが起動していない → ポート
8001を確認 - Javaバックエンドが起動していない → ポート
8080を確認 - CORSエラー →
localhost:5174経由でアクセスしているか確認(file://ではなく)
ミニプログラムがバックエンドに接続できない
- スマートフォンとPCが同じWi-Fiネットワークに接続されていることを確認
config.jsにLAN IPが設定されていることを確認(localhostや127.0.0.1ではなく)- PCのファイアウォールがポート
8080の受信接続を許可していることを確認 - スマートフォンのブラウザから
curl http://YOUR_LAN_IP:8080/api/medicine/healthを試す
音声認識が動作しない(Web)
ブラウザはマイクアクセスにHTTPSまたはlocalhostを要求します。http://localhost:5174経由でページにアクセスしていることを確認してください(LAN IPではなく)。
音声認識が動作しない(ミニプログラム)
.envにGROQ_API_KEYが設定されていることを確認してください。.envを変更した後はPython AIサービスを再起動してください。
OCRが「不明な薬」や文字化けを返す
- 写真が鮮明で明るいことを確認してください
- 画像内に薬の名前が表示されている必要があります
- PDFの場合、ファイルがスキャン画像(検索可能なテキストではない)かどうか確認してください。システムが自動判定し画像OCRを使用します
データベースのリセット方法
mysql -u root -p -e "DROP DATABASE IF EXISTS medvision;"
mysql -u root -p < sql/init.sqlその後、Javaバックエンドを再起動してデフォルトの管理者アカウントを再作成してください。
管理者パスワードの変更方法
管理ダッシュボード(http://localhost:8502)にログイン後に変更するか、MySQLで直接更新:
USE medvision;
UPDATE admin_users SET password_hash = '$2a$10$...' WHERE username = 'admin';BCryptハッシュはオンラインツールまたはPythonで生成:
from passlib.hash import bcrypt
print(bcrypt.hash("your_new_password"))このリポジトリには現在ライセンスファイルが含まれていません。想定範囲外で配布または再利用する前に、明示的なライセンスを追加してください。
