Skip to content
John Hodge

← Blog

APAB 0.3.0: observability and provenance for agentic phased-array design

APAB could already design a phased array. What you could not do was see how: which tools the agent called, in what order, how long each took, what it cost, and whether you could reproduce the run a month later. Version 0.3.0 answers those questions. It adds an observability and audit layer on top of the existing Model Context Protocol (MCP) tool layer and run bundles, rather than rebuilding APAB around an agent framework.

If you are new to the project: APAB does agentic phased-array design. An LLM agent runs the design pipeline, from unit cell to array pattern to link budget, by calling real RF antenna tools over MCP, and it writes an auditable run bundle. The architecture post covers how that works; this one covers what 0.3.0 changed. APAB is on PyPI, MIT-licensed, and now beta.

Every session is a trace

Install the observability extra and every APAB session becomes an OpenTelemetry trace.

pip install "apab[observability]"

The trace nests the way the work does: one span for the session, one per turn, and one per LLM call and tool call inside it.

apab.session
└─ apab.turn
   ├─ apab.llm.chat        # tokens, latency, cost estimate
   └─ apab.tool.<name>     # arguments (redaction-aware), status, timing

Each span carries token counts, latency, and a cost estimate, plus the tool arguments captured under a redaction-aware policy. Spans can go three places: a per-run trace.jsonl you can read with no OpenTelemetry tooling at all, the console, or any OTLP endpoint. A one-container Jaeger lab (lab/docker-compose.yml) is included if you want a flame-graph view.

The point is the questions this makes answerable. Which tool dominated wall-clock time? Which calls failed, and why? Did the agent loop on the same call three times before moving on? Before 0.3.0 none of that was inspectable.

Provenance you can reproduce from

A design result is only trustworthy if you can tie it back to the exact code, configuration, and model that produced it. APAB already wrote run bundles, but the provenance record was computed and never actually written at runtime, so the reproducibility claim had nothing behind it.

0.3.0 closes that gap. Every completed run now writes a manifest.json next to its audit.json:

workspace/runs/<run_id>/
  manifest.json     # config hash, dependency versions, final status, token usage, trace ID
  audit.json        # per-tool-call record, each entry tagged with trace_id and span_id
  trace.jsonl       # the OpenTelemetry spans for the run

All three share one trace ID, so a plot, the tool calls that produced it, and the timing behind those calls line up as a single record. The architecture post has more on what a run bundle holds.

Real providers, one usage interface

APAB is local-first and defaults to Ollama, and that has not changed. But the OpenAI, Anthropic, and Gemini providers were stubs, and the observability layer needs one consistent way to read usage. So all of them are now real implementations, and every provider (Ollama, OpenAI, Anthropic, Gemini, and an OpenAI-compatible one that covers vLLM, LM Studio, and Together) reports per-call tokens, latency, and a cost estimate through the same ProviderUsage interface.

That uniformity is what lets the trace attach a cost to any call, whichever backend produced it. Stay local and you pay nothing while still seeing the token and latency numbers; reach for a cloud model and you see what it cost.

Adapters for other agent frameworks

A recurring question about APAB is whether it is tied to its own agent loop. It is not. The MCP tool layer is the durable asset, and the agent shell on top of it is replaceable. Two new examples show this from opposite directions.

Example 07 runs a Strands agent against APAB’s tools over stdio, using that framework’s own tracing to watch the same tool calls. Example 08 goes the other way: a deterministic LangGraph pipeline that runs the fixed engineering sequence with no LLM at all.

pip install "apab[strands]"     # example 07: Strands agent over APAB's MCP tools
pip install "apab[langgraph]"   # example 08: deterministic pipeline, SQLite checkpointing, no LLM

The LangGraph graph runs validate, pattern, system, constraints, plots, then report, checkpointing each node to SQLite so a run can resume where it stopped. It is the reproducible counterpart to the agent: same tools, fixed order, no model in the loop.

Golden-task evals

Once tool selection depends on a model and a prompt, you need a way to tell whether a change made it better or worse. 0.3.0 adds a golden-task eval harness (evals/run_evals.py) that scores a run against its own bundle: did the agent call the expected tools in a sensible order, did the run finish, did it stay within a call budget, and did the output metrics land within threshold. The scorer is LLM-free, so it runs in CI without an API key and without nondeterminism.

Housekeeping

A few smaller changes matter. The CLI commands no longer re-implement the agent loop; apab design and apab run render from a single instrumented run_to_completion, so tracing lives in one place. EdgeFEM moved from a core dependency to an optional one (pip install "apab[edgefem]"), which drops the C++ build for anyone who only needs the array and system tools. A new apab doctor checks your environment. Releases publish to PyPI through Trusted Publishing (OIDC) instead of manual twine uploads. The test suite is up to 274 from 188, and the PyPI development status moved from alpha to beta.

Try it

pip install "apab[observability]"      # tracing
pip install "apab[ollama,edgefem]"     # local model + full-wave unit cell
apab init --name mmwave_28ghz --quickstart
apab doctor                            # environment health check
apab design                            # interactive agent session

The repo has the agent, the MCP tool definitions, the two adapter examples, and the observability docs; APAB is on PyPI as apab. For the design pipeline these tools wrap, see the companion post on modeling phased arrays in Python, and the project page has the short version.

APAB is beta software. This is an independent project I build on my own time. The views are my own and do not represent any current or former employer.

Frequently asked questions

What is agentic phased-array design?

Using an LLM agent to run the phased-array design pipeline (unit cell, array pattern, system metrics, trade study) by calling real RF tools, rather than doing each step by hand. APAB does this over the Model Context Protocol and writes an auditable run bundle.

What does apab[observability] add?

OpenTelemetry traces of every session, turn, LLM call, and tool call, with token counts, latency, and cost estimates. Spans go to a per-run trace.jsonl, the console, or any OTLP endpoint, and a one-container Jaeger lab is included.

Do I need a cloud API key to run APAB?

No. APAB is local-first and defaults to Ollama. The OpenAI, Anthropic, and Gemini providers are optional and report cost the same way when you use them.

Is EdgeFEM still required?

No. As of 0.3.0 EdgeFEM is optional (pip install apab[edgefem]); the array-pattern and system tools work without it, so there is no C++ build for most users.