🦁

PDF の内容を小クイズ化する生成 AI アプリを作る

2025/01/27に公開

はじめに

昨今、生成 AI を利用したアプリが蔓延っており、ユーザのニーズに合致するようなものが数多く生まれてます。自分も何かいいアイデアがないかなーと考えてたとき、ふと高校時代のことを思い出しました。毎回必ず小テストが存在する授業です。高校時代の時は、解く側だったので先生の気持ちなど知るよしもなく、ただただ面倒だなーと思っていたのですが、本当に面倒だったのは問題を作る側の先生だった!と大学時代の塾講師の経験から気付かされました。そこで、教科書の内容に関する小クイズを自動で生成したら、全国の先生たちの業務効率化できるんじゃないかと考えました。ということで、教科書からではないのですが、まずは PDF の内容を小クイズ化する生成AIアプリ作ってみようと思います。

使用技術

  • 生成 AI API
    • VertexAI (gemini-1.5-pro)
  • Gradio
  • LangChain
  • poetry

実装

API キー設定とモデル初期化

API キーと使用する LLM の設定です。

pdf_quiz/app.py
import gradio as gr
import PyPDF2
from langchain.prompts import PromptTemplate
from langchain.chains import LLMChain
from langchain_google_vertexai import VertexAI
import os

os.environ["GOOGLE_API_KEY"] = "自分のAPIキー"

llm = VertexAI(
    model_name="gemini-1.0-pro",
    location="使用するリージョンを指定",  
    project="プロジェクトIDを指定",  
)

今回は、手元で動かすだけなので直接コード上で環境変数に API キーを入れてます。[1]
LLM model には gemini-1.5-pro を使います。

PDF から text 抽出、クイズ生成

PDF を入力として、クイズを生成する部分の実装です。

pdf_quiz/app.py
quiz_prompt = PromptTemplate(
    input_variables=["content"],
    template=(
        "以下の文章を読んで、この内容に基づいた3つの短いクイズを考えてください。それぞれのクイズには選択肢と正しい答えを含めてください。\n\n"
        "文章全文:\n{content}\n\nクイズ:"
    )
)
quiz_chain = LLMChain(llm=llm, prompt=quiz_prompt)

def extract_text_from_pdf(pdf):
    """PDFからテキストを抽出する"""
    pdf_reader = PyPDF2.PdfReader(pdf)
    text = ""
    for page in pdf_reader.pages:
        text += page.extract_text()
    return text

def generate_quiz_from_pdf(pdf):
    """PDFからクイズを生成する"""
    try:
        # PDFの内容をテキストとして抽出
        text = extract_text_from_pdf(pdf)
        
        # LangChainを使ってクイズを生成
        quiz = quiz_chain.run(content=text.strip())
        return quiz
    
    except Exception as e:
        return f"エラーが発生しました: {str(e)}"

プロンプトテンプレートを使って、入力内容に基づいてクイズを生成するように指示するプロンプトを設定してあげます。PromptTemplateinput_variablesに PDF の内容が入力される想定です。このプロンプトと、設定した LLM で LLMChain を作成します。
extract_text_from_pdf関数で、Python のライブラリである PyPDF2 を使って PDF からテキストを抽出し、generate_quiz_from_pdf関数で、抽出されたテキストに対して、quiz_chainを使ってクイズを生成します。

Gradioインターフェースの構築

Gradio インターフェースの部分の実装です。

pdf_quiz/app.py
with gr.Blocks() as demo:
    gr.Markdown("### PDF内容に基づくクイズ生成アプリ")
    with gr.Row():
        pdf_file = gr.File(label="PDF ファイルをアップロード", file_types=[".pdf"])
    with gr.Row():
        generate_button = gr.Button("クイズを生成")
    quiz_output = gr.Textbox(label="生成されたクイズ", lines=10)

    generate_button.click(
        generate_quiz_from_pdf,
        inputs=pdf_file,
        outputs=quiz_output,
    )

demo.launch()

PDF をアップロードして「クイズを生成」ボタンを押すとクイズとクイズの答えを生成して表示するような単純な仕組みです。

仮想環境構築

portry を使って仮想環境を構築します。

pyproject.toml
[tool.poetry]
name = "pdf-quiz"
version = "0.1.0"
description = ""
readme = "README.md"

[tool.poetry.dependencies]
python = "^3.12"
gradio = "^5.7.1"
pypdf2 = "^3.0.1"
langchain = "^0.3.9"
google-cloud-aiplatform = "^1.73.0"
langchain-google-vertexai = "^2.0.8"


[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"

pyproject.toml ファイルの内容です。必要なパッケージやライブラリを記載し、下記のコマンドを実行して仮想環境にインストールします。

$ poetry install

デモ

上記実装したコードを実行してみます。
今回は Google の API を使っているので、下記のコマンドを実行して SDK 認証を行います。

$ gcloud auth application-default login

アプリを実行するために下記コマンドを実行します。

$ poetry run python pdf_quiz/app.py

http://127.0.0.1:7860 にアクセスすると、下記のデモ動画のような画面になります。
今回は、Gemini 1.5 の論文を入力としてみました。

まとめ

今回は、PDF の内容に関するクイズを生成するアプリを作ってみました。まだまだ全国の先生を助けられるほどのアプリではないですが、いずれはこのアイデアを活用して実用的なwebアプリを作ってみたいと思います。

脚注
  1. 本来セキュリティや保守性の観点からベストプラクティスではないです。dotenv や secret manager など、API 管理ライブラリ・サービスを使いましょう。 ↩︎

Discussion