Skip to main content

aimai-kit

CI PyPI Python License: MIT

A framework-free LLM engineering toolkit in one Python package: provider adapters, prompt and context engineering, structured outputs, a tool layer, a bounded agent loop, and a harness for long-running work.

Five layers, each built on the one below it, each with its own measurements.

Layer Package What it adds
1 provider/ Token/cost/latency measurement, four adapters, retry and fallback
2 prompts/ Versioned prompts, context budget, structured output, a repair loop
3 tools/ Schemas from signatures, three provider exports, a five-gate executor
4 agent/ A bounded loop, four budgets, loop detection, checkpoints
5 harness/ Segments, spill, compaction, a memory store, sub-agents

343 tests, no vendor SDK outside provider/adapters/, and every layer runnable without an API key.


Install

pip install "aimai-kit[providers]"

From source:

uv sync --all-extras --group dev
cp .env.example .env     # add your keys
uv run pytest            # 343 tests, live ones excluded

Quick start

from aimai_kit.provider.adapters import make_adapter
from aimai_kit.provider.types import ChatRequest, Message, Role

client = make_adapter("anthropic:claude-opus-5")
result = client.complete(
    ChatRequest(
        messages=[Message(role=Role.USER, content="Say hello.")],
        system="Be brief.",
        max_output_tokens=64,
    )
)
print(result.text, result.usage.input_tokens, result.usage.output_tokens)

Structured extraction with citation verification:

from aimai_kit.prompts import PromptRegistry, build_request, generate_structured
from aimai_kit.prompts.grounding import verify_citations
from aimai_kit.prompts.schemas import ContractSummary

built = build_request(
    PromptRegistry("prompts"), "extract_contract@v2", document, schema=ContractSummary
)
repaired = generate_structured(client, built.req, ContractSummary)
summary, grounding = verify_citations(repaired.value, document)
print(summary.amount_minor, grounding.ratio)   # ungrounded fields are dropped

An agent with tools:

from aimai_kit.agent import Agent, Budgets, Thread
from aimai_kit.tools import CallContext, ToolExecutor
from aimai_kit.tools.examples.orders import build_registry, seed_database

seed_database()
executor = ToolExecutor(build_registry())
agent = Agent(client, executor, budgets=Budgets(max_steps=8, max_seconds=60))
run = agent.run(Thread(), "What is the status of order 1002?",
                ctx=CallContext(user_id="u-1", tenant_id="t-1"))
print(run.stop_reason, run.answer)

Command line

# Compare models: TTFT from streaming, real usage from one complete call
uv run model-probe --prompt evals/probe/sample-prompt.txt \
  --models anthropic:claude-opus-5 anthropic:claude-haiku-4-5 -n 5

# Extraction quality against a golden set (no API key needed)
uv run prompt-lab eval --prompt extract_contract@v2 --schema v2 \
  --pricing config/pricing.toml --pricing-model claude-opus-5

# With a real model
uv run prompt-lab --model anthropic:claude-opus-5 eval

Why each layer looks the way it does

Short version below; the full reasoning, including what was rejected and why, is in docs/.

Provider — one internal message format and five error classes. Retry decisions are driven by the error class, never by matching message text. Cached tokens are normalized to a single rule across providers, because Anthropic reports them outside input_tokens and every cost calculation downstream depends on which convention you picked.

Prompts and context — prompts are versioned files identified as name@vN+fingerprint. The document goes into a user message, never the system block, so the cache prefix stays byte-identical across requests. Trimming is an explicit decision that produces a report line, and the non-trimmable sections raise rather than shrink.

Tools — the schema is derived from the function signature, so the two cannot drift apart. Five gates run before anything executes, each producing a message the model can act on. Server context (tenant_id) is injected from the call and is absent from the schema, so a model cannot claim to be another tenant.

Agent loop — four budgets, one stop reason, and a final tool-free turn so a stopped run still answers. Every tool call gets a result, including refused ones. Repetition is warned about before it is stopped, because a warned model usually recovers.

Harness — the atomic unit of context is a segment, not a message, so trimming can never separate a tool call from its result. Large output spills to disk with a reference the agent can follow. Compaction converts old turns instead of dropping them, with a versioned prompt that names what must survive.


Measurements

Every number below is reproducible from this repository with no credentials. Full tables and the honest caveats are in docs/measurements.md.

