
Research
/Security News
Malicious npm Packages Target WhatsApp Developers with Remote Kill Switch
Two npm packages masquerading as WhatsApp developer libraries include a kill switch that deletes all files if the phone number isnβt whitelisted.
A Python library for generating high-quality question-answer pairs from PDF, DOCX, MD, and TXT files
Intelligent Question-Answer Generation with Advanced Semantic Understanding For AI Fine-Tuning
Overview β’ Installation β’ Quickstart β’ Feature Overview β’ Core Capabilities β’ Advanced Features β’ Project File Organization β’ Architecture β’ Configuration β’ API Reference β’ CLI Reference β’ Usage Examples β’ Extension β’ Troubleshooting β’ License
Alpha Release (v0.10): This library is in active development and not functional yet. I estimate it is 90% complete, so the last %10 percent may take 90% of the time. However, the feature set is amazing IMO, and I am looking forward to completing this library. If you are interested in helping, please fork the repo and help bring this Python library to life.
SemanticQAGen is a powerful Python library for generating high-quality question-answer pairs from text documents. It uses advanced semantic understanding to intelligently process content, analyze information density, and create diverse questions across multiple cognitive levels.
This builds upon concepts from the Augmentoolkit project by Evan Armstrong and other QA generation projects. I tried Evan's project on some test data and fell in love with it. I originally intended to fork his project and work on adding features I wanted to see. After making the plan, I realized that this wasn't simply a fork. It just felt wrong to try and completely redesign someone else's excellent library and I wanted a much different feature set and so this library is the result.
SemanticQAGen features enhanced semantic chunking, dynamic question generation, optional validation of questions and answers using retrieval-augmented generation (RAG), and flexible LLM routing capabilities. You can run all tasks locally on an OpenAI compatible server, run them off an Internet hosted API, or split specific tasks (eg. chunking, validation, analysis, generation) between local and remote servers. The library is designed with the "for Humans" philosophy - simple for basic use cases while providing advanced capabilities for power users.
pip install semantic-qa-gen
# With PDF support
pip install semantic-qa-gen[pdf]
# With full document support (PDF, DOCX, etc.)
pip install semantic-qa-gen[docs]
# With RAG validation capabilities
pip install semantic-qa-gen[rag]
# With enhanced UI and NLP capabilities
pip install semantic-qa-gen[full]
# Development installation with testing tools
pip install semantic-qa-gen[dev]
from semantic_qa_gen import SemanticQAGen
# Initialize with default settings
qa_gen = SemanticQAGen()
# Process a document
result = qa_gen.process_document("path/to/document.txt")
# Save the questions to a JSON file
qa_gen.save_questions(result, "output")
# Generate questions from a document with default settings
semantic-qa-gen process document.pdf -o questions_output
# Process a whole directory of documents
semantic-qa-gen process-batch input_directory/ -o output_directory/
# Create a config file interactively
semantic-qa-gen init-config config.yml --interactive
# Process with a specific configuration
semantic-qa-gen process document.txt --config config.yml --format json
SemanticQAGen offers a comprehensive set of features designed to produce high-quality question and answer sets:
Feature Category | Capability | Included |
---|---|---|
Document Processing | Document format support: TXT, PDF, DOCX, MD | β |
Batch document processing | β | |
Automatic document type detection | β | |
Cross-page content handling | β | |
Header/footer detection and removal | β | |
Content Analysis | Semantic document chunking | β |
Information density analysis | β | |
Topic coherence evaluation | β | |
Key concept extraction | β | |
Educational level classification | β | |
Question Generation | Multi-level cognitive questions (factual, inferential, conceptual) | β |
Adaptive generation based on content quality | β | |
Question diversity enforcement | β | |
Custom question categories | β | |
Answer Validation | Factual accuracy verification | β |
RAG-enhanced fact checking | β | |
Question clarity evaluation | β | |
Answer completeness assessment | β | |
LLM Integration | OpenAI API support | β |
Local LLM support (Ollama, etc.) | β | |
Hybrid task routing | β | |
Automatic fallback mechanisms | β | |
Processing Control | Checkpoint and resume capability | β |
Parallel processing | β | |
Progress tracking and reporting | β | |
Memory optimization | β | |
Output Options | Multiple export formats (JSON, CSV) | β |
Metadata inclusion | β | |
Statistics and analytics | β | |
RAG retriever creation | β | |
Extensibility | Custom document loaders | β |
Custom chunking strategies | β | |
Custom validators | β | |
Plugin architecture | β |
SemanticQAGen can read and process a variety of document formats including plain text, PDF, Markdown, and DOCX. Each format is handled by specialized loaders that extract content while preserving document structure.
# Process different file types the same way
result_txt = qa_gen.process_document("document.txt")
result_pdf = qa_gen.process_document("document.pdf")
result_md = qa_gen.process_document("document.md")
result_docx = qa_gen.process_document("document.docx")
Process multiple files in a single operation. The system can handle directories of mixed document types and will generate separate outputs for each.
# Process all files in a directory
qa_gen.process_batch(
input_dir="input/",
output_dir="output/",
file_types=["txt", "pdf", "docx", "md"]
)
The system automatically detects document types using both file extensions and content analysis, ensuring the correct loader is used even when file extensions are missing or incorrect.
For PDF documents, the system intelligently handles sentences and paragraphs that span across page boundaries, creating a seamless text flow for better semantic analysis.
Automatic detection and optional removal of repeating headers and footers in PDF documents, preventing them from being included in generated questions.
Documents are intelligently broken down into semantically coherent chunks based on content structure rather than arbitrary size limits. This preserves context and produces more meaningful question-answer pairs.
# Configure chunking strategy
config = {
"chunking": {
"strategy": "semantic", # Options: semantic, fixed_size, hybrid
"target_chunk_size": 1500,
"preserve_headings": True
}
}
Each chunk is analyzed for information density - how rich in facts and teachable content it is. This analysis guides question generation to focus on content-rich sections.
The system evaluates how well each chunk maintains a coherent topic or theme, which helps ensure generated questions relate to a consistent subject area.
Important concepts, terms, and ideas are automatically identified in each chunk, forming the basis for targeted question generation.
Content is classified by appropriate educational level (elementary, high school, undergraduate, etc.) to help generate questions at suitable complexity levels. You can remove this metadata if it isn't applicable to your dataset.
The system generates questions across three cognitive domains:
# Configure question categories
config = {
"question_generation": {
"categories": {
"factual": {"min_questions": 3, "weight": 1.0},
"inferential": {"min_questions": 2, "weight": 1.2},
"conceptual": {"min_questions": 1, "weight": 1.5}
}
}
}
The number and types of questions generated adapt automatically based on content quality. Information-dense chunks yield more questions, while sparse chunks yield fewer.
To avoid repetitive or overly similar questions, the system enforces diversity by comparing newly generated questions with existing ones and filtering out duplicates.
Users can define custom question categories beyond the standard factual/inferential/conceptual to target specific learning objectives.
All generated answers are verified against the source content to ensure they do not contain factual errors or hallucinations.
Optional LlamaIndex-based retrieval-augmented validation ensures answers are firmly grounded in the source material. This provides an additional verification layer beyond prompt-based checking.
Questions are evaluated for clarity and unambiguity, filtering out poorly formed questions that might confuse learners.
The system checks that answers thoroughly address the questions asked, eliminating partial or incomplete responses.
SemanticQAGen's most advanced validation feature uses Retrieval-Augmented Generation (RAG) through LlamaIndex to ensure factual correctness. Unlike many AI question generators that can "hallucinate" incorrect facts, the RAG validation system acts as a powerful factual grounding mechanism.
I personally prefer LangChain architecture, however LlamaIndex was selected specifically for its document-centric approach, specialized evaluation tools, and embedding management capabilities, making it ideal for factual verification. This is strictly a validation mechanism - it does not pollute or alter the Q/A generation process. The source material remains the single source of truth.
# Enable RAG validation
config = {
"validation": {
"factual_accuracy": {
"enabled": True,
"threshold": 0.7
},
"rag_factual": {
"enabled": True,
"model": "gpt-4",
"threshold": 0.75
},
"use_enhanced_validation": True # Combine traditional and RAG validation
}
}
The RAG validation system can be configured to be more or less strict depending on your needs. When using the enhanced combined validation, it benefits from both traditional prompt-based and retrieval-based approaches.
Full integration with OpenAI with optimized prompting strategies for each task in the pipeline.
Support for local LLM deployment via Ollama, LM Studio, and similar services, allowing use of models like Llama, Mistral, etc., without requiring external API access.
Intelligently route different tasks to the most appropriate LLM based on task complexity and model capability. For example, use GPT-4 for complex question generation but a local model for simple validation tasks.
config = {
"llm_services": {
"local": {
"enabled": True,
"url": "http://localhost:11434/api",
"model": "mistral:7b",
"default_for": ["chunking", "validation"]
},
"remote": {
"enabled": True,
"provider": "openai",
"model": "gpt-4",
"default_for": ["analysis", "generation"]
}
}
}
If a primary LLM service fails, the system automatically tries fallback services, ensuring robustness in production environments.
Processing can be interrupted and resumed later using a checkpoint system. This is essential for large documents or when processing must be paused.
config = {
"processing": {
"enable_checkpoints": True,
"checkpoint_dir": "./checkpoints",
"checkpoint_interval": 10 # Save every 10 chunks
}
}
Multi-threaded processing of documents and chunks with configurable concurrency levels to maximize throughput on multi-core systems.
Detailed progress reporting during processing, with support for both simple console output and rich interactive displays.
Smart memory management techniques to handle very large documents without exhausting system resources.
Export question-answer pairs in various formats including JSON, CSV, with customizable formatting options.
# Save questions in different formats
qa_gen.save_questions(result, "questions_output", format_name="json")
qa_gen.save_questions(result, "questions_output", format_name="csv")
Include rich metadata about source documents, generation parameters, and validation results with the generated questions.
Comprehensive statistics about generated questions, including category distribution, validation success rates, and content coverage.
Generated questions and answers can be exported as a LlamaIndex retriever for use in downstream applications.
# Create a retriever from generated QA pairs
retriever = qa_gen.create_qa_retriever(result, api_key="YOUR_OPENAI_API_KEY")
response = retriever.retrieve("How does photosynthesis work?")
.
βββ π __init__.py
βββ π semantic_qa_gen.py
βββ π version.py
βββ π semantic_qa_gen
β βββ π __init__.py
β βββ π main.py
β βββ π semantic_qa_gen.py
β βββ π chunking
β β βββ π analyzer.py
β β βββ π engine.py
β β βββ π strategies
β β βββ π base.py
β β βββ π fixed_size.py
β β βββ π nlp_helpers.py
β β βββ π semantic.py
β βββ π cli
β β βββ π __init__.py
β β βββ π commands.py
β βββ π config
β β βββ π manager.py
β β βββ π schema.py
β βββ π document
β β βββ π models.py
β β βββ π processor.py
β β βββ π loaders
β β βββ π base.py
β β βββ π docx.py
β β βββ π markdown.py
β β βββ π pdf.py
β β βββ π text.py
β βββ π llm
β β βββ π router.py
β β βββ π service.py
β β βββ π adapters
β β β βββ π local.py
β β β βββ π remote.py
β β βββ π prompts
β β βββ π manager.py
β βββ π output
β β βββ π __init__.py
β β βββ π formatter.py
β β βββ π adapters
β β βββ π __init__.py
β β βββ π csv.py
β β βββ π json.py
β βββ π pipeline
β β βββ π semantic.py
β βββ π question
β β βββ π generator.py
β β βββ π processor.py
β β βββ π validation
β β βββ π base.py
β β βββ π diversity.py
β β βββ π engine.py
β β βββ π factual.py
β βββ π utils
β βββ π checkpoint.py
β βββ π error.py
β βββ π logging.py
β βββ π progress.py
βββ π setup.py
βββ π tests
βββ π conftest.py
βββ π test_chunking.py
βββ π test_config.py
βββ π test_document_processor.py
βββ π test_llm_service.py
βββ π test_main.py
βββ π test_pipeline.py
βββ π test_question_generation.py
βββ π test_utils.py
βββ π test_validation.py
βββ π integration
βββ π test_minimal_pipeline.py
SemanticQAGen implements a modular pipeline architecture with clearly defined components and interfaces:
ARCHITECTURE
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β
β βββββββββββββββββββββββββββββββββββ β
β β SemanticQAGen Class β β
β β (Main User Interface) β β
β βββββββββββββββ¬ββββββββββββββββββββ β
β β β
β βΌ β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β SemanticPipeline Orchestrator β β
β ββ¬βββββββββββββββββ¬ββββββββββββββββββββ¬ββββββββββββββ¬β β
β β β β β β
β βββββββββββΌβββββββββββ β ββββββββββββββββΌββββββββββββ β β
β β Document Manager β β β Chunking & Analysis β β β
β ββ¬βββββββββββββββββ¬βββ β ββ¬ββββββββββββββββββββββ¬ββββ β β
β β β β β β β β
βββββΌββββββββ ββββββΌβββββ β ββββΌββββββββ ββββββΌβββββ β β
ββ Document β βDocument β β β Chunking β βSemantic β β β
ββ Loaders β βProcessorβ β β Engine β βAnalyzer β β β
βββββββββββββ βββββββββββ β ββββββββββββ βββββββββββ β β
β β β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββ β β
β β LLM Service Router β β β
β β β β β
β β ββββββββββββββββββ ββββββββββββββββββ β β β
β β β Remote LLM β β Local LLM β β β β
β β β (OpenAI, etc.) β β (Ollama, etc.) β β β β
β β ββββββββββββββββββ ββββββββββββββββββ β β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββ β β
β β β β
β ββββββββββββββββββββββββββ β βββββββββββββββββββββββββββββββββΌβββββββββ β
β β Question Generator β β β Validation Engine β β
β β βββΌββΌβββββ β β
β β ββββββββββββββββββββ β β β β β β
β β βCategory: Factual β β β β β βββββββββββββββ ββββββββββββββββ β β
β β ββββββββββββββββββββ β β β βββΊβ Traditional β β RAG-based β β β
β β ββββββββββββββββββββ β β β β β Validators β β Validator β β β
β β βCat: Inferential β β β β β βββββββββββββββ ββββββββββββββββ β β
β β ββββββββββββββββββββ β β β β β β
β β ββββββββββββββββββββ β β β β ββββββββββββββββββββββββββββββββ β β
β β βCat: Conceptual β β β β βββΊβ Enhanced Validator β β β
β β ββββββββββββββββββββ β β β ββββββββββββββββββββββββββββββββ β β
β βββββββββββ¬βββββββββββββββ β βββββββββββββββββββββββββββββββββββββββββ¬β β
β β β β β
β ββββββββββββββββββΌββββββββββββββββββββββββββββββββββββββββββ β
β β β
β ββββββββββββββββββββΌββββββββββββββββββββββ β
β β Output Formatter β β
β β β β
β β βββββββββββββββ ββββββββββββββββββ β β
β β β JSON Adapterβ β CSV Adapter β β β
β β βββββββββββββββ ββββββββββββββββββ β β
β ββββββββββββββββββββββββββββββββββββββββββ β
β β β
β βββββββββββββββββββΌβββββββββββββββββββββ β
β β Output Results β β
β β β’ Questions & Answers β β
β β β’ Document Metadata β β
β β β’ Statistics β β
β ββββββββββββββββββββββββββββββββββββββββ β
β β
β βββββββββββββββββββββββββββββββ β
β β Checkpoint Manager β β
β β (Resume Capabilities) β β
β βββββββββββββββββββββββββββββββ β
β β
β βββββββββββββββββββββββββββββββ β
β β Progress Reporter β β
β β (Processing Feedback) β β
β βββββββββββββββββββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
DATA FLOW
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β
β βββββββββββββ βββββββββββββ βββββββββββββ βββββββββββββ β
β β Document β β Document β β List β βChunk List β β
β β Files βββββββΊβ Model ββββββΊβ of Chunks βββββββΊβw/Analysis β β
β βββββββββββββ βββββββββββββ βββββββββββββ βββββββββββββ β
β β β
β βΌ β
β ββββββββββββββββββββββββββββββββββ β
β βββββββββββββ ββββββββββββββ β Question-Answer Generation β β
β β Final β β Validated β β ββββββββββββββ ββββββββββββββ β β
β β Output βββββββ€ Question βββββββββ€ β Question 1 β β Question 2 β β β
β β β β List β β ββββββββββββββ ββββββββββββββ β β
β βββββββββββββ ββββββββββββββ ββββββββββββββββββββββββββββββββββ β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
VALIDATION SUBSYSTEM
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β
β βββββββββββββββββ βββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β Generated β β Validation Engine β β
β β Questions ββββββΊβ β β
β βββββββββββββββββ β ββββββββββββββββββββββ βββββββββββββββββββ β β
β β β Traditional Flow β β RAG Flow β β β
β β β β β β β β
β β β ββββββββββββββββ β β βββββββββββββββ β β β
β β β β Factual β β β β Source β β β β
β β β β Accuracy β β β β Document β β β β
β β β ββββββββββββββββ β β β Index β β β β
β β β ββββββββββββββββ β β ββββββββ¬βββββββ β β β
β β β β Answer β β β β β β β
β β β β Completeness β β β ββββββββΌβββββββ β β β
β β β ββββββββββββββββ β β β LlamaIndex β β β β
β β β ββββββββββββββββ β β β Correctness β β β β
β β β β Question β β β β Evaluator β β β β
β β β β Clarity β β β ββββββββ¬βββββββ β β β
β β β ββββββββββββββββ β β β β β β
β β β ββββββββββββββββ β β ββββββββΌβββββββ β β β
β β β β Diversity β β β β Accuracy β β β β
β β β β Check β β β β Score β β β β
β β β ββββββββββββββββ β β βββββββββββββββ β β β
β β ββββββββββββββββββββββ βββββββββββββββββββ β β
β β β β
β β ββββββββββββββββββββββ β β
β β β Combine Results β β β
β β βββββββββββ¬βββββββββββ β β
β β β β β
β ββββββββββββββββββββββββΌβββββββββββββββββββββββββββ β
β β β
β βββββββββββββββββ βββββββββββΌβββββββββββ β
β β Final Valid ββββββββββββββββββββ€ Validation Results β β
β β Questions β ββββββββββββββββββββββ β
β βββββββββββββββββ β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
BATCH PROCESSING
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β
β βββββββββββββββ βββββββββββββββββββββββββ ββββββββββββββββ β
β β Input β β Batch Processor β β Checkpoint β β
β β Directory βββββββββββΊ βββββββΊβ Store β β
β βββββββββββββββ β ββββββββββββββββββ β ββββββββββββββββ β
β β β File Type β β β
β β β Detection β β β
β β ββββββββββββββββββ β β
β β ββββββββββββββββββ β β
β β β Processing β β β
β β β Queue β β β
β β ββββββββββββββββββ β β
β β ββββββββββββββββββ β ββββββββββββββββ β
β β β Parallel ββββββββββββββΊ File 1 β β
β β β Scheduler β β β Processing β β
β β ββββ¬βββββββββββββ¬β β ββββββββββββββββ β
β β β β β ββββββββββββββββ β
β β β ββββββββββββββΊ File 2 β β
β β β β β β Processing β β
β β ββββββββββββββ β ββββββββββββββββ β
β βββββββββββββββββββββββββ β
β β β
β βββββββββββββΌββββββββββββ β
β β Results Aggregator β β
β βββββββββββββ¬ββββββββββββ β
β β β
β βββββββββββββββ ββββββββββββΌββββββββββββ β
β β Output βββββββββββ€ Final Outputs β β
β β Directory β ββββββββββββββββββββββββ β
β βββββββββββββββ β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Document β Chunks β Analysis β Questions β Validation β Output
The pipeline implements a two-phase approach:
SemanticQAGen uses a hierarchical YAML configuration system with schema validation.
# SemanticQAGen configuration
version: 1.0
# Document processing settings
document:
loaders:
text:
enabled: true
encoding: utf-8
pdf:
enabled: true
extract_images: false
ocr_enabled: false
detect_headers_footers: true
markdown:
enabled: true
extract_metadata: true
docx:
enabled: true
extract_tables: true
# Chunking settings
chunking:
strategy: semantic
target_chunk_size: 1500
overlap_size: 150
preserve_headings: true
min_chunk_size: 500
max_chunk_size: 2500
# LLM services configuration
llm_services:
local:
enabled: true
url: "http://localhost:11434/api"
model: "mistral:7b"
default_for: [chunking, validation]
timeout: 60
remote:
enabled: true
provider: openai
model: gpt-4
api_key: ${OPENAI_API_KEY}
default_for: [analysis, generation]
timeout: 120
rate_limit_tokens: 90000
rate_limit_requests: 100
# Question generation settings
question_generation:
max_questions_per_chunk: 10
adaptive_generation: true
categories:
factual:
min_questions: 2
weight: 1.0
inferential:
min_questions: 2
weight: 1.2
conceptual:
min_questions: 1
weight: 1.5
diversity:
required: true
min_similarity_threshold: 0.75
# Validation settings
validation:
factual_accuracy:
enabled: true
threshold: 0.8
answer_completeness:
enabled: true
threshold: 0.8
question_clarity:
enabled: true
threshold: 0.8
diversity:
enabled: true
similarity_metric: cosine
rag_factual:
enabled: true
model: "gpt-4"
threshold: 0.7
use_enhanced_validation: true
# Batch processing settings
processing:
concurrency: 3
enable_checkpoints: true
checkpoint_interval: 10
checkpoint_dir: "./checkpoints"
log_level: "INFO"
batch:
enabled: true
input_dir: "./documents"
output_dir: "./output"
supported_types: ["txt", "pdf", "md", "docx"]
parallel_processing: true
max_concurrent_files: 2
continue_on_error: true
track_processed_files: true
skip_completed_files: true
resume_strategy: "auto-detect"
# Output settings
output:
format: json
include_metadata: true
include_statistics: true
output_dir: "./output"
json_indent: 2
csv_delimiter: ","
In the JSON output format, the metadata for each question/answer pair is integrated directly with the question/answer data. Each question is represented as a single JSON object that contains all its associated information, including the question text, answer text, category, and all metadata
{
"questions": [
{
"id": "q_c05a3e9b",
"text": "What is photosynthesis?",
"answer": "Photosynthesis is the process by which green plants and some other organisms use sunlight to synthesize foods with the help of chlorophyll. It converts light energy into chemical energy, specifically glucose, while releasing oxygen as a byproduct.",
"category": "factual",
"chunk_id": "chunk_28a1e5",
"metadata": {
"source_page": 12,
"confidence_score": 0.92,
"generated_at": "2025-03-15T14:23:47Z",
"validation_scores": {
"factual_accuracy": 0.95,
"question_clarity": 0.89,
"answer_completeness": 0.91,
"rag_factual_accuracy": 0.97
},
"topic": "Biology",
"educational_level": "High School",
"keywords": ["photosynthesis", "plants", "chlorophyll", "glucose", "energy conversion"]
}
},
// Additional questions...
Configuration values can be specified using environment variables:
llm_services:
remote:
api_key: ${OPENAI_API_KEY}
Configuration is resolved in the following order:
CLASS HIERARCHY
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β
β βββββββββββββββββββββββββββ β
β β SemanticQAGen β β
β β β β
β β - process_document() β β
β β - process_batch() β β
β β - save_questions() β β
β β - create_qa_retriever() β β
β ββββββββββββββ¬βββββββββββββ β
β β β
β β β
β β β
β ββββββββββββββββββββββΌβββββββββββββββββββ β
β β SemanticPipeline β β
β β β β
β β - build_pipeline() β β
β β - run_pipeline() β β
β βββββ¬ββββββββββββββ¬βββββββββββββ¬βββββββββ β
β β β β β
β ββββββββββββββββ ββββββββββ βββββββ β
β β β β β
β βΌ βΌ βΌ β
β ββββββββββββββββ βββββββββββββββ βββββββββββββββββ β
β βConfigManager β βEventEmitter β βProgressTrackerβ β
β ββββββββββββββββ βββββββββββββββ βββββββββββββββββ β
β β
β DOCUMENT PROCESSING β
β β
β βββββββββββββββββββββββββ β
β β DocumentProcessor β β
β β β β
β β - load_document() β β
β β - extract_sections() β β
β βββββββββββββ¬ββββββββββββ β
β β β
β βββββββββ΄βββββββββββββββββββββββββββ β
β β β β
β βΌ βΌ β
β ββββββββββββββββ βββββββββββββββββββ β
β βDocumentLoaderββββββββββββββββββ€ BaseLoader β β
β βManager β β (Abstract) β β
β ββββββββββββββββ ββββββββββ¬βββββββββ β
β β β
β βββββββββββββββββββΌβββββββββββββββββ¬ββββββββββββββββ β
β β β β β β
β βΌ βΌ βΌ βΌ β
β βββββββββββββββββ βββββββββββββββ βββββββββββββββ ββββββββββββββ
β βTextFileLoader β βPDFLoader β βDocxLoader β βMarkdownLdrββ
β βββββββββββββββββ βββββββββββββββ βββββββββββββββ ββββββββββββββ
β β
β CHUNKING β
β β
β βββββββββββββββββββββββ β
β β ChunkingEngine β β
β β β β
β β - chunk_document() β β
β β - process_chunks() β β
β βββββββββββ¬ββββββββββββ β
β β β
β β β
β βΌ β
β βββββββββββββββββββββββββ β
β βBaseChunkingStrategy β β
β β(Abstract) β β
β βββββββββββββ¬ββββββββββββ β
β β β
β βββββββββββΌβββββββββββββ¬ββββββββββββββββββββ β
β β β β β β
β βΌ βΌ βΌ βΌ β
ββββββββββββββ β ββββββββββββββ βββββββββββββββββ βββββββββββββββββ β
ββSemantic β β βFixedSize β βRecursiveChunk β βHybridChunking β β
ββChunking β β βChunking β βStrategy β βStrategy β β
ββββββββββββββ β ββββββββββββββ βββββββββββββββββ βββββββββββββββββ β
β β β
β βΌ β
β βββββββββββββββββββββββββ β
β β SemanticAnalyzer β β
β β β β
β β - analyze_chunk() β β
β β - get_content_score() β β
β βββββββββββββββββββββββββ β
β β
β LLM SERVICES β
β β
β ββββββββββββββββββββββββ β
β β LLMServiceRouter β β
β β β β
β β - route_request() β β
β β - select_service() β β
β ββββββββββββ¬ββββββββββββ β
β β β
β βΌ β
β βββββββββββββββββββββββ β
β β BaseLLMService β β
β β (Abstract) β β
β βββββββββββ¬ββββββββββββ β
β β β
β βββββββ΄βββββββ β
β β β β
β βΌ βΌ β
β βββββββββββββββ βββββββββββββββ β
β βOpenAIServiceβ βLocalLLMSvc β β
β βββββββββββββββ βββββββββββββββ β
β β
β QUESTION GENERATION β
β β
β ββββββββββββββββββββββββββ β
β β QuestionGenerator β β
β β β β
β β - generate_questions() β β
β β - create_prompts() β β
β βββββββββββββ¬βββββββββββββ β
β β β
β βΌ β
β ββββββββββββββββββββββββββ βββββββββββββββββββββββ β
β β CategoryHandler β β PromptTemplate β β
β β β β β β
β β - get_category_prompts() β - format() β β
β β - get_question_count() β β - get_variables() β β
β ββββββββββββββββββββββββββ βββββββββββββββββββββββ β
β β
β VALIDATION β
β β
β ββββββββββββββββββββββ β
β β ValidationEngine β β
β β β β
β β - validate() β β
β β - combine_results()β β
β ββββββββββ¬ββββββββββββ β
β β β
β βΌ β
β βββββββββββββββββββ β
β β BaseValidator β β
β β (Abstract) β β
β ββββββββββ¬βββββββββ β
β β β
β βββββββΌβββββββββ¬ββββββββββββββ¬ββββββββββββββββ β
β β β β β β β
β βΌ βΌ βΌ βΌ βΌ β
β ββββββββββββββ ββββββββββββ ββββββββββββββ ββββββββββββββ βββββββββββββββββββ β
β βFactualAcc β βQuestion β βAnswerComp β βDiversity β βRAGFactualValid β β
β βValidator β βClarity β βValidator β βValidator β β β β
β ββββββββββββββ ββββββββββββ ββββββββββββββ ββββββββββββββ ββββββββββ¬βββββββββ β
β β β
β βΌ β
β βββββββββββββββββββ β
β βLlamaIndexAdapterβ β
β βββββββββββββββββββ β
β β
β OUTPUT β
β β
β ββββββββββββββββββββββ β
β β OutputFormatter β β
β β β β
β β - format_output() β β
β β - save_output() β β
β ββββββββββ¬ββββββββββββ β
β β β
β βΌ β
β ββββββββββββββββββββββ β
β β BaseOutputAdapter β β
β β (Abstract) β β
β ββββββββββ¬ββββββββββββ β
β β β
β ββββββ΄ββββββββ β
β β β β
β βΌ βΌ β
β βββββββββββββ ββββββββββββ β
β βJSONAdapterβ βCSVAdapterβ β
β βββββββββββββ ββββββββββββ β
β β
β MODELS β
β β
β ββββββββββββββββββ ββββββββββββββ ββββββββββββββββ ββββββββββββββββββ β
β β Document β β Chunk β β Question β βValidationResultβ β
β β (dataclass) β β (dataclass)β β (dataclass) β β (dataclass) β β
β ββββββββββββββββββ ββββββββββββββ ββββββββββββββββ ββββββββββββββββββ β
β β
β ββββββββββββββββββ ββββββββββββββ ββββββββββββββββ β
β βDocumentMetadataβ βSection β βChunkAnalysis β β
β β (dataclass) β β(dataclass) β β (dataclass) β β
β ββββββββββββββββββ ββββββββββββββ ββββββββββββββββ β
β β
β BATCH PROCESSING β
β β
β βββββββββββββββββββββ β
β β BatchProcessor β β
β β β β
β β - process_batch() β β
β β - queue_files() β β
β ββββββββββ¬βββββββββββ β
β β β
β βΌ β
β ββββββββββββββββββββββ ββββββββββββββββββββββ β
β β ParallelScheduler β β CheckpointManager β β
β β β β β β
β β - run_parallel() β β - save_checkpoint()β β
β β - handle_results() β β - load_checkpoint()β β
β ββββββββββββββββββββββ ββββββββββββββββββββββ β
β β
β UTILITIES β
β β
β βββββββββββββββββ ββββββββββββββ ββββββββββββββ ββββββββββββββββββ β
β β TokenCounter β β Logger β βTextCleaner β βExceptionHandlerβ β
β βββββββββββββββββ ββββββββββββββ ββββββββββββββ ββββββββββββββββββ β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
SemanticQAGen
class SemanticQAGen:
"""Main interface for generating question-answer pairs from text documents."""
def __init__(self, config_path: Optional[str] = None,
config_dict: Optional[Dict[str, Any]] = None,
verbose: bool = False):
"""Initialize SemanticQAGen with optional configuration."""
def process_document(self, document_path: str) -> Dict[str, Any]:
"""
Process a document to generate question-answer pairs.
Args:
document_path: Path to the document file.
Returns:
Dictionary containing questions, statistics, and metadata.
"""
def process_batch(self, input_dir: Optional[str] = None,
output_dir: Optional[str] = None,
file_types: Optional[List[str]] = None) -> Dict[str, Dict[str, Any]]:
"""
Process multiple documents from a directory.
Args:
input_dir: Directory containing documents to process.
output_dir: Directory to save outputs.
file_types: List of file types to process (e.g., ["txt", "pdf"]).
Returns:
Dictionary mapping filenames to results.
"""
def save_questions(self, result: Dict[str, Any],
output_path: str,
format_name: Optional[str] = None) -> str:
"""
Save generated questions to a file.
Args:
result: Results from process_document.
output_path: Path where to save the output.
format_name: Format to save in (json, csv, etc.).
Returns:
Path to the saved file.
"""
def create_default_config_file(self, output_path: str) -> None:
"""Create a default configuration file."""
def create_qa_retriever(self, result: Dict[str, Any], api_key: Optional[str] = None) -> Any:
"""
Create a LlamaIndex retriever from generated QA pairs.
Args:
result: Results from process_document.
api_key: Optional OpenAI API key.
Returns:
LlamaIndex retriever object for RAG applications.
"""
For additional API details, see the complete API Documentation.
SemanticQAGen provides a comprehensive command-line interface:
semantic-qa-gen process <document> [-o OUTPUT] [-f {json,csv}] [-c CONFIG] [-v]
semantic-qa-gen process-batch [input_dir] [-o OUTPUT_DIR] [--types TYPES] [-c CONFIG]
semantic-qa-gen init-config <output> [-i]
semantic-qa-gen interactive
semantic-qa-gen version
process Process a document and generate questions
document Path to the document file
-o, --output Path for output file
-f, --format Output format (json, csv)
-c, --config Path to config file
-v, --verbose Enable verbose output
process-batch Process multiple documents from a directory
input_dir Input directory containing documents
-o, --output-dir Output directory for results
--types File types to process (comma-separated)
--exclude Files to exclude (comma-separated)
-c, --config Path to config file
--no-checkpoints Disable checkpointing
-v, --verbose Enable verbose output
init-config Create a default configuration file
output Path for the config file
-i, --interactive Create config interactively
interactive Run in interactive mode
version Show the version and exit
# Process a PDF document
semantic-qa-gen process document.pdf -o questions_output
# Process all files in a directory
semantic-qa-gen process-batch input_docs/ -o output_results/
# Process specific file types
semantic-qa-gen process-batch input_docs/ --types pdf,txt -o output_results/
# Process with a specific configuration
semantic-qa-gen process document.txt --config my_config.yml --format csv
# Create a default configuration file
semantic-qa-gen init-config config.yml
# Create a configuration file interactively
semantic-qa-gen init-config config.yml --interactive
from semantic_qa_gen import SemanticQAGen
# Initialize with default settings
qa_gen = SemanticQAGen()
# Process a document
result = qa_gen.process_document("path/to/document.txt")
# Save the questions to a JSON file
qa_gen.save_questions(result, "qa_pairs.json")
# Display stats
print(f"Generated {len(result['questions'])} questions")
print(f"Factual questions: {result['statistics']['categories']['factual']}")
print(f"Inferential questions: {result['statistics']['categories']['inferential']}")
print(f"Conceptual questions: {result['statistics']['categories']['conceptual']}")
from semantic_qa_gen import SemanticQAGen
# Configuration for batch processing with checkpoints
config = {
"processing": {
"enable_checkpoints": True,
"batch": {
"input_dir": "./documents",
"output_dir": "./results",
"supported_types": ["txt", "pdf", "md", "docx"],
"continue_on_error": True,
"skip_completed_files": True
}
}
}
# Initialize with batch processing config
qa_gen = SemanticQAGen(config_dict=config)
# Process all files in the input directory
# Will resume from previous checkpoints if available
batch_results = qa_gen.process_batch()
print(f"Processed {len(batch_results)} documents")
# You can also specify directories explicitly
batch_results = qa_gen.process_batch(
input_dir="./other_documents",
output_dir="./other_results",
file_types=["pdf", "txt"]
)
from semantic_qa_gen import SemanticQAGen
# Configuration for hybrid LLM setup
config = {
"llm_services": {
"local": {
"enabled": True,
"url": "http://localhost:11434/api",
"model": "mistral:7b",
"default_for": ["chunking", "validation"]
},
"remote": {
"enabled": True,
"provider": "openai",
"model": "gpt-4",
"api_key": "YOUR_API_KEY",
"default_for": ["analysis", "generation"]
}
}
}
# Initialize with hybrid LLM config
qa_gen = SemanticQAGen(config_dict=config)
# Process document using hybrid approach
# - Local model will handle chunking and validation
# - Remote model will handle analysis and question generation
result = qa_gen.process_document("document.pdf")
from semantic_qa_gen import SemanticQAGen
# Configuration focusing on validation
config = {
"validation": {
"factual_accuracy": {
"enabled": True,
"threshold": 0.7
},
"rag_factual": {
"enabled": True,
"model": "gpt-4",
"threshold": 0.75,
"strict_mode": True
},
"use_enhanced_validation": True # Combined approach
}
}
# Process document with enhanced validation
qa_gen = SemanticQAGen(config_dict=config)
result = qa_gen.process_document("document.pdf")
# Create a retriever from the validated questions
retriever = qa_gen.create_qa_retriever(result, api_key="YOUR_OPENAI_API_KEY")
# Use the retriever in a separate application
response = retriever.retrieve("What is the most important concept?")
config = {
"question_generation": {
"max_questions_per_chunk": 12,
"categories": {
"factual": {
"min_questions": 4, # Prefer more factual questions
"weight": 1.5
},
"inferential": {
"min_questions": 3,
"weight": 1.2
},
"conceptual": {
"min_questions": 2,
"weight": 1.0
},
"applied": { # Custom category - practical applications
"min_questions": 3,
"weight": 1.3
}
}
}
}
qa_gen = SemanticQAGen(config_dict=config)
from semantic_qa_gen import SemanticQAGen
config = {
"chunking": {
"strategy": "semantic",
"target_chunk_size": 1200, # Smaller chunks
"max_chunk_size": 1800
},
"processing": {
"concurrency": 2, # Lower concurrency to reduce memory usage
"enable_checkpoints": True,
"checkpoint_interval": 5 # Save checkpoints frequently
}
}
qa_gen = SemanticQAGen(config_dict=config)
result = qa_gen.process_document("large_document.pdf")
SemanticQAGen is designed to be easily extended with custom components.
from semantic_qa_gen.document.loaders.base import BaseLoader
from semantic_qa_gen.document.models import Document, DocumentType, DocumentMetadata
from semantic_qa_gen.utils.error import DocumentError
class CustomFileLoader(BaseLoader):
"""Loader for custom file format."""
def __init__(self, config: Optional[Dict[str, Any]] = None):
super().__init__(config)
def load(self, path: str) -> Document:
"""Load a document from a custom file format."""
if not self.supports_type(path):
raise DocumentError(f"Unsupported file type: {path}")
# Implementation for loading custom format
with open(path, 'r', encoding='utf-8') as file:
content = file.read()
# Create and return document
return Document(
content=content,
doc_type=DocumentType.TEXT,
path=path,
metadata=self.extract_metadata(path)
)
def supports_type(self, file_path: str) -> bool:
"""Check if this loader supports the given file type."""
_, ext = os.path.splitext(file_path.lower())
return ext == '.custom'
def extract_metadata(self, path: str) -> DocumentMetadata:
"""Extract metadata from the custom file."""
# Implementation for extracting metadata
return DocumentMetadata(
title=os.path.basename(path),
source=path
)
from semantic_qa_gen import SemanticQAGen
from semantic_qa_gen.document.processor import DocumentProcessor
# Create your custom loader
custom_loader = CustomFileLoader()
# Initialize SemanticQAGen
qa_gen = SemanticQAGen()
# Get the document processor
doc_processor = qa_gen.pipeline.document_processor
# Register your custom loader
doc_processor.loaders.append(custom_loader)
# Now you can process custom file formats
result = qa_gen.process_document("document.custom")
from semantic_qa_gen.question.validation.base import BaseValidator, ValidationResult
from semantic_qa_gen.document.models import Question, Chunk
class CustomValidator(BaseValidator):
"""Custom validator for specialized validation logic."""
def __init__(self, config: Optional[Dict[str, Any]] = None):
super().__init__(config)
self.threshold = self.config.get('threshold', 0.7)
async def validate(self, question: Question, chunk: Chunk) -> ValidationResult:
"""Implement custom validation logic."""
# Custom validation implementation
score = 0.8 # Example score
return ValidationResult(
question_id=question.id,
is_valid=score >= self.threshold,
scores={"custom_score": score},
reasons=[f"Custom validation: {score:.2f}"],
suggested_improvements=None if score >= self.threshold else "Suggestion for improvement"
)
from semantic_qa_gen.chunking.strategies.base import BaseChunkingStrategy
from semantic_qa_gen.document.models import Document, Section, Chunk
class CustomChunkingStrategy(BaseChunkingStrategy):
"""Custom strategy for document chunking."""
def __init__(self, config: Optional[Dict[str, Any]] = None):
super().__init__(config)
self.target_size = self.config.get('target_chunk_size', 1500)
def chunk_document(self, document: Document, sections: List[Section]) -> List[Chunk]:
"""Break a document into chunks using a custom strategy."""
chunks = []
# Custom implementation of chunking algorithm
return chunks
Issue: Missing dependencies when installing Solution: Install with the appropriate extra dependencies:
pip install semantic-qa-gen[full]
Issue: Conflicts with existing packages Solution: Use a virtual environment:
python -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
pip install semantic-qa-gen
Issue: Out of memory errors with large documents Solution: Adjust chunking and processing settings:
config = {
"chunking": {
"target_chunk_size": 1000, # Smaller chunks
"max_chunk_size": 1500
},
"processing": {
"concurrency": 1, # Reduce concurrency
"enable_checkpoints": True,
"checkpoint_interval": 3 # More frequent checkpoints
}
}
Issue: Slow processing with PDF documents Solution: Disable unnecessary PDF features:
config = {
"document": {
"loaders": {
"pdf": {
"extract_images": False,
"ocr_enabled": False,
"fix_cross_page_sentences": False
}
}
}
}
Issue: OpenAI rate limits Solution: Adjust rate limiting settings:
config = {
"llm_services": {
"remote": {
"rate_limit_tokens": 60000, # Reduce token usage
"rate_limit_requests": 50 # Reduce requests per minute
}
}
}
Issue: Local LLM not responding Solution: Check connection settings and increase timeout:
config = {
"llm_services": {
"local": {
"url": "http://localhost:11434/api", # Verify URL
"timeout": 120 # Increase timeout
}
}
}
To enable detailed logging for troubleshooting:
from semantic_qa_gen import SemanticQAGen
import logging
# Enable debug logging
logging.basicConfig(level=logging.DEBUG)
# Or enable verbose mode
qa_gen = SemanticQAGen(verbose=True)
For CLI usage:
semantic-qa-gen process document.pdf -o output --verbose
SemanticQAGen is released under the MIT License.
Copyright Β© 2025 Stephen Genusa
This project builds upon concepts from the original Augmentoolkit project. SemanticQAGen is not affiliated with or endorsed by the creators of Augmentoolkit.
FAQs
A Python library for generating high-quality question-answer pairs from PDF, DOCX, MD, and TXT files
We found that semantic-qa-gen demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago.Β It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
/Security News
Two npm packages masquerading as WhatsApp developer libraries include a kill switch that deletes all files if the phone number isnβt whitelisted.
Research
/Security News
Socket uncovered 11 malicious Go packages using obfuscated loaders to fetch and execute second-stage payloads via C2 domains.
Security News
TC39 advances 11 JavaScript proposals, with two moving to Stage 4, bringing better math, binary APIs, and more features one step closer to the ECMAScript spec.