Skip to main content

Entropy-based early exit for efficient agent reasoning

Project description

Entroplain

Entropy-based early exit for efficient agent reasoning.

Stop burning tokens. Know when your agent has finished thinking.


What It Does

Entroplain monitors your LLM's predictive entropy — the uncertainty in its output distribution — to detect when reasoning has converged.

High entropy → Model is searching, exploring, uncertain
Low entropy → Model is confident, converged, ready to output

Key insight: Reasoning follows a multi-modal entropy trajectory. Local minima ("valleys") mark reasoning milestones. Exit at the right valley, save 40-60% compute with minimal accuracy loss.


Quick Start

Install

# Python (pip)
pip install entroplain

# Node.js (npm)
npm install entroplain

Requirements

Python: 3.8+

Node.js: 18+

For cloud providers: Set API keys via environment variables:

export OPENAI_API_KEY=sk-...
export ANTHROPIC_API_KEY=sk-ant-...
export NVIDIA_API_KEY=nvapi-...

For local models: Install Ollama or llama.cpp


🚀 Works With Any Agent (Proxy Method)

The proxy is the easiest way to use Entroplain with OpenClaw, Claude Code, or any other agent framework:

How It Works

Your Agent → Proxy (localhost:8765) → Real API
               │
               ▼
         Entropy Monitor
               │
               ▼
         Early Exit Check

The proxy intercepts all LLM API calls, monitors entropy, and terminates streams when reasoning converges.

Setup (One-Time)

# Install with proxy support
pip install entroplain[proxy]

# Start the proxy
entroplain-proxy --port 8765 --log-entropy

# Point your agent to the proxy
export OPENAI_BASE_URL=http://localhost:8765/v1

# or for NVIDIA:
export NVIDIA_BASE_URL=http://localhost:8765/v1

# or for Anthropic:
export ANTHROPIC_BASE_URL=http://localhost:8765/v1

That's it! Now run your agent normally and entropy monitoring is automatic.

Proxy Options

# Monitor only, don't exit early
entroplain-proxy --port 8765 --no-early-exit

# Custom thresholds
entroplain-proxy --port 8765 --entropy-threshold 0.2 --min-valleys 3

# Enable cost tracking
entroplain-proxy --port 8765 --model gpt-4o --log-entropy

# Launch dashboard
entroplain-dashboard --port 8050

🎯 Dashboard

Real-time entropy visualization:

# Start the dashboard
entroplain-dashboard --port 8050

# Open in browser
open http://localhost:8050

The dashboard shows:

  • Live entropy curve with valley markers
  • Token count and valleys detected
  • Cost savings in real-time
  • Status badges (active/idle/exited)

💰 Cost Tracking

Track actual savings from early exit:

from entroplain import CostTracker

tracker = CostTracker(model="gpt-4o")
tracker.track_input(100)   # 100 input tokens
tracker.track_output(50)   # 50 output tokens
tracker.set_full_estimate(150)  # Would have been 150

estimate = tracker.get_estimate()
print(f"Saved ${estimate.cost_saved_usd:.4f} ({estimate.savings_percent:.1f}%)")

Supported pricing: GPT-4o, GPT-4-turbo, Claude 4, Llama 3.1 (NVIDIA), or custom rates.


Direct Usage (Python)

If you want more control, use Entroplain directly:

from entroplain import EntropyMonitor, NVIDIAProvider

monitor = EntropyMonitor()
provider = NVIDIAProvider()

for token in provider.stream_with_entropy(
    model="meta/llama-3.1-70b-instruct",
    messages=[{"role": "user", "content": "Solve: x^2 = 16"}]
):
    monitor.track(token.token, token.entropy)
    print(token.token, end="")

    if monitor.should_exit():
        print("\n[Early exit - reasoning converged]")
        break

print(f"\nStats: {monitor.get_stats()}")

How It Works

1. Track Entropy Per Token

Every token has an entropy value derived from the model's output distribution:

