← Files CRIADOR / ReefARCHIVED FILE

skills/reef-agent-improvement/references/quickstart.rst

7.96 KB · Oct 2, 2026 · 00:35 UTC

↓ Download file

Quickstart: serve inference and report feedback
===============================================

Start Reef locally, send an inference request through a hosted provider,
report feedback on the response, and inspect the release history. This
quickstart needs no GPU; the final section links to recipes that learn
from the records you collect.

A typical Reef workflow includes the following steps:

1. **Request.** Harness sends a request with a *scenario*.
2. **Response.** Reef forwards the response from the model to the harness, with
   a *receipt* attached to it.
3. **Report.** An entity provides a *report* containing feedback for the
   response associated with the *receipt* to Reef.
4. **Learn.** Reef runs the training / learning process against the reports in
   batches according to its *recipe*.
5. **Evolve.** Reef potentially creates a new version of the *artifact*, which
   may become immediately effective (e.g. model evolution) or requires a pull
   from the harness to take effect (e.g. harness evolution).
6. **Update.** Harness can view the history of served artifacts (*release
   chain*) and potentially pull a new harness tree.

This workflow touches a few key concepts:

- **scenario** - A specific type of workload. For example, a code reviewer, or a
  math problem solver. Reef manages the training of each scenario separately,
  i.e. records, training state and release chain.
- **receipt** - The id of a recorded inference exchange. It identifies the
  request, the response, and the release that produced it.
- **report** - A feedback quoting one or more receipts.
- **recipe** - How Reef use the report to evolve new versions of artifacts. A
  deployment serves one recipe, and every scenario on it evolves under that
  recipe.
- **artifact** - The content a release selects: model weights, or a harness
  tree of rules, prompts, skills, and config. Versioned.
- **release** - One accepted publication in a scenario. The chain of them is
  the scenario's history.

We will explore these concepts in greater depth later. For now, it's time to
get our hands dirty and experience these steps ourselves.

Run the loop
------------

This runs the serving half of the loop against a hosted provider, on a laptop,
with no GPU.

