karat
Evals-first prompt optimization. Label examples, get better prompts.
The prompt is a build artifact -- your labeled examples are the source of truth. When you want a better prompt, add more examples and regenerate.
Install
uv add karat
Install the /optimize skill (optional)
uvx karat install
Copies the /optimize skill into .claude/skills/optimize/SKILL.md in your project. The skill walks agents through labeling examples and optimizing prompts.
Usage
import dspy
from karat import AgentLM
lm = AgentLM()
dspy.configure(lm=lm)
class Classify(dspy.Signature):
"""Classify a GitHub repo as a curated collection or an organic project."""
readme: str = dspy.InputField()
is_collection: bool = dspy.OutputField()
classify = dspy.Predict(Classify)
result = classify(readme="# awesome-skills\n\n500+ curated Claude skills")
Loading Optimized Programs
After running /optimize, load the compiled program with load_predict:
from karat import load_predict
from my_sigs import ClassifyRepo
# Loads optimized JSON if it exists, falls back to unoptimized
classify = load_predict(ClassifyRepo, path="data/optimized_classify_repo.json")
result = classify(readme="# awesome-skills\n\n500+ curated Claude skills")
Labeling TUI
For interactive labeling in a separate terminal:
karat label examples.json --output labeled.json
The agent writes examples to a JSON file, the user labels them in the TUI, and the agent reads the results back.
Input format
{
"fields": [
{"name": "url"},
{"name": "description"},
{"name": "reasoning", "table": false},
{"name": "is_collection", "labels": ["true", "false"]}
],
"examples": [
{"url": "https://...", "description": "A curated list",
"reasoning": "YES: curated list pattern",
"is_collection": "true"}
]
}
fields: ordered array of field definitions. Each field has:name: key in example objectslabels(optional): allowed values -- makes the field editabletable(defaulttrue): show as a table columndetail(defaulttrue): show in detail panel
- Pre-populated values: if an example has a value for a label field, it's shown as an editable default
- URLs are automatically rendered as clickable links
Interaction
- Single field, <=9 labels: number keys assign directly
- Single field, >9 labels: Enter opens searchable filter, type to narrow
- Multiple fields: spreadsheet-style cell cursor, Enter on a label cell opens search, Tab/Shift+Tab move between label columns
uclears current cell,Shift+Uclears entire row,qsaves and quits
Legacy formats (label_fields/display_fields or label_field/labels) are also supported.
Options
AgentLM passes all keyword arguments through to ClaudeAgentOptions:
# Strip all tools (recommended for classification/structured output)
lm = AgentLM(tools=[])
# Allow specific tools
lm = AgentLM(allowed_tools=["Read", "Glob"])
# Set environment variables for the SDK subprocess
lm = AgentLM(env={"CLAUDECODE": ""})
Caching
Pass a cachetta instance to wrap the query function with file-backed caching:
from cachetta import Cachetta
from karat import AgentLM
cache = Cachetta(path=lambda prompt, **kw: f"cache/{prompt}.pkl", duration="7d")
lm = AgentLM(cache=cache)
Install with the cache extra: uv add "karat[cache]"
Development
uv sync --extra dev
uv run just test-unit # Run tests
uv run just ci # Full CI (lint + format + typecheck + tests)
Metadata
Release files for karat 0.2.9
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| karat-0.2.9.tar.gz | 138.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| karat-0.2.9-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 167.2 kB
Release files / karat-0.2.9.tar.gz
| Download URL | karat-0.2.9.tar.gz |
|---|---|
| Size | 138.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
fc31c5b8957b75c55cd1f5ed7578f828a6cc4e6fd8a0292cc1ca2df0aa393a25
|
|
BLAKE2b-256 checksum How to use checksums |
20734d87112ce2bc1efc174526cb6852c5d8457392a2964b483651a23a667573
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.11.7 {"installer":{"name":"uv","version":"0.11.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / karat-0.2.9-py3-none-any.whl
| Download URL | karat-0.2.9-py3-none-any.whl |
|---|---|
| Size | 28.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
8dad3832473a92cc933c448501c9f4fa95b9694a48dadb95c966bc75bc21ee11
|
|
BLAKE2b-256 checksum How to use checksums |
935feefffdf962787993bef115c2e244cbfab6eb779c0d2a7df52350fb61f466
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.11.7 {"installer":{"name":"uv","version":"0.11.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|