entropy = -sum(p * log2(p) for p in probabilities if p > 0)

2. Detect Valleys

Local minima in the entropy trajectory indicate reasoning milestones:

Entropy: 0.8 → 0.6 → 0.3* → 0.5 → 0.2* → 0.1*
                      ↑             ↑
                  Valley 1      Valley 2

3. Exit at the Right Moment

When valley count plateaus and velocity stabilizes, reasoning is complete.


Exit Strategies

Choose how Entroplain detects convergence:

Strategy Description
combined Entropy low OR valleys plateau, AND velocity stable (default)
valleys_plateau Exit when reasoning milestones stabilize
entropy_drop Exit when model confidence is high
velocity_zero Exit when entropy stops changing
repetition Exit when model starts repeating itself
confidence Exit when top token prob > 95% for N tokens
monitor = EntropyMonitor(
    exit_condition="repetition",  # or "confidence", "combined", etc.
    repetition_threshold=0.3,      # Exit when 30% of recent tokens repeat
)

Experimental Evidence

Tested on Llama-3.1-70b via NVIDIA API:

Difficulty Avg Valleys Avg Entropy Avg Velocity
Easy 61.3 0.3758 0.4852
Medium 53.0 0.3267 0.4394
Hard 70.2 0.2947 0.4095

Finding: Hard problems have more entropy valleys (70.2 vs 61.3) — valleys correlate with reasoning complexity.


Platform Support

Platform Support How to Enable
Local (llama.cpp, Ollama) ✅ Full Built-in, no config
OpenAI ✅ Yes logprobs: true
Anthropic Claude ✅ Yes (Claude 4) logprobs: True
Google Gemini ✅ Yes response_logprobs=True
NVIDIA NIM ✅ Yes logprobs: true
OpenRouter ⚠️ Partial ~23% of models support it

Integration Examples

OpenAI / NVIDIA / OpenRouter

from openai import OpenAI
from entroplain import EntropyMonitor

client = OpenAI()
monitor = EntropyMonitor()

response = client.chat.completions.create(
    model="gpt-4o",
    messages=[{"role": "user", "content": "Solve this step by step..."}],
    logprobs=True,
    top_logprobs=5,
    stream=True
)

for chunk in response:
    if chunk.choices[0].delta.content:
        token = chunk.choices[0].delta.content
        entropy = monitor.calculate_entropy(chunk.choices[0].logprobs)

        if monitor.should_exit():
            print("\n[Early exit — reasoning converged]")
            break

        print(token, end="")

Ollama (Local)

import ollama
from entroplain import EntropyMonitor

monitor = EntropyMonitor()

response = ollama.generate(
    model="llama3.1",
    prompt="Think through this carefully...",
    options={"num_ctx": 4096}
)

for token_data in response.get("token_probs", []):
    entropy = monitor.calculate_from_logits(token_data["logits"])
    monitor.track(token_data["token"], entropy)

Anthropic Claude

from anthropic import Anthropic
from entroplain import EntropyMonitor

client = Anthropic()
monitor = EntropyMonitor()

with client.messages.stream(
    model="claude-sonnet-4-20250514",
    max_tokens=1024,
    messages=[{"role": "user", "content": "Analyze this..."}],
) as stream:
    for text in stream.text_stream:
        entropy = monitor.get_entropy()

        if monitor.should_exit():
            break

        print(text, end="", flush=True)

CLI

# Analyze a prompt's entropy trajectory
entroplain analyze "What is 2+2?" --model gpt-4o

# Stream with early exit
entroplain stream "Explain quantum computing" --exit-on-converge

# Run the proxy (works with any agent)
entroplain-proxy --port 8765 --log-entropy --model gpt-4o

# Launch the dashboard
entroplain-dashboard --port 8050

# Benchmark entropy patterns
entroplain benchmark --problems gsm8k --output results.json

API Reference

EntropyMonitor

