Skip to main content

Chapter 19: Defining Agents and Tools

TL;DR

  1. Define an Agent's Persona: Call the upsert_agent tool on the worka/orchestrator pack. The description field is the most important part—it's the agent's system prompt.

    const { call: upsertAgent } = useTool('upsert_agent', orchestratorTarget);
    upsertAgent({
    name: 'research-agent',
    description: 'You are a helpful research assistant. Your job is to find information on the web and summarize it.'
    });
  2. Define a Tool's Schema: For an agent to use a tool, it needs a schema describing the tool's parameters. This is based on JSON Schema.

    const googleSearchSchema = {
    type: 'object',
    properties: {
    query: { type: 'string', description: 'The search query.' }
    },
    required: ['query']
    };
  3. Register the Tool: Call the upsert_tool tool on the worka/orchestrator pack to make the agent aware of the tool.

    const { call: upsertTool } = useTool('upsert_tool', orchestratorTarget);
    upsertTool({
    name: 'google_search',
    description: 'Performs a Google search.',
    schema: googleSearchSchema
    });

An AI workflow needs two fundamental building blocks before it can run:

  1. An Agent to do the thinking.
  2. A set of Tools for the agent to use.

You define both of these by calling tools on the worka/orchestrator virtual pack.

Creating an Agent

An Agent is an LLM with a specific persona. You create this persona by defining its properties, most importantly its description. This description acts as a powerful system prompt that guides the agent's behavior, tone, and approach to problem-solving.

You create or update an agent using the upsert_agent tool.

Example from a React Component:

import { useTool } from '@worka-ai/sdk';
import { useMemo } from 'react';

function AgentCreator() {
const orchestratorTarget = useMemo(() => ({ tenant: 'worka', name: 'orchestrator' }), []);
const { call: upsertAgent, isLoading } = useTool('upsert_agent', orchestratorTarget);

const createResearchAgent = () => {
upsertAgent({
name: 'research-agent', // A unique, machine-readable name
description: 'You are a world-class research assistant. Your goal is to find the most accurate and up-to-date information on any given topic using the tools provided. You always cite your sources.',
// We will cover rules and edges in a later chapter
});
};

return <Button onClick={createResearchAgent} isLoading={isLoading}>Create Agent</Button>;
}

Defining and Registering Tools

An agent can't do anything without tools. For an agent to use a tool from your MCP server (e.g., the greet tool we built), you must first register its schema with the Orchestrator. This schema is a machine-readable description of the tool's function and parameters, which the LLM uses to understand how and when to use it.

Step 1: Define the Tool's JSON Schema

Worka uses a format based on the widely-used JSON Schema standard. You define an object that describes the parameters your tool's function accepts.

Let's imagine we have a tool named google_search that takes a single string parameter, query.

const googleSearchSchema = {
type: 'object', // The root is always an object
properties: {
query: { // The name of the parameter
type: 'string',
description: 'The search query to send to Google.' // A description for the LLM
}
},
required: ['query'] // An array of required parameter names
};

Step 2: Register the Schema with upsert_tool

Once you have the schema, you call the upsert_tool tool on the worka/orchestrator pack. This tells the Orchestrator that this tool exists and makes it available to your agents.

// ... inside a React component

const { call: upsertTool } = useTool('upsert_tool', orchestratorTarget);

const registerMyTool = () => {
upsertTool({
name: 'google_search', // Must match the tool name in your MCP server
description: 'Performs a Google search and returns the top results.', // For the LLM
schema: googleSearchSchema // The schema object from above
});
};

By separating the tool's implementation (in your MCP server) from its registration (via upsert_tool), the system remains decoupled. The Orchestrator doesn't need to know how your tool works, only what it does and what parameters it needs. When an agent decides to use google_search, the Orchestrator will see the tool call and route it to your pack's MCP server for execution.