Skip to main content

Evals-first prompt optimization. Label examples, get better prompts.

Project description

karat

Evals-first prompt optimization. Label examples, get better prompts.

Documentation

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 objects
    • labels (optional): allowed values -- makes the field editable
    • table (default true): show as a table column
    • detail (default true): 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
  • u clears current cell, Shift+U clears entire row, q saves 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)

Project details


Download files

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

Source Distribution

karat-0.2.8.tar.gz (137.1 kB view details)

Uploaded Source

Built Distribution

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

karat-0.2.8-py3-none-any.whl (27.1 kB view details)

Uploaded Python 3

File details

Details for the file karat-0.2.8.tar.gz.

File metadata

  • Download URL: karat-0.2.8.tar.gz
  • Upload date:
  • Size: 137.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.2 {"installer":{"name":"uv","version":"0.11.2","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}

File hashes

Hashes for karat-0.2.8.tar.gz
Algorithm Hash digest
SHA256 8a9ef93a9d3e0c7e48758446e2f07f3341df8e9fb8d65b2c527c910c85017a5e
MD5 c3547f96a57c69cef169f10a3b7b5589
BLAKE2b-256 b978bb43a5a6290733fc106310430d65ee1839a34450e49bacd20ac09f3ed26f

See more details on using hashes here.

File details

Details for the file karat-0.2.8-py3-none-any.whl.

File metadata

  • Download URL: karat-0.2.8-py3-none-any.whl
  • Upload date:
  • Size: 27.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.2 {"installer":{"name":"uv","version":"0.11.2","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}

File hashes

Hashes for karat-0.2.8-py3-none-any.whl
Algorithm Hash digest
SHA256 18817c5e60997d27a196910ac0c0a7cabd8bc95bee42bc4e9eff1a4a7738484c
MD5 5a21e4308e57d8e10a0a8d1cf2e329a2
BLAKE2b-256 3a14d9f62f5b08c119fbc09cc8843591b1c8b16475929c3f708f8c6fd38cb125

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