LiteParseを使用した財務デューデリジェンスエージェントの構築方法
本記事では、SEC提出書類を取り込み、それらを検索し、正確な引用とともに質問に回答するAIエージェントのデモアプリを紹介します。重要な要素はLiteParseで、テキストとそのバウンディングボックス座標を抽出します。このプロジェクトではベクターデータベースの代わりに単純なキーワード検索を使用し、SEC EDGARと統合して直接書類を取得します。
財務デューデリジェンスは、金融業界で最もドキュメント集約型のワークフローの1つです。アナリストは手作業によるデータ抽出に最大70%の時間を費やしており、PDFをスプレッドシートに書き写したり、GL勘定をマッピングしたり、試算表を調整したりしています。1つの取引で数百ページのSEC提出書類が関係することもあり、すべての数値には出典が必要です。
本記事で紹介するデモアプリは、この問題に取り組みます。SEC提出書類を取り込み、それらを横断的に検索し、元のPDFページ上の正確なソーステキストをハイライトする正確な引用とともに質問に回答するAIエージェントです。重要な要素はLiteParseで、PDFからテキストとともにバウンディングボックス座標を抽出します。このデータを使用することで、アプリは数値がどこから取得されたかを視覚的にハイライトし、エージェントの回答に信頼性と透明性を追加します。
アーキテクチャ
このアプリはNext.jsプロジェクトで、3つの層で構成されています。Next.jsのチャットUIとPDF引用ビューア、チャット、ドキュメント取り込み、SEC EDGAR統合、引用解決のためのAPIルート、そしてコアライブラリ(PDF解析のingest.ts、検索機能付きドキュメントストアのstore.ts、エージェントツール定義のtools.ts)です。ライブラリコードは合計約600行です。ベクターデータベース、埋め込みパイプライン、またはLLM APIキー以外の外部インフラは使用していません。このシンプルさにより、プロジェクトは理解しやすく拡張しやすく、LiteParseのコアな使い方を示しています。
ステップ1:LiteParseを使用したPDFの解析
LiteParseを使用した取り込みは簡単です。PDFファイルのパス(またはファイルバッファ)を入力すると、構造化データが返されます。すべてのテキストと、各テキストのバウンディングボックス座標(x、y、幅、高さ)、フォント名、フォントサイズが含まれます。典型的な10-K提出書類(70〜100ページ以上)は数秒で解析されます。
ステップ2:シンプルなドキュメントストア
解析されたドキュメントはフラットなJSONファイルとして保存されます。検索にはベクター類似度ではなくキーワードマッチングを使用します。クエリを単語に分割し、各ページが含む単語数でスコアリングします。また、エージェントがより正確なパターンマッチングを必要とする場合(例えば、ドル金額を見つけるため)の正規表現モードもあります。著者は、このアプリで作業するドキュメントのセットは通常小規模(1〜100ファイル)であり、エージェントに公開されるツールで十分に関連情報を見つけられるため、ベクター検索は不要だと述べています。10-KなどのファイルはLLMのトレーニングデータに多く含まれているため、キーワードと構造に関する既存知識を活用できます。
ステップ3:エージェントへのツール提供
Vercel AI SDKを介して、エージェントに3つのツールが提供されます。list_document(ドキュメント一覧)、search_documents(クエリ、ファイルグロブ、最大結果数、正規表現使用の有無を指定)、get_page(ファイル名とページ番号でページテキストを取得)です。search_documentsのfile_globパラメータにより、エージェントは特定のドキュメント(例:*2024*)に検索を絞り込むことができ、複数の提出書類を読み込んで期間間で比較する場合に便利です。
ステップ4:チャットルート
チャットエンドポイントは、Vercel AI SDKのstreamTextとツール呼び出しを使用します。システムプロンプトは、モデルにどのドキュメントが読み込まれているか、引用の使用方法を伝えます。プロンプトは、引用内のテキストをドキュメントから正確にコピーするよう要求し、引用システムがその正確な文字列を見つけてハイライト位置を計算できるようにします。LLMが言い換えたり数値を再フォーマットしたりすると、マッチングに失敗します。
ステップ5:引用システム
UIがエージェントの応答内に<citation>タグを検出すると、タグを解析してファイル名、ページ番号、引用フレーズを抽出します。/api/citeを呼び出し、findTextLocation()を使用してページ上でフレーズを特定します。マッチした文字を元のテキストアイテムとその座標にマッピングしてバウンディングボックスを計算し、LiteParseのscreenshot()メソッドでPDFページをレンダリングし、正確な位置にハイライトオーバーレイを描画します。マッチングアルゴリズムは多層戦略を使用します。LLMは常に完全に逐語的ではないため、財務ドキュメント特有のエッジケースに対処するためです。マッチングが見つからない場合、UIは黄色の「未確認」バッジを表示し、ユーザーはエージェントが情報を取得しようとした場所を少なくとも確認できます。
ステップ6:SEC EDGAR統合
デモを自己完結型にするため、直接的なSEC EDGAR統合を追加しました。ユーザーがティッカー(例:AAPL)を入力すると、アプリはSECの企業ティッカーファイルを介してCIK番号に解決し、EDGAR提出APIから最近の提出書類を取得します。ユーザーがダウンロードする提出書類を選択し、ドキュメントをダウンロードしてLiteParseで解析し、ストアに追加します。EDGAR APIはHTMLとPDFの混合を返すようですが、アプリはPuppeteerを使用してHTMLをPDFに変換するため、同じ抽出パイプラインが元の形式に関係なく機能します。
デモの限界と拡張
これはデモであり、本番システムではありません。ただし、本番展開するために必要なのは、ディスクストレージをS3などのブロブストアに置き換え、フラットJSONファイルストアを検索インデックスを持つ適切なデータベースに変更し、ユーザー認証とアクセス制御を追加することだけです。これらはすべて、アプリに既にあるコア機能の上に重ねるエンジニアリングの詳細です。
完全なソースコードはGitHubにあります。Node.js 18+とAnthropic APIキーが必要です。リポジトリをクローンし、npm installを実行し、.envにAPIキーを追加してnpm run devすると、localhost:3000で起動します。EDGARタブでティッカーを検索するかファイルをアップロードし、質問を始めてください。