Prompt
I'm trying to support PDFs, Excel files, wiki pages, and Slack messages in one chatbot. How should I index them?
Latest observation
A good approach is to index everything into one retrieval system with a shared canonical schema, while preserving each source’s metadata and structure. That gives you one chatbot experience without losing the ability to filter by source, permissions, or freshness.
Recommended indexing strategy
1. Use one common document model
Convert each source into a normalized representation like:
- doc_id: unique per source item
- source_type:
pdf | excel | wiki | slack - source_uri: file path, page URL, channel/thread link, etc.
- title
- content
- chunk_id
- chunk_text
- section_path: e.g.
HR > Benefits > PTO - created_at / updated_at
- author
- permissions / ACL
- tags / labels
- embedding
- raw_metadata
This lets you search consistently across all sources.
2. Chunk by source type, not one-size-fits-all
Different data types need different preprocessing.
PDFs
- Extract text by page/section.
- Preserve headings, page numbers, tables if possible.
- Chunk by semantic boundaries:
- section/subsection
- ~300–800 tokens per chunk
- small overlap, e.g. 50–100 tokens
- Store page references for citations.
Excel files
Excel is structured, so don’t flatten it blindly.
Index at one or more of these levels:
- Workbook level: file title, description, sheet names
- Sheet level: useful for overview
- Table/range level: if sheets contain distinct tables
- Row-group level: e.g. 20–100 rows per chunk depending on density
- Cell-to-natural-language text: convert rows into descriptive text
Example row chunk:
“Sheet: Sales Q1. Region: West. Product: Widget A. Revenue: $42,000. Margin: 18%.”
Keep column headers in every row chunk so retrieval is meaningful.
Wiki pages
- Chunk by heading hierarchy.
- Keep breadcrumbs like
Parent > Child > Subchild. - Good for semantic search because wikis already have structure.
- Preserve page version and section anchors.
Slack messages
Slack is conversational and time-sensitive. Index:
- individual messages
- threaded replies with parent context
- optionally thread-level summaries
- include:
- channel
- timestamp
- author
- thread_ts / parent message id
- mentions, reactions, links
For Slack, a chunk may be:
- one message
- a small thread window
- a summarized thread plus key messages
3. Store both embeddings and keyword fields
Use hybrid search:
- Vector embeddings for semantic matching
- BM25 / keyword search for exact terms, IDs, error codes, names
This is especially important for:
- PDFs with exact policy wording
- Excel with numbers, SKUs, product codes
- Slack with names and short phrases
4. Keep metadata for filtering and ranking
At minimum, store:
- source type
- department/team
- date
- author
- access control
- document/page/thread identifiers
- version / last updated
- language
Use metadata to:
- filter by user permissions
- boost recent content for Slack
- prefer official docs over chat
- limit results to relevant teams
5. Add source-specific preprocessing
Examples:
- PDFs: OCR for scanned documents, table extraction, header/footer removal
- Excel: detect numeric columns, formulas, merged cells, hidden sheets
- Wiki: strip nav boxes, preserve hierarchy
- Slack: remove bot noise, deduplicate quoted text, handle threads
6. Consider separate indexes only if retrieval behavior differs a lot
Usually, one unified index is best. But you may split into:
- one main search index
- one metadata/ACL store
- optionally, a separate structured-data engine for Excel if users ask lots of analytical questions
If Excel queries are mostly analytical (“What were Q3 sales by region?”), you may want:
- embeddings for discovery
- a SQL/query layer for exact aggregation
Practical architecture
Ingestion pipeline
- Extract raw content from each source
- Normalize into canonical documents
- Chunk source-appropriately
- Generate embeddings
- Index into vector DB + keyword index
- Attach metadata and ACLs
- Refresh incrementally as sources change
Retrieval pipeline
- User asks question
- Apply permission filter
- Run hybrid search across all sources
- Re-rank results
- Feed top chunks into the LLM with citations
- Answer with source references
Best practices
- Don’t mix all content into identical chunks.
- Preserve source structure and provenance.
- Use hybrid retrieval, not embeddings alone.
- Keep Excel structured where possible.
- Prioritize ACLs and freshness.
- Cite the exact source/chunk in answers.
Simple rule of thumb
If you want one chatbot:
- One unified index
- Source-aware chunking
- Rich metadata
- Hybrid retrieval
If you want, I can also propose:
- a schema for the indexed documents,
- a chunking strategy per file type, or
- a reference architecture using Pinecone/Weaviate/Elastic/Postgres.