Skybert documentation

Build Python agents locally with Pi, capture observations with the Skybert SDK, evaluate against datasets, and monitor shipped versions in Cloud when you are ready.

User Journey

  1. Install Skybert in the Python project where the agent will live.
  2. Prepare providers with Pi and the model provider you want to use.
  3. Build locally from the fullscreen skybert workspace. Choose Build new agent or Add existing agent.
  4. Run normally. Decorated functions capture observations in .skybert/. If you are logged in, runs will sync to Cloud for user-friendly annotation and dataset building.
  5. Review and evaluate local observations or synced datasets. Pi edits code, prompts, contracts, validators, and versions.
  6. Ship through git. Review and deploy changes like you normally would. Agents in production will automatically upload observations if configured with Cloud credentials.

Installation

Install Skybert in the agent project. The package includes the Python SDK, local workspace, fullscreen CLI, dataset tools, eval helpers, and Cloud login commands.

uv

uv add skybert

pip

pip install skybert

Poetry

poetry add skybert

Running the CLI: use uv run skybert status in uv projects, poetry run skybert status in Poetry projects, or skybert status when your virtualenv is active.

Install Pi and connect your model provider:

terminal
npm install -g --ignore-scripts @earendil-works/pi-coding-agent
pi
/login
Provider setup: use Pi's /login command, then follow the Pi provider docs for the model provider you want.

New Agent

The guided path starts from a clean folder and the fullscreen workspace.

terminal
mkdir my-first-agent
cd my-first-agent
uv init
uv add skybert
skybert
Add useful data before you launch. Put examples, CSV exports, JSON, JSONL, specs, prompts, or notes in the agent folder. Skybert inspects the project scope, summarizes discovered data files, and Pi asks which data should guide the build.
Skybert fullscreen workspace with Build new agent selected

Choose Build new agent. Skybert launches Pi, checks provider readiness, asks what useful task data you already have, generates or edits code locally, and writes evidence for the next step.

Add Existing Agent

Use this path when your repo already has agent, workflow, prompt, tool, API handler, or pipeline code and you want Skybert to add instrumentation around the right boundary.

terminal
cd existing-agent-repo
uv add skybert
skybert
  • Choose Add existing agent in the fullscreen workspace.
  • Pi inspects the active folder, finds likely agent entrypoints, and asks which path is the real agent if the code is ambiguous.
  • Skybert should wrap the smallest stable task function, not app startup, server glue, or unrelated framework plumbing.
  • Existing CSV, JSON, and JSONL files can be used as task examples or evaluation data.

Existing Agents

Agents show up in the Skybert TUI when Skybert detects decorated functions in the folder structure you launched from.

How detection works

Skybert performs a static scan for @skybert.optimize(...) decorators under the active project scope. It does not import your modules just to discover agents.

When nothing appears

Start skybert from the repo or subfolder that contains the decorated code, or set SKYBERT_FOCUS to the folder Skybert should scan.

Select an existing agent from the Home screen to review runs, inspect datasets, monitor versions, or continue the same Pi build session with its prior context.

Skybert Framework

Skybert works at the Python function boundary. Decorate the function whose output you want to observe, review, evaluate, and improve.

Agent

agent="..." groups related functions, observations, datasets, evals, and production monitoring.

Version

version="0.1.0" is required. Increment it whenever agent behavior changes so Cloud can compare shipped versions.

Target

target="..." names the returned field reviewers and evals should judge.

  • inputs=[...] names the function arguments that define a dataset row, such as question, topic, ticket_text, or document.
  • Inputs are the case being evaluated. They are kept stable when Skybert reviews, compares, and reruns an example.
  • Function parameters not listed as inputs can be useful tunable values, such as prompt, model, temperature, thresholds, or grader instructions.
  • display_results=[...] can show extra returned fields beside the target.
minimal.py
import skybert

@skybert.optimize(
    agent="support-agent",
    version="0.1.0",
    inputs=["question"],
    target="answer",
)
def answer_question(question: str, prompt: str = "Answer briefly."):
    return {"answer": call_your_agent(question, prompt=prompt)}

Local Workspace

Skybert is local-first. Normal agent runs do not ask login questions or require Cloud. Observations, annotations, traces, datasets, sync state, and auth live under the project .skybert/ workspace.

Connected dev runs: local runs always write to .skybert/. When the workspace has saved Cloud credentials from skybert login, normal non-interactive runs sync to Cloud unless Cloud upload is disabled.

Default

Start skybert from the agent folder. The workspace is ./.skybert.

Override

Use SKYBERT_WORKSPACE=/path/to/project for a project workspace or SKYBERT_CONFIG_DIR=/path/to/.skybert for an exact data directory.

File Purpose
runs.jsonl Recorded decorated function calls.
annotations.jsonl Local review feedback from the TUI, CLI, or code.
traces.jsonl Trace bundles around larger work.
gold_datasets.json Local datasets used for eval and improvement.
sync_state.json Dataset sync bookkeeping.
auth.json Saved Cloud credentials from skybert login.

Run skybert workspace when you need to see exactly which workspace is active.

Fullscreen CLI

Run skybert with no arguments to open the local workspace. It is the primary product surface for local work.

  • Home shows Cloud login state, local counts, Pi readiness, and known agents.
  • Build new agent launches the Pi builder for a new production-grade agent.
  • Add existing agent asks Pi to inspect existing code and add instrumentation at the right function boundary.
  • Continue with agent reopens the same Pi build session, so Pi keeps the prior build context when you resume work on an existing agent.
  • View runs lets you review local observations as good, bad, partial, or unsure.
  • Datasets previews local and Cloud datasets.
  • Monitor summarizes run quality by decorator version when Cloud is connected.

