Source spans make model output inspectable
LangExtract's useful move is to keep extracted text tied to the document it came from. You define classes, attributes, instructions, and examples; a model produces structured items; the resolver finds the matching character intervals in the source. A reviewer can then see each claim in context. When an item cannot be located, its character interval is null, giving application code a reason to reject or quarantine it.
That is different from assuming the model's JSON is true. The README warns that examples should use verbatim text in source order and can trigger alignment warnings when they do not. It also says a model may copy material from the few-shot examples into its answer. Filtering null intervals catches output that cannot be grounded, but a phrase can exist in the document and still be labeled incorrectly. The final check remains a domain decision.
Long documents are split, repeated, and reviewed
For a long input, LangExtract divides text into chunks, sends work in parallel, and can make multiple extraction passes. The README's sample sets extraction_passes=3, max_workers=20, and a 1,000-character buffer. Those are controls, not a promised speed or accuracy result. More passes and smaller chunks change request count, cost, context, and the chance that a relationship crosses a boundary.
Results can be saved as JSONL and rendered as a self-contained interactive HTML file. Highlighted spans let a human move between the structured item and its source sentence. That review surface is one reason to choose LangExtract over a small script that asks for JSON. Missing spans, repeated mentions, and inferred attributes become visible.
What happened when we ran it
Our sandbox installed 128 Python packages in 25 seconds and occupied 290 MB on disk. The package build succeeded in 1 second. We tested commit 62b933a in an unprivileged Python 3.12 Bookworm container with 3 CPUs and 8 GB of RAM. The checkout contained 150 files, about 41,621 lines of source, and used 13.1 MB before dependencies.
Pytest exited with code 1 after 82 seconds. It reported 877 passed, 3 failed, and 20 skipped out of 880 tests, alongside 52 passing subtests and 94 warnings. Each failure came from create_provider_plugin_test.py: one expected an offline-safe editable install to succeed with pip, while 2 expected generated wheel, source distribution, or PEP 660 installation checks to return successfully. The supplied log tail does not show the underlying stdout, so we cannot assign a cause.
Pip-audit reported 3 known vulnerabilities in the installed environment. Our measurement does not identify them in the supplied block, so this review will not guess which packages or advisories were involved. The repository also had 11 CI workflows, a Dockerfile, and a tests directory. Those are good maintenance signals, but they do not turn this particular failing run into a pass.
Provider choice changes more than the API key
Gemini is the default path in the current quick start. OpenAI support needs the optional extra, while Vertex AI accepts a project, location, service-account authentication, and an optional batch configuration. Ollama provides a local route with no cloud key, but the README says its provider does not support output_schema. A custom provider can be shipped as a separate package and discovered through an entry point.
Those paths do not have identical behavior. Issue 529 reports that top-level temperature=0.0 is silently omitted when callers pass a prebuilt config or model, even though it reaches the provider with model_id. Issue 532 reports that Vertex batch mode places tools inside generationConfig, where the batch schema rejects it. Both reports include isolated reproductions. Test the exact provider, real-time or batch path, and configuration style you plan to deploy.
Schema controls still need examples and rejection rules
Gemini and OpenAI can use an explicit output schema, with or without few-shot examples. Supported models can also use controlled generation. That narrows the response shape, but it does not decide which facts belong in a field. A good extraction job still needs examples that cover ambiguous mentions, absent values, repeated names, and attributes that must remain tied to literal evidence.
Issue 542 gives a narrower warning about configuration compatibility. Passing format_type through the older resolver_params route can leave a string where the formatter expects an enum, leading to an AttributeError before inference. A pull request was open when we checked. Pin LangExtract, validate the configuration at startup, and keep document fixtures that must produce expected spans.
Release 1.7.0 is active, while the queue is busy
Version 1.7.0 was published on September 13, 2026. Its notes cover repeated-mention alignment, provider-plugin generation, Gemini settings, unusable provider responses, and OpenAI routing. The main branch advanced to commit 62b933a on September 21, and GitHub showed 123 combined open issues and pull requests plus 38,841 stars. Activity continued in the queue through September 24.
Google labels the project as unofficially supported, despite the organization name. Health-related examples carry an additional terms notice and say they are demonstrations rather than approved products. Source grounding makes review easier; it does not certify an extraction for diagnosis, treatment, compliance, or any other decision where a wrong field can harm someone.
Choose it when evidence must travel with the field
Instructor is a closer fit when typed responses and retries are enough. Presidio is narrower and more predictable for PII detection and redaction. Unstructured belongs earlier in the pipeline when document parsing and layout are the obstacle. LangExtract earns the extra machinery when the extracted record must point back into its source and a person will inspect that link.
The 877 passing tests show substantial exercised code, while the 3 packaging failures and 3 audit findings set the terms for adoption. Start with one provider and a representative document set. Reject null spans, record the model and prompt configuration, and read the HTML output before feeding extracted fields into another system. That workflow uses LangExtract's strongest feature without mistaking traceability for correctness.