class EntropyMonitor:
    def __init__(
        self,
        entropy_threshold: float = 0.15,
        min_valleys: int = 2,
        velocity_threshold: float = 0.05,
        min_tokens: int = 50,
        exit_condition: str = "combined"
    ):
        ...

    def track(self, token: str, entropy: float, confidence: float = 0.0) -> EntropyPoint:
        """Track a token and its entropy value."""

    def should_exit(self) -> bool:
        """Determine if reasoning has converged."""

    def get_valleys(self) -> List[Tuple[int, float]]:
        """Get all entropy valleys (local minima)."""

    def get_stats(self) -> Dict:
        """Get current statistics."""

    def reset(self) -> None:
        """Clear all tracked data."""

CostTracker

class CostTracker:
    def __init__(self, model: str = "default"):
        ...

    def track_input(self, tokens: int):
        """Track input tokens."""

    def track_output(self, tokens: int):
        """Track output tokens."""

    def set_full_estimate(self, tokens: int):
        """Set estimated output if no early exit."""

    def get_estimate(self) -> CostEstimate:
        """Get cost estimate with savings."""

EntropyProxy

# Run the proxy
entroplain-proxy --port 8765 --log-entropy --model gpt-4o

# Options
--entropy-threshold 0.15    # Exit threshold
--min-valleys 2             # Minimum valleys
--no-early-exit             # Monitor only, don't exit
--log-entropy               # Log entropy values
--model gpt-4o              # Model for cost tracking
--no-cost-tracking          # Disable cost tracking

Research

Paper

See paper.md for the full research proposal:

"Entropy-Based Early Exit for Efficient Agent Reasoning"

Key Findings

  1. H1 Supported: Entropy valleys correlate with reasoning complexity (70.2 valleys for hard problems vs 61.3 for easy)
  2. H2 Supported: Entropy velocity differs by difficulty (0.4852 easy vs 0.4095 hard)
  3. Potential: 40-60% compute reduction with 95%+ accuracy retention

Citation

@software{entroplain2026,
  title = {Entroplain: Entropy-Based Early Exit for Efficient Agent Reasoning},
  author = {Entroplain Contributors},
  year = {2026},
  url = {https://github.com/entroplain/entroplain}
}

Contributing

We welcome contributions! See CONTRIBUTING.md for guidelines.

Development Setup

git clone https://github.com/entroplain/entroplain.git
cd entroplain
pip install -e ".[dev]"
pytest

License

MIT License — see LICENSE for details.


Links


Acknowledgments

  • Research inspired by early exit architectures in transformers
  • Experimental validation using NVIDIA NIM API
  • Built for the agent-first future of AI

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

entroplain-0.2.2.tar.gz (37.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

entroplain-0.2.2-py3-none-any.whl (31.3 kB view details)

Uploaded Python 3

File details

Details for the file entroplain-0.2.2.tar.gz.

File metadata

  • Download URL: entroplain-0.2.2.tar.gz
  • Upload date:
  • Size: 37.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.5

File hashes

Hashes for entroplain-0.2.2.tar.gz
Algorithm Hash digest
SHA256 e17297884fb7a818ff16037e732135d59c1764c8a7e96e8b6ec445e97ab8d654
MD5 9a788d96f9d26a9a7595843d6d9655a4
BLAKE2b-256 36fb54a53501b96966baff45b21860b371d048c0e7f791b1a95794ed7e25c281

See more details on using hashes here.

File details

Details for the file entroplain-0.2.2-py3-none-any.whl.

File metadata

  • Download URL: entroplain-0.2.2-py3-none-any.whl
  • Upload date:
  • Size: 31.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.5

File hashes

Hashes for entroplain-0.2.2-py3-none-any.whl
Algorithm Hash digest
SHA256 7c03554c26201b63a43d3ce3e621cfe2f9a0535f8e8a6aa9b81d372e848941d0
MD5 a63d7a77805e5fbd70ba99050879bb58
BLAKE2b-256 4d2bffe1fedd133ddf9eaf814f97b28f14e2391e29118383195ef45784f32f65

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page