AIアプリ開発入門 その2:Webサイト要約・YouTube動画要約アプリを作る

この記事の内容

  • Streamlit Community CloudへのAIアプリのデプロイ方法を学びます
  • BeautifulSoupとChatGPT APIを使ったWebサイト要約アプリの仕組みを解説します
  • LangChainのDocument LoaderとLoad Summarize Chainを使ったYouTube動画要約アプリを作ります
  • 長い動画・文章に対応するためのMapReduceチェーンとテキストスプリッターの使い方を学びます
  • GPT-3.5 Turbo 16Kモデルの活用とAPIコストの目安を紹介します

AIアプリをWebにデプロイする(Streamlit Community Cloud)

ローカルで開発したStreamlitアプリをWeb上に公開する方法として、Streamlit Community Cloudがあります。Streamlit製のアプリケーションを簡単にWeb上で公開・共有できるサービスで、無料プランも用意されています。

デプロイの基本的な手順は以下のとおりです。

  1. Streamlit Community Cloudにアカウント登録する
  2. コードと依存関係をGitHubリポジトリにプッシュする
  3. 設定ファイルを修正し、アプリ設定をカスタマイズする
  4. デプロイを実行する

コードを更新するたびに自動的にアプリが更新される仕組みも備わっています。ただし、本番利用には向かないため、PoC(概念実証)やデモ用途として活用するのが現実的です。なお、プライベートリポジトリへの閲覧権限を要求される点は注意が必要です。


Webサイト要約アプリを作る

アプリの概要

WebサイトのURLを入力すると、そのページの内容を取得し、ChatGPT APIを使って要約してくれるアプリです。学習目的のため、クラスへの切り出しやファイル分割はあえて行わず、134行程度のシンプルな構成になっています。

アプリの処理フローは次のとおりです。

URLgCehtaCtoGnPtTenAtP(I)We1b000使

Webページのコンテンツ取得

ページの取得にはgetContent()関数を使います。内部ではBeautifulSoupを利用しており、<main>タグや<article>タグなど本文に相当する要素があればそれを取得し、なければページ全体を返す仕組みになっています。

pip install streamlit
pip install beautifulsoup4

プロンプトの組み立て

コンテンツが長い場合は先頭の1000文字のみを使用し、以下のようなプロンプトでChatGPT APIに要約を依頼します。

{3100000}

モデルの選択はサイドバーで切り替えられるようになっており、URLのバリデーションも実装されています。このようにシンプルな構成でも、Webサイトの要約アプリは十分に動作します。


YouTube動画要約アプリを作る

LangChainのDocument Loaderを活用する

LangChainにはDocument Loaderという機能があり、さまざまなデータソースからデータを読み込んで、言語モデルが処理しやすい「ドキュメント」形式に変換してくれます。

YouTubeの字幕(トランスクリプト)を取得するには以下のように書くだけです。

from langchain.document_loaders import YoutubeLoader

loader = YoutubeLoader.from_youtube_url(
    url,
    add_video_info=True,
    language=["en", "ja"]
)
documents = loader.load()

取得できるメタデータには、タイトル・説明文・再生回数・サムネイルURL・公開日・動画の長さ・投稿者名などが含まれます。LangChainはYouTubeの他にも、Twitter、Slackなど多様なデータソースに対応しています。

なお、このライブラリの利用には事前にパッケージのインストールが必要です。

pip install youtube-transcript-api
pip install pytube

Load Summarize Chainで要約する

取得したドキュメントの要約にはLoad Summarize Chainを使います。非常にシンプルに記述できます。

from langchain.chains.summarize import load_summarize_chain

chain = load_summarize_chain(llm, chain_type="stuff")
result = chain({"input_documents": documents}, return_only_outputs=True)

chain_typeには以下の3種類があります。

chain_type概要
stuffドキュメントをそのままLLMに渡す基本的な方式
map_reduce複数のドキュメントを個別に要約してからまとめる方式
refine先頭から順番に処理し、前の要約に次の内容を合わせて徐々に精緻化していく方式

短い動画であればstuffで問題ありませんが、長い動画ではトークン数の上限を超えてエラーになります。


長い動画に対応する:MapReduceとテキストスプリッター

MapReduceチェーンを使う

長い動画を要約するにはchain_type="map_reduce"を使います。処理の流れは以下のとおりです。

rmeadpuce

この方式を使うことで、49分を超えるような長い動画でも要約を生成できます。

テキストスプリッターの使い方

LangChainではテキストスプリッターを使って長いテキストを自動的に分割できます。代表的なものがRecursiveCharacterTextSplitterです。

from langchain.text_splitter import RecursiveCharacterTextSplitter

text_splitter = RecursiveCharacterTextSplitter.from_tiktoken_encoder(
    model_name="gpt-3.5-turbo",
    max_tokens=<モデルの最大トークン数>,
)

from_tiktoken_encoderを使うことで、文字数ではなくトークン数を基準に分割できます。日本語と英語ではトークン数が大きく異なるため、複数言語を扱う際はこの方式が特に有効です。

また、chunk_overlapパラメーターを使うと、チャンク同士を一定文字数ずつ重複させることができます。これにより、分割された前後のチャンクで文脈が途切れるのを防げます。

LangChainには他にも以下のテキストスプリッターが用意されています。

  • LatexTextSplitter:LaTeX形式のテキスト向け
  • MarkdownTextSplitter:Markdown形式のテキスト向け

GPT-3.5 Turbo 16Kの活用

gpt-3.5-turbo-16kモデルを使うと、1回のリクエストで処理できるトークン数が大幅に増えます。長いコンテンツを扱う場合にはこちらのモデルが有効です。ただし、通常のgpt-3.5-turboよりもAPIコストが高くなる点には注意が必要です。


APIコストについて

動画内では49分の動画をmap_reduce + GPT-3.5 Turbo 16Kで要約した際のコストが紹介されていました。

  • 要約1回あたり:約0.64ドル(約100円)

試行錯誤しながら遊ぶとコストがかさむため、実際に利用する際はコストの管理を意識することが大切です。


まとめ

この記事では、LangChainとStreamlitを組み合わせたAIアプリ開発の実践的な手法を紹介しました。

  • Webサイト要約はBeautifulSoupでHTMLを取得し、ChatGPT APIにプロンプトを投げるだけで実現できます
  • YouTube動画要約はLangChainのDocument Loaderを使うことで、字幕の取得からLLMへの受け渡しまでを簡潔に記述できます
  • 長い動画への対応にはMapReduceチェーンとテキストスプリッターを組み合わせることで解決できます
  • RecursiveCharacterTextSplitter.from_tiktoken_encoderを使うとトークン数ベースで正確に分割でき、多言語対応にも有効です

YouTube動画のトランスクリプトから記事を生成するような応用も十分に可能であり、コンテンツ制作の効率化に役立てられそうです。