Skip to main content
Version: v6.0.0 [Falcon]

Lab 4: Onboard a custom agent

In this lab you move the Throughput Checker of Lab 3 from your computer into the cluster, next to the agents of Lab 1. At the end, the Supervisor uses it to answer your questions in MX-UI.

                     You, in MX-UI
│
┌──────▼──────┐
│ Supervisor │
└─┬────┬────┬─┘
┌─────────┘ │ └──────────┐
┌────▼────┐ ┌─────▼────┐ ┌──────▼─────────────┐
│ KPI │ │ Topology │ │ Throughput Checker │ ← new
└────▲────┘ └──────────┘ └──────┬─────────────┘
└──────────── asks ────────────┘

By the end of this lab you will be able to:

  • build the container image of your blueprint and push it to a registry;
  • create the CompositionModel of your blueprint;
  • add your agent to an existing AIFabric;
  • update the fabric.

Before you start, you need:

  • the fabric observability-lab of Lab 1 and its file observability-lab.yaml;
  • the blueprint tutorial/ of Lab 3, working;
  • Docker, and a container registry you can push to (or the ready-made image, see Part 1).

Where to run the commands:

  • bat and docker commands: in the tutorial/ folder, where you developed in Labs 2 and 3.
  • brc and kubectl commands: on the cluster master node, as in Lab 1.

If these are two different machines, this lab tells you when to copy a file from one to the other with scp. If you work on the master node, skip the scp steps.

Part 1: Build and push the image​

The cluster runs agents from container images. Your blueprint becomes one image that holds all its agents, like the Observability blueprint.

⚠️ Your own images need the extendability capability.

The cluster only runs images from hub.bubbleran.com, unless your BubbleRAN license has the extendability capability. Without it, the cluster refuses to start your agent.

If you don't have this capability, or no registry, you can still follow this lab with the ready-made image of the Throughput Checker on hub.bubbleran.com: skip to Part 2. BubbleRAN can also provide a registry for your images: ask your BubbleRAN contact.

Step 1: Choose where to push​

An image name has three parts: <registry>/<repository>:<version>. Tell bat your registry and repository once:

bat set image --docker-registry <your-registry> --repo <your-team>/tutorial

For example, --docker-registry registry.example.com --repo my-team/tutorial.

You should see:

Updated: /home/you/tutorial/Makefile
Keys updated: DOCKER_REGISTRY, REPO

Then log in to your registry, once:

docker login <your-registry>

Step 2: Build the image​

bat build --version 1.0.0

It takes a few minutes. At the end you should see:

Docker image built successfully: registry.example.com/my-team/tutorial:1.0.0
  • bat build first writes uv.lock, the exact list of package versions. Keep this file: the next builds use the same versions.
  • Your .env file is not put in the image. In the cluster, the API key comes from the Secret you created before Lab 1.

Step 3: Push the image​

bat push --version 1.0.0

You should see, at the end:

Docker image pushed successfully: registry.example.com/my-team/tutorial:1.0.0

Part 2: Create the CompositionModel​

In Lab 1 you installed the CompositionModels of BubbleRAN's blueprints: their catalogs of agents. Now you create the catalog of your blueprint.

💡 Using the ready-made image? BubbleRAN ships the Throughput Checker with its CompositionModel, also called tutorial. Install it on the master node, then skip to Part 3:

brc install model tutorial

bat writes the CompositionModel for you:

bat manifests composition-model --namespace trirematics --vendor lab --version 1.0.0

You should see:

Wrote /home/you/tutorial/composition-model.yaml
added: throughput-checker
image: registry.example.com/my-team/tutorial:1.0.0 (push it: `bat push`, same options)

bat wrote the file composition-model.yaml:

composition-model.yaml
apiVersion: orama.trirematics.io/v1
kind: CompositionModel
metadata:
name: tutorial
namespace: trirematics
spec:
provider: bubbleran
version: v0.1.0
deploymentModes:
throughput-checker:
kind: agent
name: throughput-checker
vendor: lab
imageTag: registry.example.com/my-team/tutorial:1.0.0
args:
- throughput_checker
env:
- name: AGENT_CARD_PATH
value: throughput_checker/agent.json
rules: []
# Instead, e.g. to read the cluster's networks and terminals:
# rules:
# - apiGroups: [athena.trirematics.io]
# resources: [networks, terminals]
# verbs: [get, watch]

