PageIndex
フレームワークVectifyAI/PageIndex
ベクトル不要の推論ベース RAG システム。階層ツリーインデックスを使用して人間のような検索を実現します。
概要
PageIndex は、ベクトルを使用しない推論ベースの RAG システムであり、長文書から階層的なツリーインデックスを構築します。LLM を活用してコンテキストを認識した人間のような検索を実現し、従来のベクトル類似度検索に代わります。FinanceBench などの専門文書分析ベンチマークでトップクラスの精度を達成しています。
README プレビュー
\n \n\n \n\n\n\n\n\n\n \n\n\n# PageIndex: Vectorless, Reasoning-based RAG\n\nReasoning-based RAG ◦ No Vector DB or Chunking ◦ Context-Aware ◦ Human-like Retrieval\n\n\n 🌐 Homepage • \n 🖥️ Chat Platform • \n 🔌 MCP & API • \n 📖 Docs • \n 💬 Discord • \n ✉️ Contact \n\n \n\n\n\n\n📢 Updates\n\n- 🔥 [**Agentic Vectorless RAG**](https://github.com/VectifyAI/PageIndex/blob/main/examples/agentic_vectorless_rag_demo.py) — A simple *agentic, vectorless RAG* [example](#agentic-vectorless-rag-an-example) with self-hosted PageIndex, using OpenAI Agents SDK.\n- [**Scale PageIndex to Millions of Documents**](https://pageindex.ai/blog/pageindex-filesystem) — *PageIndex File System* is a file-level tree layer that lets PageIndex reason over an entire corpus, not just a single document, enabling massive-scale document search.\n- [PageIndex Chat](https://chat.pageindex.ai) — Human-like document analysis agent [platform](https://chat.pageindex.ai) for professional long documents. Also available via [MCP](https://pageindex.ai/developer) or [API](https://pageindex.ai/developer).\n- [PageIndex Framework](https://pageindex.ai/blog/pageindex-intro) — Deep dive into PageIndex: an *agentic, in-context tree index* that enables LLMs to perform *reasoning-based, context-aware retrieval* over long documents.\n\n \n\n\n\n---\n\n# 📑 Introduction to PageIndex\n\nAre you frustrated with vector database retrieval accuracy for long professional documents? Traditional vector-based RAG relies on semantic *similarity* rather than true *relevance*. But **similarity ≠ relevance** — what we truly need in retrieval is **relevance**, and that requires **reasoning**. When working with professional documents that demand domain expertise and multi-step reasoning, similarity search often falls short.\n\nInspired by AlphaGo, we propose **[PageIndex](https://vectify.ai/pageindex)** — a **vectorless**,
FAQ (5)
トラブル対応TOC 処理中に process_none_page_numbers で発生する "KeyError: 'page'" を修正するにはどうすればよいですか?
安全でないキーの削除を、pop() とデフォルト値を使う方法に置き換えてください。pageindex/page_index.py(または pageindex/page_index_classic.py)で、以下を変更します:
del item_copy['page']
del item['page']
変更後:
item_copy.pop('page', None)
item.pop('page', None)
これにより、キーが存在する場合は削除され、TOC アイテムに page フィールドがない場合に KeyError が発生する代わりに None が返されます。また、最新リリースへのアップグレードでも問題が解決する可能性があります。レガシーな TOC パスは、追加のバリデーション、クリーンアップ、リトライ、エラーハンドリングを備えたものに置き換えられているためです。
トラブル対応TOCアイテムにページ番号がない場合に process_none_page_numbers で発生する KeyError: 'page' を修正するにはどうすればよいですか?
del を使用する代わりに、キーの削除をガードしてください。pageindex/page_index.py または pageindex/page_index_classic.py で、次のコードを:
del item['page']
del item_copy['page']
以下に置き換えます:
item.pop('page', None)
item_copy.pop('page', None)
これにより、page が存在する場合にのみ安全に削除されます。インストール済みのリリースを使用している場合は、最新バージョンにアップグレードしてください。レガシーな TOC パスは、その後パーサーのバリデーションおよびエラーハンドリングの変更によって置き換えられたか、カバーされています。エラーが解決しない場合は、入力の形状、モデル/プロバイダー、パッケージバージョン、トレースバックを報告してください。
トラブル対応LLMが不正なJSONを返した場合に発生する AttributeError: 'str' object has no attribute 'get' または 'dict' object has no attribute 'extend' を修正する方法
JSON フォールバックを修正し、実行時の型バリデーションを追加してください。pageindex/utils.py では、ToC の呼び出し側が dict のリストを期待しているため、パースに失敗した場合に extract_json() が {} ではなく [] を返すようにしてください:
def extract_json(text):
try:
data = json.loads(text)
except (json.JSONDecodeError, TypeError):
return []
return data if isinstance(data, list) else []
LLM の出力は使用する前に正規化してください:
def normalize_toc_items(data):
if not isinstance(data, list):
return []
return [item for item in data if isinstance(item, dict)]
meta_processor では、.get() を呼び出す前に dict アイテムのみをフィルタリングしてください:
toc_with_page_number = normalize_toc_items(toc_with_page_number)
toc_with_page_number = [
item for item in toc_with_page_number
if item.get("physical_index") is not None
]
process_no_toc では、.extend() を呼び出す前に両方の値がリストであることを確認してください:
toc_with_page_number = normalize_toc_items(
generate_toc_init(group_texts[0], model)
)
for group_text in group_texts[1:]:
additional = normalize_toc_items(
generate_toc_continue(toc_with_page_number, group_text, model)
)
toc_with_page_number.extend(additional)
あるいは、PR #210、#217 に含まれる不正な JSON に対するクラッシュガード、または issue #199 で参照されている包括的な修正を含むリリースに更新してください。
トラブル対応PageIndex 実行時に convert_physical_index_to_int で発生する KeyError: 'physical_index' の修正方法
これは、パースされたPDFエントリの一部に physical_index フィールドが欠落していたという初期バージョンのバグが原因でした。修正とリグレッションテストが含まれる最新バージョンにPageIndexを更新してください:
cd PageIndex
git pull
pip install -r requirements.txt
その後、元のPageIndexコマンドを再実行してください。Python 3.9が原因であることは確認されていません。古いPDFや複雑なPDFでエラーや認識の問題が解消されない場合、PyPDFが確実にパースできない可能性があります。回避策として、OCRを使用しており、そのようなPDFをより適切に処理できる可能性があるホスト版のPageIndex APIをご利用ください。
トラブル対応並行 LLM リクエストでツリーインデックスを生成する際に、HTTP 429 レート制限エラーに続いて KeyError 'toc_detected' が発生する問題を修正するにはどうすればよいですか?
最新の pageindex リリースにアップグレードしてください。このリリースでは、クライアント側のレート制限、上限付き並行処理、Retry-After のハンドリング、ジッター付き指数バックオフ、および不正な形式の LLM JSON レスポンスの検証が追加されています:
python -m pip install -U pageindex litellm
アップグレード後は、並行呼び出しが asyncio.gather でバースト的に実行されることがなくなり、空または失敗した LLM レスポンスに対して {}['toc_detected'] へアクセスする代わりに、適切なハンドリングが行われます。
すぐにアップグレードできない場合は、以下の回避策を適用してください:
1. セマフォで LLM の並行数を制限します:
sem = asyncio.Semaphore(2) # プロバイダーの RPM/TPM ティアに合わせる
async def guarded_llm_call(coro):
async with sem:
return await coro
await asyncio.gather(*(guarded_llm_call(task) for task in tasks))
2. 固定の 1 秒リトライを、指数バックオフ、ジッター、および Retry-After サポートに置き換えます:
import asyncio, random
delay = min(60, (2 ** attempt) + random.random())
retry_after = getattr(exc, "response", None)
if retry_after is not None:
delay = float(retry_after.headers.get("Retry-After", delay))
await asyncio.sleep(delay)
3. キーへの直接アクセスを行う前に、パースされた JSON を検証します:
json_content = extract_json(response)
if not json_content or "toc_detected" not in json_content:
raise RuntimeError("LLM returned an invalid or empty JSON response")
return json_content["toc_detected"]
TOC の完了チェックにおける completed などのフィールドにも、同様のキー存在チェックを適用してください。