Discourse AIにおけるPDF対応

:bookmark: このガイドでは、基本的なテキスト抽出とLLM支援による高度な処理の両方を含む、discourse-ai内でPDF処理機能を実装および使用する方法について説明します。

:person_raising_hand: 必要なユーザーレベル: 管理者

まとめ

discourse-aiプラグインは、RAG(Retrieval-Augmented Generation)のために、2つの異なるモードでPDF処理をサポートしています。

  1. 基本的なテキスト抽出
  2. LLM分析による高度な処理

基本的なテキスト抽出

このモードは、基本的なPDF処理機能を提供します。

  • pdf-reader gemを使用してテキストコンテンツを抽出します。
  • 最大100MBのファイルをサポートします。
  • プラグインインストール後すぐに機能します。
  • テキストのみのコンテンツを処理します(視覚要素は無視されます)。

LLM改善による高度な処理

:information_source: このモードは、特定の構成が必要であり、より高度な機能を提供します。

要件:

  • EnterpriseプランのサブスクリプションまたはセルフホストのDiscourse
  • コンテナにGhostscriptサポート付きのImageMagickがインストールされていること
  • ai_rag_images_enabled サイト設定が有効になっていること

機能:

  • 画像、グラフ、図を解釈します。
  • 視覚要素からコンテキストを提供します。
  • PDFをページごとに処理します。
  • 100MBのファイルサイズ制限を維持します。

実装の詳細

処理仕様

  • ページ処理解像度: 300 DPI
  • 最大処理時間: 600秒(10分)
  • 一時ファイルの自動クリーンアップ
  • RAGドキュメント埋め込みとの完全な統合

処理ワークフロー

  1. PDFのアップロードと検証
  2. コンテンツ抽出(基本または高度なモード)
  3. 設定可能なオーバーラップによるテキストチャンキング
  4. チャンクの埋め込みと保存
  5. MessageBusによる進捗追跡

制限事項

:warning: PDF処理を実装する際は、これらの制約に注意してください。

  • ファイルサイズ制限:
    • 既存のPDF処理では100MB
    • 新しい管理インターフェイスのアップロードでは20MB
  • 高度なモードでは追加のシステムリソースが必要です。
  • 複雑なPDFレイアウトは完全に解釈されない場合があります。
  • 高度な処理は処理時間を大幅に増加させます。
「いいね!」 11

これは本当に素晴らしいニュースです。チームに感謝!強化処理が完了するのを待ちきれません。それはLLMsの論文研究にとって非常に重要になるでしょう。

また、PDFをアップロードしてAIボットのプライベートメッセージやトピック/投稿で言及しながらRAG "チャット・ウィズ・ユア・PDFs"を行うことを許可する計画はありますか?

「いいね!」 1

@sam この素晴らしい選択肢を説明するためのシンプルなビデオを提供できますか?あなたが言及した内容が十分に明確でないため、実装が難しいです。

この設定はどこで見つけられますか

これは隠し設定で、コンソールを使用する必要がありますが、コンテナも構成する必要があります。数週間待つことをお勧めします。

「いいね!」 3

ありがとうございます。素晴らしい仕事に感謝します。

私のウェブサイト(アラビア語フォーラム)で、最初の投稿「トピック」に法律を追加し、AIを使用して質問しましたが、回答が不正確でした。これはコンテキストラギングではないためだと思います。

申し訳ありませんが、その仕組みではありません。ペルソナまたはツールを定義してから、そこにアップロードを追加する必要があります。

「アップロードと質問」のサポートについては、ここでいくつかの議論がありました:Upload and discuss pdfs in composer が、まだサポートされていません。

「いいね!」 1

まず、素晴らしい仕事をしていただき、本当にありがとうございます。とても気に入っています。

設定を色々試して、AIモデルをGemini-Flash-2.0に変更したところ、うまく動作しました。私の状況は以下の通りです。

私たちは監査法人、会計士、税理士のコミュニティであり、関連法規を共有し、それらについての議論を促すツールが必要でした。私たちはこの分野の専門家なので、この議論は訪問者にとって非常に役立つはずです。私たちは、AIモデルに法規をチェック・分析させ、私たちの質問に答えることを目標としています。この素晴らしい実験の結果、最初の投稿に追加されたコンテキストについて議論できること、そしてAIモデルが十分に賢ければ、非常に質の高いアウトプットで私たちの質問に答えてくれることがわかりました。

