Quickstart

Get Kalibr working in 5 minutes.


Prerequisites

  • Python 3.10+ (check with python --version)
  • Provider API keys for models you want to use (OpenAI, Anthropic, etc.)

1. Install

Install Kalibr and provider SDKs for your models:

pip install kalibr openai anthropic
npm install @kalibr/sdk openai @anthropic-ai/sdk

2. Set your keys

Get your Kalibr key from dashboard.kalibr.systems

export KALIBR_API_KEY=your-api-key
export KALIBR_TENANT_ID=your-tenant-id
export OPENAI_API_KEY=sk-...
export ANTHROPIC_API_KEY=sk-ant-...

Important: You need API keys for each provider in your paths. If you use gpt-4o, you need OPENAI_API_KEY. If you use claude-sonnet-4-20250514, you need ANTHROPIC_API_KEY.

3. Replace your LLM call

Before (hardcoded model):

from openai import OpenAI
client = OpenAI()

response = client.chat.completions.create(
    model="gpt-4o",
    messages=[{"role": "user", "content": "Extract the company: Hi from Stripe"}]
)

After (Kalibr picks the model):

from kalibr import Router

router = Router(
    goal="extract_company",
    paths=["gpt-4o", "claude-sonnet-4-20250514"]
)

response = router.completion(
    messages=[{"role": "user", "content": "Extract the company: Hi from Stripe"}]
)

router.report(success=True)

Before (hardcoded model):

import OpenAI from 'openai';

const client = new OpenAI();
const response = await client.chat.completions.create({
  model: 'gpt-4o',
  messages: [{ role: 'user', content: 'Extract the company: Hi from Stripe' }],
});

After (Kalibr picks the model):

import { Router } from '@kalibr/sdk';

const router = new Router({
  goal: 'extract_company',
  paths: ['gpt-4o', 'claude-sonnet-4-20250514'],
});

const response = await router.completion([
  { role: 'user', content: 'Extract the company: Hi from Stripe' }
]);

await router.report(true);

That's it. Kalibr now picks which model to use and learns from the outcome.


3.5 Handle Errors

Provider errors (rate limits, API issues) pass through Kalibr. Wrap your calls in try/catch:

try:
    response = router.completion(
        messages=[{"role": "user", "content": "Extract the company: Hi from Stripe"}]
    )
    result = response.choices[0].message.content
    router.report(success=len(result) > 0)
except Exception as e:
    # Kalibr automatically reports failure on exception
    print(f"Error: {e}")
    # Handle gracefully - retry, fallback, or alert
try {
  const response = await router.completion(messages);
  const result = response.choices[0].message.content;
  await router.report(result.length > 0);
} catch (error) {
  // Kalibr automatically reports failure on exception
  console.error('Error:', error);
  // Handle gracefully
}

Note: Kalibr automatically reports a failure when an exception occurs, so routing still learns from errors.


4. Report outcomes

Kalibr learns from outcomes. Call report() after you know if it worked.

response = router.completion(messages=[...])
result = response.choices[0].message.content

if result and len(result) > 0:
    router.report(success=True)
else:
    router.report(success=False, reason="empty_response")

For simple checks, use success_when to auto-report:

router = Router(
    goal="extract_company",
    paths=["gpt-4o", "claude-sonnet-4-20250514"],
    success_when=lambda output: len(output) > 0
)

response = router.completion(messages=[...])
# report() called automatically
const response = await router.completion(messages);
const result = response.choices[0].message.content;

if (result && result.length > 0) {
  await router.report(true);
} else {
  await router.report(false, 'empty_response');
}

For simple checks, use successWhen to auto-report:

const router = new Router({
  goal: 'extract_company',
  paths: ['gpt-4o', 'claude-sonnet-4-20250514'],
  successWhen: (output) => output.length > 0,
});

const response = await router.completion(messages);
// report() called automatically

More success_when Examples

# Check for email format
router = Router(
    goal="extract_email",
    paths=["gpt-4o-mini", "claude-sonnet-4-20250514"],
    success_when=lambda output: "@" in output and "." in output
)

# Check for valid JSON
router = Router(
    goal="generate_json",
    paths=["gpt-4o", "claude-sonnet-4-20250514"],
    success_when=lambda output: output.strip().startswith("{")
)

# Check minimum word count
router = Router(
    goal="write_summary",
    paths=["gpt-4o", "claude-sonnet-4-20250514"],
    success_when=lambda output: len(output.split()) >= 50
)
// Check for email format
const router = new Router({
  goal: 'extract_email',
  paths: ['gpt-4o-mini', 'claude-sonnet-4-20250514'],
  successWhen: (output) => output.includes('@') && output.includes('.')
});

// Check for valid JSON
const router = new Router({
  goal: 'generate_json',
  paths: ['gpt-4o', 'claude-sonnet-4-20250514'],
  successWhen: (output) => output.trim().startsWith('{')
});

// Check minimum word count
const router = new Router({
  goal: 'write_summary',
  paths: ['gpt-4o', 'claude-sonnet-4-20250514'],
  successWhen: (output) => output.split(' ').length >= 50
});

When NOT to use success_when: Use manual report() if success depends on external APIs, multi-step validation, or you need to include a failure reason.

See which model was chosen

Check the response to see which model Kalibr selected:

response = router.completion(messages=[...])
print(f"Kalibr chose: {response.model}")
# Output: Kalibr chose: gpt-4o-mini
const response = await router.completion(messages);
console.log(`Kalibr chose: ${response.model}`);
// Output: Kalibr chose: gpt-4o-mini

5. Check your dashboard

Go to dashboard.kalibr.systems to see:

  • Success rate per model
  • Which model Kalibr is routing to
  • Cost per successful call

After ~20-50 outcomes per path, routing becomes stable and Kalibr will favor the model that works best for your goal.


What just happened

  • Kalibr registered your two paths
  • On completion(), Kalibr picked a model (exploring early on)
  • The call went directly to the provider (OpenAI or Anthropic)
  • On report(), Kalibr recorded the outcome
  • Next time, Kalibr uses this to make a better choice

Common Mistakes

  • Missing provider SDK - If you get "No module named 'anthropic'", run pip install anthropic
  • Forgetting report() - Kalibr can't learn if you don't report outcomes. Always call report().
  • Wrong Python version - Kalibr requires Python 3.10+. Check with python --version.

Next