.. steps::

   #. **Install.** Follow the laptop path in `Installation
      <installation.rst>`__.

   #. **Serve.** Connect an OpenAI-compatible provider and record what it
      serves, without a YAML file or GPU.

      .. code:: bash

         export REEF_TOKEN=reef-local
         export REEF_UPSTREAM_API_KEY=sk-...

         reef serve \
           --inference.upstream-url https://api.openai.com \
           --inference.upstream-model gpt-4o

      Reef listens on ``127.0.0.1:8900`` and writes state under ``.reef/`` in
      the directory where you run it. The upstream key and Reef token come
      from the environment. Without ``-c``, no config file is read. To connect
      another provider, change the URL and model. Existing deployments can
      still use ``reef serve -c recipes/basic/external-provider.yaml``.

      ``reef serve`` runs in the foreground and holds the terminal until
      Ctrl-C. Leave it running and open a second terminal for everything below.

      .. code:: bash

         curl -f http://127.0.0.1:8900/healthz     # {"ok": true}

   #. **Send a request and report on it.** The body is the provider's;
      ``x-reef-scenario`` is the only thing Reef adds. The response header
      ``x-reef-agent-record-id`` carries the **receipt**, which names the
      stored exchange. Tests, a verifier, a rubric, a thumbs-down, or any other
      grader you already have can report feedback against it.

      .. code:: python

         import httpx

         reef = httpx.Client(
             base_url="http://127.0.0.1:8900",
             headers={"Authorization": "Bearer reef-local", "x-reef-scenario": "hello-reef"},
         )

         response = reef.post(
             "/v1/chat/completions",
             json={"model": "gpt-4o", "messages": [{"role": "user", "content": "Return exactly: reef is ready"}]},
         )
         response.raise_for_status()
         receipt = response.headers["x-reef-agent-record-id"]  # e.g. ee5aa401634b4567bf9dae21816abde4
         matched = response.json()["choices"][0]["message"]["content"].strip() == "reef is ready"

         report = reef.post(
             "/reef/report",
             json={"score": float(matched), "feedback": "matched" if matched else "wrong answer", "references": [receipt]},
         )
         print(report.json())
         # {"agent_record_id": "cce17dd7...", "scenario": "hello-reef", "request_type": "report"}

      Reports are records too, so the response carries the report's own record
      id. Only inference-record ids are receipts, and they appear only
      in ``references``.

   #. **Or use the wire client.** Install the stdlib-only ``reef-client`` with
      ``pip install reef-client``. It keeps the receipt for you.

      .. code:: python

         from reef_client import ReefClient

         client = ReefClient("http://127.0.0.1:8900", token="reef-local")

         body, receipt = client.inference_with_record(
             "hello-reef",                                   # the scenario
             "/v1/chat/completions",
             {"model": "gpt-4o", "messages": [{"role": "user", "content": "hi"}]},
         )
         answer = body["choices"][0]["message"]["content"]

         # ... whatever already judges your agent decides this score ...
         client.report("hello-reef", {"score": 1.0}, references=[receipt])

      With an OpenAI SDK instead, point ``base_url`` at
      ``http://127.0.0.1:8900/v1``, send ``x-reef-scenario`` as a default
      header, and read ``x-reef-agent-record-id`` off the raw response.

      On the wire it is an ordinary provider request with one added header, and
      the receipt comes back in a response header:

      .. code:: bash

         curl -sS -D - -o /dev/null \
           http://127.0.0.1:8900/v1/chat/completions \
           -H "Authorization: Bearer reef-local" \
           -H "x-reef-scenario: hello-reef" \
           -H "Content-Type: application/json" \
           -d '{"model": "gpt-4o", "messages": [{"role": "user", "content": "hi"}]}'
         # x-reef-agent-record-id: ee5aa401634b4567bf9dae21816abde4

   #. **Read the release chain.**

      .. code:: bash

         curl -sS -H "Authorization: Bearer reef-local" \
           http://127.0.0.1:8900/reef/scenarios/hello-reef/releases
         # {"scenario": "hello-reef", "releases": [{"release_id": "...", "operation": "creation", "current": true, ...}]}

      One release, and it will stay at one: this deployment's recipe is the
      core ``recipe``, which records and trains nothing.

To make the chain advance, bind a recipe that learns. To use a weight recipe,
start from ``recipes/sao/examples/sao/serve.yaml``. It selects
``recipe.implementation: recipes.sao.recipe:SAORecipe`` and configures the
training driver and model workers.
Weight recipes need GPUs (`Evolve your model
<../user-guide/evolve-your-model.rst>`__).

The one that runs on a laptop is ``evolve-your-harness``, and it takes a second
file: a **preset** naming your ``propose`` and ``evaluate`` callables and the
tasks to evaluate on. ``tutorials/evolve-your-harness/run.sh`` wires the whole loop
together. Run it, then read `Evolve your harness
<../user-guide/evolve-your-harness.rst>`__ for an explanation of each piece.

Choose your next step
---------------------

- `Compare learning recipes <../user-guide/recipes.rst>`__ to choose between
  model training and harness evolution based on the feedback you have.
- Try `GEPA harness optimization <../user-guide/recipes/gepa.rst>`__ or
  `SkillClaw skill evolution <../user-guide/recipes/skillclaw.rst>`__ for
  worked harness examples, or `SAO rollout training
  <../user-guide/recipes/sao.rst>`__ for a GPU training example with results.
- Use the `HTTP API reference <../reference/http-api.rst>`__ when connecting
  your own agent: it covers inference headers, feedback reports, and release
  management.

SHA-256: 72f9b3c9f9193d1085b9dd4c27f70718e619517ac8914cddf3c9cee2a0a95f60