Using Tools
By the Syncfusion DevTutorials team · Last updated
How an agent finds the right tool, checks the call against a schema, makes sure it is allowed, runs it in sync, async or background mode, and checks what comes back.
Think about a plumber at a job.
The plumber has a toolbox. First, they look through it to see which tools are available. Then they choose the right tool for the problem.
Before using it, they check that it is the correct size and type. Some tools, such as a gas key, may require the owner's approval before they can be used.
Some tasks are quick, like tightening a nut. Others take longer, such as waiting for glue to dry.
While the glue dries, the plumber checks on it from time to time. At the end, they inspect the pipe to make sure the leak is actually fixed.
An agent uses tools in the same way.
The main idea: To use a tool correctly, the agent finds the right tool, validates the request, checks whether the action is allowed, runs the tool, and then examines the result.
A Real-World Example
The Brightgrid agent wants to fix a file. Here is everything that happens around a write_file call:
- Find: The registry contains
write_file, and its description says it modifies a file. - Check: The request contains
pathandcontent, the two inputs required by the tool. - Allow: The path is inside
web/, and the agent has permission to write there. - Run: The application saves the file.
- Process: The result says
"Saved web/format.js (5 lines)". That result becomes the next observation.
If any of these checks fail, the tool does not run and the agent receives a clear error.
In simple words: find it, check it, allow it, run it, read it.
What You Will Learn
In this lesson, you will learn:
- How an agent discovers available tools and matches them to a task.
- How to validate a tool call by checking its schema, parameters, and readiness.
- How access controls determine which tools an agent is allowed to use.
- How a tool call is built, dispatched, and completed.
- The difference between synchronous, asynchronous, and background tools.
- How to validate tool outputs and turn them into observations.
The Agent Lab includes three tool-related problems in this lesson: a call with incorrect argument names, a test run that executes in the background, and a read-only agent that has no write tool. The Tools tab always shows the registry for the current scenario.
The path of a tool call: discover, validate, check access, dispatch, and process the response. If any check fails, the call stops before the tool runs.
Tool Discovery
Available Tools
The available tools are the tools listed in the registry for the current run. The agent can only use tools that appear in this list. The application sends the tool list, along with each tool's description, to the model.
Tool Selection
Tool selection is the process of choosing one tool for the next step. The model makes this choice by reading the tool descriptions.
Capability Matching
Capability matching means matching what the agent needs to do with what a tool can do. Clear tool descriptions make this easy. Vague descriptions force the model to guess.
Match a need to a tool by its description
const tools = [
{ name: "run_tests", description: "run all tests and report which fail" },
{ name: "read_file", description: "read the text of one file" },
{ name: "write_file", description: "change the text of one file" },
{ name: "search_docs", description: "search the help pages for a word" },
];
function match(need) {
const words = need.toLowerCase().split(" ");
const scored = tools.map((t) => ({ name: t.name, score: words.filter((w) => t.description.split(" ").includes(w)).length }));
scored.sort((a, b) => b.score - a.score);
return scored[0].score > 0 ? scored[0].name : "no tool fits";
}
console.log("which tests fail -> " + match("which tests fail"));
console.log("change the file text -> " + match("change the file text"));
console.log("send an email -> " + match("send an email"));
Expected output:
which tests fail -> run_tests
change the file text -> write_file
send an email -> no tool fits
"Send an email" does not match any available tool, so the agent learns that it has no tool capable of performing that action. That is much safer than choosing a random tool.
Tool Validation
Validation means checking a tool call before it is allowed to run.
Schema Checks
A schema describes a tool's inputs: their names, types, and which ones are required. A schema check compares the requested tool call against that schema.
Parameter Validation
Parameter validation checks each input value:
- Is the value present?
- Is it the correct type?
- Is it within a safe and valid range?
Check a call against the tool's schema
const schema = {
path: { type: "string", required: true },
content: { type: "string", required: true },
};
function validate(args) {
const errors = [];
for (const [name, rule] of Object.entries(schema)) {
if (!(name in args)) { if (rule.required) errors.push("missing " + name); continue; }
if (typeof args[name] !== rule.type) errors.push(name + " must be a " + rule.type);
}
for (const name of Object.keys(args)) if (!(name in schema)) errors.push("unknown input " + name);
return errors.length ? "INVALID: " + errors.join("; ") : "valid";
}
console.log(validate({ path: "web/format.js", content: "..." }));
console.log(validate({ file: "web/format.js", text: "..." }));
console.log(validate({ path: "web/format.js", content: 42 }));
Expected output:
valid
INVALID: missing path; missing content; unknown input file; unknown input text
INVALID: content must be a string
The second call used the wrong names: file and text. The error clearly lists what is wrong, so the agent can correct the request.
Wrong Argument Names
At step 3, the agent sends file and text. The registry rejects the call.
At step 4, its thought quotes the error and sends path and content instead. One clear error message is enough for the agent to fix the call.
Readiness Verification
Readiness means the tool can run right now. For example, the test server is running and the file exists. Checking readiness first produces a clear error instead of failing halfway through execution.
Access Controls
Scope Restrictions
A scope restriction limits where a tool may act. You have used one since Lesson 1: write_file may change files only inside web/.
Permission Checks
A permission controls who may use a tool. For example, a reviewer agent may read files but not write them. A developer agent may do both.
Availability Rules
An availability rule controls when a tool is available. For example, in read-only mode, write tools are not included in the registry.
Permissions by role, plus read-only mode
const permissions = {
reviewer: ["read_file", "run_tests"],
developer: ["read_file", "run_tests", "write_file"],
};
const writeTools = ["write_file"];
function canUse(role, tool, readOnly) {
if (readOnly && writeTools.includes(tool)) return "not available (read-only mode)";
return permissions[role].includes(tool) ? "allowed" : "not permitted for " + role;
}
console.log("developer, write_file: " + canUse("developer", "write_file", false));
console.log("reviewer, write_file: " + canUse("reviewer", "write_file", false));
console.log("developer, write_file, read-only: " + canUse("developer", "write_file", true));
Expected output:
developer, write_file: allowed
reviewer, write_file: not permitted for reviewer
developer, write_file, read-only: not available (read-only mode)
Read-only mode overrides every role. Even a developer cannot write when read-only mode is enabled.
Read-Only Mode
The agent finds the fix and tries to write it. However, the registry does not contain write_file, so the call fails.
The agent then stops and includes the suggested fix in its final answer. A person can review the change and apply it manually.
Dispatch Workflows
Dispatch means sending a tool call to the code that actually runs it.
Request Construction
Request construction creates a clean request containing:
- an id
- the tool name
- the validated inputs
The id is used later to match the result to the original request.
Runtime Dispatch
Runtime dispatch looks up the requested tool in the registry and runs it.
Result Collection
Result collection gathers everything returned by the tool into a single result object. It contains:
- the request id
- whether the call succeeded
- the output
Build, dispatch and collect one call
const registry = {
read_file: (args) => "text of " + args.path,
};
let nextId = 1;
function dispatch(tool, args) {
const request = { id: nextId++, tool, args };
const run = registry[request.tool];
if (!run) return { id: request.id, ok: false, output: "no tool named " + tool };
return { id: request.id, ok: true, output: run(request.args) };
}
console.log(JSON.stringify(dispatch("read_file", { path: "web/format.js" })));
console.log(JSON.stringify(dispatch("delete_file", { path: "web/format.js" })));
Expected output:
{"id":1,"ok":true,"output":"text of web/format.js"}
{"id":2,"ok":false,"output":"no tool named delete_file"}
Both results have the same structure: an id, an ok value, and an output. Because of that, the loop can handle every result in the same way, whether the call succeeded or failed.
Execution Modes
Synchronous Calls
A synchronous (sync) call means the agent waits for the tool to finish before continuing. read_file is a sync tool. It is fast, so waiting is reasonable.
Asynchronous Calls
An asynchronous (async) call starts the work and returns immediately. The result becomes available later, so the agent must come back and check for it.
Background Operations
A background operation is a long-running async task, such as a large test run. The tool immediately returns a job id. The agent then checks the job status until the work is finished.
Start a background job, then check it
const jobs = {};
function startTests() {
jobs[1] = { checksLeft: 2, result: "3 passed, 0 failed" };
return "Job 1 started";
}
function checkJob(id) {
const job = jobs[id];
if (job.checksLeft > 0) { job.checksLeft--; return "Job " + id + ": still running"; }
return "Job " + id + ": done. " + job.result;
}
console.log(startTests());
for (let i = 0; i < 4; i++) {
const status = checkJob(1);
console.log(status);
if (status.includes("done")) break;
}
Expected output:
Job 1 started
Job 1: still running
Job 1: still running
Job 1: done. 3 passed, 0 failed
The agent never assumes the job is finished. It keeps checking until the job reports that it is complete. The for loop also has a limit, so a job that never finishes cannot trap the agent forever.
Background Test Job
The registry in this scenario provides start_tests and check_job instead of run_tests. Each test run takes three steps: start the job, check and see "still running", then receive the final result. The agent waits for the actual result before making any decision.
Easy Way to Remember: sync means "wait here". Async means "I'll call you back". Background means "here is a ticket, come back and check later".
Response Processing
Output Validation
Output validation checks whether a tool's result looks correct. For example, the result of a test run should contain "passed". If it does not, something may have gone wrong even though no error was reported.
Error Detection
Error detection finds failures hidden inside apparently successful results. Many tools return messages such as "Error: timeout" as plain text instead of reporting a formal failure.
Observation Creation
Observation creation turns the tool result into the clean observation that the agent reads in the next step. You learned this process in Lesson 9.
Validate the output and catch hidden errors
function process(result) {
if (!result.ok) return "ERROR: " + result.output;
if (/error|timeout|failed to/i.test(result.output) && !/passed/.test(result.output)) return "ERROR (hidden in the output): " + result.output;
if (!/passed/.test(result.output)) return "ERROR: unexpected output: " + result.output;
return result.output;
}
console.log(process({ ok: true, output: "3 passed, 0 failed" }));
console.log(process({ ok: true, output: "Error: test server timeout" }));
console.log(process({ ok: true, output: "" }));
Expected output:
3 passed, 0 failed
ERROR (hidden in the output): Error: test server timeout
ERROR: unexpected output:
The second result says ok, but the output itself contains an error. The third result is empty. Both are detected before the agent can mistake them for successful results.
Never assume a tool worked just because it did not crash. Always validate the output itself.
Common Mistakes
| Mistake | Wrong idea | Correct idea | What goes wrong |
|---|---|---|---|
| Vague tool descriptions | "The model will figure it out." | Clearly describe what each tool does. | The model chooses the wrong tool. |
| No schema validation | "The model always sends the correct inputs." | Validate input names and types before running the tool. | The tool crashes or behaves incorrectly. |
| Same tools for every agent | "More tools make the agent smarter." | Give each role only the tools it needs. | A reviewer agent modifies files it should only inspect. |
| Not waiting for async results | "I started the tests, so they must have passed." | Check the job until it reports completion. | The agent makes decisions without a real result. |
Trusting ok without checking output | "No crash means success." | Validate the output text as well. | Hidden errors are treated as successful results. |
Exercises
Each exercise ends with a value on the last line. Press Check to compare it with the expected answer.
What to Remember
- Find it, check it, allow it, run it, read it.
- Clear tool descriptions help the agent choose the right tool.
- Validate every tool call against its schema and return clear error messages when validation fails.
- Control tool access using scope restrictions, permissions, and availability rules.
- Wait for asynchronous and background operations to complete, and always validate the output before using it.
Next: Action Coordination, how an agent runs several actions in the right order, or at the same time.