Skip to main content

json-correction-loop

A Python library for iteratively correcting large LLM-generated JSON and knowledge graphs via RFC 6902 patches and a multi-agent sub-task stack (path_finder, context narrowing, request validator, patch evaluator). Composable critic loop with convergence policies. Works with OpenAI, Anthropic, OpenRouter.

PyPI Python License CI Status

TL;DR. When an LLM regenerates a 100-entity / 183-edge JSON knowledge graph on critic feedback (the prevailing "full-regen" pattern), gpt-4o-mini fixes 0 / 8 flagged defects and burns 73K tokens. This library — a critic loop with surgical RFC 6902 patching and sub-agent decomposition — fixes 8 / 8 at 17K tokens.

Why this exists

When an LLM produces a large JSON artifact — an agent's memory, a generated knowledge graph, a structured config tree, a multi-step plan — the prevailing pattern is to re-emit the entire object on every critic pass. This is a problem.

We measured it: on a synthetic 100-entity / 183-edge knowledge graph, gpt-4o-mini saturates its 8K max_tokens ceiling mid-array, returns truncated JSON, and across five hardcapped loop iterations fixes 0 of 8 critic-flagged defects while burning 73K tokens and 8.5 minutes of wall clock.

size=100 (100 entities, 183 edges, 8 defects):
  full-regen baseline:    fix=0%   tokens=73,740   wall=435s
  this library (O2N):     fix=100% tokens=17,117   wall=26s

Surgical patching alone isn't enough either: a naive RFC 6902 patcher inside a critic loop only fixes 35–64% of defects, because the LLM acts on critic-flagged symptoms (an edge with the wrong predicate) rather than root causes (the entity whose type was actually flipped). Closing that gap requires sub-agents.

What this library is

A composable gather → plan → execute loop with four sub-agent slots:

  • Critics (you supply) report defects against stable item IDs (JSON pointers, entity IDs).
  • path_finder maps each critic-flagged symptom pointer to its root-cause pointer.
  • Context narrowing scopes both the sub-agent and the patcher to the slice of state implicated by flagged paths — turns out to be a correctness component, not just a cost optimization.
  • Surgical patcher emits RFC 6902 ops via tool calling, validated and applied with a standard JSON Patch library.
  • Convergence policies (quality-stable, hardcap) compose as Protocols.

The library imports no specific LLM client, persistence layer, or event sink. Storage backends and event sinks are Protocols you plug in.

Install

pip install json-correction-loop      # coming soon to PyPI

Or from source:

git clone https://github.com/warpspaceinc/json-correction-loop
cd json-correction-loop
pip install -e ".[dev]"
pytest

Quickstart

The smallest end-to-end example wires fakes through the full loop — no LLM required — to show how the pieces compose:

from json_correction_loop import (
    CorrectionLoopConfig,
    CriticIssue, CriticReport,
    ExecuteResult,
    make_callback_executor,
    make_identity_planner,
    run_correction_loop,
)

# 1. Define your state and a critic.
state = {"items": [{"id": "a", "ok": False}, {"id": "b", "ok": True}]}

def gather(state, iteration, model):
    issues = [
        CriticIssue(
            target_id=f"/items/{i}/ok",
            severity="major",
            issue_type="needs_fix",
            description=f"set ok=True on item {item['id']}",
        )
        for i, item in enumerate(state["items"]) if not item["ok"]
    ]
    return [CriticReport(issues=issues, score=10 if not issues else 4)]

# 2. Define an executor that applies one correction at a time.
def apply_one(state, flagged_paths, feedback_by_path, model):
    traces = []
    for path in flagged_paths:
        # In production this is your LLM patcher; here we just patch.
        idx = int(path.strip("/").split("/")[1])
        state["items"][idx]["ok"] = True
        traces.append(type("T", (), {
            "id": f"t-{idx}", "requirement_id": path,
            "addressed": True, "reason": "set ok=True",
        })())
    return traces

# 3. Run the loop.
def parse(issues):
    return ([iss.target_id for iss in issues],
            {iss.target_id: iss.description for iss in issues})

cfg = CorrectionLoopConfig(level="items", max_loops=5)
ok = run_correction_loop(
    state, cfg,
    gather_fn=gather,
    plan_fn=make_identity_planner(parse),
    execute_fn=make_callback_executor(apply_one),
)
assert ok and all(item["ok"] for item in state["items"])

For a real LLM-driven example with a knowledge-graph correction workload, see examples/kg_correction/ and tests/test_loop.py. The end-to-end ablations (full-regen vs single-shot patch vs full sub-agent stack) and size-sweep numbers are documented in EXPERIMENTS.md.

What's inside

Core

Module Purpose
json_correction_loop.loop The run_correction_loop driver
json_correction_loop.models Correction, CorrectionPlan, CriticIssue, CriticReport
json_correction_loop.planners Identity + oscillation-aware planners
json_correction_loop.executors make_callback_executor factory
json_correction_loop.convergence QualityStablePolicy, HardcapPolicy
json_correction_loop.events EventSink Protocol + NullEventSink
json_correction_loop.storage StorageBackend Protocol + NullStorageBackend

Sub-agents

Module Sub-agent Status
json_correction_loop.path_finder Symptom → root cause pointer redirect Stable
json_correction_loop.template_filler Empty-container enumeration filler Stable
json_correction_loop.request_validator Reject malformed patch requests upstream Stable
json_correction_loop.patch_evaluator Score patches against intent before commit Stable
json_correction_loop.patcher Surgical RFC 6902 patcher Stable

Status

  • Alpha (v0.1). Public API may change before 1.0.
  • Domain-neutral library — bring your own critic, patcher prompt, and storage backend.

Experiments

These design choices are measured on a synthetic knowledge-graph perturbation benchmark. Headline result: at 100 entities, full-regeneration achieves 0% fix rate while the full library stack achieves 100% at ~5× fewer tokens.

See EXPERIMENTS.md for the setup, ablations, and size-sweep numbers.

Contributing

Issues and PRs welcome. Please run pytest and ruff before submitting.

License

Apache-2.0. See LICENSE.

Release files for json-correction-loop 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for json-correction-loop 0.1.0
File Size Uploaded
json_correction_loop-0.1.0.tar.gz 93.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for json-correction-loop 0.1.0
File Interpreter ABI Platform
json_correction_loop-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 186.6 kB

Release files / json_correction_loop-0.1.0.tar.gz

Download URL json_correction_loop-0.1.0.tar.gz
Size 93.8 kB
Tags Source
SHA-256 checksum
How to use checksums
f9f1d4b8faed187a0c33eef7aa0d6dbc995e89baeb4119384ee0e26984c95006
BLAKE2b-256 checksum
How to use checksums
abec9c1b82b681f9bc0b7ce01781bac53e9bc1a6c9482156934edab62eb35d8a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on May 8, 2026.

Transparency log

Release files / json_correction_loop-0.1.0-py3-none-any.whl

Download URL json_correction_loop-0.1.0-py3-none-any.whl
Size 92.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
559982f78286cf6ffd5c9b6958196062992a10aea5b054ea9983c60bfd1bf560
BLAKE2b-256 checksum
How to use checksums
1971bde9b022a864f02bc7ecd703bd78c8ba1139a08494804848d5c5258c89c9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on May 8, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page