Design an agent
Plan an AI agent on one page, agree it with the people it serves, then turn each part of the plan into a file in your Hub.
An agent is what it knows plus what it can reach. Most of the work in a useful agent is choosing both, and that is quicker on one page than in code. By the end of this guide you will have a one-page plan and a first version of it in my-hub, with a check for each behavior you planned.
This is a working practice, not something Hubzoid enforces. The example plans a support assistant for Kestrel & Oak, the fictional home-goods shop in the starter Hub.
What you need
- The
my-hubstarter from the quickstart, with its model working. - One job you want an agent to do, and the person who asked for it.
Write the one job
Before you create any files, write down three things:
- One goal you can check. If it needs a paragraph, it is not clear yet.
- Up to three things the agent does. More than three usually means two agents.
- What stays human. What the agent decides, what it drafts for a person to approve, and who signs off the rules it follows.
Goal: support staff answer refund, approval and opening-hours questions
in under a minute, with the source named.
The agent:
1. Answers policy questions from the house rules.
2. Works out refund options from a delivery date.
3. Drafts a reply for a person to send.
Stays human: sending replies, approving orders over $500.
Rules owner: the support lead.Choose the four parts
Each part answers one question. The Hub shows them around the agent's definition in AGENTS.md.
| Part | The question | Where it lives |
|---|---|---|
| Knowledge | What must it hold as true? | knowledge/, raw_data/ |
| Skills | Which procedures does it follow? | skills/ |
| Tools | What must it compute or check? | tools_local/, restricted/ |
| Connections | Which live systems must it reach? | connectors/: a remote MCP server as a connector, or servers in .mcp.json |
For the Kestrel & Oak plan, the house rules are knowledge, the date arithmetic is a tool and the reply draft is a skill. It needs no live system yet.
Agree the plan
Share the page with the person who asked and the owner of each knowledge source, and get both to approve it. Record it next to the Hub, for example as a reviewed change in Git, so the build points back to what was agreed.
Put the job in AGENTS.md
AGENTS.md holds the role, the duties, the tone, which knowledge or skill to use when, and what to refuse. Rewrite the starter's file for the plan:
---
description: Answers refund, approval and support-hours questions for the Kestrel & Oak support team.
suggestions:
- A customer wants a refund 40 days after delivery. What can we offer?
- Who has to approve a $650 order?
- When is support open?
---
You help the Kestrel & Oak support team answer customers.
- Answer from the files in `knowledge/` and name the file you used.
- If the files do not answer the question, say so instead of guessing.
- Draft replies for a person to send. Never promise a refund or approve an order yourself.
- Keep answers short.Describe the knowledge
The agent chooses a knowledge file from its name and description, so say when to read it. Add a description to the top of the starter's house rules and leave the rules as they are:
---
description: Refund window, large-order approval and support hours. Read it for any question about refunds, approvals or when support is open.
---
# House rulesTurn each behavior into a check
The starter already checks the refund rule in evals/refund-window.md. Add one case for the approval rule:
---
contains: ["manager"]
---
## Prompt
Who has to approve a $650 order?
## Criteria
Says a manager must approve it before it ships, because it is over $500,
and names house-rules.md as its source.Check the first version
Run the setup checks first:
hubzoid doctor my-hub✓ Agent builds: 'my-hub' via ClaudeRuntime
· Sign-in is off: local mode, whoever opens the web app is the hub's owner (admin@localhost). Fine on this machine.
✓ Local mode: the web app stays on 127.0.0.1Then run both cases:
hubzoid eval run my-hubBoth should pass. When one fails, hubzoid eval explain my-hub large-order shows the answer, every check and the judge's reasoning. The fix is usually a clearer line in AGENTS.md or in the knowledge description. Restart hubzoid run to see the change in chat. See evals.
Release with a short note
Tell people what the agent does, who can use it and where, and what it does not do. On a shared Hub, give each person Use this agent on the agent's Access tab in Settings.
New sources or feedback start the loop again. A change inside the agreed scope, such as a new skill or refreshed knowledge, can go straight to the checks.
Rules of thumb
- Knowledge first, tools second, live systems last. Most of an agent's value is what it knows. A first version with no live connections ships quickly and is safe to test.
- Small, named knowledge files. Keep one topic per file, with a description that says when to read it. Copy sources into the Hub rather than linking to them, and give each source an owner who confirms it.
- One skill per task. Write it as plain numbered steps. Only a skill's name and description sit in the prompt until it is loaded, so many skills cost little.
- Never let the model produce a number that matters. Compute totals, dates and thresholds in a tool, and let the model explain the result. When the model fills in fields, allow "not found", because a field that must always have a value invites an invented one.
- Keep the tool list short. Every tool's description takes context on every call and adds a choice the model can get wrong. Turn off the web tools with
HUBZOID_DISABLE_HTTP_GETandHUBZOID_DISABLE_WEB_SEARCHwhen the agent does not need them, and give each delegate atools:list. - Connections read-only and restricted. Put tools that reach live systems in
restricted/, so only people and workflows granted the permission can run them and every call is recorded. A connector reaches only the people granted it, and each person can sign in with their own account. Nothing intools_local/orconnectors/.mcp.jsonchecks who is asking, so give their credentials the narrowest scope. Prefer a system's API to driving its screens with the shared browser.
From plan to folder
Every part of an agreed plan has a home in the Hub. A row with no home is not ready to build.
| In the plan | In the Hub | Built as |
|---|---|---|
| The one job | AGENTS.md | Role, duties, tone, which knowledge and skill to use when, and what to refuse |
| Knowledge | knowledge/, raw_data/ | Topic files with descriptions, plus copied source material to search |
| Skills | skills/ | One procedure per task |
| Tools | tools_local/ | Python functions with @function_tool |
| Connections | restricted/, connectors/ | Restricted tools with one permission per file, connectors in connectors/<id>.yaml, or MCP servers in connectors/.mcp.json with a narrow credential |
| Scheduled work | schedule/, workflows/ | A markdown task with a cron or webhook trigger, or a code workflow on a schedule, a webhook or a request in chat |
| Checks | evals/ | One case per behavior |
| Who may use it | Settings | Use this agent and capability grants on the agent's Access tab |
Project structure lists every file, and bring an existing agent covers starting from a project you already have.
If something goes wrong
| What you see | What to do |
|---|---|
no eval cases — add markdown files under .../evals/ | Save the case as a .md file in the Hub's evals/ folder. |
unknown frontmatter key(s): expected_tools | A key is misspelled. The case file accepts expect_tools. |
| The agent answers from general knowledge, not the file | Say in AGENTS.md to answer from knowledge/, make the knowledge description say when to read it, then restart hubzoid run. |
| A part of the plan has no row in the table above | It is not ready to build. Agree where it lives first. |

