← All case studies
Own product · runs unattendedPaper-only evaluation

An AI analyst that measures its own accuracy and switches itself off

Most AI analysis tools let the model do everything and can't tell you whether they work. I built one where code gathers and checks the data, the model only reasons over clean inputs, every output is tracked to its outcome, and the system rewrites its own lessons each week. It ran unattended for weeks and paused itself when it crossed its loss limit, exactly as designed.

What this is and isn't: a paper-only market-analysis agent used as a reliability and cost-engineering project. It makes no profitability claims, and the evaluation window is still open.
718
structured signals generated
743
LLM calls, each cost-logged
58
automated post-mortems
5 / 682
calls that failed validation after retries

How it works

  1. Data in code, not in the prompt. A Python service pulls from 9 sources (prices, news, calendars, macro data), caches everything and compares two price feeds within 0.15%. A third source breaks ties. If they still disagree, the instrument is skipped and logged. The model never sees conflicting data.
  2. Rules in code. Indicators are computed in Python. A plain IF node blocks analysis around high-impact events and earnings. That is a rule, not a judgment call.
  3. Structured output. Claude returns a strict JSON signal with an explicit invalidation condition. "No trade" is a normal answer: about 90% of outputs were exactly that.
  4. Validate and retry. The validator finds the right content block, checks the schema and, on failure, sends the model its own answer plus the exact error. Two retries, then a logged failure.
  5. Outcomes and post-mortems. A nightly job resolves every signal with no AI. Post-mortems run through the Batch API at half price, judged against the news available at the time to avoid hindsight bias.
  6. Self-rewritten memory. Each week a larger model consolidates the lessons file under a token cap, retires lessons that new evidence contradicts, and commits the change to git.
  7. Kill switch. If drawdown passes 10%, the system deactivates its own signal workflow through the n8n API and alerts me. The alert fires even if the deactivation call fails.
CodeAIHumanData
Execution replay of the design, not live data

Cost engineering

  • Model routing per stage: a mid-size model for signals and post-mortems, the largest model only for the weekly memory rewrite, and no model at all for outcome checks and the kill switch.
  • Prompt caching: the static block (instructions and lessons) always goes first, dynamic data after. Calls were serialized after I found parallel calls each wrote their own cache.
  • Batch API for post-mortems, at 50% off.
  • Every call logged with input, output, cache-read and cache-write tokens. Budget model: about $19 a month with caching and batching against about $33 without, with an alarm at $30.

Debugging stories

Thinking blocks broke parsing

The validator assumed the first content block was the answer, so every retry failed. Fixed by locating the text block properly.

A guardrail leak in production

When a tiebreak failed, conflicting prices slipped into the prompt through an error message. The model correctly refused every trade. Fixed with clean-record-or-raise.

Rate limits at scale

Growing the watchlist from 5 to 19 instruments needed 13-second throttling, retry with backoff on 429s and degrade-not-fail on secondary sources.

An honest self-audit

After the kill switch fired, I documented the real flaws: no open-position guard and no holiday skip caused stacked duplicate signals.

Need AI you can leave running?

Message me on Upwork