Stabilized Recursive Barrier Network: stability primitives for long-horizon LLM workflows
Project description
SRBN
Stabilized Recursive Barrier Networks — a small, dependency-free Python library that turns flaky long-horizon LLM workflows into stable, observable control loops.
Authored by Vikrant Rathore and Ronak Rathore, authors of the paper Stability Is All You Need I: Lyapunov-Guided Hierarchies for Long-Horizon LLM Reliability. SRBN is the practical, black-box instantiation of the control loop proved stable in that paper.
import srbn
def generate(prompt: str, feedback: str | None) -> str:
# Call your favourite LLM here. The library makes no assumptions.
...
result = srbn.run(
"Draft a polite reply",
generate=generate,
checks=[srbn.contains("please"), srbn.min_length(20)],
)
print(result.ok, result.output, result.num_attempts)
That's the whole interface. No agents, no orchestrators, no hidden state.
Install
pip install srbn
# or, with uv:
uv add srbn
Python 3.12+. The core has zero runtime dependencies.
The idea in one picture
An LLM left to its own devices drifts: small errors correlate and compound over a long task until the output leaves the set of valid states. SRBN treats generation not as "sampling text" but as steering a dynamical system back onto a safe manifold — the set of outputs that satisfy your barriers (checks).
Each attempt measures how far the current output is from valid, turns that distance into actionable feedback, and feeds it back into the next generation. The loop stops when the output is provably inside tolerance, when it stops improving, or when the attempt budget is spent.
Mathematical foundation
SRBN is the engineering reduction of a control-theoretic result. The notation below is rendered as Unicode so it displays identically on Codeberg and on PyPI (neither relies on a math renderer).
1. Sheaf consistency → a Lyapunov energy. A long-horizon task is a hierarchy
of sub-tasks (a DAG). A global state is valid when every parent task U and
child task V agree under a restriction map ρ_VU (the high-level plan and the
low-level output must be consistent). The total disagreement is summarized by a
single non-negative energy function:
V(x) = Σ_{U,V} ‖ ρ_VU(x_U) − x_V ‖² (Lyapunov energy; V(x) = 0 ⇔ valid)
In this library, V(x) is exactly the instability score returned on every
attempt (attempt.score): the aggregate residual of your barriers. score = 0
means the state sits on the safe manifold M_safe = { x : V(x) = 0 }.
2. The control law. Rather than re-sampling blindly, SRBN applies a
correction in the descent direction of the energy — gradient flow on V:
v(x) = −α ∇V(x) ẋ = f(x) + v(x)
f(x) is the agent's reasoning drift; v(x) is the barrier's correction.
In the open-weight setting v(x) is a steering vector added to the residual
stream; in the black-box setting it is projected to a feedback prompt — a
lossy but effective approximation. This library implements the black-box case:
attempt.feedback is the discrete stand-in for v(x).
3. The stability guarantee. Under the paper's assumptions — the barrier is
stronger than the drift (β < α), the energy is well-conditioned
(Polyak–Łojasiewicz constant μ > 0), and the safe set is reached without
overshoot — the error energy decays exponentially toward zero:
continuous time: V(x(t)) ≤ V(x₀) · e^(−λ t), λ = 2μ(α − β) > 0
discrete steps: V(x_k) ≤ (1 − 2η c μ)^k · V(x₀), 0 < step η < η_max
Real LLMs have persistent noise δ (confident hallucination), so convergence
is not to exactly zero but to a bounded floor whose size topology suppresses:
limsup_{t→∞} V(x(t)) ≤ δ² / ( 2 (α − β)² μ ) (error floor)
4. What the library enforces. SRBN does not have model gradients, so it
enforces the discrete analogue of the descent condition V̇ < 0 directly: with
Policy(require_descent=True, min_descent=δ) the loop demands that the score
strictly decrease between attempts and aborts early when it stalls — a practical
guard that the system is actually descending the energy, not thrashing.
| Paper | Library |
|---|---|
Lyapunov energy V(x) |
attempt.score (0.0 = stable) |
Safe manifold M_safe = {V = 0} |
every check passes within score_tolerance |
Correction flow v(x) = −α∇V(x) |
attempt.feedback fed into the next generate |
Descent condition V̇ < 0 |
Policy(require_descent=True, min_descent=…) |
| Attempt budget / step bound | Policy(max_attempts=…) |
See Stability Is All You Need I for the assumptions, proofs (Theorems 5.1, 5.2, 12.1), and the TLA+ safety model.
30-second tour
import srbn
result = srbn.run(
"Write a SQL query for active users",
generate=my_llm,
checks=[srbn.contains("SELECT"), srbn.not_contains("DROP")],
policy=srbn.Policy(max_attempts=4),
)
for attempt in result.trace:
print(attempt.index, attempt.ok, attempt.score, attempt.feedback)
API at a glance
| Symbol | What it is |
|---|---|
srbn.run(prompt, *, generate, checks, policy=None) |
One-call stabilization. |
srbn.stabilize(initial_state, *, barrier, update, policy=None) |
Generic SRBN barrier loop over arbitrary state. |
srbn.Client(generate, checks=(), policy=Policy()) |
Reusable session. |
srbn.Policy(...) |
Control parameters (max_attempts, score_tolerance, require_descent, min_descent). |
srbn.contains, not_contains, matches, min_length, max_length, json_valid, predicate |
Built-in checks (barriers). |
srbn.all_of, srbn.any_of |
Compose checks. |
The full public surface is curated in
src/srbn/__init__.py.
Examples and benchmarks
Runnable examples cover the quickstart, descent policies, check plugins, and structured barrier plugins — none require API keys. Deterministic control-behaviour benchmarks:
python -m benchmarks.srbn_benchmark --tasks 50 --max-attempts 6
Development
uv sync
uv run pytest tests
uv run ruff check .
License
GNU Lesser General Public License v3.0 only (LGPL-3.0-only).
© Vikrant Rathore, Ronak Rathore. See
LICENSE.
As an LGPL library, SRBN can be imported by software under any license; changes to SRBN's own source must be shared under the LGPL.
Citing
If you use SRBN in research, please cite:
@article{rathore2025stability,
title = {Stability Is All You Need I: Lyapunov-Guided Hierarchies
for Long-Horizon LLM Reliability},
author = {Rathore, Vikrant and Rathore, Ronak},
year = {2025}
}
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 srbn-0.1.0.tar.gz.
File metadata
- Download URL: srbn-0.1.0.tar.gz
- Upload date:
- Size: 31.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.6 {"installer":{"name":"uv","version":"0.11.6","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1aa19562a003dc4265d2176a08f8e5970b1fe33e4ae9ef67b4be19495f0b284e
|
|
| MD5 |
8834c0e6e11e568ed3ab9afa2017f61e
|
|
| BLAKE2b-256 |
54a60664d16619dacb90411fb44924de5a2fa64c47762f660f5467d49fde958e
|
File details
Details for the file srbn-0.1.0-py3-none-any.whl.
File metadata
- Download URL: srbn-0.1.0-py3-none-any.whl
- Upload date:
- Size: 23.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.6 {"installer":{"name":"uv","version":"0.11.6","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
41a2d1b243744419dba2b7698db92d2907197b5f0fd1128fd9332a4f7963c6ae
|
|
| MD5 |
0e1d1157925cfc43c7e09aca5b449f31
|
|
| BLAKE2b-256 |
21b07a44d7cb338b25cd5953cc155365c9361717b5671fdb5bf20b98f52265e4
|