Tool definition — the input/output schema contract
The flow for defining one tool — name · description · input parameters · output schema · the *when does the LLM call this tool* decision signal.
A tool is the agent's read entry point. This lesson nails down how to define a new tool. The core idea: state, via a schema line and a description paragraph, exactly when and how the LLM should call this tool.
The four areas of a tool definition
In D.Hub, a tool comprises four areas.
1. Name + description
- Name — English snake_case. The LLM calls this as a function name.
- Description — 1–3 sentences. The core signal the LLM uses to decide when to use this tool.
A good description states the invocation condition.
"Given a customer's order ID, returns one row of enrichment data (with customer metadata, past refund count) for that order. Use during context gathering for refund decisions."
A bad description only states the technical action.
"Fetch a row from the enriched_orders dataset."
2. Input parameters — JSON Schema
The tool's input is specified as JSON Schema. Example (get_enriched_order):
{
"type": "object",
"properties": {
"order_id": {
"type": "string",
"description": "Unique order identifier (e.g. ORD-007)"
}
},
"required": ["order_id"]
}
The description on each parameter is as important as the description on the function itself — the LLM uses these to decide what values to pass. Input format requirements (e.g. "ORD-" prefix required) belong in the description.
3. Output schema — JSON Schema
Specify outputs the same way.
{
"type": "object",
"properties": {
"order_id": {"type": "string"},
"customer_id": {"type": "string"},
"total_amount": {"type": "number"},
"tier": {"type": "string", "enum": ["standard", "silver", "gold", "platinum"]},
"past_refund_count": {"type": "integer"},
"past_approval_rate": {"type": "number"}
}
}
When the output schema is explicit, the LLM knows precisely which fields are available for downstream reasoning.
4. Implementation — code node or external call
The actual behavior is implemented as a code node (D.Hub's code resource) — one function that takes the input parameters and returns JSON matching the output schema. Code-node authoring follows the Engineer Path Lesson 4 pattern.
Example implementation for get_enriched_order (Python, simplified):
def get_enriched_order(order_id: str) -> dict:
row = enriched_orders.filter(f"order_id = '{order_id}'").first()
if row is None:
return {"error": "order not found"}
return {
"order_id": row.order_id,
"customer_id": row.customer_id,
"total_amount": row.total_amount,
"tier": row.tier,
"past_refund_count": row.past_refund_count,
"past_approval_rate": row.past_approval_rate,
}
Register the tool — wire it to the agent
Wire the tool you authored into the agent. In the agent builder, left panel Tools area → + Add tool → pick the one you just defined. 5–10 tools per agent is typical.
Tool vs Actor — the one-line distinction
The tool in this lesson handles side-effect-free reads only. External state changes like firing a refund or sending an email belong to actors (next lesson). A function that does read + write at once leaves no place to put a safety gate.
What you should be able to do after this lesson
- The four areas of tool definition — Name / Input schema / Output schema / Implementation
- That one description paragraph drives LLM tool selection
- The tool = read, actor = write division
Next lesson
Separate actors into automated vs human-review, and design a HITL workflow.