Datasets and Eval

Datasets are the bridge between real observations and repeatable improvement. They can come from reviewed local runs, JSONL files, or production datasets created in Skybert Cloud and pulled locally.

interactive eval
python agent.py --interactive
skybert eval run --agent support-agent --function answer_question --dataset <dataset-id>
  • Interactive mode is only for eval/control loops. Normal agent runs just record observations.
  • SKYBERT_INTERACTIVE=1 python agent.py also starts interactive mode.
  • skybert eval run-command ... -- python agent.py can launch the interactive process for a one-shot eval.
  • Pi uses datasets and eval evidence to make local code improvements.

Cloud and Production

Cloud is optional for local builds. Use it when you want hosted observations, team review, production dataset creation, and version monitoring.

production secrets
skybert login
skybert show-token

export SKYBERT_ENV=production
export SKYBERT_API_KEY=...
export SKYBERT_GIT_SHA=...
  • Store the token from skybert show-token as SKYBERT_API_KEY in your deployment secret store.
  • Set SKYBERT_ENV=production on deployed agents so production observations upload.
  • Do not commit or log tokens. Use skybert show-token --json for automation.
  • The TUI sync path is dataset-only. Runs sync from instrumented code when Cloud credentials are active.
Open Cloud Dashboard

Telemetry

Skybert records runs without telemetry extras. Add an extra only when you want Skybert spans in your existing OpenTelemetry or Logfire setup.

Install Use it for
uv add "skybert[otel]" Adds OpenTelemetry dependencies. With SKYBERT_TELEMETRY=otel, Skybert creates run and trace spans; your app still controls exporters and OTel environment.
uv add "skybert[logfire]" Adds Logfire support. With SKYBERT_TELEMETRY=logfire, Skybert configures Logfire and instruments OpenAI and Pydantic AI when those packages are installed.
Content capture: Logfire content capture is off by default. Set SKYBERT_LOGFIRE_INCLUDE_CONTENT=1 only when prompt and output content is safe to send to your telemetry backend.

Annotations and Tracing

Use annotations when your product already knows whether an output was good, bad, incomplete, or preferred by a user. This is useful in user-facing products: thumbs up/down, edits, approvals, expert reviews, and support outcomes can become feedback on the exact run that produced the output.

That feedback gives human experts a direct way to steer the system. Skybert can turn annotated runs into datasets, so future build and optimization work is shaped by real user preferences and expert judgment. Skybert attaches feedback to the latest run unless you pass a specific run_id.

feedback.py
result = answer_question("How do I deploy?")

skybert.annotate(
    verdict="partial",
    corrected_output={"answer": "Deploy normally and set SKYBERT_API_KEY."},
    comment="The answer missed the token setup.",
)

For asynchronous product flows, store the run id with your own job, message, or review record, then annotate that run when feedback arrives later.

async_feedback.py
async def create_answer(question: str):
    result = await answer_question(question)
    return {
        "answer": result["answer"],
        "skybert_run_id": skybert.last_run_id(),
    }

async def handle_user_feedback(run_id: str, accepted: bool, edited_answer: str | None = None):
    skybert.annotate(
        run_id=run_id,
        verdict="good" if accepted else "partial",
        corrected_output={"answer": edited_answer} if edited_answer else None,
        comment="User feedback from the product UI.",
    )

Accepted verdict shortcuts are good, bad, partial, and unsure. Use skybert.Trace(...) to group larger work inside a run.

CLI

Command Use it for
skybert Open the fullscreen local workspace.
skybert login Log in to Skybert Cloud and save credentials locally.
skybert show-token Print the saved token for SKYBERT_API_KEY deployment secret setup.
skybert status Show Cloud auth state, workspace, counts, and dataset-only sync mode.
skybert workspace Show the active local workspace path and resolution source.
skybert inspect --json Return machine-readable workspace, provider, dataset, and agent discovery data.
skybert providers check Check provider readiness without printing secrets.
skybert agents list List known agents and decorated functions.
skybert runs list List captured local observations.
skybert runs review Attach a local verdict annotation to a run.
skybert datasets ... List, import, create, pull, publish, and preview dataset sync.
skybert eval ... Run current local code against datasets through an interactive agent process.
skybert doctor Check workspace access, auth state, and Cloud reachability when connected.
skybert logout Clear saved Cloud credentials.
skybert reset Delete local Skybert state in the workspace.

Environment

Variable Purpose
SKYBERT_WORKSPACE Project workspace override. Skybert stores data in $SKYBERT_WORKSPACE/.skybert.
SKYBERT_CONFIG_DIR Exact .skybert data-directory override.
SKYBERT_FOCUS Directory the decorator scanner should focus on.
SKYBERT_ENV Set to production for deployed agents that should upload production observations.
SKYBERT_API_KEY Production Cloud token from skybert show-token.
SKYBERT_INTERACTIVE Set to 1 to start an agent process in interactive eval mode.
SKYBERT_RUN_MODE Set to interactive for interactive mode. eval is no longer supported.
SKYBERT_GIT_SHA Optional deployed git SHA attached to production observations.
SKYBERT_DISABLE_CLOUD_UPLOAD Set to 1 to prevent runtime Cloud observation upload.
SKYBERT_TELEMETRY Set to logfire or otel for optional telemetry integration.
SKYBERT_LOGFIRE_INCLUDE_CONTENT Set to 1 to include prompt and output content in Logfire instrumentation.