Skip to main content
The Python SDK is how you turn your own code into an agent. It provides the worker runtime, the agent definition, and helpers for producing well-formed output and evidence. This page walks the path: install, define, implement, emit evidence, test locally, deploy.

Install

Agents are built with the komodor-agentops package, on Python 3.11 or newer. The SDK is framework-agnostic — a plain function, a chain, a tool-using loop — and adapters ship as extras:

Project layout

The agent’s identity and knowledge live as files next to the code:
agent-spec.yaml is the source of truth for identity:
AgentSpec.from_dir(...) loads the spec, then picks up agent.md and skills/ automatically. Declared triggers and skills are registered when the worker connects.

A minimal worker

A worker is three things: an agent spec, an async handler turning a run’s input into its output, and a run call.
.run() configures logging, pulls the agent’s credentials at boot, dials the control plane, and begins heartbeating. To embed the worker in an existing application, await AgentOpsWorker(...).serve() instead.
The worker binds no port and serves nothing. It dials out and receives its runs over that one connection — no HTTP server to expose, no inbound rule, nothing for an ingress to point at.
Raising from the handler fails the run, with the exception as the reported error. There is no “return a failed result” form. summarize_incident is your own application function and must be implemented or imported — this is an integration skeleton, not a complete incident-analysis implementation. A genuinely minimal handler can just return what it was given.

The output contract

A result can carry structured fields and descriptive text, and getting this right is what makes an agent usable in more than one place: Both live in the one dict the handler returns. An automation-only agent can return structured fields alone; an agent whose result a human reads should provide both. Keep them aligned — do not bury machine values inside prose, and do not invent a second human-text field, because text is reserved. When an agent provides no descriptive text, the platform renders the structured output readably instead.

Emitting evidence

While it runs, your agent can stream the same evidence the built-in agents do:
  • Spans — wrap a function with @observe(name="...", as_type="tool") to record nested trace spans.
  • Streaming textawait stream_status_text("...") streams partial output to streaming-capable callers such as chat; it is a no-op elsewhere.
  • Artifacts — attach files and reports to the run through the artifact client.
With a framework adapter most of this is automatic: the adapters record model calls, tool calls, and token usage without extra code.

Credentials

Do not bake keys into the image. Store them as credentials, bind them to the agent, and the SDK delivers them:
  • Per run — bound credentials arrive with each run; call apply_secret_to_env("ANTHROPIC_API_KEY") or get_secret(...) in your handler.
  • At boot — for a token needed before any run, nothing is required: the worker pulls the on-demand credentials bound to it at start-up.
Values delivered this way are masked out of the evidence the worker emits; see Secrets & credential handling.

Test locally

Run your handler once, with no control plane, using the CLI installed with the SDK:
It loads env files, exposes detected secrets as run-scoped secrets and puts them in the environment the way a real run does, calls your handler with a Run built from the flags, and writes the output. Anything uploaded with run.upload_artifact(...) lands in --artifact-dir. The same flow is available programmatically as run_worker_once and run_worker_once_sync.

Deploy

A worker is a normal service you deploy however you run software. It needs two things from the platform, both as environment variables:

Use cases

An agent can advertise named, schema-typed actions in its agent-spec.yaml, and each becomes a callable tool on that agent’s own MCP endpoint:
Read them back off a stored agent card with UseCase.list_from_card(agent_card). Every agent also advertises two built-ins — a connectivity check and a sample run — without declaring anything. See Use cases for the full field list and how they are called.

Next steps

Go SDK

The same worker contract, without Python in the container.

Agent identity

Where the worker token comes from, and how to rotate it.

Runs & evidence

What the evidence you emit becomes.

Skills

The skills/ directory, and what happens to it.