yKesamaru / make_GPTs_document_from_web

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

WEBドキュメントをMy GPTsとして作成する方法

この記事で作成されたMy GPTsは、[最新ドキュメントを知ってるPillowちゃん](https://chat.openai.com/g/g-9bLQujz1z-zui-xin-dokiyumentowozhi-tuterupillowtiyan)として共有します。

https://chat.openai.com/g/g-9bLQujz1z-zui-xin-dokiyumentowozhi-tuterupillowtiyan

はじめに

皆さんがGPT-4を使ってコーディングをするとき、GPT-4が「非推奨のメソッド」を提案することはありませんか?また、GPT-4が「この関数は存在しません」と言っているのに、その関数が実際には存在することはありませんか?

本来、このような現象を解決するために、GPT-4に「WEBブラウジング機能」が実装されたのでした。

一般的に、GPT-4はBingのような検索エンジンを使用して情報を検索し、最新かつ的確な情報を提供すると考えられがちです。

しかし、現実には、うまく行きません。 単純な応答ならいざ知らず、GPT-4を使ってブレインストーミングをしていたり、コーディングのコパイロット的な使い方をする時、調べられた情報はその内容が浅く、またチャット中に忘れてしまうことが多いのです。

その結果、「使えねーな!!」となってしまいます。

この記事では、Web上のドキュメントを使用してGPTモデルを事前に学習させることにより、これらの問題を克服する方法を紹介します。

つまり、WEBドキュメントを使ってMy GPTsを作成します。

最初に結論の一部を紹介すると、単純にクローリングしたhtmlファイルの束をzip圧縮してアップロードしても、期待した成果は得られません。全てのドキュメントをPDFファイル化する必要があります。

もちろん、ドキュメントのPDF化は、半自動化したものを紹介します。

このアプローチにより、モデルが最新知識を持ち、対話の中での論理的一貫性が維持されます。

さて、この記事では題材としてPillowドキュメントを学習させます。 GPT-4はPillowを理解していますが、その知識は古く、かなり多くの非推奨メソッドを使いたがります。

続いて、GPT-4が間違いを犯す例を紹介しますが、忙しい方はドキュメントを取得するまで飛ばして下さい。

GPT-4が間違いを犯す例

例を挙げましょう。

stackoverflowからPython pillow/PIL doesn't recognize the attribute "textsize" of the object "imagedraw"を見てみましょう。 Q&Aのベストアンサーは以下のとおりです。

textsize was deprecated, the correct attribute is textlength which gives you the width of the text. for the height use the fontsize * how many rows of text you wrote.
(textsize は非推奨になりました。正しい属性はテキストの幅を与える textlength です。)

質問されたエラーの出るコードは以下のとおりです。

def metti_testo_su_sfondo(testo, sfondo, posizione=(10, 10), colore_testo=(0, 0, 0), dimensione_font=25):
# Apri l'immagine dello sfondo
immagine_sfondo = Image.open(sfondo)
disegno = ImageDraw.Draw(immagine_sfondo)
font = ImageFont.truetype("/usr/share/fonts/truetype/ubuntu/Ubuntu-R.ttf", dimensione_font)

text_width, text_height = disegno.textsize(testo, font=font)  # この行がエラー

# Calcola le coordinate del testo centrato
x = (immagine_sfondo.width - text_width) // 2
y = (immagine_sfondo.height - text_height) // 2

disegno.text((x, y), testo, fill=colore_testo, font=font)
immagine_sfondo.save("spotted.png")
testo_da_inserire = "Ciao, mondo!"
sfondo_da_utilizzare = "background.png"
metti_testo_su_sfondo(testo_da_inserire, sfondo_da_utilizzare)

エラー内容は以下のとおりです。

    text_width, text_height = disegno.textsize(testo, font=font)
                              ^^^^^^^^^^^^^^^^
AttributeError: 'ImageDraw' object has no attribute 'textsize'

つまり、textsize属性は無いと言われています。

質問内容

では、このエラーを質問してみましょう。 fontのパスと画像ファイル名を実際とおなじものに変更しています。

def metti_testo_su_sfondo(testo, sfondo, posizione=(10, 10), colore_testo=(0, 0, 0), dimensione_font=25):
# Apri l'immagine dello sfondo
immagine_sfondo = Image.open(sfondo)
disegno = ImageDraw.Draw(immagine_sfondo)
font = ImageFont.truetype("/usr/share/fonts/truetype/ubuntu/Ubuntu-R.ttf", dimensione_font)

text_width, text_height = disegno.textsize(testo, font=font)  # この行がエラー

# Calcola le coordinate del testo centrato
x = (immagine_sfondo.width - text_width) // 2
y = (immagine_sfondo.height - text_height) // 2

disegno.text((x, y), testo, fill=colore_testo, font=font)
immagine_sfondo.save("spotted.png")
testo_da_inserire = "Ciao, mondo!"
sfondo_da_utilizzare = "background.png"
metti_testo_su_sfondo(testo_da_inserire, sfondo_da_utilizzare)

このコードを実行したところ、以下のエラーが発生しました。エラーの回避策をおしえて下さい。

    text_width, text_height = disegno.textsize(testo, font=font)
                              ^^^^^^^^^^^^^^^^
AttributeError: 'ImageDraw' object has no attribute 'textsize'

最新のGPT-4に質問した場合の回答

提供されたコードには、ImageDraw オブジェクトの textsize メソッドに関するエラーが発生しています。ImageDraw オブジェクトには textsize メソッドは存在しません。このメソッドは ImageFont オブジェクトに属しています。したがって、textsize メソッドを使用する際には、ImageFont オブジェクトを使う必要があります。

以下に、修正されたコードを示します。コメントを追加して、各行の機能を明確にしました。

from PIL import Image, ImageDraw, ImageFont  # PILモジュールをインポート

def metti_testo_su_sfondo(testo, sfondo, posizione=(10, 10), colore_testo=(0, 0, 0), dimensione_font=25):
    # 画像ファイルを開く
    immagine_sfondo = Image.open(sfondo)
    disegno = ImageDraw.Draw(immagine_sfondo)

    # フォントを設定
    font = ImageFont.truetype("/usr/share/fonts/truetype/ubuntu/Ubuntu-R.ttf", dimensione_font)

    # テキストのサイズを取得
    text_width, text_height = font.getsize(testo)  # フォントオブジェクトのgetsizeメソッドを使用する

    # テキストを**に配置するための座標を計算
    x = (immagine_sfondo.width - text_width) // 2
    y = (immagine_sfondo.height - text_height) // 2

    # テキストを画像に描画
    disegno.text((x, y), testo, fill=colore_testo, font=font)

    # 画像を保存
    immagine_sfondo.save("spotted.png")

# テキストと背景画像を設定
testo_da_inserire = "Ciao, mondo!"
sfondo_da_utilizzare = "background.png"

# 関数を実行
metti_testo_su_sfondo(testo_da_inserire, sfondo_da_utilizzare)

この修正により、ImageDraw オブジェクトの textsize メソッドのエラーを回避し、期待通りの動作を実現することができるはずです。また、フォントファイル /usr/share/fonts/truetype/ubuntu/Ubuntu-R.ttf が存在し、適切なパスに配置されていることを確認してください。

このように回答しました。 しかしこの回答は間違っています。 font.getsizeはPillow バージョン 10.0.0 で削除されています。ですのでコードを変更してもエラーが発生します。

このあと何度も質問しましたが、すべて間違った回答が返ってきました。

最新ドキュメントを知ってるPillowちゃん」に質問した場合の回答

はい、エラーの原因と回避策について説明しますね。

エラーメッセージは、ImageDraw オブジェクトの textsize メソッドが存在しないことを示しています。実は、Pillow バージョン 10.0.0 から ImageDraw.textsize()ImageDraw.multiline_textsize() メソッドは削除されています【8†source】。代わりに ImageDraw.textbbox() または ImageDraw.textlength() メソッドを使用することが推奨されています。

コードを修正するためには、ImageDraw.Draw.textsizeImageDraw.Draw.textbbox() に置き換える必要があります。このメソッドは、テキストの描画される境界ボックスを返します。この境界ボックスから、テキストの幅と高さを計算することができます。

以下は修正されたコードの例です:

# ... 以前のコード ...

# text_width, text_height = disegno.textsize(testo, font=font)
bbox = disegno.textbbox((0, 0), testo, font=font)
text_width, text_height = bbox[2] - bbox[0], bbox[3] - bbox[1]

# ... 続きのコード ...

この修正により、ImageDraw オブジェクトの textsize メソッドを呼び出す代わりに、textbbox を使用してテキストのサイズを取得します。これにより、エラーを回避し、期待通りの動作を実現できるはずです。

このような回答を得ましたのでコードを修正し実行したところ、エラーは回避され、期待通りの動作をすることができました。

  • background.png(背景画像)
  • spotted.png(生成された画像)

ドキュメントを取得する

アップロードするドキュメントは、PDFファイルである必要があります。 このPDFファイルは3つの工程を経て生成されます。

  1. Inspectorを用いてselectorを取得する
  2. 得られた複数のURlからPDFを生成する
  3. PDF Arrangerを用いて単一PDFに結合する

この工程に必要なアプリケーションを先にインストールします。

wkhtmltopdfをインストールする

# wkhtmltopdfをインストール
sudo apt install wkhtmltopdf -y

pdfarrangerをインストールする

pdfarranger公式ページ

Flathubsnapからインストールできます。

Inspectorを用いてselectorを取得する

Pillow (PIL Fork) 10.1.0 documentation

取得したセレクターを用いて、複数のURLを取得する

from urllib.parse import urljoin, urlparse
import requests
from bs4 import BeautifulSoup
def fetch_document_links(url, selector):
"""
指定されたURLとCSSセレクターを使用して、ドキュメントのリンクを取得する関数
Args:
url (str): ドキュメントの完全なURL
selector (str): CSSセレクター
Returns:
None
"""
# URLを解析して、ベースURLとドキュメントのパスを取得
parsed_url = urlparse(url)
base_url = f"{parsed_url.scheme}://{parsed_url.netloc}"
doc_path = parsed_url.path
# ページの内容を取得
response = requests.get(url)
html = response.text
# BeautifulSoupを使用してHTMLを解析
soup = BeautifulSoup(html, 'html.parser')
# 指定されたCSSセレクターを使用して要素を見つける
elements = soup.select(selector)
# 各要素の処理
for elem in elements:
links = elem.find_all('a')
for link in links:
# 相対リンクを絶対リンクに変換
absolute_url = urljoin(base_url, link.get('href'))
print(absolute_url)
def main():
"""
url、selectorを指定して下さい。
"""
# ドキュメントのURLとCSSセレクターを指定
url = 'https://pillow.readthedocs.io/en/stable/index.html'
selector = '#overview > div > ul'
# ドキュメントのリンクを取得する関数を呼び出す
fetch_document_links(url, selector)
# プログラムの実行
if __name__ == "__main__":
main()

得られた複数のURlからPDFを生成する

#!/bin/bash
urls=(
https://pillow.readthedocs.io/en/stable/installation.html
https://pillow.readthedocs.io/en/stable/installation.html#warnings
https://pillow.readthedocs.io/en/stable/installation.html#python-support
https://pillow.readthedocs.io/en/stable/installation.html#basic-installation
https://pillow.readthedocs.io/en/stable/installation.html#building-from-source
https://pillow.readthedocs.io/en/stable/installation.html#platform-support
https://pillow.readthedocs.io/en/stable/installation.html#old-versions
https://pillow.readthedocs.io/en/stable/handbook/index.html
https://pillow.readthedocs.io/en/stable/handbook/overview.html
https://pillow.readthedocs.io/en/stable/handbook/tutorial.html
https://pillow.readthedocs.io/en/stable/handbook/concepts.html
https://pillow.readthedocs.io/en/stable/handbook/appendices.html
https://pillow.readthedocs.io/en/stable/reference/index.html
https://pillow.readthedocs.io/en/stable/reference/Image.html
https://pillow.readthedocs.io/en/stable/reference/ImageChops.html
https://pillow.readthedocs.io/en/stable/reference/ImageCms.html
https://pillow.readthedocs.io/en/stable/reference/ImageColor.html
https://pillow.readthedocs.io/en/stable/reference/ImageDraw.html
https://pillow.readthedocs.io/en/stable/reference/ImageEnhance.html
https://pillow.readthedocs.io/en/stable/reference/ImageFile.html
https://pillow.readthedocs.io/en/stable/reference/ImageFilter.html
https://pillow.readthedocs.io/en/stable/reference/ImageFont.html
https://pillow.readthedocs.io/en/stable/reference/ImageGrab.html
https://pillow.readthedocs.io/en/stable/reference/ImageMath.html
https://pillow.readthedocs.io/en/stable/reference/ImageMorph.html
https://pillow.readthedocs.io/en/stable/reference/ImageOps.html
https://pillow.readthedocs.io/en/stable/reference/ImagePalette.html
https://pillow.readthedocs.io/en/stable/reference/ImagePath.html
https://pillow.readthedocs.io/en/stable/reference/ImageQt.html
https://pillow.readthedocs.io/en/stable/reference/ImageSequence.html
https://pillow.readthedocs.io/en/stable/reference/ImageShow.html
https://pillow.readthedocs.io/en/stable/reference/ImageStat.html
https://pillow.readthedocs.io/en/stable/reference/ImageTk.html
https://pillow.readthedocs.io/en/stable/reference/ImageWin.html
https://pillow.readthedocs.io/en/stable/reference/ExifTags.html
https://pillow.readthedocs.io/en/stable/reference/TiffTags.html
https://pillow.readthedocs.io/en/stable/reference/JpegPresets.html
https://pillow.readthedocs.io/en/stable/reference/PSDraw.html
https://pillow.readthedocs.io/en/stable/reference/PixelAccess.html
https://pillow.readthedocs.io/en/stable/reference/PyAccess.html
https://pillow.readthedocs.io/en/stable/reference/features.html
https://pillow.readthedocs.io/en/stable/PIL.html
https://pillow.readthedocs.io/en/stable/reference/plugins.html
https://pillow.readthedocs.io/en/stable/reference/internal_design.html
https://pillow.readthedocs.io/en/stable/porting.html
https://pillow.readthedocs.io/en/stable/about.html
https://pillow.readthedocs.io/en/stable/about.html#goals
https://pillow.readthedocs.io/en/stable/about.html#license
https://pillow.readthedocs.io/en/stable/about.html#why-a-fork
https://pillow.readthedocs.io/en/stable/about.html#what-about-pil
https://pillow.readthedocs.io/en/stable/releasenotes/index.html
https://pillow.readthedocs.io/en/stable/releasenotes/10.1.0.html
https://pillow.readthedocs.io/en/stable/releasenotes/10.0.1.html
https://pillow.readthedocs.io/en/stable/releasenotes/10.0.0.html
https://pillow.readthedocs.io/en/stable/releasenotes/9.5.0.html
https://pillow.readthedocs.io/en/stable/releasenotes/9.4.0.html
https://pillow.readthedocs.io/en/stable/releasenotes/9.3.0.html
https://pillow.readthedocs.io/en/stable/releasenotes/9.2.0.html
https://pillow.readthedocs.io/en/stable/releasenotes/9.1.1.html
https://pillow.readthedocs.io/en/stable/releasenotes/9.1.0.html
https://pillow.readthedocs.io/en/stable/releasenotes/9.0.1.html
https://pillow.readthedocs.io/en/stable/releasenotes/9.0.0.html
https://pillow.readthedocs.io/en/stable/releasenotes/8.4.0.html
https://pillow.readthedocs.io/en/stable/releasenotes/8.3.2.html
https://pillow.readthedocs.io/en/stable/releasenotes/8.3.1.html
https://pillow.readthedocs.io/en/stable/releasenotes/8.3.0.html
https://pillow.readthedocs.io/en/stable/releasenotes/8.2.0.html
https://pillow.readthedocs.io/en/stable/releasenotes/8.1.2.html
https://pillow.readthedocs.io/en/stable/releasenotes/8.1.1.html
https://pillow.readthedocs.io/en/stable/releasenotes/8.1.0.html
https://pillow.readthedocs.io/en/stable/releasenotes/8.0.1.html
https://pillow.readthedocs.io/en/stable/releasenotes/8.0.0.html
https://pillow.readthedocs.io/en/stable/releasenotes/7.2.0.html
https://pillow.readthedocs.io/en/stable/releasenotes/7.1.2.html
https://pillow.readthedocs.io/en/stable/releasenotes/7.1.1.html
https://pillow.readthedocs.io/en/stable/releasenotes/7.1.0.html
https://pillow.readthedocs.io/en/stable/releasenotes/7.0.0.html
https://pillow.readthedocs.io/en/stable/releasenotes/versioning.html
https://pillow.readthedocs.io/en/stable/deprecations.html
)
# 配列の各要素に対してループ
for (( i=0; i<${#urls[@]}; i++ )); do
# 出力ファイル名に連番を使用
output_file=$(printf "%02d_output.pdf" $((i+1)))
# wkhtmltopdf コマンドを実行
wkhtmltopdf "${urls[i]}" "$output_file"
done
echo "PDF変換完了"

pdfarrangerを用いて単一PDFに結合する

全部で273ページ、8.3MBのPDFが生成されました。 GPTsでは、一度に100MBまでのファイルをアップロード可能です。

これで、「最新ドキュメントを知ってるPillowちゃん」が完成しました。

おわりに

この記事では、WEBドキュメントを利用してMy GPTsを作成する方法を解説しました。このプロセスは、最新のドキュメントや情報をモデルに学習させ、より正確で現実的な回答を得るための効果的な手段です。

作成した「最新ドキュメントを知ってるPillowちゃん」は、Pillowライブラリの最新情報を反映しており、古いメソッドや非推奨の機能に関する誤った提案を避けることができます。通常のGPT-4では、誤った提案が繰り返されてしまうので、My GPTsの提供はそれを回避する方法が提供された、と思えます。

この方法の鍵は、WEB上のドキュメントをPDF化してGPTに取り込むことにあります。この記事で紹介したツールと手順を使えば、誰でも自分の必要とする分野のMy GPTsを作成できるようになります。

以上です。ありがとうございました。

About


Languages

Language:Shell 77.3%Language:Python 22.7%