Schema-first LLM extraction framework with entity grounding and deterministic post-processing
Project description
Sourcery: Schema-First LLM Document Extraction for Python
Sourcery is a Python LLM extraction framework for turning unstructured text, PDFs, HTML, URLs, and VLM OCR image sources into typed, source-grounded Pydantic data.
Define your extraction schema with Pydantic, run chunked model extraction, align every result back to source spans, optionally reconcile mentions into canonical claims, and export JSONL or HTML review workflows.
What Is Sourcery
Sourcery is for people building:
- document AI pipelines,
- compliance and legal extraction systems,
- financial filing intelligence,
- contract and policy analyzers,
- review workflows with human approval.
Core idea:
- Define extraction contracts in Pydantic v2.
- Run deterministic chunked extraction with LLM structured output.
- Align results to source offsets.
- Reconcile at document-level into canonical claims.
- Review/export via JSONL + HTML reviewer.
Why Sourcery
Sourcery is optimized for type safety + runtime reliability + deterministic post-processing.
- Pydantic contracts are first-class (
EntitySpec.attributes_model). - BlackGeorge-native runtime orchestration (no custom provider router stack).
- Deterministic alignment statuses (
exact,fuzzy,partial,unresolved). - Deterministic merge behavior across passes.
- Typed error taxonomy for provider/runtime/pipeline/ingestion failures.
- Run replay via BlackGeorge run store.
- Built-in reviewer UI (search/filter/approve/export).
- Document-level reconciliation support with BlackGeorge Workforce + Blackboard + resolver worker.
BlackGeorge Relationship
Sourcery is an application layer on top of BlackGeorge runtime primitives (Desk, Flow, Worker, Workforce, RunStore, EventBus).
- Sourcery handles extraction domain logic.
- BlackGeorge handles model execution, workflow orchestration, events, pause/resume, and run storage.
This means BlackGeorge is a hard runtime dependency in this project.
Features
- Schema-first extraction with Pydantic models.
- Ingestion adapters: text, file, PDF, HTML, URL, VLM-based image OCR.
- Deterministic chunking and alignment.
- Multi-pass extraction with stop-when-no-new-results.
- Cross-chunk refinement and document-level reconciliation.
- Session-based refinement mode.
- Reviewer HTML UI + export to JSONL/CSV.
- Real async extraction (native async/await, no thread pools).
- Streaming extraction — yields results per chunk as they land.
- Run tracing and replay.
Install
uv sync --extra dev --extra ingest
PyPI distribution name: sourceryforge
Python import path: sourcery
Install from PyPI:
pip install sourceryforge
Or with uv:
uv add sourceryforge
If you want benchmark tooling:
uv sync --extra benchmark
Set your provider key (example):
export DEEPSEEK_API_KEY="..."
Set RuntimeConfig.model to a provider/model route supported by your BlackGeorge runtime setup.
Reproducible Benchmark
Run the benchmark from this repo root:
uv run sourcery-benchmark --text-types english,japanese,french,spanish --max-chars 4500 --max-passes 2 --sourcery-model deepseek/deepseek-chat
Run it from any directory:
uv run --project /path/to/sourcery sourcery-benchmark --text-types english
Or run the compatibility wrapper:
uv run benchmark_compare.py --text-types english
Output JSON is written to benchmark_results/ and includes:
- run settings,
- tokenization throughput table,
- per-language extraction metrics,
- aggregate framework summaries.
Benchmark Port Scope
The benchmark runner compares Sourcery with LangExtract using a similar Gutenberg sampling flow. It is not a byte-for-byte clone of LangExtract's benchmark script.
- Ported: Gutenberg text sampling flow, per-language extraction runs, retry behavior, timing, grounded/unresolved metrics, JSON output artifacts.
Quickstart
from pydantic import BaseModel
import sourcery
from sourcery.contracts import (
EntitySchemaSet,
EntitySpec,
ExtractRequest,
ExtractionExample,
ExtractionTask,
ExampleExtraction,
RuntimeConfig,
)
class PersonAttrs(BaseModel):
role: str | None = None
request = ExtractRequest(
documents="Alice is the CEO of Acme.",
task=ExtractionTask(
instructions="Extract people.",
schema=EntitySchemaSet(
entities=[EntitySpec(name="person", attributes_model=PersonAttrs)]
),
examples=[
ExtractionExample(
text="Bob is the CTO.",
extractions=[
ExampleExtraction(entity="person", text="Bob", attributes={"role": "CTO"})
],
)
],
),
runtime=RuntimeConfig(model="deepseek/deepseek-chat"),
)
result = sourcery.extract(request)
print(result.metrics.model_dump(mode="json"))
More examples: CODE_EXAMPLES.md
Full usage and API guide: USAGE.md
Notebook workflows: examples/notebooks/sourcery_quickstart.ipynb, examples/notebooks/sourcery_pdf_workflow.ipynb
Project Structure
sourcery/contracts: public types and contracts.sourcery/pipeline: chunking, prompt compiler, aligner, merger.sourcery/runtime: engine + BlackGeorge runtime integration.sourcery/ingest: document loaders and adapters.sourcery/io: JSONL, visualization, reviewer UI.sourcery/observability: run trace collection.
Validation
uv run --extra dev pytest -q
uv run --extra dev ruff check sourcery tests
uv run --extra dev mypy sourcery
Documentation Site
Build and serve project docs with MkDocs:
uv run --extra docs mkdocs serve
uv run --extra docs mkdocs build --strict
Common Use Cases
- Regulatory compliance extraction.
- SEC filing and earnings-call intelligence.
- Contract clause extraction and renewal tracking.
- Policy change monitoring.
- Research paper benchmark extraction.
- Incident/postmortem structure mining.
License
Licensed under the MIT License. See LICENSE.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file sourceryforge-0.2.0.tar.gz.
File metadata
- Download URL: sourceryforge-0.2.0.tar.gz
- Upload date:
- Size: 274.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.8 {"installer":{"name":"uv","version":"0.11.8","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3cbdee016fca70512a5ada1eca08cc1b102b4c9a412c48fd79f1848113b75834
|
|
| MD5 |
ea0295e327f5bd46bab0669030a5e0a9
|
|
| BLAKE2b-256 |
c84b63350ff4fda01ee52539cf1ebc4d40bc104ca53f188e891fbe057c982ce7
|
File details
Details for the file sourceryforge-0.2.0-py3-none-any.whl.
File metadata
- Download URL: sourceryforge-0.2.0-py3-none-any.whl
- Upload date:
- Size: 58.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.8 {"installer":{"name":"uv","version":"0.11.8","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f9242ea82db56490edb8b96919eac6a263e49519b753259a463da2c09daf92cb
|
|
| MD5 |
25acf8ceebb9507b199af46b73d2ec5f
|
|
| BLAKE2b-256 |
ed77ea1424b447a292f1507000c7db4a202ea8c9abac1a139921856e354c37a8
|