← All courses ← Course home

Lesson 03 of 05

Sketch a tiny harness

Build a short Python harness on a Mac or any CPU. Fake tools, a scoped context pack, a verifier, and a loop limit.

Agent brief (llms.md)

Environment setup

Use Python 3.11 or newer on a Mac or any CPU machine. uv manages the project. This sketch uses the standard library only. Do not install PyTorch. Do not use CUDA.

curl -LsSf https://astral.sh/uv/install.sh | sh
mkdir -p harness-sketch && cd harness-sketch
uv init --python 3.11
uv venv
# Save the lesson code as harness.py, then:
uv run python harness.py

uv run uses the project environment. You do not need a global pip install. The script should print one passing KPI answer and one stop.

The "model" here is a tiny stand-in. Swap that function later for a real model. The harness stays: scoped context, a fixed KPI tool, a loop limit, and a verifier that checks the tool ran and the answer cites evidence.

"""Tiny agent harness. CPU only. No model download."""

CONTEXT = {
    "who_asked": "finance-ops",
    "period": "2026-Q2",
    "allowed_metrics": ("revenue_per_user",),
    "evidence": {
        "revenue_per_user": {
            "value": 42.5,
            "source": "finance_kpi_table",
        }
    },
}

MAX_STEPS = 3


def calc_kpi(name):
    """Fixed KPI math. The model must not invent this number."""
    if name not in CONTEXT["allowed_metrics"]:
        raise ValueError(f"kpi not in approved pack: {name}")
    row = CONTEXT["evidence"][name]
    return {"name": name, "value": row["value"], "source": row["source"]}


def fake_model_plan(question, already_called):
    """Stand-in for a model. Swap this function later. The harness stays."""
    q = question.lower()
    if "revenue per user" in q and not already_called:
        return "tool:calc_kpi:revenue_per_user"
    if already_called:
        return "answer"
    return "stop"


def run_agent(question):
    tools_called = []
    traces = []
    answer = ""
    evidence_row = None

    for step in range(MAX_STEPS):
        action = fake_model_plan(question, bool(tools_called))
        traces.append({"step": step, "action": action})

        if action.startswith("tool:calc_kpi:"):
            name = action.split(":", 2)[2]
            evidence_row = calc_kpi(name)
            tools_called.append("calc_kpi")
            traces[-1]["result"] = evidence_row
            continue

        if action == "answer" and evidence_row:
            answer = (
                f"Revenue per user in {CONTEXT['period']} is {evidence_row['value']}. "
                f"Evidence: {evidence_row['source']}."
            )
            break

        answer = "I do not have approved data for that. Stopping."
        break

    return {
        "question": question,
        "answer": answer,
        "tools": tools_called,
        "traces": traces,
        "who_asked": CONTEXT["who_asked"],
    }


def verify(run):
    """Pass only if the KPI tool ran and the answer cites evidence."""
    errors = []
    if "calc_kpi" not in run["tools"]:
        errors.append("tool was not called")
    if "Evidence:" not in run["answer"]:
        errors.append("answer does not cite evidence")
    return errors


if __name__ == "__main__":
    good = run_agent("What is revenue per user for 2026-Q2?")
    print(good["answer"])
    print("verify:", verify(good) or "ok")

    bad = run_agent("What is our secret margin?")
    print(bad["answer"])
    print("verify:", verify(bad) or "ok")

Read the two prints. The first run calls calc_kpi, cites finance_kpi_table, and the verifier returns ok. The second run has no approved metric, so the loop stops. The verifier fails on purpose: the tool was not called and there is no evidence line. That fail is useful. It is a golden case you can keep.

The context pack is narrow on purpose. Only revenue_per_user is allowed. A wider pack would leak numbers the asker should not see. That is the trusted-context layer from lesson 02.

Rule. The model function is a stand-in. Do not train anything for this lesson.

Next, turn a bad run into an improve loop.

Key concepts

  • Set up uv and Python 3.11+ first. Standard library only. No CUDA.
  • Scoped context is an allow-list of metrics and evidence, plus who asked.
  • calc_kpi is fixed logic. The stand-in model may call it. It may not invent the number.
  • The verifier checks two things: the tool was called, and the answer cites evidence.
  • MAX_STEPS is the orchestration limit. A missing metric stops the loop.

Takeaways

  • You can run this sketch on a Mac or any CPU with uv run python harness.py.
  • A failing verifier is a seed for a golden case, not a reason to fine-tune.
  • Swap fake_model_plan later. Keep the pack, the tool, the verifier, and the limit.