🤖 Action Perfect Get On Go

🌟 概要: 完璧な情報取得とAI構造化
Action Perfect Get On Go は、複数のウェブページから本文を並列で高速に取得し、その結合されたテキストを LLM(大規模言語モデル) のマルチステップ処理によって情報欠落なく重複排除、重要な情報を保持したまま、情報密度の高い簡潔な文章に論理的に構造化する、高い保守性と堅牢性を備えたコマンドラインツールです。
このツールは、ローカルファイルパスに加えて、Google Cloud Storage (GCS) バケット内のファイルからでも、処理対象のURLリストを透過的に読み込むことができます。また、最終的な構造化結果は、自動的に完全なHTMLドキュメントに変換され、ローカルファイルパスまたは GCS URI (gs://...) を出力先として、柔軟に書き出すことが可能です。初期からの並列処理での負荷や一時的なネットワークエラーに耐えるための堅牢なリトライ・遅延メカニズムを備えており、明確に分離されたDIパイプライン設計により、高い保守性を実現しています。
🛠️ 主な機能と堅牢性
- 堅牢なWebスクレイピングと並列数制御:
- 複数のURLからの本文抽出をGoルーチンで同時に実行します。(最大並列数はCLIオプションで制御されます。デフォルトは10)
- 並列処理にはセマフォ機構を採用し、実行スロットの上限を厳密に管理することで、対象サーバーへの過負荷を防止し、アプリケーションのリソース消費を最適化します。
- 個々のGoroutineは、依存性注入されたカスタムHTTPクライアントのタイムアウトとリトライロジックによって堅牢に制御されます。
- Webスクレイピングとリトライ戦略は、
runner.ReliableScraperという独立したコンポーネントにカプセル化され、DIパイプラインのContentFetcherに注入されます。これにより、堅牢性ロジックのテスト容易性と交換性が向上しました。
- LLMマルチステップ処理 (MapReduce型) の堅牢な実行:
- 巨大な結合テキストをセグメントに分割。
- 各セグメントを並列でLLM処理し、中間要約(Map)を作成。
- LLM処理の並列実行とレートリミット管理は、
LLMExecutorインターフェースにカプセル化されています。
- 中間要約を統合し、最終的な重複排除と論理構造化を実行します。この際、各主要セクション(
##)の直後に、そのセクションの情報を構成した参照元URLリストを付与し、情報源の透明性を確保します。
- AI駆動のデータクリーンアップと構造化: 結合されたテキストから重複コンテンツやノイズ(フッター、ナビゲーションなど)を排除し、情報構造を再構築します。処理指示は日本語で行われます。(内部で
go-ai-client を利用)
- 堅牢なデータ入力層 (GCSサポート):
- Go SDKを利用してGCSパス (
gs://...) を検知し、Cloud Run Jobやローカル環境で認証情報(ADC)を用いてセキュアかつ確実にファイルを読み込みます。
- 入力ファイルの読み込みロジックは、
pipeline.InputReaderインターフェース(go-remote-ioパッケージの抽象化を利用)によって抽象化されます。GCSとローカルファイルの読み込みは、依存性注入された外部コンポーネントが透過的に担います。これにより、I/O責務がpipelineパッケージから完全に分離されています。
- 堅牢なデータ出力層 (GCSサポート):
- 出力パスの柔軟性:
--output フラグにローカルパスまたはGCS URI (gs://bucket/object) を指定することで、出力先を透過的に切り替えられます。
- 排他的な出力制御: GCS URIが指定された場合、ローカルファイルへの書き込みや標準出力へのプレビューは自動的にスキップされ、GCSへの出力のみが実行されます。
- GCSへの出力には、
pipeline.Writerインターフェース(go-remote-ioパッケージの抽象化) の実装が使用されます。GCS URIのパースロジックも外部ユーティリティに委譲されており、認証は入力層と同様にアプリケーションのデフォルト認証情報 (ADC) に依存します。
- 柔軟な設定: 各フェーズでタイムアウトを設定可能にし、LLM APIキーを環境変数またはCLIオプションで柔軟に設定できます。
- 内部設計の最適化:
- DIベースの明確なパイプライン構造: アプリケーションは「URL生成」「コンテンツ取得」「AIクリーンアップ・出力」の3つの独立したステージに分割され、DIによって結合されます。特に「コンテンツ取得」ステージには、リトライ戦略を責務とする独立した
ScraperRunner実装が注入され、パイプラインの各コンポーネントが単一の責務を持つように設計されています。
- プロンプト定義を外部ファイル(
.md)に分離し、Goのembedパッケージでバイナリに組み込むことで、デプロイの堅牢性を確保。
- LLMプロンプトの生成にビルダーパターンを採用し、テンプレートパースのコストを削減するため再利用可能なインスタンスとして管理しています。
- CLIオプションを構造体に集約することで、グローバル変数への依存を減らし、コードの堅牢性を高めています。I/O処理は
log/slog による構造化ロギングに移行し、ファイル書き込み時のディレクトリ自動作成と堅牢なファイル上書きロジックを追加しました。
✨ 技術スタック
| 要素 |
技術 / ライブラリ |
役割 |
| 言語 |
Go (Golang) |
ツールの開発言語。並列処理と堅牢な実行環境を提供します。 |
| CLI |
Cobra |
コマンドライン引数とオプションの解析に使用します。 |
| Web抽出 |
github.com/shouni/go-web-exact |
任意のウェブページからメインの本文コンテンツを正確に抽出します。 |
| AI通信 |
github.com/shouni/go-ai-client |
LLM(Gemini)への通信を管理し、自動リトライ機能を提供します。 |
| I/O, GCS |
github.com/shouni/go-remote-io) |
ローカルファイルとGCSへの透過的な入出力を抽象化し、パイプラインのI/O責務を分離します。 |
| HTML変換 |
github.com/shouni/go-text-format) |
LLMが出力したMarkdownを完全なHTMLドキュメントに変換・レンダリングします。 |
| プロンプト |
text/template, embed |
プロンプトを外部ファイル化し、テンプレートパースのコストを抑えた効率的なプロンプト生成ロジックを実現します。 |
| 並列処理 |
sync.WaitGroup / Goルーチン |
複数のURLへのアクセス、およびLLMマルチステップ処理における中間要約の生成 (Mapフェーズ) を並列で高速に実行します。 |
| 設計パターン |
依存性注入 (DI) / パイプライン / ビルダーパターン |
処理フロー全体を構造化し、モック化と保守性を向上させます。I/Oとクライアントの構築は、外部のfactoryパッケージに委譲され、internal/builderは注入の調整役のみを担います。 |
🗃️ 処理の流れ (Pipeline Flow)
本ツールは、依存性注入(DI)で結合された3つの主要なパイプラインステージを順に実行します。
1. 外部パイプラインステージ
| ステージ |
担当コンポーネント |
役割 |
| Stage 1: URL生成 |
pipeline.URLGenerator |
依存性注入された pipeline.InputReader を使用し、GCS URIまたはローカルファイルからURLリストを読み込み、処理対象のURLを抽出する。 |
| Stage 2: コンテンツ取得 |
pipeline.ContentFetcher |
並列スクレイピングと堅牢なリトライを実行し、本文コンテンツを抽出する。 |
| Stage 3: AIクリーンアップ・出力 |
pipeline.LLMOutputGenerator |
抽出コンテンツを結合し、MapReduce処理(cleaner.Cleaner)を実行して最終結果をHTMLドキュメントとして柔軟に出力する。 |
2. Stage 3 内部 (LLM MapReduceフロー)
Stage 3(AIクリーンアップ)の処理は、cleaner.Cleanerが以下の詳細なMapReduceフローを実行することで行われます。
- コンテンツ結合と分割: 成功したすべての抽出コンテンツを結合し、LLMのトークン制限(
MaxSegmentChars)に従って安全なチャンク(Segment)に分割する。
- Mapフェーズ (並列実行):
- 各チャンクは、
LLMExecutor の並列セマフォとレートリミッターの制御下でLLM(Gemini-2.5-Flash)に並列で送られる。
- LLMは各チャンクに対して「中間要約」を生成する。
- Reduceフェーズ (単一実行):
- すべての中間要約を統合し、LLMに送り、最終的な重複排除、論理的な構造化を実行する。
- 結果の付与: この際、統合に用いられた各ソースURLが、関連する主要セクション(
##)の直下にリストとして挿入される。
- 出力: LLMが構造化した最終的なテキスト(Markdown形式)が、
go-text-formatによって完全なHTMLドキュメントに変換された後、--outputで指定されたパス(ローカルまたはGCS) に書き込まれる。
🛠️ 事前準備と設定
1. ビルド
# リポジトリをクローン
git clone git@github.com:your-repo-path/action-perfect-get-on-go.git
cd action-perfect-get-on-go
# 依存関係をダウンロード (GCS SDKを含む)
go mod tidy
# 実行ファイルを bin/ ディレクトリに生成 (カレントディレクトリの main パッケージを使用)
go build -o bin/llm_cleaner .
実行ファイルは ./bin/llm_cleaner に生成されます。
2. LLM API キーの設定 (必須)
LLM(Gemini)を利用するためには、APIキーが必要です。設定は以下のどちらかの方法で行います。
- 推奨: コマンド実行時に
-k または --api-key フラグで直接指定する。
- 代替: 環境変数
GEMINI_API_KEY を設定する。
注意: コマンドラインフラグでキーを指定した場合、環境変数の設定よりも常に優先されます。
# 例: 環境変数に設定する場合
export GEMINI_API_KEY="YOUR_GEMINI_API_KEY"
3. GCSからの読み込み/書き込み設定 (クラウド/ローカル)
GCSバケットからファイルを読み込む、またはGCSバケットへファイルを書き込む場合(-f gs://... または -o gs://...)、プログラムはアプリケーションのデフォルト認証情報 (ADC) を使用して認証を行います。
- Cloud Run Job: Jobに割り当てられたサービスアカウントに、GCSバケットに対する適切なロール(読み込みには
Storage オブジェクト閲覧者、書き込みには Storage オブジェクト作成者 や Storage オブジェクト管理者 など)を付与する必要があります。
- ローカルPC: 以下のコマンドを実行し、ローカル環境に認証情報を設定する必要があります。
gcloud auth application-default login
🚀 使い方 (Usage)
本ツールは、処理対象のURLを記載したファイルを読み込む形式のみをサポートします。
実行コマンド形式とオプション
| オプション |
フラグ |
説明 |
デフォルト値 |
--api-key |
-k |
Gemini APIキーを直接指定します(推奨)。 |
なし |
--url-file |
-f |
処理対象のURLリストを記載したファイルパスを指定します。ローカルパスまたはGCS URI (gs://...) を指定できます。 (必須) |
なし |
--output |
-o |
最終的な構造化結果の出力先パスを指定します。ローカルパスまたはGCS URI (gs://...) を指定できます。GCS URIを指定した場合、ローカルへの出力はスキップされます。 |
標準出力 |
--llm-timeout |
-t |
LLM処理全体のタイムアウト時間。 |
5m0s (5分) |
--scraper-timeout |
-s |
Webスクレイピング(HTTPアクセス)のタイムアウト時間。 |
15s (15秒) |
--parallel |
-p |
Webスクレイピングの最大同時並列リクエスト数。 |
10 |
1. URLファイル (urls.txt の例) の作成
ファイル内に、1行に1つずつ処理したいURLを記述します。
# ファイル名: urls.txt
https://example.com/page-a
https://example.com/page-b
https://example.com/page-c/specification
2. 実行コマンド形式
処理を実行するには、必ず run サブコマンドと --url-file または -f フラグを使用して有効なファイルパスを指定する必要があります。URLを直接引数として渡す形式はサポートされていません。
# 最小実行形式 (ローカルファイルから読み込み、結果は標準出力)
# 標準出力へはMarkdown形式のプレビューが出力されます。
./bin/llm_cleaner run -f ./urls.txt
# 推奨実行形式 (APIキー、カスタムタイムアウト、ローカルファイルに出力)
# 出力ファイルは完全なHTMLドキュメント (output.html) となります。
./bin/llm_cleaner run -k "YOUR_API_KEY" -f ./urls.txt -s 30s -t 3m -p 5 -o ./output/summary.html
# クラウド運用向け実行形式 (GCSバケットから読み込み、GCSバケットへ書き出し)
# JobサービスアカウントにGCS読み書き権限が必要です。
./bin/llm_cleaner run -k "YOUR_API_KEY" \
-f "gs://my-project/input/urls.txt" \
-o "gs://my-project/output/summary.html"
📜 ライセンス (License)
このプロジェクトは MIT License の下で公開されています。