Skip to main content

anti-resonance

Counteract positive recall bias in memory-augmented AI systems. Zero dependencies.

Install

pip install anti-resonance

Quick Start

from anti_resonance import ensure_negative_ratio

# Your RAG/memory system returned 10 results — mostly wins
results = [
    {"text": "Trade won +$150", "pnl": 150, "score": 0.9},
    {"text": "Trade won +$80",  "pnl": 80,  "score": 0.8},
    {"text": "Trade won +$200", "pnl": 200, "score": 0.85},
    {"text": "Trade won +$50",  "pnl": 50,  "score": 0.7},
    {"text": "Trade won +$120", "pnl": 120, "score": 0.75},
]

# Losses from your full memory pool
candidates = [
    {"text": "Trade lost -$90 (SL hit in ranging market)",  "pnl": -90,  "score": 0.6},
    {"text": "Trade lost -$200 (gap against position)",     "pnl": -200, "score": 0.4},
    {"text": "Trade lost -$45 (spread widened at news)",    "pnl": -45,  "score": 0.5},
]

# Force at least 20% losses into the context window
balanced = ensure_negative_ratio(
    results, candidates,
    min_negative_ratio=0.2,
    score_key="score",         # score-aware: replaces lowest-score wins
)

The agent now sees both wins AND losses before making its next decision.

The Problem: Parametric-External Memory Resonance

When an LLM-based agent retrieves memories to inform a decision, two bias sources resonate with each other:

  1. Parametric bias (inside the LLM): Language models trained on internet text have a built-in optimism bias. Success stories, best practices, and positive outcomes are overrepresented in training data.

  2. External memory bias (in the retrieval system): Similarity-based retrieval (vector search, embedding lookup) clusters positive outcomes together. Winning trades look alike ("strong momentum", "breakout confirmed"). Losing trades are diverse and scattered ("gap down", "spread spike", "regime change") — they don't cluster, so they rank low in similarity search.

When the LLM's parametric optimism meets a one-sided positive context window, the biases amplify each other. The model becomes dangerously overconfident because both its training and its retrieved evidence agree.

This is Parametric-External Memory Resonance — a feedback loop between the model's internal beliefs and the retrieval system's structural bias toward positive outcomes.

The Fix

Break the resonance by forcing counterexamples into the context window. anti-resonance does this at the post-retrieval stage:

Query → Retrieval → [anti-resonance] → LLM
                          ↑
                    Force 20% negatives
                    into the result set

The algorithm is simple:

  1. Count negative items in top-K results
  2. If ratio >= threshold → return unchanged
  3. Otherwise → replace lowest-scoring positives with highest-scoring negatives from the candidate pool
  4. Re-sort by score

Score-aware replacement (v0.2.0) ensures you sacrifice the least-relevant positive items and inject the most-relevant negative ones.

API

ensure_negative_ratio(results, candidates, min_negative_ratio=0.2, negative_classifier=None, score_key=None)

Parameter Type Default Description
results list[dict] required Top-K retrieval results
candidates list[dict] required Full candidate pool
min_negative_ratio float 0.2 Minimum negative fraction [0.0, 1.0]
negative_classifier Callable None Returns True for negative items. Default: item["pnl"] < 0
score_key str None Dict key for relevance score. Enables score-aware replacement

Returns: New list (same length) with at least min_negative_ratio negatives.

ensure_negative_balance

Alias for ensure_negative_ratio (backward compatibility with TradeMemory).

Use Cases

Trading Memory

balanced = ensure_negative_ratio(
    recalled_trades, all_trades,
    min_negative_ratio=0.2,
    score_key="owm_score",
)
# Agent sees losing trades alongside winners before deciding

RAG Pipelines

balanced = ensure_negative_ratio(
    search_results, full_corpus,
    negative_classifier=lambda doc: doc["sentiment"] < 0,
    score_key="relevance",
)
# LLM sees failure cases alongside success stories

Customer Support

balanced = ensure_negative_ratio(
    similar_tickets, all_tickets,
    negative_classifier=lambda t: t["resolution"] == "unresolved",
)
# Agent considers unresolved similar cases, not just resolved ones

Related Work

  • FinMem (Yu et al., 2024) — FinMem: A Performance-Enhanced LLM Trading Agent with Layered Memory and Character Design. Identified the echo chamber problem in LLM trading agents where memory retrieval reinforces existing beliefs. arXiv:2311.13743

  • TradeMemory Protocol — Open-source trading memory layer where anti-resonance was first implemented. The ensure_negative_balance() function in TradeMemory's hybrid recall pipeline is the production origin of this package. GitHub

  • Building Anti-Resonance for AI Trading Agents (Sean, 2026) — DEV.to article explaining why RAG-based trading agents develop confirmation bias and how to fix it. DEV.to

License

MIT

Metadata

Release files for anti-resonance 0.2.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 anti-resonance 0.2.0
File Size Uploaded
anti_resonance-0.2.0.tar.gz 7.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for anti-resonance 0.2.0
File Interpreter ABI Platform
anti_resonance-0.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 13.4 kB

Release files / anti_resonance-0.2.0.tar.gz

Download URL anti_resonance-0.2.0.tar.gz
Size 7.1 kB
Tags Source
SHA-256 checksum
How to use checksums
1788f086b6b8a7319f5d89ac7d6c2a01932adf581f6bd083ac4c88c8367e8953
BLAKE2b-256 checksum
How to use checksums
28f476ce3766f3c439dba8ebccee19476158923be064e29068b37efa68908a66
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

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 Mar 25, 2026.

Transparency log

Release files / anti_resonance-0.2.0-py3-none-any.whl

Download URL anti_resonance-0.2.0-py3-none-any.whl
Size 6.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
781ae1e4ea6c90d81a534f0ea95f3a121967e9942c1e41bc8cc61254b482bcc9
BLAKE2b-256 checksum
How to use checksums
783b688ab9193be29a36d440b48477e2727807edbfcbb4d3feaac8cafde48f5d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

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 Mar 25, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.2.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