What each part means:

PartMeaning
metadata.nameThe name of the catalog: tutorial. It is the first half of <model>/<mode>.
metadata.namespaceWhere it lives: trirematics, the same namespace as your fabric.
specWho provides the catalog, and its version. For information only.
deploymentModesThe list of modes: one per agent of your blueprint. It sits at the top level, not under spec.
throughput-checkerThe name of the mode: the second half of <model>/<mode>. So your agent is tutorial/throughput-checker.
kind, name, vendorIt is an agent; its name (always the same as the mode); who made it (--vendor, ideally three lowercase letters).
imageTagThe image to run.
argsWhich agent of the image to start. It is the same name you used with make throughput_checker.
envEnvironment variables. AGENT_CARD_PATH tells the agent where its card is in the image.
rulesThe Kubernetes permissions the agent needs. Your agent only talks to the KPI agent, so it needs none. The comment shows an example.

What the cluster adds by itself:

  • every agent listens on port 9900;
  • the cluster gives the agent a new config.yaml instead of yours: the KPI agent's address inside the cluster instead of localhost:9310, and the LLM of the fabric;
  • the API key comes from the fabric's Secret.

Install the CompositionModel in the cluster. If you work on your own computer, first copy the file to the master node:

scp composition-model.yaml <user>@<master-node>:

Then, on the master node:

kubectl apply -f composition-model.yaml

You should see:

compositionmodel.orama.trirematics.io/tutorial created

Part 3: Add the agent to the AIFabric​

On the master node, open the file observability-lab.yaml of Lab 1, and add your agent at the end of the agents list:

    - name: throughput-checker
type: internal
internal:
model: tutorial/throughput-checker
llm: openai
role: worker
dependencies:
- kpi
annotations:
env.orama.t9s.io/TARGET_DL_MBPS: "50"

What each part means:

PartMeaning
nameThe name of your agent in the fabric.
type: internalThe cluster runs this agent for you, from a CompositionModel.
internal.modelYour mode, tutorial/throughput-checker: the CompositionModel tutorial of Part 2, and its mode throughput-checker.
internal.llmThe LLM of the fabric, the same one your agent used on your computer.
internal.roleworker: the Supervisor calls every worker, so it can now use your agent.
internal.dependenciesThe agents yours may call: kpi, as in the remote-agents of your config.yaml. The cluster also starts your agent only once kpi is ready.
internal.annotationsenv.orama.t9s.io/<NAME> sets the environment variable <NAME> in the agent. Here it sets the target, as your .env file did on your computer. Always write the value in quotes.

Your file now looks like this:

observability-lab.yaml (click to open)
apiVersion: orama.trirematics.io/v1
kind: AIFabric
metadata:
name: observability-lab
namespace: trirematics
spec:
telemetry:
endpoint: http://phoenix-svc.monitoring.svc.cluster.local:6006
projectName: observability-lab
llms:
- name: openai
provider: openai
model: gpt-6-luna
reasoningEffort: low
apiKeySecretRef:
name: openai-api-key
key: OPENAI_API_KEY
mcp:
- name: victoria-metrics
type: external
external:
baseUrl: http://vmm-victoria-metrics-mcp.monitoring.svc.cluster.local:8080/mcp
agents:
- name: supervisor
type: internal
internal:
model: supervisor/base
llm: openai
role: supervisor
- name: kpi
type: internal
internal:
model: observability/kpi
llm: openai
role: worker
mcpServers:
- victoria-metrics
- name: topology
type: internal
internal:
model: observability/topology
llm: openai
role: worker
- name: throughput-checker
type: internal
internal:
model: tutorial/throughput-checker
llm: openai
role: worker
dependencies:
- kpi
annotations:
env.orama.t9s.io/TARGET_DL_MBPS: "50"

💡 A private registry? If the cluster needs a password to pull your image, create a pull Secret once, on the master node:

kubectl -n trirematics create secret docker-registry my-registry \
--docker-server=<your-registry> \
--docker-username=<user> --docker-password=<password>

Then add it to observability-lab.yaml, under spec:

  imagePullSecrets:
- name: my-registry

Part 4: Reinstall the fabric​

To change a fabric, remove it and install it again. On the master node:

brc remove aifabric observability-lab.yaml
brc install aifabric observability-lab.yaml

You should see:

aifabric.orama.trirematics.io "observability-lab" deleted
aifabric.orama.trirematics.io/observability-lab created

Why remove it first? The Supervisor learns which agents exist only when it starts. Reinstalling restarts all the agents, so the Supervisor finds your new agent.

In MX-UI, open the Fabrics page: observability-lab now has four agents. Wait until they are all ready. The cluster starts your agent after KPI, and the Supervisor last.

Part 5: Try it​

In MX-UI, go to the Chats page, select observability-lab and choose the Supervisor. Ask:

Does network o-ran meet its throughput target?

The Supervisor reads the agent cards, sees that the Throughput Checker answers this kind of question, and asks it. Your agent then asks the KPI agent, exactly as it did on your computer. You should get an answer like:

o-ran: BELOW TARGET — 12.4 Mbps measured, target 50.0 Mbps.

Your numbers depend on your network and its traffic.

Now choose the Throughput Checker itself in the chat, and ask the same question: you talk to your agent directly.

Now change the target. On the master node, in observability-lab.yaml, set the annotation to "1":

        annotations:
env.orama.t9s.io/TARGET_DL_MBPS: "1"

Reinstall the fabric (the two brc commands of Part 4) and ask again. While there is traffic, the answer becomes MEETS TARGET.

💡 Optional: see what the agents did. The fabric sends the traces of all its agents, yours included, to the Phoenix of your cluster, in the project observability-lab. The trace of your last question shows the work of the Supervisor, of the Throughput Checker and of the KPI agent. To open it, see Phoenix: agents in your cluster.

Part 6: Grow your blueprint​

A blueprint can hold many agents. To add one:

bat add agent my_second_agent --clients Helper

bat creates the folder my_second_agent/, and gives it the next free port on your computer (9901). Write its logic as in Lab 2 and run it with make my_second_agent. Then follow this lab again: bat build and bat push put both agents in the same image, bat manifests composition-model adds a second mode, tutorial/my-second-agent, and you add a second entry to the agents of your fabric, as in Part 3.

If something goes wrong​

What you seeWhat to do
bat push says no Docker registry setRun bat set image (Part 1, Step 1).
bat push says denied or unauthorizedLog in with docker login <your-registry>, then push again.
In MX-UI, the fabric is not ready and the message says an image outside hub.bubbleran.com needs the "extendability" license capabilityYour license does not allow your own images. Use the ready-made image (Part 2), or contact BubbleRAN.
The Throughput Checker never becomes ready, and the message talks about pulling the imageCheck that you pushed the image (Part 1, Step 3) and that imageTag is right. If your registry is private, add a pull Secret (end of Part 3).
The Supervisor answers without asking the Throughput CheckerCheck that the agent has role: worker, and reinstall the fabric (Part 4).
The Throughput Checker answers UNKNOWNThe KPI agent gave no throughput number. Ask the KPI agent directly in MX-UI to see its answer, and check the network name.
Still stuck?Contact BubbleRAN customer support through your usual support channel.

Clean up​

Lab 5 still uses the fabric: clean up after it. When you are done with the labs, remove the fabric and your CompositionModel. On the master node:

brc remove aifabric observability-lab.yaml
kubectl delete -f composition-model.yaml

If you used the ready-made image, remove its CompositionModel with brc remove model tutorial instead of the kubectl delete command.

If you deployed the network of Lab 1 only for these labs, remove it too:

brc remove network open-ran.yaml

What you learned​

  • bat build and bat push turn your blueprint into one container image.
  • bat manifests composition-model writes your blueprint's catalog: one mode per agent, which an AIFabric picks as <model>/<mode>.
  • A few lines of YAML add an agent to an existing fabric: its mode, its LLM, its role and the agents it calls. Annotations set environment variables.
  • To change a fabric, remove it and install it again with brc.
  • Your code does not change between your computer and the cluster: only config.yaml does, and the cluster writes it for you.

In Lab 5 you measure how well your agent answers, with a test set that bat runs and scores for you.