Chapter 25
Improvement 1: Observability
Week 6 Day 5
Improvement 1: Observability
The custom tracer behind the log
Each panel has a live log of the trader's activity, coloured by the kind of step: agent, function call, generation, response, and account events. That log is your own work. The OpenAI Agents SDK lets you plug into its tracing, and backend/tracers.py defines a LogTracer, a TracingProcessor that writes every span to the database as the trader runs. It is registered once with add_trace_processor(LogTracer()), which you saw in the previous lab. The API reads those rows back and the frontend colours them, so the thinking you watch scroll past is coming straight from the SDK's trace stream, captured by your own processor.
Take a look at backend/tracers.py to see how it works.
Improvement 2: Evaluation & Feedback
A strategy that improves itself
Each trader's strategy is shown at the top of its panel. The traders are not locked into it. change_strategy is one of their tools, defined in backend/accounts_server.py, and their instructions ask them to look at how their trades have actually performed and fold those lessons into the strategy. When a trader does this, you will see its strategy text change and a "Changed strategy" entry appear in its log.
This closes a feedback loop that is one of the most important ideas in agentic AI: a real-world evaluation, here the portfolio's returns, feeds back into how the agent decides next time. The agent uses the results of its own actions to rewrite its instructions and improve over time.
Improvement 3: The production frontend
In the last lab our dashboard was a Gradio app. It ran inside Python and read the trading database directly, which makes it quick to build and ideal as an internal tool. A production system is usually arranged differently: the backend exposes its data over an HTTP API, and a separate frontend web app consumes that API. This final lab does exactly that for our trading floor. The traders and the database are unchanged. We add a small FastAPI layer in front of them, and a Vite and TypeScript frontend on top.
How it is split
Two new pieces sit alongside the backend package you already have.
backend/api.py is a thin FastAPI app. It reads the same accounts and logs the Gradio dashboard read, and returns them as JSON: the roster of traders, each trader's portfolio value, profit, holdings and transactions, the live activity log, and which market data source is running. It does not run the traders. The trading floor engine still does that on its own.
frontend/ is a Vite and TypeScript app. It calls the API every couple of seconds and draws the four traders in a grid, each with a live portfolio chart, a holdings heatmap, and the activity log from your custom tracing. It has a dark and light theme, and a badge showing whether prices are simulated or live.
The two halves only talk over HTTP, so you could host them separately or put a different client in front of the same API. In development the Vite server proxies /api to the FastAPI backend on port 8000, so the browser sees a single origin and there is no CORS to configure.
The whole API is just a handful of read-only endpoints. Here they are:
from backend.api import app
for route in app.routes:
methods = getattr(route, "methods", None)
if methods and route.path.startswith("/api"):
print(sorted(methods), route.path)One time setup
The frontend is a Node project, so install its dependencies once. Node is already on your machine from the earlier labs that used npx.
cd 6_mcp/frontend
npm install
Run it
Three terminals, opened with the plus on the terminal panel.
First, start the API:
cd 6_mcp
uv run uvicorn backend.api:app --port 8000
FastAPI also serves interactive docs at http://localhost:8000/docs if you want to explore the endpoints yourself.
Next, start the frontend:
cd 6_mcp/frontend
npm run dev
Open http://localhost:5173. The four traders appear straight away, reading from the API. Try the theme toggle in the corner, and notice the market data badge in the sidebar.
Finally, start the trading floor engine and watch the traders come to life:
cd 6_mcp
uv run -m backend.trading_floor