Experiment Finding
Schema v1 vs v2 Grounding 0% → 100%, at 0.06 more attempts and 16% more cost per document
Grounding attribution v1's start_date reads 0% with grounding on and 88.9% with it off — the drop is the missing citation field, not extraction
Tool descriptions Cutting descriptions to one line leaves selection accuracy unchanged but raises forbidden-tool calls from 0% to 4.5%
Loop detection p95 steps 7 → 3, at the cost of completion 100% → 75% on runs that would have recovered on their own
Harness configurations Naive trim 101k tokens and no answer; compaction 69.5k and no answer; compaction plus a sub-agent 12k and the answer survives

The models behind these numbers are deterministic stubs, not providers. That is deliberate: the point is that the measurement harness works and the comparisons are reproducible. Run the same commands with --model anthropic:claude-opus-5 for numbers about a model.


Testing

CI runs the suite on Python 3.12 and 3.13, and a second job re-runs every measurement script and fails if a committed result changed. A table in the docs that no longer matches the code is a broken build, not a reader's problem.

uv run pytest                 # 343 tests
uv run pytest -m live         # calls real APIs, needs keys
uv run ruff check src/ tests/

A few tests are worth calling out because of what they protect:

Test Guards against
test_no_vendor_leak.py An SDK import escaping adapters/ (AST-based, with an inverse check)
test_prefix_stable.py A variable field leaking into the cache prefix and silently multiplying the bill
test_schema_regression.py A schema changing without anyone noticing that old eval results are now incomparable
test_segments.py A trim separating a tool call from its result
test_compaction.py Compaction dropping a planted fact — three needles, both prompt versions
test_eval_harness.py The eval harness silently returning "correct" for everything

Known limits

  • The golden sets are synthetic. scripts/generate_golden_set.py writes 36 contracts, 10 of them deliberate edge cases. Replace them with your own documents for a real evaluation; the EDGE_CASES map is the guide for what to look for.
  • The stubs are not models. They perform real extraction and real selection, but they know the shape of the synthetic data, so their accuracy is optimistic.
  • The pricing catalog only ships Anthropic rows. OpenAI and Gemini are commented out in config/pricing.toml; fill them from your own billing page. A missing model produces a visible "window not in catalog" warning rather than a silent zero.
  • Synchronous only. Async adds no teaching value at this size.
  • Isolation is three layers and only two are in this repository. The in-process path jail and the cleaned subprocess environment are here; closing the network belongs to deployment, and it is the layer that matters most.

Brand assets

assets/ holds the mark in both forms. _generate.py builds all of them, so a logo nobody can regenerate is not what ships here:

python assets/_generate.py            # the SVGs
uvx --from pillow python assets/_generate.py --png   # the rasters
File Use
header.svg / header.png README and docs banner
logo.svg Wordmark for slides and docs
icon.svg / icon.png Avatar, favicon, social card

License

MIT.

Release files for aimai-kit 1.0.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for aimai-kit 1.0.1
File Size Uploaded
aimai_kit-1.0.1.tar.gz 247.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for aimai-kit 1.0.1
File Interpreter ABI Platform
aimai_kit-1.0.1-py3-none-any.whl Python 3 none any Details

Total release size: 364.8 kB

Release files / aimai_kit-1.0.1.tar.gz

Download URL aimai_kit-1.0.1.tar.gz
Size 247.8 kB
Tags Source
SHA-256 checksum
How to use checksums
5ac553c034418b30ad93285b6ff7566e38ee1822f0833e902473bad1e52bf399
BLAKE2b-256 checksum
How to use checksums
146a39a88f83b69449c99e23bfea378ccbe66fdf83e155d9e7ea7a2d47403d48
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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 Sep 7, 2026.

Transparency log

Release files / aimai_kit-1.0.1-py3-none-any.whl

Download URL aimai_kit-1.0.1-py3-none-any.whl
Size 117.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
19eb3fba040421766e3d5e770028e0d87ab35919f0789c832323bf5cdc5e4ad2
BLAKE2b-256 checksum
How to use checksums
3004f97a0df0d09f1e10a049ca2a8176d027a75778b450a17fd0342ceda7d22f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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 Sep 7, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

1.0.1 This release

2 release files

1.0.0

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