FractoP
長すぎる文書を、AIに読ませて処理するためのライブラリ
ChatGPTやClaudeのようなAIには、一度に読める文字数に上限があります。FractoPは、100ページの報告書や大量のログファイルのような長い文書を、AIが扱える大きさに分割し、全体を理解した結果を返します。
どんな課題を解決するのか
例1: 長い契約書からリスク項目を抽出したい
あなたの会社に200ページの契約書が届きました。AIに「リスクのある条項を抜き出してほしい」と頼みたいのですが、AIは一度に50ページ分しか読めません。
FractoPなし: 手作業で50ページずつコピペして、4回AIに読ませる必要があります。しかも、結果をまとめる作業も必要です。
FractoPあり: 200ページ全体を渡すだけで、自動的に分割処理し、重複を除いた結果を返します。
例2: カスタマーレビュー1万件から頻出キーワードを抽出
ECサイトに寄せられた大量のレビューから、よく言及される問題点や評価ポイントを知りたい。
FractoPなし: データを手動で分割し、それぞれ処理して、結果を集計する必要があります。途中でエラーが出たら最初からやり直しです。
FractoPあり: 全データを渡せば、自動的に処理を分散し、エラーがあれば自動でリトライ。最終的にキーワードとその重要度をまとめて返します。
どう動作するのか
FractoPは、人間が長い本を読むときと同じ方法で文書を処理します。
1. 章ごとに分けて読む
100ページの文書を10ページずつ、10の「チャンク」に分割します。ただし、文の途中で切れないように、段落や文の区切りを見つけて分割します。
2. 前後のつながりを保つ
各チャンクの最後と次のチャンクの最初を少しだけ重複させます。これにより、「前の章で何が語られたか」という文脈を保ったまま読み進められます。
3. 全体像を覚えておく
最初に文書全体を軽く読んで要約を作ります。各チャンクを処理するときは、この要約を参照して「今読んでいる部分が全体の中でどういう位置づけか」を理解します。
4. 結果をまとめる
10個のチャンクから得られた結果を統合します。たとえば、複数のチャンクで「価格が高い」というキーワードが出てきたら、それらを1つにまとめて重要度を高く評価します。
5. 安定性を確保
途中でAIが応答しなくなったり、エラーが発生したりしても、自動的にリトライします。何度も失敗する場合は処理を中断して、不完全な結果を返さないようにします。
何に使えるのか
- 文書の要約: 長い報告書、論文、ニュース記事をまとめる
- キーワード抽出: 顧客レビュー、アンケート、SNS投稿から重要なトピックを見つける
- データ分析: ログファイル、チャット履歴、メールから傾向を分析
- 翻訳: 長い文書を分割して翻訳し、自然な流れを保つ
- 品質チェック: コードレビュー、文書校正、コンプライアンスチェック
技術詳細
基本的な使い方
FractoPは、LLM(大規模言語モデル)と組み合わせて使います。以下は、長い文書からキーワードを抽出する例です。
import { FractalProcessor } from '@aid-on/fractop';
// プロセッサを作成
const processor = new FractalProcessor(llm, {
chunkSize: 12000, // 1チャンクあたり約12,000文字
overlapSize: 500, // チャンク間で500文字重複
});
// 長い文書を処理
const keywords = await processor.process(longDocument, {
// 文書全体の要約を生成
generateContext: async (text) => {
return await llm.chat('Summarizer', `以下の文書を要約:\n\n${text.substring(0, 8000)}`);
},
// 各チャンクを処理
processChunk: async (chunk, context) => {
const response = await llm.chat('Extractor',
`文書全体の概要: ${context.globalContext}\n\n` +
`前のセクションの内容: ${context.previousSummary || 'なし'}\n\n` +
`以下のテキストからキーワードを抽出してください:\n${chunk}`
);
return { items: parseKeywords(response), summary: '抽出完了' };
},
// 結果を統合
mergeResults: (results) => weightedMerge(results, (item) => item.keyword, 30),
getKey: (item) => item.keyword,
});
スマート分割
FractoPは、文字数を数えて機械的に分割するのではなく、自然な区切りを探します。
- 段落境界: まず段落の切れ目で分割を試みます
- 文境界: 段落が大きすぎる場合は、文の終わりで分割します
- 句点: それでも大きすぎる場合は、句点(。)で分割します
- オーバーラップ: 前後のチャンクで一部を重複させ、文脈の断絶を防ぎます
const processor = new FractalProcessor(llm, {
chunkSize: 12000, // 目標サイズ
overlapSize: 500, // 重複させる文字数
});
コンテキストの伝播
各チャンクを処理するとき、以下の情報が利用できます。
- globalContext: 文書全体の要約(最初に一度だけ生成)
- previousSummary: 前のチャンクの処理結果サマリー
これにより、「今読んでいる部分」と「全体の流れ」の両方を理解した処理ができます。
自動重複除去
複数のチャンクで同じキーワードが抽出された場合、weightedMergeを使うと自動的に統合され、重要度が累積されます。
import { weightedMerge } from '@aid-on/fractop';
const mergeResults = (results) =>
weightedMerge(results, (item) => item.keyword, 30);
// 重複を除去し、上位30件を返す
エラーハンドリングとリトライ
実際の運用では、ネットワークエラーやAPIのタイムアウトが発生します。FractoPはこれらに対応する機能を内蔵しています。
タイムアウト制御
const processor = new FractalProcessor(llm, {
timeout: 300000, // 全体で5分まで
chunkTimeout: 60000, // 各チャンクは1分まで
});
自動リトライ(指数バックオフ)
失敗したチャンクは、待機時間を徐々に増やしながら最大3回まで再試行します。
const processor = new FractalProcessor(llm, {
maxRetries: 3, // 最大3回リトライ
retryDelay: 1000, // 最初は1秒待機、次は2秒、次は4秒...
});
サーキットブレーカー
連続してエラーが発生する場合、処理を中断して無駄なAPI呼び出しを避けます。
const processor = new FractalProcessor(llm, {
circuitBreakerThreshold: 3, // 3回連続失敗で遮断
});
const result = await processor.processWithMetadata(text, options);
if (result.circuitBreakerTripped) {
console.error('エラーが多発したため処理を中断しました');
}
進捗の監視
イベントシステムを使って、処理の進行状況をリアルタイムで把握できます。
processor.on((event) => {
switch (event.type) {
case 'chunk_start':
console.log(`チャンク ${event.index + 1}/${event.total} を処理中`);
break;
case 'chunk_complete':
console.log(`チャンク ${event.index + 1} が完了`);
break;
case 'chunk_retry':
console.warn(`チャンク ${event.index} をリトライ中 (${event.attempt}回目)`);
break;
case 'complete':
console.log(`全処理が完了しました: ${event.totalItems}件の結果`);
break;
}
});
技術仕様
- TypeScript: 型安全な開発体験
- プロバイダー非依存: OpenAI、Anthropic、Google、どのLLMでも使用可能
- ゼロ依存: 外部ライブラリに依存せず、軽量で安全
インストール
npm install @aid-on/fractop
FractoPを使えば、AIの文字数制限を気にせず、どんなに長い文書でも確実に処理できます。