Skip to main content

Semantic-aware chunking with provenance tracking for production RAG and LLM data pipelines

Project description

chunkops

Semantic-aware chunking with provenance tracking for production RAG and LLM data pipelines.

pip install llm-chunk-optimizer

The problem

Every RAG system reinvents chunking from scratch. Existing tools (LangChain splitters, LlamaIndex nodes) are buried inside their frameworks, don't interop, and return plain strings with no provenance. When your pipeline gives a wrong answer three weeks after deploy, you have no way to trace which chunk caused it.

chunkops solves three things:

  1. Standalone chunking — works with any vector DB, any LLM, any framework
  2. Provenance — every ChunkResult carries a stable ID, character span, and lineage so you can trace any LLM output back to its exact source passage
  3. Benchmarking — run 3–4 strategies on your actual corpus with one function call before committing

Installation

# Core — fixed, recursive, structural strategies + provenance + benchmark
pip install llm-chunk-optimizer

# Add semantic chunking (embedding-based topic boundaries)
pip install "llm-chunk-optimizer[semantic]"

# Everything + dev/test tools
pip install "llm-chunk-optimizer[dev]"

Import name vs install name

  • Install name: llm-chunk-optimizer
  • Import name: chunkops

Dependencies

Package When required Why
tiktoken always accurate token counting
sentence-transformers chunkops[semantic] only semantic boundary detection
numpy chunkops[semantic] only vector operations
scikit-learn chunkops[semantic] only cosine similarity
pytest chunkops[dev] only running tests

Quick start

from chunkops import Chunker

chunker = Chunker(strategy="recursive", min_tokens=100, max_tokens=400)
chunks = chunker.chunk(text, doc_id="my_doc.txt")

for c in chunks:
    print(c.id, c.token_count, c.span, c.text[:60])

Strategies

Strategy Best for Speed Quality
fixed quick prototyping fastest poor — breaks sentences
recursive most documents fast good — respects paragraphs
structural markdown, wikis, docs fast great — uses headings
semantic dense unstructured prose slow best — topic boundaries
adaptive mixed corpora fast good — auto-selects
# Semantic chunking (requires pip install chunkops[semantic])
chunker = Chunker(
    strategy="semantic",
    min_tokens=150,        # prevents micro-fragments
    max_tokens=512,
    semantic_threshold=0.25,
    embedding_model="all-MiniLM-L6-v2",
)
chunks = chunker.chunk(text, doc_id="paper.txt")

ChunkResult — provenance fields

chunk = chunks[0]

chunk.id            # "3f8a1c9b2d41"  — stable 12-char hash
chunk.doc_id        # "my_doc.txt"
chunk.chunk_index   # 0
chunk.span          # (0, 712)        — char offsets in original text
chunk.token_count   # 142
chunk.strategy      # ChunkStrategy.RECURSIVE
chunk.merged_from   # [0, 1, 2]       — sentence indices merged here
chunk.metadata      # {"source": "arxiv", "year": 2017}
chunk.text          # "The transformer architecture..."

ProvenanceStore

Trace any LLM output back to its exact source passage. Uses SQLite — zero infrastructure required.

from chunkops import ProvenanceStore

store = ProvenanceStore()              # in-memory
store = ProvenanceStore("./prov.db")   # persistent on disk

store.register(chunks)

# Later — your RAG pipeline cites a chunk_id
origin = store.trace("3f8a1c9b2d41")
print(origin.doc_id)        # "my_doc.txt"
print(origin.span)          # (0, 712)
print(origin.merged_from)   # [0, 1, 2]
print(origin.text)          # exact source passage

# All chunks from a document
doc_chunks = store.trace_doc("my_doc.txt")

# Stats
print(store.count())        # 487
print(store.docs())         # ["my_doc.txt", "paper2.txt", ...]

Benchmark

Find the best strategy for your corpus before committing.

from chunkops import benchmark

