🤖 Action Perfect Get On Go

🌟 概要: 完璧な情報取得とAI構造化
Action Perfect Get On Go は、複数のウェブページから本文を並列で高速に取得し、その結合されたテキストを LLM(大規模言語モデル) のマルチステップ処理によって情報欠落なく重複排除、重要な情報を保持したまま、情報密度の高い簡潔な文章に論理的に構造化する、高い保守性と堅牢性を備えたコマンドラインツールです。
このツールは、初期の並列処理での負荷や一時的なネットワークエラーに耐えるための堅牢なリトライ・遅延メカニズムを備えており、明確に分離されたDIパイプライン設計により、高い保守性を実現しています。
🛠️ 主な機能と堅牢性
- 堅牢なWebスクレイピングと並列数制御:
- 複数のURLからの本文抽出をGoルーチンで同時に実行します。(最大並列数はCLIオプションで制御されます。デフォルトは10)
- 並列処理にはセマフォ機構を採用し、実行スロットの上限を厳密に管理することで、対象サーバーへの過負荷を防止し、アプリケーションのリソース消費を最適化します。
- 個々のGoroutineは、依存性注入されたカスタムHTTPクライアントのタイムアウトとリトライロジックによって堅牢に制御されます。
- 並列処理後の固定遅延(
initialScrapeDelay)と、抽出失敗時の固定遅延(retryScrapeDelay)後の順次リトライ(1回)ロジックにより、サーバー負荷を軽減しつつ取得成功率を最大化します。
- LLMマルチステップ処理 (MapReduce型) の堅牢な実行:
- 巨大な結合テキストをセグメントに分割。
- 各セグメントを並列でLLM処理し、中間要約(Map)を作成。
- LLM処理の並列実行とレートリミット管理は、
LLMExecutorインターフェースにカプセル化されています。
- 中間要約を統合し、最終的な重複排除と論理構造化を実行します。この際、各主要セクション(
##)の直後に、そのセクションの情報を構成した参照元URLリストを付与し、情報源の透明性を確保します。
- AI駆動のデータクリーンアップと構造化: 結合されたテキストから重複コンテンツやノイズ(フッター、ナビゲーションなど)を排除し、情報構造を再構築します。処理指示は日本語で行われます。(内部で
go-ai-client を利用)
- 柔軟な設定: 各フェーズでタイムアウトを設定可能にし、LLM APIキーを環境変数またはCLIオプションで柔軟に設定できます。
- 内部設計の最適化:
- DIベースの明確なパイプライン構造: アプリケーションの処理フロー全体を、「URL生成」「コンテンツ取得」「AIクリーンアップ・出力」の3つの独立したステージに分割し、依存性注入 (DI) によって結合するパイプライン設計を採用。これにより、各ステージのモック化、テスト容易性、および保守性を最大限に高めています。
- プロンプト定義を外部ファイル(
.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)への通信を管理し、自動リトライ機能を提供します。 |
| プロンプト |
text/template, embed |
プロンプトを外部ファイル化し、テンプレートパースのコストを抑えた効率的なプロンプト生成ロジックを実現します。 |
| 並列処理 |
sync.WaitGroup / Goルーチン |
複数のURLへのアクセスを同時に高速で実行します。 |
| 設計パターン |
依存性注入 (DI) / パイプライン |
スクラップロジックの依存性を外部から注入し、処理フロー全体を構造化することで、モック化と保守性を向上させています。 |
🛠️ 事前準備と設定
1. ビルド
# リポジトリをクローン
git clone git@github.com:your-repo-path/action-perfect-get-on-go.git
cd action-perfect-get-on-go
# 依存関係をダウンロード
go mod tidy
# 実行ファイルを bin/ ディレクトリに生成
go build -o bin/llm_cleaner ./cmd
実行ファイルは ./bin/llm_cleaner に生成されます。
2. LLM API キーの設定 (必須)
LLM(Gemini)を利用するためには、APIキーが必要です。設定は以下のどちらかの方法で行います。
- 推奨: コマンド実行時に
-k または --api-key フラグで直接指定する。
- 代替: 環境変数
GEMINI_API_KEY を設定する。
注意: コマンドラインフラグでキーを指定した場合、環境変数の設定よりも常に優先されます。
# 例: 環境変数に設定する場合
export GEMINI_API_KEY="YOUR_GEMINI_API_KEY"
🚀 使い方 (Usage)
本ツールは、処理対象のURLを記載したファイルを読み込む形式のみをサポートします。
実行コマンド形式とオプション
| オプション |
フラグ |
説明 |
デフォルト値 |
--api-key |
-k |
Gemini APIキーを直接指定します(推奨)。 |
なし |
--url-file |
-f |
処理対象のURLリストを記載したファイルパスを指定します。ファイル内ではURLを改行区切りで記述します。 (必須) |
なし |
--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を直接引数として渡す形式はサポートされていません。
# 最小実行形式 (環境変数にAPIキーが設定されている場合)
./bin/llm_cleaner run -f ./urls.txt
# 推奨実行形式 (APIキーとカスタムタイムアウト、並列数を指定)
./bin/llm_cleaner run -k "YOUR_API_KEY" -f ./urls.txt -s 30s -t 3m -p 5
# 並列数をデフォルトの10のまま実行する場合
./bin/llm_cleaner run -k "YOUR_API_KEY" -f ./urls.txt
🗃️ 処理の流れ (Pipeline Flow)
本ツールは、依存性注入(DI)で結合された3つの主要なパイプラインステージを順に実行します。
1. 外部パイプラインステージ
| ステージ |
担当コンポーネント |
役割 |
| Stage 1: URL生成 |
pipeline.URLGenerator |
URLリストファイルを読み込み、処理対象のURLを抽出する。 |
| Stage 2: コンテンツ取得 |
pipeline.ContentFetcher |
並列スクレイピングと堅牢なリトライを実行し、本文コンテンツを抽出する。 |
| Stage 3: AIクリーンアップ・出力 |
pipeline.LLMOutputGenerator |
抽出コンテンツを結合し、MapReduce処理(cleaner.Cleaner)を実行して最終結果を出力する。 |
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形式)が、
log/slogと共にファイルまたは標準出力に出力される。
📜 ライセンス (License)
このプロジェクトは MIT License の下で公開されています。