Metadata-Version: 2.4
Name: llm-feedback-control
Version: 0.2.3
Summary: Reliable, checkable structured output from a small local LLM, by wrapping it in a deterministic feedback loop: a regime gate + exact graph analysis + explicit refusal, plus a bounded re-extraction loop. Zero runtime dependencies; runs with no model at all.
Author-email: Edward Chalk <edward.chalk@sapientronic.ai>
License: llm-feedback-control
        
        Copyright (c) 2026 Edward Chalk (sapientronic.ai)
        
        Permission is hereby granted, free of charge, to any person obtaining a copy
        of this software and associated documentation files (the "Software"), to use,
        copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
        the Software, and to permit persons to whom the Software is furnished to do
        so, subject to the following conditions:
        
        1. The above copyright notice and this permission notice shall be included
           in all copies or substantial portions of the Software.
        
        2. Attribution. Any publication, presentation, derivative work, or product
           that uses or builds on this Software must include visible attribution to
           Edward Chalk and sapientronic.ai. The phrase "Built with llm-feedback-control
           by Edward Chalk (sapientronic.ai)" or equivalent is acceptable.
        
        3. The Software is provided "AS IS", without warranty of any kind, express
           or implied, including but not limited to the warranties of merchantability,
           fitness for a particular purpose, and noninfringement. In no event shall
           the authors or copyright holders be liable for any claim, damages, or
           other liability, whether in an action of contract, tort, or otherwise,
           arising from, out of, or in connection with the Software or the use or
           other dealings in the Software.
        
        This license is modeled on the MIT License with an explicit attribution
        clause (clause 2).
        
Project-URL: Homepage, https://github.com/pcoz/llm-feedback-control
Project-URL: Repository, https://github.com/pcoz/llm-feedback-control
Project-URL: Issues, https://github.com/pcoz/llm-feedback-control/issues
Project-URL: Changelog, https://github.com/pcoz/llm-feedback-control/blob/main/docs/CHANGELOG.md
Keywords: llm,feedback-control,structured-extraction,state-machine,workflow,hallucination,reliability,ollama,small-language-model,auditable,refusal
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Science/Research
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: Text Processing :: Linguistic
Requires-Python: >=3.8
Description-Content-Type: text/markdown
License-File: LICENSE
Provides-Extra: aws
Requires-Dist: boto3>=1.26; extra == "aws"
Provides-Extra: dev
Requires-Dist: pytest>=7.0; extra == "dev"
Requires-Dist: build>=1.0; extra == "dev"
Requires-Dist: twine>=4.0; extra == "dev"
Dynamic: license-file

# LLM Feedback Control

**Get reliable, checkable structured data out of a small, local language model — by
wrapping it in deterministic feedback.**

[![CI](https://github.com/pcoz/llm-feedback-control/actions/workflows/ci.yml/badge.svg)](https://github.com/pcoz/llm-feedback-control/actions/workflows/ci.yml)

## What it does

Language models are fluent but they make things up — and they sound just as sure
when they're wrong. That bites hardest when you ask one to pull **structure** out of
text (the steps of a process, the fields of a form): it gets most of it right, then
quietly invents or drops the rest.

This library turns free text into **structured data you can trust.** It pairs the
model with a deterministic **reference** — real checking code suited to what you're
extracting — and runs a feedback loop that:

- **verifies** the model's answer against that reference,
- **fills in** what the model missed by re-asking with the gaps pointed out,
- **refuses** — says "I'm not sure" — when it can't verify the result, instead of
  guessing.

Because the **checking** (not the model's size) does the heavy lifting, a small
model you run for free on a laptop becomes reliable enough to use. In our tests a
3.8B model wrapped this way matches one about seven times larger.

### What you can extract

It's **one engine pointed at different targets.** A target is anything you can pair
with a schema and a deterministic check — **two ship today**, more are a small
addition (the loop is public and injectable):

- **workflows / processes → state machines** (`run_audit`) — states, transitions,
  dead ends, unreachable steps, loops;
- **form fields** (invoices, applications, claims) against a field schema
  (`extract_form`) — verifies each value against the source, recovers ones the model
  hallucinated, refuses on missing required fields;
- **records / tables**, **entities & relations**, **configs / specs** — bring a
  schema + a reference and call `feedback_loop`.

It helps on the **structured, verifiable slice** — where a deterministic reference
exists. For open-ended generation (summaries, sentiment) there's nothing to check
against, so it refuses to claim exactness, by design.

## Documentation

The full **user manual** is in [`docs/`](docs/index.md):

| chapter | contents |
|---|---|
| [Getting started](docs/manual/01-getting-started.md) | install, the API, the `lfc` CLI, choosing/bringing a model, configuration |
| [How it works](docs/manual/02-how-it-works.md) | the op-amp model: negative/positive feedback, refusal-as-stabilizer, the general engine |
| [API reference](docs/manual/03-api-reference.md) | every public function |
| [Results](docs/manual/04-results.md) | measured numbers, method, honest scope |
| [Worked examples](docs/manual/05-examples.md) | actual run transcripts |
| [FAQ](docs/manual/06-faq.md) | GPU? models? offline? why did it refuse? |
| [Changelog](docs/CHANGELOG.md) | release history |

## Install

```bash
pip install llm-feedback-control     # zero dependencies
```

Then follow [Getting started](docs/manual/01-getting-started.md). The deterministic
parts run with no model at all; a model (local Ollama, OpenAI, or your own callable)
is a pure upgrade.

## License

MIT with an attribution clause — see [`LICENSE`](LICENSE).
Built with llm-feedback-control by Edward Chalk (sapientronic.ai).