改めて感謝いたします。PDFサポートがDiscourseを最高のフォーラムソフトウェアにするのを楽しみにしています。

「いいね!」 3

最新のDiscourseイメージは、テストしたい場合に高度なモードをサポートしています

「いいね!」 2

コンソール経由で有効にする必要がありますか?UIからは高度なモードのオプションが見つかりません。

さらに、このPDFをアップロードしようとするとエラーが発生します。サイズは34MBですが、最大添付ファイルサイズは100MBに設定しています(管理者設定とapp.ymlの両方)。奇妙なのは、圧縮版は16MBで正常にアップロードできることです。しかし、おそらく大きなPDFは現時点では複雑すぎるのでしょうか?画像や数式などがたくさん含まれています。

はい、それを有効にするには、RailsコンソールでSiteSetting.ai_rag_images_enabled = trueを入力する必要があります。

「いいね!」 1

ここでの私の推測では、コンテナ内のnginxの設定も変更する必要があるため、拒否されなくなるということです。

「いいね!」 1

こんにちは @sam

PDF のアップロードとインデックス作成に問題が発生しています。エラーは次のとおりです。Job exception: undefined method `length’ for nil.

このエラーは、前述の設定に関連しているのでしょうか。
インターフェースはインデックス作成 0% でスタックし、進みません。
例外の詳細は以下のとおりです。

/var/www/discourse/plugins/discourse-ai/app/jobs/regular/digest_rag_upload.rb:81:in `chunk_document'
/var/www/discourse/plugins/discourse-ai/app/jobs/regular/digest_rag_upload.rb:40:in `block in execute'
activerecord-7.2.2.1/lib/active_record/connection_adapters/abstract/transaction.rb:616:in `block in within_new_transaction'
activesupport-7.2.2.1/lib/active_support/concurrency/null_lock.rb:9:in `synchronize'
activerecord-7.2.2.1/lib/active_record/connection_adapters/abstract/transaction.rb:613:in `within_new_transaction'
activerecord-7.2.2.1/lib/active_record/connection_adapters/abstract/database_statements.rb:361:in `transaction'
activerecord-7.2.2.1/lib/active_record/transactions.rb:234:in `block in transaction'
activerecord-7.2.2.1/lib/active_record/connection_adapters/abstract/connection_pool.rb:415:in `with_connection'
activerecord-7.2.2.1/lib/active_record/connection_handling.rb:296:in `with_connection'
activerecord-7.2.2.1/lib/active_record/transactions.rb:233:in `transaction'
/var/www/discourse/plugins/discourse-ai/app/jobs/regular/digest_rag_upload.rb:39:in `execute'
/var/www/discourse/app/jobs/base.rb:316:in `block (2 levels) in perform'
rails_multisite-6.1.0/lib/rails_multisite/connection_management/null_instance.rb:49:in `with_connection'
rails_multisite-6.1.0/lib/rails_multisite/connection_management.rb:21:in `with_connection'
/var/www/discourse/app/jobs/base.rb:303:in `block in perform'
/var/www/discourse/app/jobs/base.rb:299:in `each'
/var/www/discourse/app/jobs/base.rb:299:in `perform'
sidekiq-7.3.9/lib/sidekiq/processor.rb:220:in `execute_job'
sidekiq-7.3.9/lib/sidekiq/processor.rb:185:in `block (4 levels) in process'
sidekiq-7.3.9/lib/sidekiq/middleware/chain.rb:180:in `traverse'
sidekiq-7.3.9/lib/sidekiq/middleware/chain.rb:183:in `block in traverse'
/var/www/discourse/lib/sidekiq/pausable.rb:132:in `call'
sidekiq-7.3.9/lib/sidekiq/middleware/chain.rb:182:in `traverse'
sidekiq-7.3.9/lib/sidekiq/middleware/chain.rb:183:in `block in traverse'
sidekiq-7.3.9/lib/sidekiq/job/interrupt_handler.rb:9:in `call'
sidekiq-7.3.9/lib/sidekiq/middleware/chain.rb:182:in `traverse'
sidekiq-7.3.9/lib/sidekiq/middleware/chain.rb:183:in `block in traverse'
sidekiq-7.3.9/lib/sidekiq/metrics/tracking.rb:26:in `track'
sidekiq-7.3.9/lib/sidekiq/metrics/tracking.rb:134:in `call'
sidekiq-7.3.9/lib/sidekiq/middleware/chain.rb:182:in `traverse'
sidekiq-7.3.9/lib/sidekiq/middleware/chain.rb:173:in `invoke'
sidekiq-7.3.9/lib/sidekiq/processor.rb:184:in `block (3 levels) in process'
sidekiq-7.3.9/lib/sidekiq/processor.rb:145:in `block (6 levels) in dispatch'
sidekiq-7.3.9/lib/sidekiq/job_retry.rb:118:in `local'
sidekiq-7.3.9/lib/sidekiq/processor.rb:144:in `block (5 levels) in dispatch'
sidekiq-7.3.9/lib/sidekiq/config.rb:39:in `block in <class:Config>'
sidekiq-7.3.9/lib/sidekiq/processor.rb:139:in `block (4 levels) in dispatch'
sidekiq-7.3.9/lib/sidekiq/processor.rb:281:in `stats'
sidekiq-7.3.9/lib/sidekiq/processor.rb:134:in `block (3 levels) in dispatch'
sidekiq-7.3.9/lib/sidekiq/job_logger.rb:15:in `call'
sidekiq-7.3.9/lib/sidekiq/processor.rb:133:in `block (2 levels) in dispatch'
sidekiq-7.3.9/lib/sidekiq/job_retry.rb:85:in `global'
sidekiq-7.3.9/lib/sidekiq/processor.rb:132:in `block in dispatch'
sidekiq-7.3.9/lib/sidekiq/job_logger.rb:40:in `prepare'
sidekiq-7.3.9/lib/sidekiq/processor.rb:131:in `dispatch'
sidekiq-7.3.9/lib/sidekiq/processor.rb:183:in `block (2 levels) in process'
sidekiq-7.3.9/lib/sidekiq/processor.rb:182:in `handle_interrupt'
sidekiq-7.3.9/lib/sidekiq/processor.rb:182:in `block in process'
sidekiq-7.3.9/lib/sidekiq/processor.rb:181:in `handle_interrupt'
sidekiq-7.3.9/lib/sidekiq/processor.rb:181:in `process'
sidekiq-7.3.9/lib/sidekiq/processor.rb:86:in `process_one'
sidekiq-7.3.9/lib/sidekiq/processor.rb:76:in `run'
sidekiq-7.3.9/lib/sidekiq/component.rb:10:in `watchdog'
sidekiq-7.3.9/lib/sidekiq/component.rb:19:in `block in safe_thread'
「いいね!」 1

この素晴らしいアップデートありがとうございます。
ただ、一点気になるのですが、各Persona AIボットのための100MBの制限は、個々のボットに適用されるのですか、それともすべてのPersonaに適用されるのですか?

Discourse AI は初めてですが、一般的な Discourse は使い慣れています。

現時点ではデモ形式で、特定のユースケースでこれを試してみたいと考えています。

非表示のサイト設定を有効にしました。

SideKiq には何も表示されません。実際に機能しているかどうかを確認するにはどうすればよいですか?

これがプレリリース機能であり、まだ本番環境で使用できる状態ではないことは承知していますが、体験して試すことができれば素晴らしいと思います。

これを試している方からのヒント、コツ、スクリーンショット、またはレシピがあれば、ぜひ教えてください。

サイト上のPDFの内容を要約するようにボットに依頼したときに、このエラーが発生します。拡張処理を有効にしておらず、GPT 4.1を使用しています。何か間違っている点はありますか?

申し訳ありませんが、システムが予期せぬ問題に遭遇したため、返信できませんでした。

エラー詳細

{
“error”: {
“message”: “‘tool_calls’ を持つアシスタントメッセージの後には、各 ‘tool_call_id’ に応答するツールメッセージが続く必要があります。以下の tool_call_ids には応答メッセージがありませんでした: call_nrDCba5mt83oavbXfPq2BtEV”,
“type”: “invalid_request_error”,
“param”: “messages.[2].role”,
“code”: null
}
}”}

PDFサポートの現在の状況についてお伺いしてもよろしいでしょうか?:face_with_peeking_eye:

「いいね!」 1

app.ymlでアップロードサイズを設定すると、サイト全体に適用されるため、各ペルソナに適用されます。

「いいね!」 1

この件に関して何か進展はありますか?AIとの会話を開始する際にPDFを添付していますが、まだ認識されていないようです。現在GPTを利用しています。PDF処理専用に設計された別のモデルを使用することを検討すべきでしょうか?

「いいね!」 1