| name | implementing-document-indexing |
| description | Implements document indexing with heading-boundary chunking, embedding, FAISS vector store, and PageIndex-style hybrid retrieval. Use when building RAG pipelines, document search, or memory layers. |
| compatibility | Designed for Claude Code |
| metadata | {"allowed-tools":"Read, Grep, Glob, Edit, Write, Bash","argument-hint":["module-or-feature"],"stability":"development","last-verified-cc-version":"1.0.34"} |
Document Indexing Implementation
Target: $ARGUMENTS
Implements a document indexing and hybrid retrieval pipeline: parse documents,
build a heading-based tree index, chunk by heading boundaries, embed with
sentence-transformers, store in FAISS, and retrieve via hybrid search.
Architecture Overview
Document --> Parser --> Pages --> TreeIndex (PageIndex)
|
v
Chunker (heading-boundary + max-token)
|
v
Embedder (sentence-transformers)
|
v
VectorStore (FAISS IndexFlatIP)
|
v
HybridRetrieval (vector search -> full page -> tree filter)
Chunking Strategy
See references/chunking-strategies.md for full reference.
Heading-boundary chunking (primary):
- Split document by heading boundaries (H1-H6)
- Each section becomes a chunk with heading hierarchy as metadata
- If a section exceeds max tokens, split at sentence boundaries
- Preserve heading path (e.g.,
H1 > H2 > H3) as chunk metadata
Max-token splits (fallback):
- Default max: 512 tokens
- Overlap: 64 tokens between splits
- Never split mid-sentence
Retrieval Pipeline
See references/retrieval-patterns.md for full reference.
Hybrid retrieval (vector search + tree filter):
- Embed query with same model used for indexing
- Vector search top-k chunks from FAISS (cosine similarity via IndexFlatIP)
- Full page fetch -- retrieve complete pages containing matched chunks
- Tree filter -- use PageIndex tree to filter to relevant sections only
- Return filtered sections with source citations (page, heading path)
Data Models
@dataclass
class Document:
pages: list[Page]
metadata: dict[str, str]
@dataclass
class Page:
number: int
content: str
headings: list[str]
@dataclass
class TreeNode:
heading: str
level: int
content: str
children: list[TreeNode]
def filter(self, predicate: Callable) -> TreeNode | None: ...
Dependencies
[project]
dependencies = [
"sentence-transformers>=3.0",
"faiss-cpu>=1.9",
]
Workflow
- Define data models -- Document, Page, TreeNode dataclasses
- Implement parser -- extract pages with headings from source documents
- Build tree index -- construct PageIndex tree from heading hierarchy
- Implement chunker -- heading-boundary splits with max-token fallback
- Implement embedder -- sentence-transformers wrapper (encode, batch)
- Implement vector store -- FAISS IndexFlatIP with add/search/save/load
- Implement hybrid retrieval -- full pipeline: embed, search, fetch, filter
- Wire CLI -- ingest and search commands
Quality Checks
make validate
All type checks, linting, and tests must pass.