October workshops are openBuild a Search AI Agent$99 early bird

Enroll now
Skip to content

PHASE 2 · LESSON 8 OF 24 · 3 SMALL IDEAS + A GUIDED LAB

Return something another program can use

A confident paragraph is hard to validate. Can another program safely read your answer?

You will learn to: Validate result types, preserve evidence, and distinguish success, no match, and tool failure.

Preparing your lesson and this browser’s progress…
Read the complete lessonAll the ideas in one place · works without the editor

Use these notes to review a concept or read at your own pace. The interactive workspace above adds predictions, editable code, and actual run results.

IDEA 1

Give output a small schema

A schema describes which fields are required and what their values mean. Our room answer has status, roomId, and evidenceId. A selected result needs string IDs; a no-match result uses null for both IDs.

Parsing JSON only turns text into a value. You must still validate the value's shape and types. Even a schema-valid answer can name a room that does not exist, so the next step checks it against tool evidence.

Parse, validate, verify

  1. Parse. Turn JSON text into a value; malformed text fails here.
  2. Validate. Require the agreed status and field types.
  3. Verify. Compare valid-looking IDs with the returned catalog.

The proposed answers are authored classroom fixtures, not live model outputs.

A shape can look valid and still be wrong

{
  "status": "selected",
  "roomId": "invented-room",
  "evidenceId": "catalog-1"
}

This object has string IDs and a recognized status, but the room may not appear in catalog-1. Shape validation cannot establish factual membership.

Think it through: A result has every required field but names a nonexistent room. What failed?

IDEA 2

Represent success, no match, and failure

Use separate statuses for separate outcomes. selected means the choice is supported. no-match means a successful catalog read found no selectable entries under this exercise's simple rule. tool-error means the read failed, so the catalog's contents are unknown.

Returning no-match after a failed read confuses ‘there are no options’ with ‘I could not check.’ The lab validates a proposal only after the catalog is available, and retains an error result if that read fails.

Absence is not a failed read

  1. Known choice. The selected ID appears in the observed catalog.
  2. Known absence. The observed eligible-room list is empty.
  3. Unknown. A failed tool read does not establish whether rooms exist.

This exercise's catalog contains already-eligible rooms; selection requires membership, not additional ranking.

Preserve the read failure

const catalog = tools.readCatalog();
if (!catalog.ok) return { status: "tool-error", roomId: null, evidenceId: null };

The early return prevents a failed observation from being mistaken for an empty catalog. The output keeps the same fields with an explicit failure status.

Think it through: The catalog tool fails. Can the validator conclude no rooms are available?

IDEA 3

Add async calls only after the synchronous loop

The tools in this lab return their observations immediately inside the isolated runtime. Real network APIs often return a Promise: an object representing an operation that may finish later. An async function can await that operation before using its result.

await does not guarantee success, truth, or permission. A real integration still needs error handling, validation, and limits. The diagram below is conceptual JavaScript, not a live SDK connection; our runnable exercise intentionally uses synchronous tools so you can focus on result checks.

Same responsibilities, different timing

  1. Start. A real client may return a Promise while work is pending.
  2. Wait. await pauses this async function until fulfillment or rejection.
  3. Check. A fulfilled response still needs status and evidence validation.

Conceptual async sequence; no network call runs in this lesson.

Conceptual async wrapper

async function readAndCheck(client) {
  try {
    const catalog = await client.readCatalog();
    return { status: "received", catalog };
  } catch {
    return { status: "read-failed", catalog: null };
  }
}

client is an illustrative supplied object, not an installed library. try/catch handles a rejected operation. A received result still requires its own validation before use.

Think it through: What does await establish when a Promise fulfills?

Put it into practice

Accept only a correctly shaped, evidence-supported proposal; preserve read failures.

  1. Read the proposal and catalog input together.
  2. Run the starter and observe that even a valid proposal is rejected.
  3. Insert the shape check; the supplied evidence checks then run afterward.
  4. Experiment with a room ID missing from the catalog and compare invalid-evidence with tool-error.

Your next experiment: Keep the shape valid but change roomId to oak. Which check rejects the answer?

A useful result is structured, evidence-checked, and honest about absence or failure.

Key terms

Promise
A JavaScript object representing an operation that may fulfill with a value or reject with an error later.
Structured result
An output with agreed fields and types that another program can inspect.

Sources and scope

Original Stemtiq teaching, reviewed 2026-09-14. The named researchers and organizations do not endorse this course. Classroom cases are authored exercises, not published findings.

Anthropic: Writing effective tools for agents — with agents

11 September 2025

Design distinct tools with clear parameters, relevant returned information, and evaluations of how the agent actually uses them.

A description or schema does not guarantee the right action. A live tool can return different data for the same arguments as its environment changes.

MDN Web Docs: JavaScript Guide

Updated 7 November 2025

Functions, objects, conditions, loops, and asynchronous code provide the programming foundations for an agent controller.

Ordinary JavaScript rules do not imply that a language model is running. An execution environment may support only part of the language or its host APIs.

Your JavaScript really runs. The model decisions and school data are authored simulations, so you can learn without an API key. Every workspace also includes a separate real SDK example to explore next. Passing the lab’s cases is practice, not proof that an agent is ready for real-world use.