The interesting failure in an agent is almost never the model. It is the routing. Ask an HR agent for last month payslip and watch it write a friendly paragraph about how payroll works, instead of calling the one tool that would have returned the number. The model was fine. The agent did not know the request belonged to a tool, or to another agent, and a bigger LLM does not fix that. watsonx Orchestrate is IBM platform for building agents that make that decision well, and this part is how you build one.
Parts 8 through 14 built the pieces an agent stands on. You called models over the inference API in Part 8, grounded them with retrieval in Part 9, and tuned Granite in Part 11. An agent is the thing that decides which of those to use for a given request, and when to hand the whole task to another agent. Orchestrate gives you two ways to build one. There is a no code Agent Builder in the browser, and there is a pro code Agent Development Kit, the ADK, a Python library and command line tool you run from your laptop. I will use the ADK here, because an agent you can put in Git and import with one command is an agent you can review, test, and ship like any other code.
What a watsonx Orchestrate agent is made of
A native agent, meaning one that runs on Orchestrate itself rather than on a remote service, is a small bundle of configuration around a language model. Strip away the refinements and it is six things. It has an LLM that does the reasoning. It has instructions, plain language that tells it who it is and how to behave. It has a style, which decides how hard it thinks before it acts. And it has three ways to reach past its own weights: tools, collaborators, and a knowledge base. Every other field in the spec is a tuning knob on those six.
The three reach out fields are worth separating clearly, because choosing between them is half the design work. A tool is a function the agent can call: an OpenAPI endpoint, a Python function, or a tool exposed by an external MCP server, which is a small server that publishes callable tools over a shared protocol. A collaborator is another agent this one can hand a subtask to. A knowledge base is a set of documents or a connected vector store, such as Milvus or Elasticsearch, that the agent retrieves from before it answers, the same retrieval pattern we built in Part 9. Instructions tell the agent when to use each.
| Field | What it is | Example value |
|---|---|---|
| llm | The model that reasons and writes | watsonx/ibm/granite-3-8b-instruct |
| instructions | Plain language behaviour and rules | You are an HR assistant. Use tools for facts. |
| style | How much it plans before acting | default, react, or planner |
| tools | Functions it can call | get_payslip, an OpenAPI or Python tool |
| collaborators | Other agents it can route to | benefits_agent, payroll_agent |
| knowledge_base | Documents or a vector store to retrieve from | hr_policies (Milvus, Elasticsearch) |
How the orchestrator routes a request
When a request lands, the agent that receives it acts as the orchestrator for that turn. It reads its own instructions, then reads the short descriptions attached to each of its tools, collaborators, and knowledge bases, and it decides one of four things. Answer from the model directly. Call a tool. Retrieve from the knowledge base. Or route the whole request to a collaborator, an agent invoked by another agent to handle a subtask it is better suited for. The chosen path runs, the result comes back, and the orchestrator decides whether it is done or needs another step.
That decision is made from text, not code. The agent picks a tool because the tool description matched the request, and it routes to a collaborator because the collaborator description said it handles that kind of work. This is the single most important thing to understand about Orchestrate, and it is where most first agents go wrong. The diagram below is one turn through that loop.
flowchart TD
U[User request] --> O[Orchestrator agent reads instructions and descriptions]
O --> D{Best match?}
D -->|Own knowledge| A[Answer from the model]
D -->|A fact or action| T[Call a tool]
D -->|Your documents| K[Retrieve from knowledge base]
D -->|Another skill| C[Route to a collaborator agent]
T --> R[Compose reply]
K --> R
C --> R
A --> R
R --> Q{Task complete?}
Q -->|No| O
Q -->|Yes| Z[Return to user]
Gotcha
The description field is not documentation, it is routing logic. A tool called get_payslip with the description a helper will be ignored, because the router cannot tell it applies to a pay question. Write descriptions for the router, not for a human reader: say what the tool or collaborator does and when to reach for it. Half the misrouting I see traces back to a vague description, not a weak model.
Which agent style fits the task
The style field changes how much the agent deliberates before it acts, and it is the knob people leave on the wrong setting. Orchestrate offers default, react, planner, and a react_intrinsic variant for models that reason natively. Default uses the model built in reasoning in a light, tool centric loop, and suits simple, loosely ordered tasks. React runs an explicit think, act, observe cycle where each step depends on the last outcome, which earns its extra model calls on ambiguous problems. Planner writes a plan first and then executes it step by step, so you get a flow you can inspect before it runs.
The trade is calls to the model. Default might reason once and call a tool. React reasons before and after every action, so a three step task can mean six model calls instead of two. Every one of those is latency the user waits through and tokens you pay for. Reach for react when a default agent visibly fumbles the order of steps, not before.
| Style | How it works | Reach for it when | Cost |
|---|---|---|---|
| default | Light tool centric loop on the model own reasoning | Simple, loosely ordered tasks | Lowest |
| react | Explicit think, act, observe each step | Ambiguous work where steps depend on results | Highest |
| planner | Writes a plan, then executes it | Multi step flows you want to inspect first | Medium |
My take
Start every agent on default. It is cheaper, faster, and easier to reason about, and most business tasks are more ordered than they first look. Move a single agent to react only after you have watched it, in the chat UI, fail to sequence its steps. Switching to react to feel safe is how a two second reply becomes an eight second one and the bill triples, for a task default handled fine.
Build a native agent with the ADK
The ADK turns an agent into a YAML file and a couple of commands. You define the agent, point the CLI at an environment, which is a target instance whether local, SaaS on IBM Cloud or AWS, or on prem, and import it. Below is a native HR agent that owns one tool and one collaborator. The instructions do real work: they tell the router to prefer the tool for facts rather than answering from memory, which is exactly the fix for the misroute in the opener.
orchestrate env list and confirm you are pointed at a local or test instance before importing, not production. Names collide, so an import can overwrite an existing agent of the same name.# hr_agent.yaml spec_version: v1 kind: native name: hr_agent llm: watsonx/ibm/granite-3-8b-instruct style: default description: > Answers employee HR questions about pay, leave, and benefits. Route here for anything an employee asks about their own HR record. instructions: > You are an HR assistant. For any question about a specific pay figure, leave balance, or benefit, call a tool. Do not answer pay questions from memory. If the question is about benefits enrollment, route to the benefits_agent collaborator. tools: - get_payslip collaborators: - benefits_agent knowledge_base: - hr_policies # import the tool, then the agent, into the active environment orchestrate env activate local orchestrate tools import -k python -f get_payslip.py -r requirements.txt orchestrate agents import -f hr_agent.yaml orchestrate chat start # opens the local chat UI to test it
Expected: each import prints a confirmation that the tool and then the agent were created, and orchestrate chat start opens a browser chat where hr_agent appears in the agent list. Ask it for a payslip and it calls get_payslip instead of describing payroll.
Failure mode: the import of hr_agent fails with an unknown collaborator or unknown tool error. Order matters. Import get_payslip and benefits_agent before the agent that references them, because the agent spec is validated against what already exists in the environment. Import the dependencies first, then the orchestrator.
Add a tool, a collaborator, or knowledge?
Every new capability you want to give an agent is one of three shapes, and picking the right one keeps the design from sprawling. If you need a deterministic action or a fact from a system, a payslip, a ticket, a database row, that is a tool. If you need a whole skill that already exists as its own agent, say a benefits agent another team built and governs, that is a collaborator. If you need the agent to answer from your own documents, a policy handbook, a set of runbooks, that is a knowledge base and the retrieval we covered in Part 9.
The trap is reaching for a collaborator when a tool would do. A collaborator is another full agent, another model call, another description the router has to weigh. If the job is fetch this value, a tool is cheaper and more predictable every time. Collaborators earn their cost when the subtask genuinely needs its own reasoning, tools, and ownership, not when it is a single function wearing an agent costume.
Where multi-agent routing goes wrong
Multi-agent setups fail in ways a single agent never does, and the failures cost money quietly. The common four: overlapping descriptions, so the router cannot tell two collaborators apart and picks the wrong one; over collaboration, where a request bounces through three agents that each add a model call for no new work; circular routing, where agent A routes to B which routes back to A; and cost creep, because every hop is another full reasoning pass. None of these throws an error. They show up as slow replies and a bill that climbs faster than your traffic.
Cost is the one to model up front. A single agent answering from a tool spends one routing pass plus one tool call. Send that same request through an orchestrator to a collaborator and you pay the orchestrator routing pass, the collaborator reasoning pass, and then the tool. The worked example puts numbers on that gap.
Worked example
Take one pay question. Handled by a single agent with a tool, the model reads the request and the tool result, roughly 900 input tokens and 150 output, call it 1,050 tokens. Now route it through an orchestrator to a payroll collaborator. The orchestrator reasons over its collaborator descriptions first, about 700 tokens, then the collaborator does the same 1,050 token pass. That is roughly 1,750 tokens for the identical answer, about 1.7 times the single agent cost, before you add a second collaborator.
The lesson: each hop is a real multiplier on token spend, so route to a collaborator because the task needs it, not because the diagram looks tidier. Numbers are illustrative and depend on your model and prompt sizes.
From Developer Edition to a live instance
The reason to build with the ADK rather than only clicking in the browser is the path from laptop to production. Developer Edition is a self contained local copy of Orchestrate that runs on your machine, started with orchestrate server start. You import your agent, test it in orchestrate chat start, and iterate in isolation without spending on a hosted instance or touching anyone else data.
When it behaves, you add a remote environment, activate it, and run the same import commands against it. The YAML does not change. That is the whole argument for treating agents as code: the artifact you reviewed locally is the artifact that ships, and you can wire the import into a pipeline so a merge to main updates the live agent. We build that pipeline out properly when the series reaches LLMOps on watsonx in Part 22; here the point is that the ADK makes it possible at all.
Start with one agent, orchestrate only when it strains
Here is the recommendation, and it is a real one. Build one native agent on the default style, give it the tools it needs, write descriptions the router can actually use, and ship that. Do not start with a mesh of collaborators. Add a second agent only when a distinct domain, with its own tools, knowledge, and owner, clearly deserves to be separate, and add react only when you have watched default fail. Most teams that struggle with Orchestrate over built the graph on day one and then fought the routing and the bill ever after.
Three moves carry a first agent a long way. Keep it on default until you see a reason not to. Prefer a tool over a collaborator whenever the job is fetch a value. And write every description for the router, not for a person. Do those and the agent routes correctly, answers fast, and costs what it should. The next Part puts these agents in front of users: Part 16 is watsonx Assistant, conversational applications, where the agent you just built becomes something people actually talk to. Before you read it, open orchestrate chat start, ask your agent one real question, and watch which tool it reaches for.
References
- IBM watsonx Orchestrate ADK, Authoring native agents
- IBM, watsonx Orchestrate AI agent and tool builder
- GitHub, IBM watsonx Orchestrate ADK
- Cross-series, Multi-agent systems on Vertex AI with ADK and Agent Engine


DrJha