GPT-6 Astra Function Calling Guide: Schemas, Validation, Retries and Tool Results
Implement reliable GPT-6 Astra function calling with strict JSON schemas, argument validation, idempotent execution, retries, parallel calls, and structured results.

Function calling lets GPT-6 Astra request code that your application controls. The model chooses a function and proposes arguments; your runtime validates them, performs the operation, and sends the result back. Reliability depends less on a clever tool description than on a disciplined execution loop.
Define a strict contract
OpenAI recommends strict: true. Strict schemas require additionalProperties: false, and every property must appear in required. Represent an optional value as a union including null.
const tools = [{
type: "function",
name: "lookup_order",
description: "Return the current status of one order visible to the user.",
strict: true,
parameters: {
type: "object",
properties: {
order_id: { type: "string", description: "Canonical order ID" },
include_events: { type: ["boolean", "null"] }
},
required: ["order_id", "include_events"],
additionalProperties: false
}
}];
Keep functions small and names concrete. A large manage_account tool with many modes invites invalid combinations and hides risk. Prefer get_account, update_shipping_address, and close_account, with approval around consequential operations.
The execution loop
In the Responses API, a requested call appears in response.output as an item with type: "function_call", call_id, name, and JSON-string arguments. The application parses and validates the arguments, runs trusted code, then continues with a matching function_call_output.
const first = await client.responses.create({
model: "gpt-6-astra",
tools,
input: "Where is order ORD-1042?"
});
const outputs = [];
for (const item of first.output) {
if (item.type !== "function_call") continue;
const args = JSON.parse(item.arguments);
const result = await lookupOrder(args);
outputs.push({
type: "function_call_output",
call_id: item.call_id,
output: JSON.stringify(result)
});
}
const final = await client.responses.create({
model: "gpt-6-astra",
previous_response_id: first.id,
input: outputs
});
Never execute arbitrary names from the model. Resolve against a fixed registry. Validate again in application code even with strict mode: schema validity does not prove authorization, record existence, business-rule compliance, or safety.
Design useful tool results
Return the smallest complete result. Include stable identifiers, status, typed fields, and machine-readable error codes. Avoid dumping an entire database row or stack trace.
{
"ok": false,
"error": {
"code": "ORDER_NOT_VISIBLE",
"message": "The order was not found in the caller's account.",
"retryable": false
}
}
The message helps the model explain; the code helps the orchestration layer decide. Do not reveal whether another tenant owns a hidden identifier.
Retries require two policies
Transport retries address API timeouts, 429s, and transient 5xx failures. Tool retries address your own dependency failures. Separate them.
Safe reads can usually retry with exponential backoff and jitter. Writes need an idempotency key and reconciliation. If the connection disappears after create_refund, check whether the refund exists before calling again. Give each logical action a stable operation ID and store the tool call ID with the result.
Never ask the model alone whether retrying is safe. The tool registry should declare retry class, timeout, and side-effect level.
Parallel calls and ordering
The model may request multiple function calls. Parallel execution is useful for independent reads, such as checking weather in three cities. It is unsafe when call B depends on call A or when two writes touch the same record.
Collect every function-call item; do not assume there is only one. Build a dependency-aware executor, or disable/avoid parallel behavior where ordering matters. Return each result using its own call_id.
Control tool selection
tool_choice can allow automatic selection, require a tool, prevent tools, or force a named function. Use auto for open-ended agents, force a tool when an API operation is the explicit purpose of the endpoint, and choose none when processing must remain model-only.
For user-facing actions, a two-phase pattern is strong: first prepare and display a proposed change; then execute a separate confirmed tool. This prevents a friendly sentence from becoming implicit authorization.
Test the contract
Create cases for missing fields, null optionals, invalid enums, unauthorized IDs, timeouts, duplicate submissions, partial failures, multiple calls, huge outputs, and malicious strings inside tool results. Evaluate whether the final answer accurately reflects failure instead of claiming success.
Log schema version, call ID, tool name, sanitized arguments, duration, outcome, and retry count. Keep secrets and sensitive content out of telemetry.
Schema design review checklist
Review every tool as if it were a public API. Enums should reflect real supported values rather than asking the model to invent strings. Dates need a declared format and timezone. Numeric fields need units and bounds. Identifiers should be canonical, not free-form customer names when a lookup step can resolve ambiguity. Descriptions should state preconditions and what the function does not do.
Avoid boolean traps such as force, override, or skip_checks. They collapse important policy decisions into one model-generated bit. If an exceptional operation is legitimate, expose it as a separate high-risk tool with stronger authorization and approval.
Version incompatible contracts. Running response chains may still contain calls or results shaped by an older schema. Your executor should reject unsupported versions explicitly and return a recoverable error rather than guessing how to translate a sensitive request.
Finally, compare the function result with the user-facing claim. A tool returning {ok:false} must never become “Done.” Automated evals should inspect both the call trace and final prose, because an operationally correct tool layer can still be misrepresented by the model.
FAQ
Does strict mode eliminate validation code?
No. It improves structural adherence. Your application still enforces permissions, ranges, invariants, and business policy.
Must tool output be JSON?
The output field is a string, so JSON is a practical convention for structured results. Keep the contract consistent.
When should I force a tool?
When the endpoint’s purpose requires that operation and the user has authorized it. Do not force unnecessary calls merely to make behavior look deterministic.
Can GPT-6 Astra execute my function itself?
No. It emits the call request; your application executes the function and returns the result.
Conclusion
Reliable function calling is a protocol: strict schema, fixed registry, application validation, authorization, controlled execution, structured result, and verified continuation. Add idempotency and retry classification before enabling writes. The model proposes; your system remains accountable for every effect.






























































































