Does Botie Need to Choose the Next Step?
A request to find a maintenance record and an investigation of an unfamiliar fault ask different things of the program. Compare what fixed steps can do before giving a model more decisions.
15 sections · 4 questions · 1 coding challenge
The arrow keys move between sections too.
Separating a Predetermined Route from a Model’s Choice
BOTIE
Think about the maintenance desk. Retrieving a known record already has a route. Investigating a poorly described fault may require looking at a result before deciding what to inspect next. Our examples use invented measurements to make that design choice visible. They are not benchmark results for any provider or framework.
We Have Built a Tool Loop. Do We Need It for This Job?
A technician asks for the inspection date of pump P7. We already know the steps: check access, look up P7, and display the date. Giving Botie freedom to invent a plan adds decisions to a job whose route we can write down ourselves.
Now consider a request to explain why several pumps began vibrating after a maintenance visit. The useful follow-up depends on what the records reveal. We need a way to decide where a model’s choice of next step actually helps. We will compare candidate controllers on the same invented maintenance requests, including their mistakes.
The trials are invented. This workshop compares records; it does not run a model or establish production reliability.
Step 1 of 2
The same request can travel through different controllers
The route belongs to application code in a workflow. A model chooses the next operation in our agent candidate.
| Request | Known steps | What could require another decision? |
|---|---|---|
| When was P7 inspected? | Authorise → lookup → display date | Missing or inaccessible record has a defined error path |
| Explain the new vibration | Start from the reported symptom | The next useful record depends on the evidence returned |
When was P7 inspected?
- Known steps
- Authorise → lookup → display date
- What could require another decision?
- Missing or inaccessible record has a defined error path
Explain the new vibration
- Known steps
- Start from the reported symptom
- What could require another decision?
- The next useful record depends on the evidence returned
Step 2 of 2
Compare success before preferring fewer moving parts
Each candidate receives the same three fictional requests. Here the workflow already satisfies the task checks.
| Controller | Task checks passed | Slowest observed request | Total invented cost units |
|---|---|---|---|
| Rules | 1 of 3 | 12 ms | 0 |
| Workflow | 3 of 3 | 800 ms | 6 |
| Agent | 3 of 3 | 1600 ms | 16 |
Rules
- Task checks passed
- 1 of 3
- Slowest observed request
- 12 ms
- Total invented cost units
- 0
Workflow
- Task checks passed
- 3 of 3
- Slowest observed request
- 800 ms
- Total invented cost units
- 6
Agent
- Task checks passed
- 3 of 3
- Slowest observed request
- 1600 ms
- Total invented cost units
- 16
Use evidence to decide who chooses the next operation
Task evidence determines eligibility. The declared simplicity preference chooses among eligible controllers without hiding their measurements.
Which controller meets the maintenance desk’s requirements?
Keep the task checks beside each controller’s time and cost. Connect the comparison before choosing the amount of autonomy.
BOTIE
Selected controller
workflow
Follow the operations
1. Controllers tested on the same requests
[ { "name": "rules", "rank": 0, "passed": [ true, false, false ], "latency_ms": [ 10, 12, 11 ], "cost_units": [ 0, 0, 0 ] }, { "name": "workflow", "rank": 1, "passed": [ true, true, true ], "latency_ms": [ 600, 800, 700 ], "cost_units": [ 2, 2, 2 ] }, { "name": "agent", "rank": 2, "passed": [ true, true, true ], "latency_ms": [ 1200, 1600, 1400 ], "cost_units": [ 5, 6, 5 ] } ]2. Summarise each controller's trials
[ { "name": "rules", "rank": 0, "passes": 1, "cases": 3, "worst_ms": 12, "total_cost": 0 }, { "name": "workflow", "rank": 1, "passes": 3, "cases": 3, "worst_ms": 800, "total_cost": 6 }, { "name": "agent", "rank": 2, "passes": 3, "cases": 3, "worst_ms": 1600, "total_cost": 16 } ]3. Task, time and cost requirements
{ "min_passes": 3, "max_latency_ms": 2000, "max_cost_units": 20 }4. Keep controllers that meet the requirements
[ { "name": "workflow", "rank": 1, "passes": 3, "cases": 3, "worst_ms": 800, "total_cost": 6 }, { "name": "agent", "rank": 2, "passes": 3, "cases": 3, "worst_ms": 1600, "total_cost": 16 } ]5. Choose the least autonomy that passed
workflow
6. Result
workflow
The small invented trial set is a teaching comparison. It omits repeated model runs, uncertainty intervals and production security review.
1. Write down what a completed maintenance request means
Start with the result the technician needs. For a record lookup, success means returning the correct authorised record or accurately reporting that it is unavailable. For an investigation, success may mean identifying relevant evidence and explaining what remains uncertain. A fluent response that omits the missing evidence does not complete that job.
Choose the acceptance checks before trying architectures. Keep cases where a record is missing, where access is denied, and where two assets have similar names. If only the happy path appears in the test set, the most fragile controller can look convincing.
The checks describe the job. The controller is one proposal for doing it.
2. Try the route we can already specify
A direct database lookup is a useful baseline for a date request. A baseline is a working comparison that tells us what extra machinery improves. It may be ordinary code, a search interface, or one model call with supplied evidence.
A fixed workflow can validate a request, retrieve a manual, ask a model for a supported summary, then check its output. Branches for absent evidence and failed validation remain explicit. We can test each branch without asking a model to discover the order again. The wording step may still be uncertain, so fixed orchestration does not make the whole system deterministic.
Give the baseline a fair implementation. An intentionally weak prompt would make a larger architecture appear more useful than it is.
3. Find the decision that depends on a previous result
Suppose the first maintenance record points to a replacement coupling. Botie might need the coupling specification next. A different record might point to a changed sensor. We can allow a model to choose among a limited set of read operations based on that evidence.
This creates a new responsibility: checking whether each proposed action is permitted and whether the investigation has enough evidence to stop. Tool feedback tells the loop what happened. A missing record can trigger a supported answer about uncertainty rather than another speculative query. Keep the earlier output and permission checks when adding this freedom.
Choose an agent because the task benefits from adaptive decisions. The presence of several tools alone does not establish that benefit.
4. A second agent adds a handoff we must explain
Separate specialists can examine genuinely independent records in parallel. Before adding them, identify what each receives, what it must return, and who combines conflicting findings. A handoff should preserve the request identity and source IDs. The coordinator needs a way to recognise partial or failed work.
Sending the same full conversation to several agents repeats input work and introduces several proposals to reconcile. Parallel work can reduce elapsed time while increasing total compute. A copied mistake may appear in every answer, so agreement is not independent evidence. Begin with one controller and measure whether delegation improves the task enough to justify its coordination and operating costs.
For the maintenance desk, two independent manual searches may be useful. Two agents that both create the same work order introduce a different problem.
Check yourself
Questions on Parts 1 to 4
Question 1 of 2
Which description fits this controller?
Use the information below.
P7 lookup always follows access check → database lookup → response. A model formats the response but cannot choose another operation.5. Keep trial results aligned with their measurements
The workshop stores each controller as a dictionary. passed is a list of boolean outcomes in the agreed case order. latency_ms and cost_units have one entry for each of those same cases. rank records our declared preference for less autonomy: rules first, then workflow, then agent. A rank is a design policy, not a measure of intelligence.
We summarise how many checks passed, the slowest observed request, and total cost over the fixture. Comparing different case sets would confound architecture with task difficulty. Real evaluations should retain case IDs and versions, repeat stochastic runs, and report uncertain estimates. Our short list assumes that alignment has already been checked.
Latency and cost answer different questions. A parallel controller may have a smaller wall-clock maximum and a larger total bill.
Read one controller’s aligned trial rows
zip pairs the values by position. Check equal lengths first so a missing measurement cannot disappear silently.
passed = [True, False, True]
latency_ms = [420, 510, 470]
cost_units = [2, 3, 2]
assert len(passed) == len(latency_ms) == len(cost_units)
for case, (ok, elapsed, cost) in enumerate(zip(passed, latency_ms, cost_units), start=1):
print(case, ok, elapsed, cost)
print("passes:", sum(passed))1 True 420 2
2 False 510 3
3 True 470 2
passes: 2The failed case remains in the measurements. Removing it would hide both the failure and the resources it consumed.
6. Apply requirements before choosing simplicity
Filter the summaries against the acceptance requirements. Our fixture requires every supplied task check to pass and bounds observed latency and total cost. Among candidates that meet those requirements, choose the lowest autonomy rank. If ranks tie, choose lower total cost, then the alphabetically earlier name so the result is repeatable.
This is an explicit teaching policy. A real service may prioritise tail latency, audit requirements, operating effort or a risk threshold differently. State that policy before looking at the candidate scores. If no candidate passes, return a review outcome. Quietly selecting the least bad failure would erase the meaning of the requirements.
eligible = task_passes >= required_passes
and worst_latency <= latency_limit
and total_cost <= cost_limitPassing this fixture is permission to investigate a candidate further. It is not a guarantee about future requests.
7. Let a new kind of fault challenge the chosen route
The changed workshop case gives the fixed workflow a request it cannot resolve. Its score now fails the task requirement, while the agent candidate meets the same requirements. Keep the selection policy unchanged and inspect which evidence changed the decision.
A single adaptive example should not make every request autonomous. Routing well-defined requests through the simpler path and reserving an agent for measured difficult cases can be useful. The router needs its own evaluation, including false escalations and difficult requests it incorrectly keeps on the simple path.
The useful outcome is a design tied to task evidence, with a clear fallback when the evidence is insufficient.
8. Keep the operating boundary when the controller changes
A workflow and an agent can use the same scoped read tool, output validator and human approval boundary. Changing who chooses the next step does not change who is authorised to read a customer’s records or create an inspection.
Version the controller along with prompts, tools, model settings and evaluation data. Re-run the comparison after a meaningful change. Watch the real request mix: a controller chosen for mostly date lookups may need reconsideration when most users begin asking open investigations. Frameworks in the next lessons can organise these components, but their abstractions should leave the decision boundaries visible.
We can now ask a more useful framework question: does it make the controller we chose easier to implement, test and inspect?
Check yourself
Questions on Parts 1 to 8
Question 1 of 2
Which controller does this declared policy select?
Use the information below.
Workflow and agent both pass all required cases. Workflow rank is 1 and total cost is 8. Agent rank is 2 and total cost is 6. Both satisfy the time and cost limits. Policy prefers lower rank before cost.Try it with Botie
Build with Botie
Write and run Python