result = benchmark(
    docs=[doc1, doc2, doc3],
    strategies=["fixed", "recursive", "structural"],
    metric="coherence",     # or "chunk_count", "avg_tokens"
)
result.report()
# ── chunkops benchmark ──────────────────────────────────────────────────────
#   docs: 3   metric: coherence   best: recursive
# ────────────────────────────────────────────────────────────────────────────
#   strategy       chunks   avg tok    min    max   coherence  breaks      ms
# ────────────────────────────────────────────────────────────────────────────
#   fixed              18      47.2     12    112       0.142       4     2.1
# * recursive           9      91.4     63    147       0.381       0     1.3
#   structural          9      91.4     63    147       0.374       0     1.2
# ────────────────────────────────────────────────────────────────────────────

print(result.best_strategy)   # "recursive"
print(result.best().avg_tokens)

BatchChunker

Process large corpora with concurrency and checkpoint/resume.

from chunkops import BatchChunker

bc = BatchChunker(
    strategy="adaptive",
    workers=8,
    checkpoint="./ckpt/run_001",   # crash at doc 80k → resume from 80k
    min_tokens=150,
    max_tokens=512,
)

results = bc.run(
    docs_iterator,   # iterable of (doc_id, text) tuples, or plain strings
    on_progress=lambda n, t: print(f"{n}/{t} docs"),
)
# 10000/100000 docs
# 50000/100000 docs  [checkpoint saved]
# KeyboardInterrupt → resume → 100000/100000 docs
# Total: 487,302 chunks

CLI

# Chunk a file
chunkops chunk my_doc.txt --strategy recursive --max-tokens 400

# Benchmark strategies on a file
chunkops bench my_doc.txt --strategies fixed,recursive,structural --metric coherence

RAG pipeline integration

from chunkops import Chunker, ProvenanceStore

# 1. Ingest
chunker = Chunker(strategy="recursive")
store = ProvenanceStore("./prov.db")

for doc_id, text in your_documents:
    chunks = chunker.chunk(text, doc_id=doc_id)
    store.register(chunks)
    your_vector_db.upsert([
        {"id": c.id, "vector": embed(c.text), "text": c.text}
        for c in chunks
    ])

# 2. Query
results = your_vector_db.search(query, k=5)

# 3. Trace
for r in results:
    origin = store.trace(r["id"])
    print(f"Source: {origin.doc_id}  span: {origin.span}")

Development

git clone https://github.com/yourusername/chunkops
cd chunkops
pip install -e ".[dev]"
pytest

Roadmap

  • LATE chunking strategy (late chunking / contextual retrieval)
  • LangChain TextSplitter adapter
  • LlamaIndex NodeParser adapter
  • Async BatchChunker
  • Export provenance to Parquet / Arrow
  • OpenTelemetry tracing integration

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

llm_chunk_optimizer-0.1.2.tar.gz (22.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

llm_chunk_optimizer-0.1.2-py3-none-any.whl (20.8 kB view details)

Uploaded Python 3

File details

Details for the file llm_chunk_optimizer-0.1.2.tar.gz.

File metadata

  • Download URL: llm_chunk_optimizer-0.1.2.tar.gz
  • Upload date:
  • Size: 22.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.15

File hashes

Hashes for llm_chunk_optimizer-0.1.2.tar.gz
Algorithm Hash digest
SHA256 767bcc9299229b5358dc3f3b3b8d0c13100dbbfd1e745ce9cc6d5704ff95b2a9
MD5 ffdbbd2eeecc5003e807f8c57d20a86f
BLAKE2b-256 2a02cabf2058ff80c50b98d5750de6544b5ec250a9148b423a034b67ff17fd31

See more details on using hashes here.

File details

Details for the file llm_chunk_optimizer-0.1.2-py3-none-any.whl.

File metadata

File hashes

Hashes for llm_chunk_optimizer-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 cf14c659a58a74b066cd51f874a68b5abdfd87dd5b00452382fcaace6a824d7e
MD5 566dc4d108c9a238b4b8ea10d03aea0c
BLAKE2b-256 4c0ea6cb95b79c62185ebf27ba366996ba76d151b9497338b1b00399e838cea8

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page