はじめに
みなさんは、ChatGPTなどのAIエージェントをどのように活用していますか?
僕は最近、資料作成の際に「テーマに対する背景の肉付け」をしたいときによく使っています。
というのも、あるテーマの背景を調べる際には、限られた時間の中で大量の資料を読み漁り、要点をまとめる必要があります。それが思った以上に手間で、正直かなり億劫に感じていました。
そこで、ChatGPTにテーマに関連しそうな資料を提示してもらい、それをもとに効率よく情報収集するというスタイルで活用しています。
この方法でかなり作業が楽になった反面、別の課題も見えてきました。
例えば、ChatGPTが提案してくれたWebページがリンク切れになっていたり、ページ内に求めていた情報が載っていなかったりすることが、頻繁にあり正直イヤになっていました。
今回やること
そこで今回は、任意のURLを入力すると、そのページの内容を自動で要約してくれるアプリを作ってみようと思います。
実装
Beautifulsoupについて
BeautifulSoupとは、Pythonで使える外部ライブラリの一つです。
このライブラリを使うと、取得したURLの構造を解析して必要なデータを抽出することができます。
具体的には、HTMLで書かれた記事のタグや属性にアクセスして、本文の部分を取り出すことが可能です。
今回のアプリでは、このBeautifulSoupを用いてWebページから本文を抽出し、その内容をAIに要約させる仕組みを作っています。
soup = BeautifulSoup(response.text, "html.parser")
要点まとめプロンプト
入力したWebサイトの内容をどのようにまとめてもらいたいかは、プログラム側であらかじめ定義できます。
実際の運用を考えると、Webサイトにはブログ形式やレポート形式など、さまざまな論調がありますよね。
そこで、異なる論調のWebページに柔軟に対応できるよう、以下のような定義を作成しました。
なお、プログラム側でAIに対して回答の指示を出す際は、トリプルクォート(”””)で囲むことで、複数行にわたる命令文をまとめて渡すことが可能です。
SUMMAARIZE_PROMPT = """
以下は、あるWebページの本文内容です。
この内容をもとに、各セクションごとに重要なポイントを簡潔に整理し、要点を箇条書きでまとめてください。
ただし、Webページの構成や論調に応じて、単なる箇条書きだけでなく、必要に応じてセクション単位でのまとまりを意識した形式で要約してください。
{content}
"""
本文抽出
URLからテキスト情報を取得する処理は get_content
関数で行っています。詳細は else
以下の部分をご確認ください。
ここからは、取得したテキスト情報をAIに渡して要約させる流れについて説明します。
AIエージェントの出力は、「ユーザープロンプト → モデル → 出力」というパイプラインで処理されます。(この処理はinit_chain
関数内で実装しており、以前の説明で触れているためここでは割愛します。)
以上の仕組みを使い、取得したテキストの一部をプロンプトとしてAIに入力することで、要約結果を得ることができるようになります。
def main():
cf.init_page()
chain = cf.init_chain()
if url := st.text_input("URL: ", key = "input"):
is_valid_url = cf.validate_url(url)
if not is_valid_url:
st.write("Please input valid url")
else:
if content := cf.get_content(url):
st.markdown("## Summary")
st.write_stream(chain.stream({"content": content}))
st.markdown("---")
st.markdown("### Original Text")
st.write(content)
完成
ここまでの実装では、StreamlitというWebアプリケーションフレームワークを使用しています。
実際に動かすと、以下のような画面が表示されます。

出力の比較
レポート調
AIの出力の形式を冒頭で定義した通りになっているか確認をしてみましょう。
僕が毎週書いているレポート調な記事では下記のように要約されることを確認できました。
記事概要
目的: PyTorchを用いたニューラルネットワークによる積雪深予測の精度向上
前回との違い: scikit-learnからPyTorchへの移行によるモデルの柔軟性向上
主要セクション別要点
1. 今回の取り組み目標
PyTorchでニューラルネットワークを一から構築
モデル構造や学習設定の柔軟なカスタマイズ
積雪深予測精度の向上を目指す
2. 実装面での改善点
PyTorchへの移行理由
scikit-learnの限界:モデル構造のカスタマイズに制約
データセット量が不十分な状況での柔軟な拡張が必要
より細かな調整が可能な環境の構築
ネットワーク構造の特徴
入力層:13次元 → 出力層:1次元
隠れ層:128 → 64 → 32 → 16のステップダウン構造
各層にDropout(30%)を適用し過学習を防止
ReLU活性化関数を使用
3. データセットの拡張
従来の11項目から13項目へ拡張
既存:月、日、現地気圧、海面気圧、降水量、気温、湿度、最大風速、風向、降雪量、前日積雪深との差
新規追加:日照時間、合計日射量
データ期間:2016年〜2025年(約10年分)
4. 学習結果と評価
学習パフォーマンス
学習エポック数:450回
収束:約300エポック付近で安定
前回比でTrain RMSEは改善
評価指標(RMSE)
訓練データ:6.093 cm
テストデータ:11.105 cm
差分:約5 cm(過学習の兆候あり)
課題の分析
データのばらつきが大きい
全体的なデータ量不足
実運用での安定性には慎重な検証が必要
5. 今後の展望
短期的課題
データ量の増加と品質向上
過学習対策の強化
長期的展望
2015年以降の全国衛星画像データの活用検討
より多様なデータセットでの検証
地域・年次変動への対応強化
結論
適用場面の使い分け:データ量が十分な場合はscikit-learn、柔軟なカスタマイズが必要な場合はPyTorchが有効
PyTorchの優位性:データにばらつきがあり、モデルの柔軟性が求められるケースに適している
実用化への課題:気象データの特性(年・地域変動)を考慮した検証が今後必要
ブログ調
一方で下記の狩野英孝さんのブログでは次のように要約されていることを確認しました。
アンバサダー就任の報告
Sammyのパチンコ台『P真 北斗無双第3章』のアンバサダーに就任
実際にSammy社を訪問し、パチンコ台を体験
実機体験の感想
演出面:迫力のある演出でドキドキする体験
ゲーム性:大当たりを実際に引くことができた
総合評価:打った人にしか分からない感動があると評価
ユーザーへの推奨
パチンコ店は安全第一で営業している現状を説明
機会があれば実際にプレイすることを推奨
楽しさを強調してアピール
関連コンテンツの紹介
Sammy公式YouTubeチャンネルに出演
様々な企画(トーク、ゲーム等)に参加していることを告知
視聴を呼びかけ
※全体的に体験談を交えた親しみやすいトーンで、商品の魅力とコンテンツの宣伝を行う構成となっている

まとめ
レポート調とブログ調で比較をしてみましたが、出力のテンプレート形式があるのか要約のされ方にそれほど違いがあるようには思えませんでした。
考察としては冒頭で定義した”柔軟に対応してください”というようなプロンプトには対応できないということなのでしょうね。
ですが、モデル次第で違いはあるので、それを試してみるとかなりおもしろいです。
おわりに
いかがでしたでしょうか。
書籍を参考にしつつBeautifulsoupでURLから取得したテキスト情報をAIに渡すことで要約してくれるアプリを作ってみました。
今後はこれを応用した議事録アプリが作れそうなので、やってみると面白いかもしれませんね。
今回作成したアプリケーションは下記URLから使うことができますが、API keyが必要なためご自分で用意していただく必要がありますのでご注意ください。