Back to course syllabus
Automate with permission, recovery, and cost controlsCore control path · 5 / 12

Design an AI agent tool contract before exposing the function

Specify an agent tool's input schema, preconditions, authorization, side effects, idempotency, timeout results, and trace before making it callable.

DECISION TOPICAgent architecture
LESSON OUTPUT · tool-calling contractUPDATED · Oct 1, 2026
PATH READ0 / 12
HOW TO USE THIS LESSON

Read with one real task in mind, then complete the workbench. The lesson is done when another person can review what you made.

A tool call is a proposal from the model to your application. The application decides whether to execute it. A useful tool contract therefore has two halves: a model-visible interface that helps select and fill the tool, and an enforced execution contract that validates identity, conditions, effects, and the returned state. A good description alone cannot enforce a permission rule; a strict backend with a vague description may be called at the wrong time.

Write one contract per meaningful operation. “Manage customer account” hides too many effects. “Read the approved service policy for this account” and “schedule one technician visit for this approved work order” are separately testable. The contract below connects a tool definition to the real system that runs it. For tools supplied by an external MCP server, first use the third-party server intake to check the whole connection’s actual capabilities and data path.

Make the model-visible interface narrow

The name should describe one action. The description should say when to call it, what evidence it returns, and when it should not be used. Required parameters need types, units, permitted values, and a clear meaning. A caller should not have to infer whether a date is local or UTC, whether an identifier belongs to a customer or a job, or whether an omitted field means “any.”

Keep trusted context out of model-supplied arguments. The application can bind the authenticated user, tenant, and approved scope from its own session. A model-generated user_id is data to validate, not proof of that user’s identity. Validate required fields, ranges, object relationships, and unexpected properties again at the server before invoking the underlying service.

Contract fieldQuestion it must settle
Input schemaWhich fields are required, typed, bounded, and mutually dependent?
PreconditionsWhat record state or source version must exist before execution?
AuthorityWhich identity, tenant scope, and exact approval are checked by the executor?
Side effectWhat may change, who can observe it, and what cannot be undone?
Repeat behaviorWhat identifies the same logical operation and for how long?
ResultHow are success, rejection, ordinary failure, and unknown remote state distinguished?
TraceWhich call, checks, effect, and result can a reviewer reconstruct without exposing secrets?

Put a concrete shape beside the prose

Here is a provider-neutral sketch for the read-only example below. Adapt the exact schema syntax to the platform you use; the execution checks still belong in your application.

{
  "name": "get_approved_policy_excerpt",
  "description": "Use for an approved warranty-policy question; return eligible source text, not a final decision.",
  "parameters": {
    "type": "object",
    "properties": {
      "policy_id": { "type": "string", "description": "Policy identifier from the selected account" },
      "jurisdiction": { "type": "string", "description": "Applicable region code" },
      "effective_on": { "type": "string", "description": "Calendar date in YYYY-MM-DD form" }
    },
    "required": ["policy_id", "jurisdiction", "effective_on"],
    "additionalProperties": false
  }
}

The authenticated worker and account are absent from the model-supplied schema because the server binds them. An illustrative timeout result for a write is { "status": "unknown", "code": "REMOTE_TIMEOUT", "operation_id": "visit-42", "next_action": "lookup" }. The result says what to do next without claiming the write failed.

Specify effects and repeat behavior before implementation

Read-only tools still need a data boundary. For tools that write, state the exact object and visible consequence. A scheduling tool might reserve a slot and notify a customer; those are two effects, even if one API request triggers both. The contract should say when human approval is required and what exact parameters that approval covers. A changed date or customer invalidates an approval for the previous request.

Give repeated writes a stable operation identifier generated by the application for the same logical intent. The executor must define its deduplication window and what happens if the same key arrives with different parameters. Never promise safe retry merely because a caller supplied an idempotency_key; verify that the downstream service or your adapter actually prevents duplicate effects. If a timeout leaves the remote outcome uncertain, return an explicit unknown state with a lookup reference. Do not translate uncertainty into a plain “failed” result that invites a second write.

Use a small result vocabulary such as succeeded, rejected, failed, and unknown. Attach a stable machine-readable code, a concise human explanation, and the next permitted action. A refusal because approval is missing differs from a validation error; both differ from a service timeout after a request may have been accepted. Never hide a partial effect in a success message.

Example: a read-only policy excerpt tool

