1. Install¶
Time budget: under 5 minutes. This is the gate for the whole
Getting Started tutorial — if you finish this section you have a
working zeroth-core install and have made a real LLM call through
it.
Install the package¶
Or with uv:
Optional backends (Postgres, pgvector, Chroma, Elasticsearch, Redis,
Regulus economics), the web console, and the LangGraph integrations are
available through extras; see pyproject.toml for the full list. The Getting
Started tutorial runs entirely on the default in-memory SQLite backend,
so you do not need any extras to complete the tutorial.
Published package versus current docs
This documentation is built from main, which can be ahead of the latest
package on PyPI. For the exact
source documented here, use the repository checkout below and run commands
with uv run.
Set an API key¶
The hello example below makes one real LLM call through
litellm using OpenAI
(openai/gpt-4o-mini). Set your key:
Any litellm-supported provider works — edit the model= argument in the
hello script to switch (e.g. anthropic/claude-sonnet-5 with
ANTHROPIC_API_KEY).
Run the hello example¶
The canonical smoke test lives at examples/00_hello.py in the
repository — the examples/ directory is not shipped inside the wheel,
so clone the repo to run it:
(No clone handy? zeroth-core seed-demo && zeroth-core serve gives you a
running demo service from the bare pip install — see
Local development.)
It builds a one-node graph, wires a real AgentRunner through
LiteLLMProviderAdapter, and runs it through the orchestrator. If
this runs end-to-end your install is healthy.
"""00 — Hello, Zeroth: a single agent node, run through the real runtime.
What this shows
---------------
The smallest possible end-to-end invocation. One :class:`AgentNode`, one
real :class:`AgentRunner` backed by the real :class:`LiteLLMProviderAdapter`,
run through the real :class:`RuntimeOrchestrator`. No stubs, no hacks, no
``litellm.completion`` calls in user code — this file is what the library
wants you to write.
Requirements
------------
* ``OPENAI_API_KEY`` in the environment (uses ``openai/gpt-4o-mini``).
Set ``ZEROTH_EXAMPLE_MODEL`` to override the model name.
Run
---
uv run python examples/00_hello.py
"""
from __future__ import annotations
# Allow python examples/NN_name.py to find the sibling examples/_common.py helper.
import sys as _sys
from pathlib import Path as _Path
_sys.path.insert(0, str(_Path(__file__).resolve().parents[1]))
import asyncio
import os
import sys
from examples._common import (
DEMO_GRAPH_ID,
print_run_summary,
require_env,
running_service,
)
from examples._contracts import Answer, Question
from zeroth.contracts.graph import (
AgentNode,
AgentNodeData,
DisplayMetadata,
ExecutionSettings,
Graph,
)
from zeroth.runtime.agents import (
AgentConfig,
AgentRunner,
LiteLLMProviderAdapter,
)
def build_graph(model_name: str) -> Graph:
"""A one-node graph whose only step is a Q&A :class:`AgentNode`."""
graph_version_ref = f"{DEMO_GRAPH_ID}@1"
return Graph(
graph_id=DEMO_GRAPH_ID,
name="Hello, Zeroth",
version=1,
entry_step="qa",
execution_settings=ExecutionSettings(max_total_steps=5),
nodes=[
AgentNode(
node_id="qa",
graph_version_ref=graph_version_ref,
display=DisplayMetadata(title="Q&A"),
input_contract_ref="contract://question",
output_contract_ref="contract://answer",
agent=AgentNodeData(
instruction=(
"You are a helpful assistant. Answer the user's question in one "
"short sentence. Return JSON matching the output schema."
),
model_provider=model_name,
model_params={"temperature": 0.2, "max_tokens": 120},
),
),
],
edges=[],
)
async def main() -> int:
if not require_env("OPENAI_API_KEY"):
return 0
model_name = os.environ.get("ZEROTH_EXAMPLE_MODEL", "openai/gpt-4o-mini")
# Build one real AgentRunner for the one node in the graph. The
# LiteLLMProviderAdapter reads OPENAI_API_KEY from the environment.
runner = AgentRunner(
AgentConfig(
name="qa",
description="Answers a user question in one sentence.",
instruction="Answer the user in one short sentence.",
model_name=model_name,
input_model=Question,
output_model=Answer,
),
LiteLLMProviderAdapter(),
)
async with running_service(
build_graph(model_name),
contracts={
"contract://question": Question,
"contract://answer": Answer,
},
agent_runners={"qa": runner},
) as demo:
run = await demo.service.orchestrator.run_graph(
demo.service.graph,
{"question": "What is Zeroth in one sentence?"},
deployment_ref=demo.deployment_ref,
)
print_run_summary(run, label="hello")
return 0
if __name__ == "__main__":
sys.exit(asyncio.run(main()))
Run it:
Expected output: a single short greeting sentence from the LLM.
If OPENAI_API_KEY is unset the script prints a SKIP notice to
stderr and exits 0 — that same behaviour keeps CI green on forked
pull requests that do not have secrets configured.
Next¶
→ Section 2: First graph with an agent, a tool, and an LLM call