Quickstart

Install, wrap your client, scope one step, and report what happened. About five minutes.

1. Get a key

Sign up at rfa-labs.com/optimizer/signup. The key is shown once — it is stored hashed and cannot be recovered.

export SHIMMY_API_KEY=sk-opt-...
export SHIMMY_BASE_URL=https://rfa-labs.com   # optional

2. Install

bash
npm install @rfa-labs/shimmy

3. Wrap, scope, report

quickstart.ts
import OpenAI from 'openai';
import { Shimmy } from '@rfa-labs/shimmy';

const shimmy = new Shimmy();

// `wrap` returns your own client, repointed at the optimizer and annotated.
// Every OpenAI feature the SDK has never heard of keeps working.
const openai = shimmy.wrap(new OpenAI());

const messages = [
  { role: 'user' as const, content: 'Is this a bug or a feature request?' },
];

await shimmy.run('triage-inbox', async () => {
  // `model: 'auto'` lets the optimizer route. A pinned model is treated as
  // an instruction and disables routing — correct, but also most of the saving.
  const res = await shimmy.step('classify', { kind: 'classification' }, () =>
    openai.chat.completions.create({ model: 'auto', messages }),
  );

  const answer = res.choices[0]?.message.content ?? '';

  // Free evidence. The quality gate otherwise pays an LLM judge to decide
  // whether a cheaper model held up; your code already knows.
  await shimmy.report({ schema_valid: answer.length > 0 });
});
Compiled in CI. If this stops working against the SDK, our build fails before you ever see it.

That is the whole loop. Four things are happening:

  • wrap() returns your client, repointed at the optimizer. Nothing is reimplemented, so every OpenAI feature the SDK has never heard of keeps working.
  • run() opens a run. Everything inside belongs to it, including work on other tasks.
  • step() names one call and declares what kind of work it is. That is the difference between the router knowing and the router guessing.
  • report() tells the optimizer whether the answer was usable.

Any provider, one client

Use an OpenAI client for everything. Naming a Claude model is all it takes:

{ "model": "claude-haiku-4-5", "messages": [{ "role": "user", "content": "hi" }] }

The edge translates OpenAI’s wire format to each provider’s server-side, so tool calls, images, documents, prompt-cache breakpoints and streaming all keep working. There is no separate Anthropic client to install and no client-side translation to lose anything in.

4. See what it did

The response carries the optimizer’s own accounting:

FieldMeaning
savingBaseline cost minus what was actually spent
baseline_costWhat this call would have cost on your pinned model
served_costThe optimized path alone
exploration_costWhat was paid to learn whether a downshift was safe
cache_hitWhether it was served from cache

exploration_cost is the one to watch. It converges toward zero as a step settles — and reporting outcomes is what makes it converge faster, since verified evidence replaces paid grading.

Next

  • Concepts — what runs, steps and outcomes actually mean, and why the edge cannot infer them.
  • Instrument an agent — the parallel case, which is where this stops being cosmetic.
  • Report outcomes — the guide that shrinks exploration_cost.