get_approved_policy_excerpt answers a field worker’s question about an equipment warranty. It accepts a policy identifier, jurisdiction, and effective date. The application supplies the authenticated worker and account scope. Before retrieval, the executor checks that the worker may view that account and that the selected policy version was effective on the requested date. Its output contains a short excerpt, source version, effective window, and citation locator—not a general answer invented by the tool.

The model-visible description says to call this tool only for an approved policy question and to report “no eligible passage” when none exists. A test set includes an ordinary request, an expired version, a cross-account identifier, and a date without a matching policy. The cross-account case must be rejected by the executor even if the model confidently supplies the identifier. The trace stores the policy version and access decision, while avoiding a second copy of the full protected document.

Example: a write tool for one service visit

schedule_equipment_visit accepts an approved work-order ID, a slot ID, and a customer-facing summary. The application binds the customer and creates a stable operation key. The executor checks that the work order is approved, the slot is still available, the caller has scheduling authority, and an approval token matches this exact customer, slot, and summary. Its stated effects are one booking and one confirmation notification.

A useful result contains booking ID, notification state, and operation key. Suppose the booking succeeds but the notification service times out: report the booking as completed and notification as unknown; do not submit another booking. A follow-up lookup must inspect the notification using its reference. Test a duplicate request, a changed slot with the old approval, an unavailable slot, and a timeout after booking. These tests exercise the contract’s behavior at the boundary where a pretty schema offers little protection.

Review the call from both sides

Pair each tool definition with a trace from a real or simulated call: model request, normalized arguments, server-side validation, identity and approval decision, downstream operation ID, side effects, and result. Redact tokens and private input while retaining enough identifiers for an authorized reviewer to reconstruct the decision. Define who owns the tool and when its schema or behavior must be versioned.

Have one reviewer use the description to decide whether a call is appropriate, and another use the execution contract to predict what happens with invalid, duplicated, unauthorized, and timed-out requests. Disagreement means the interface still relies on unwritten assumptions. When several calls can run together, document their dependencies and effect order; independent reads may differ from two writes against the same record.

Common questions

Is a JSON Schema enough for a tool contract?

No. It describes argument structure. It cannot by itself establish user identity, current record state, approval, downstream repeat safety, or the meaning of a timeout. Provider-supported schema features also vary, so test the actual integration. For the final answer delivered to a user or another system, use the output protocol check to choose its format and parser-failure route separately.

Should errors be phrased for the model or for an operator?

Return a stable code and a safe short message that the model can use, plus a trace reference for an authorized operator. Keep credentials, private data, and raw internal errors out of model-visible results.

Boundary

This page designs one callable operation; it does not replace system-level permission policy, incident recovery, or security review. For payments, medical decisions, production changes, or other high-impact effects, an approved contract is necessary but does not establish that the automation should execute. If the underlying service cannot report whether an effect occurred, keep the action behind human reconciliation rather than pretending retries are safe.

SOURCES CHECKED

Which first-party sources informed this guide?

Sources anchor definitions, risk boundaries, or operational facts. The decision framework and workbench are original to AI Vista.

  1. OpenAI API documentation — Function callingChecked 2026-10-01
  2. Claude API documentation — Tool use overviewChecked 2026-10-01
  3. Model Context Protocol — Tools specificationChecked 2026-10-01

AI tools may assist with research, outlining, and language editing. Facts, cases, and final wording are reviewed by the editor. Report an error through the contact page.

TAKEAWAY TOOL

AI tool-calling contract

Make one callable operation understandable to the model and enforceable by the executor.

tool / contract
USE THIS WHENBefore an agent can call a new tool or a tool's behavior changes
YOU WILL GETA reviewable interface, execution boundary, and failure test set
HOW TO USE01—03
  1. 01
    Describe the taskDescribe the result with a sanitized summary.
  2. 02
    Fill the decision fieldsRecord input categories, risk, evidence pointers, and handoff.
  3. 03
    Ask a colleague to reviewThe tool is ready when someone else can restate the decision.
DONE WHENFields are complete, boundaries are clear, and the result is reviewable.
Edits save automatically

LESSON READ

Finish the workbench, then mark it read.

The read state updates the syllabus and your course progress.

  1. 01Fields filled
  2. 02Case tested
  3. 03Reviewable

GUIDE PRACTICE NOTES

Leave a judgment you can review later.

The fictional examples below show the format. Your own notes stay in this browser. Record what worked, which boundary failed, or one question worth testing.

↗
RELATED GUIDEDesign an AI agent tool contract before exposing the functionSee examples and local notes →
0 examples and local notesINSIGHTS · QUESTIONS · IDEAS