Surgically reloads a single PDF to Qdrant by deleting old chunks and re-uploading with fixes...
This skill helps users surgically reload a single PDF document to Qdrant without reloading the entire collection, using the LOAD_DB/reload_single_pdf.py script.
Activate this skill automatically when the user:
A surgical reload is a targeted operation that:
Benefits:
Ask the user which PDF file needs to be reloaded. The filename must match exactly (e.g., document-name.pdf).
Check that the PDF file exists in the scraped_content/raw/pdfs/ directory:
ls scraped_content/raw/pdfs/document-name.pdf
If not found, inform the user and ask them to verify the filename.
Execute the surgical reload:
cd LOAD_DB
python reload_single_pdf.py document-name.pdf
The script takes the PDF filename as the only argument.
The script will output progress through these stages:
After completion, summarize:
The script applies the fixed text cleaner which:
The script generates contextual metadata:
These contexts are included in embeddings to improve retrieval accuracy.
Table-heavy PDFs (configured in config.TABLE_PDFS):
Standard PDFs (PyMuPDF extraction):
RecursiveCharacterTextSplitterBy default, reloads to the contextual collection (tro-child-1 or similar).
User: "The income eligibility PDF has garbled text. Can you reload it with the fixed text cleaner?"
Claude: I'll surgically reload that PDF with the updated text cleaner.
[Runs command]
cd LOAD_DB
python reload_single_pdf.py bcy-26-income-eligibility-and-maximum-psoc-twc.pdf
[Script output shows progress]
ā Deleted 12 old chunks
ā Loaded 8 pages
ā Created 10 chunks after filtering (removed 2 TOC chunks)
ā Generated contextual metadata
ā Uploaded 10 new chunks
Reload complete! The document has been refreshed with:
- Fixed text cleaning
- TOC filtering
- Fresh contextual embeddings
Old chunks: 12 deleted
New chunks: 10 uploaded
User: "I replaced the payment rates PDF with a corrected version. Please reload it."
Claude: I'll reload the payment rates PDF with the new version.
[Runs command]
cd LOAD_DB
python reload_single_pdf.py bcy25-child-care-provider-payment-rates-twc.pdf
ā Surgical reload complete!
Deleted: 5 old chunks (single-page table)
Uploaded: 5 new chunks
The updated PDF is now in Qdrant with fresh contextual embeddings.
User: "Can you regenerate the contextual embeddings for the state plan document?"
Claude: I'll reload the state plan to regenerate contextual metadata.
cd LOAD_DB
python reload_single_pdf.py tx-ccdf-state-plan-ffy2025-2027-approved.pdf
This will:
1. Delete existing chunks
2. Re-process the PDF
3. Generate new document and chunk contexts
4. Upload with fresh embeddings
[After completion]
ā Reloaded with new contextual embeddings:
- Document context: [summary of document]
- Chunk contexts: Generated for all 87 chunks
User: "The PSOC chart isn't being retrieved correctly. It's a single-page table PDF."
Claude: Single-page PDFs are loaded as one chunk to preserve table structure. Let me reload it.
cd LOAD_DB
python reload_single_pdf.py bcy2025-psoc-chart-twc.pdf
ā Single-page PDF: loading as 1 chunk (3,245 characters)
ā Uploaded 1 chunk with full table content
The table is now loaded as a single coherent chunk, which should improve retrieval.
Rule of thumb: If updating < 10 PDFs, use surgical reload. If updating > 10 PDFs or making system-wide changes, use full reload.
LOAD_DB/reload_single_pdf.pyscraped_content/raw/pdfs/QDRANT_COLLECTION_NAME_CONTEXTUAL from configThe reload script uses a modular architecture:
LOAD_DB/extractors/): Factory pattern for PyMuPDF vs. Docling selectionLOAD_DB/shared/): Common processing and upload logicThe script requires:
PyMuPDFLoader, RecursiveCharacterTextSplitter)text-embedding-3-small)config.TABLE_PDFS)extractors - Factory pattern and extractor classesshared - Processing utilities and upload logiccontextual_processor - Context generationtext_cleaner - Text cleaning and TOC detectionprompts - Master context template1. DELETE PHASE
āā Scroll through collection
āā Find chunks where filename == pdf_filename
āā Delete all matching chunks
2. EXTRACTION PHASE (via Factory Pattern)
āā Check if PDF in config.TABLE_PDFS
āā If YES: Use DoclingExtractor
ā āā Convert PDF with Docling
ā āā Extract tables as markdown
ā āā Group items by page and sort by y-position
ā āā Create item-level chunks (tables + narrative)
āā If NO: Use PyMuPDFExtractor
āā Load PDF with PyMuPDFLoader (standard extraction)
3. PROCESS PHASE (via shared utilities)
āā Clean text on each page (clean_documents)
āā Enrich metadata (enrich_metadata)
āā Split into chunks if multi-page (text_splitter)
āā Filter out TOC chunks (filter_toc_chunks)
āā Add chunk metadata (add_chunk_metadata)
4. CONTEXT PHASE (Contextual Mode)
āā Generate document context from first 2000 chars
āā Generate chunk context for each chunk (uses previous chunk)
āā Add master context, document context, chunk context to metadata
5. UPLOAD PHASE (via shared uploader)
āā Generate OpenAI embeddings from enriched text
āā Create Qdrant points with embeddings + metadata
āā Store only original content in page_content
āā Upload in batches (100 per batch)
Each uploaded chunk includes:
{
'text': chunk.page_content,
'filename': pdf_filename,
'content_type': 'pdf',
'page': page_number,
'total_pages': total_page_count,
'chunk_index': chunk_number,
'total_chunks': total_chunk_count,
'chunk_type': 'table' | 'narrative', # Docling only
'extractor': 'docling' | 'pymupdf',
'has_context': True,
'master_context': master_context_text,
'document_context': document_summary,
'chunk_context': previous_chunk_summary,
'source_url': url (if available from metadata.json)
}
If the PDF doesn't exist in scraped_content/raw/pdfs/:
If deletion fails:
retrieve_chunks_by_filename.py)If PDF processing fails:
If upload fails:
Use the qdrant-chunk-retriever skill to check existing chunks before reloading.
After reloading, use the qdrant-chunk-retriever skill to confirm:
qdrant-file-exporter skill to export chunks before reloadcd LOAD_DB
python reload_single_pdf.py doc.pdf
qdrant-file-exporter skill again to export chunks after reloadqdrant-chunk-retriever: Verify chunks before/after reloadqdrant-doc-deleter: Delete without reloading (if you just want to remove)qdrant-file-exporter: Export all chunks from a PDF to text fileLOAD_DB/load_pdf_qdrant.py: Full collection reload (all PDFs)LOAD_DB/verify_qdrant.py: Verify collection statisticsLOAD_DB/extractors/: PDF extraction with factory patternLOAD_DB/shared/: Common processing and upload utilities