💬

対話型AIの可能性は? - 音声入力RAGチャットボットの概念実証

に公開

概要

RAG(Retrieval-Augmented Generation)チャットボットの機能拡張として、音声入力機能の実装を試みました。本記事では、Streamlitを用いた簡易的なプロトタイプの作成過程で得られた知見を共有します。

構成

本システムは以下の3つの主要コンポーネントで構成されています:

  • フロントエンド(Streamlit)
  • 音声処理システム
  • RAGシステム

これらのコンポーネントが連携して、ユーザーの音声入力をテキストに変換し、関連文書を検索して応答を生成する流れを実現しています。

デモ

主要コンポーネントの詳細解説

1. フロントエンド(Streamlit)

Streamlitを採用することで、最小限のコードで直感的なユーザーインターフェースを実現しています。

主な機能は以下の通りです:

  • 音声録音機能(audio_recorder_streamlitライブラリを使用)
  • PDFファイルのアップロード機能
  • チャット履歴の表示
  • 対話インターフェース

2. 音声処理システム

音声入力の処理には、OpenAIが開発したWhisperモデルを使用しています。以下の特徴があります:

  • 高精度な音声認識
  • 一時的な音声ファイルの保存と管理
  • 非同期処理による高速なレスポンス

3. RAGシステム

文書検索と応答生成の中核となるRAGシステムは、以下のコンポーネントで構成されています:

  • PDF処理: PyPDF2によるテキスト抽出
  • テキスト分割: LangChainによる適切なチャンクサイズでの分割
  • ベクトルストア: FAISSによる高速な類似度検索
  • 埋め込み: HuggingFaceの埋め込みモデルによるベクトル化

4. セッション状態管理

Streamlitのセッション状態機能を活用して、以下の情報を管理しています:

  • 録音状態
  • チャット履歴
  • PDF処理状態
  • RAGシステムの状態

実装のポイント

1. 非同期処理の活用

音声処理には時間がかかるため、非同期処理を採用しています:

async def process_audio(audio_bytes, processor, model):
    """Process audio data"""
    try:
        # Save temporary audio file
        timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
        audio_path = f"audio_{timestamp}.wav"
        with open(audio_path, "wb") as f:
            f.write(audio_bytes)

        # Transcribe audio
        transcribed_text = transcribe(audio_path, processor, model)
        if transcribed_text.strip():
            add_message("user", transcribed_text)
            
            # Generate RAG query response
            if st.session_state.pdf_processed:
                contexts = st.session_state.rag_system.query(transcribed_text)
                await display_rag_chunks(contexts)
            else:
                add_message("assistant", "Please upload a PDF file before querying for information.")

    except Exception as e:
        st.error(f"Error during processing: {str(e)}")

2. 効率的なベクトル検索

FAISSを使用することで、大量の文書に対しても高速な類似度検索を実現しています:

def process_pdf(self, pdf_file) -> None:
        try:
            pdf_reader = PyPDF2.PdfReader(pdf_file)
            text = ""
            for page in pdf_reader.pages:
                text += page.extract_text()

            chunks = self.text_splitter.split_text(text)
            self.vector_store = FAISS.from_texts(
                chunks,
                self.embeddings
            )
            st.success("PDF processing completed")
        except Exception as e:
            st.error(f"PDF processing error: {str(e)}")
            raise

3. 自動サイレンス検出

1.5秒の無音を検出して自動的に録音を終了する機能を実装しています:

# Show voice input only when recording is active
        if st.session_state.recording_started:
            audio_bytes = audio_recorder(
                pause_threshold=1.5,
                recording_color="#e74c3c",
                neutral_color="#666666",
                key="audio_recorder"
            )

            # Process new audio data if threshold time has passed
            current_time = time.time()
            if audio_bytes and (current_time - st.session_state.last_process_time) >= 1.5:
                st.session_state.last_process_time = current_time
                await process_audio(audio_bytes, processor, model)

セットアップと起動

システム要件

Python 3.11以降
最小4GB RAM
マルチコアプロセッサー推奨
CUDA対応GPU(オプション)

インストール手順

仮想環境の作成:

python3.11 -m venv voice
source voice/bin/activate  # Unix/macOS

依存パッケージのインストール:

pip install --upgrade pip
pip install -r requirements.txt

アプリケーションの起動:

python3.11 -m streamlit run app/main.py

まとめ

音声入力対応のRAGチャットボットを実装することで、以下のような知見が得られました:

  • より自然な対話インターフェースの実現
  • 音声入力からテキストに変換する処理のレスポンスの検証
  • 効率的な文書検索と応答生成

今後の展開として、以下のような機能追加を検討しています:

  • マルチモーダル対応(画像認識との統合)
  • 多言語対応の強化
  • リアルタイム音声認識への拡張

参考文献

Streamlit
FAISS
LangChain
transformers

コード

github

Discussion