Skip to main content

Cambium

Cost discipline and bounded agency for LLM call sites — the deterministic spine decides what to ask, the model only answers.

PyPI Python License: Apache-2.0

What it is

Cambium is the cost-discipline / bounded-agent layer that sits in front of your model calls. Instead of handing an LLM every decision, it routes work through the cheapest path that can answer it and only pays for the model when nothing cheaper will do. Three deterministic, pure-Python capabilities anchor the public surface:

  • cambium.distill — pre-call payload minimization. Decide whether a payload even needs the model (assemble / pass / condense / summarize), shrink oversized payloads deterministically, and record what every call cost via a CostLedger.
  • cambium.resolve — a cost-tiered resolution ladder. Try resolvers in cost order (deterministic → statistical → generative) and stop at the first one confident enough; the expensive generative tier is a budget-gated last resort.
  • cambium.adapt — the feedback substrate for outcome-driven learning: record predictions, observe real outcomes, score them, and attribute credit/blame across the features and strategies that produced them.

The package import name is cambium; the PyPI distribution is cambium-ai.

Install

pip install cambium-ai

The core (distill / resolve / adapt) has no LLM dependency. Live generative clients are optional extras:

pip install "cambium-ai[claude]"   # live Anthropic client
pip install "cambium-ai[gemini]"   # live Gemini generator

cambium.distill — pre-call payload minimization + cost ledger

prepare runs the full routing pipeline and hands back a ready-to-send payload plus the accounting the ledger needs. Route.ASSEMBLE means no model call at all.

from cambium.distill import prepare, Route, CostLedger

prepared = prepare(task_output, budget_tokens=2000)
ledger = CostLedger(job_id="research-run")

if prepared.route is Route.ASSEMBLE:
    answer = format_table(task_output)                 # deterministic, no model
    ledger.record_avoided(label="summary", route="assemble",
                          tokens_saved=prepared.tokens_saved)
else:
    response = claude.call(prompt_with(prepared.content))   # your model call
    ledger.record(label="summary", model="claude-3-5-haiku",
                  input_tokens=response.input_tokens,
                  output_tokens=response.output_tokens,
                  tier="generative", tokens_saved=prepared.tokens_saved)

report = ledger.report
report.within_budget(max_cost_usd=0.05)   # cost-regression gate

estimate_tokens(content) and condense(content, max_tokens=...) are also public if you want the pieces directly.

cambium.resolve — cost-tiered resolution ladder

Implement a Resolver per tier and let resolve climb only as far as it must. The generative tier is skipped once the ledger is over budget.

from cambium.resolve import Tier, Resolution, resolve
from cambium.distill import CostLedger

class ExactMatch:
    tier = Tier.DETERMINISTIC
    name = "exact_match"
    def resolve(self, request):
        hit = lookup(request)
        if hit is None:
            return None
        return Resolution(value=hit, confidence=1.0, tier=self.tier)

ledger = CostLedger()
result = resolve(
    request,
    [ExactMatch(), embedding_resolver, llm_resolver],
    ledger=ledger,
    threshold=0.8,
    max_cost_usd=0.05,   # gates the generative tier
)

resolve returns the first resolution at/above threshold, else the best below-threshold one, else None. ResolverRegistry is available for grouping resolvers by decision type.

cambium.adapt — outcome-driven feedback substrate

Record predictions, feed back real outcomes, and mature them into scored attributions that a reweighting layer can consume.

from cambium.adapt import (
    PredictionRecord, OutcomeRecord, InMemoryPredictionLedger, mature,
)

led = InMemoryPredictionLedger()
led.record_prediction(PredictionRecord(
    id="p1", subject="AAPL", strategy="momentum",
    features={"rsi": 0.7, "trend": 0.3}, predicted=1.0, baseline=0.0,
))
led.record_outcome(OutcomeRecord(prediction_id="p1", actual=1.0))

scores = mature(led)   # [PredictionScore(accuracy=1.0, attributions={...})]

Weights / update / aggregate and predict_from_attributes / blend_strategies / best_strategy close the loop for the reweighting phase.

License

Apache-2.0. See LICENSE.

Download files

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

Source Distribution

cambium_ai-0.2.6.tar.gz (123.4 kB view details)

Uploaded Source

Built Distribution

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

cambium_ai-0.2.6-py3-none-any.whl (118.7 kB view details)

Uploaded Python 3

File details

Details for the file cambium_ai-0.2.6.tar.gz.

File metadata

  • Download URL: cambium_ai-0.2.6.tar.gz
  • Upload date:
  • Size: 123.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.0.1 CPython/3.13.14 Linux/6.17.0-1018-azure

File hashes

Hashes for cambium_ai-0.2.6.tar.gz
Algorithm Hash digest
SHA256 71a66cef09948beee911048c7233edf01116d85d039681865494f2687758e4f3
MD5 ef88ca9a6e69e2de0fcf6d1856dbab90
BLAKE2b-256 5292a4be724213c8beed44643e777c852779b112782e03f22906ad70223dd4d8

See more details on using hashes here.

File details

Details for the file cambium_ai-0.2.6-py3-none-any.whl.

File metadata

  • Download URL: cambium_ai-0.2.6-py3-none-any.whl
  • Upload date:
  • Size: 118.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.0.1 CPython/3.13.14 Linux/6.17.0-1018-azure

File hashes

Hashes for cambium_ai-0.2.6-py3-none-any.whl
Algorithm Hash digest
SHA256 33c965d9ac8b6d06a317855cb96ce70453ec823b96c228c08f11f48a2b369516
MD5 63158474b5eb04aeb6a93cc6d4501cd9
BLAKE2b-256 b1c24a8267e3147f579509fae79dce9361bd19fd1236400b0434e9a1489eada8

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