ExtractThinker Documentation

repository·main·Indexed 23 days ago

https://github.com/enoch3712/extractthinker

A document intelligence library (v0.1.14) used to extract and classify structured data from various document formats using Large Language Models (LLMs). It provides an ORM-like interface featuring Document Loaders, Extractors, Splitters, and Pydantic-based Contracts to define target data structures. The tool supports asynchronous batch processing, multi-page document splitting via the Process class, and integration with local LLMs such as Ollama.

Tokens
59.2K
Snippets
135
Records
241
Agent score
81%

What's inside extract_thinker

  1. Core features of ExtractThinker

    main

    ExtractThinker provides several native capabilities for Document Intelligence Processing (IDP):

    • Extraction with Pydantic: Use Pydantic models for structured data extraction, validation, and prompt engineering.
    • Classification & Split: Intelligent document classification and splitting with support for consensus strategies, eager/lazy splitting, and confidence thresholds.
    • PII Detection: Automatic detection and handling of sensitive personal information with a privacy-first approach.
    • LLM and OCR Agnostic: Ability to switch between different LLM providers and OCR engines based on cost and performance requirements.
  2. Define data extraction contracts using Pydantic

    main

    ExtractThinker uses Contract classes (inheriting from Pydantic's BaseModel logic) to define the schema for extracted data. You use Field to provide natural language descriptions that guide the LLM on how to interpret and extract specific information. This allows for structured extraction of complex entities like job roles or resumes.

    from extract_thinker import Contract
    from typing import List, Optional
    from pydantic import Field
    
    class RoleContract(Contract):
        company_name: str = Field("Company name")
        years_of_experience: int = Field("Years of experience required. If not mention, calculate with start date and end date")
        is_remote: bool = Field("Is the role remote?")
        country: str = Field("Country of the role")
        city: Optional[str] = Field("City of the role")
        list_of_skills: List[str] = Field("list of strings, e.g [\"5 years experience\", \"3 years in React\", \"Typescript\"]\nMake the lists of skills to be a yes/no list for matching with candidates")
  3. Available Classification Strategies

    main

    When using multi-model techniques like Mixture of Models (MoM), you can specify how the final result is determined using one of the following strategies:

    • CONSENSUS: The final classification is only returned if all participating models agree on the same result.
    • HIGHER_ORDER: The system selects the classification result from the model that reported the highest confidence.
    • CONSENSUS_WITH_THRESHOLD: Requires all models to reach a consensus, and that consensus must meet a minimum confidence threshold.
  4. Define data structures using Contracts

    main

    Contracts in ExtractThinker are Pydantic models used to define the specific structure of the data you want to extract. By inheriting from the Contract class, you provide type safety and automatic validation for the extracted information. You can use standard Python type hints and Pydantic's Field to provide descriptions that help the extraction engine understand what each field represents.

    from extract_thinker import Contract
    from typing import List, Optional
    from pydantic import Field
    
    class InvoiceLineItem(Contract):
        description: str = Field(description="Description of the item")
        quantity: int = Field(description="Quantity of items")
        unit_price: float = Field(description="Price per unit")
        amount: float = Field(description="Total amount for line")
    
    class InvoiceContract(Contract):
        invoice_number: str = Field(description="Invoice identifier")
        date: str = Field(description="Invoice date")
        total_amount: float = Field(description="Total invoice amount")
        line_items: List[InvoiceLineItem] = Field(description="List of items in invoice")
        notes: Optional[str] = Field(description="Additional notes", default=None)
  5. Use the Concatenate strategy for large LLM responses

    main

    The CONCATENATE strategy is used when the content to be extracted or the desired response exceeds the LLM's output context window. It works by splitting the task into chunks, processing them sequentially, and combining the partial responses into a single valid JSON object.

    Workflow

    1. Initial Request: Sends content to the LLM with the requested structure.
    2. Continuation: If the LLM returns a truncated response (finish_reason="length"), the strategy automatically builds a continuation request including the previous partial response for context.
    3. Validation: Once the LLM indicates completion (finish_reason="stop"), the strategy combines all parts and validates the final JSON against your specified ResponseModel.

    When to use

    • Large Context Windows: Best for models like gpt-4o or claude-3-5-sonnet.
    • Moderate Document Size: Suitable for documents that are not excessively large (e.g., up to ~500 pages).

    Note: For extremely large documents, use the PAGINATE strategy instead.

    from extract_thinker import Extractor
    from extract_thinker.models.completion_strategy import CompletionStrategy
    
    extractor = Extractor()
    extractor.load_llm("gpt-4o")
    
    result = extractor.extract(
        file_path,
        ResponseModel,
        completion_strategy=CompletionStrategy.CONCATENATE
    )
  6. Use Type Mapping with Contracts for improved classification

    main

    When defining a Classification, you can pass a contract argument. This contract should be a class that inherits from extract_thinker.models.contract.Contract.

    By providing a contract, the structure is automatically injected into the LLM prompt. This helps the model understand the specific schema and fields expected for that document type, which significantly improves classification accuracy and data extraction consistency.

    from typing import List
    from extract_thinker.models.contract import Contract
    
    class InvoiceContract(Contract):
        invoice_number: str
        invoice_date: str
        lines: List[LineItem]
        total_amount: float
    
    class DriverLicense(Contract):
        name: str
        age: int
        license_number: str
  7. How ExtractThinker works: Core Architecture

    main

    ExtractThinker uses a modular architecture to handle Intelligent Document Processing (IDP):

    • Document Loaders: Preprocess documents from various sources (e.g., Tesseract, PyPdf).
    • Extractors: Orchestrate the flow between loaders and LLMs.
    • Splitters: Break documents into manageable chunks (e.g., ImageSplitter).
    • Contracts: Define the target data structure using Pydantic models.
    • Classifications: Determine the document type to select the correct contract.
    • Processes: Manage the end-to-end workflow of loading, classifying, splitting, and extracting.
  8. Understand Completion Strategies in ExtractThinker

    main

    ExtractThinker uses Completion Strategies to manage how document content is processed by LLMs, specifically addressing scenarios where document content might exceed the model's context window.

    There are three primary strategies available:

    1. FORBIDDEN: The default strategy. It prevents processing if the content exceeds the model's context window, ensuring data integrity by not attempting partial or broken extractions.
    2. CONCATENATE: Designed for content that exceeds the output capacity but fits within the input context window. It handles large content automatically.
    3. PAGINATE: Designed for multi-page documents where the content exceeds both the output and the input context window. This strategy allows for parallel processing and includes mechanisms for conflict resolution between pages.

    Choosing the right strategy depends on your document size and whether you need to process the document as a single unit or in parallel chunks.

  9. Document Classification Overview

    main

    Document classification is the process of identifying the type of a document, which serves as a prerequisite for targeted data extraction and analysis. ExtractThinker provides LLM-based classification that is model-agnostic, avoiding the vendor lock-in associated with services like Azure Document Intelligence.

    ExtractThinker offers four primary classification techniques:

    1. Basic Classification: Uses a single LLM with contract mapping.
    2. Mixture of Models (MoM): Combines multiple models using different strategies to enhance accuracy.
    3. Tree-Based Classification: Designed for complex hierarchies and distinguishing between similar document types.
    4. Vision Classification: Utilizes visual features of the document to improve classification accuracy.
  10. Use caching with Document Loaders

    main

    All Document Loaders support built-in caching via the CachedDocumentLoader base class. You can configure the Time-To-Live (TTL) for cached results during initialization to avoid redundant processing of the same documents.

    from extract_thinker.document_loader import DocumentLoader
    
    class MyCustomLoader(DocumentLoader):
        def __init__(self, content: Any = None, cache_ttl: int = 300):
            # 300 seconds default TTL
            super().__init__(content, cache_ttl) 
  11. How dynamic parsing template structure works

    main

    When dynamic parsing is enabled, the system uses a specific prompt template to guide the model to provide its reasoning within <think> tags before the JSON output. The expected structure is:

    Please provide your thinking process within <think> tags, followed by your JSON output.
    
    JSON structure:
    {your_structure}
    
    OUTPUT example:
    <think>
    Your step-by-step reasoning and analysis goes here...
    </think>
    
    ##JSON OUTPUT
    {
        ...
    }