🚀 Technical Briefing: This tutorial is part of our deep-dive series on Agentic Workflows at Gate of AI. For the full technical breakdown, interactive code sandbox, and the native Arabic translation, visit the original article here.
Tutorial
Next.js OpenAI Weather Agent: A Safer Tool-Calling Design
Design a weather assistant that treats the language model as an orchestrator, keeps factual measurements in trusted tools, and enforces explicit policies before data is shown to a user.
Important scope before you build
A weather assistant sounds simple: a person asks for rain, temperature, wind, or a recommendation such as whether to carry an umbrella. But the application is making factual claims about an external, changing environment. A language model can write a clear explanation, yet it is not itself a weather instrument, forecast service, numerical solver, or authorization system.
The verified research context supports a practical principle for this kind of agent: a numerical result should be reported only when it originates from a trusted tool and passes explicit verification. The principle comes from research on LLM and agentic systems for smart grids, a domain where outputs can appear numerically plausible while remaining physically infeasible or untrustworthy. Weather applications are different from grid control, but the design lesson transfers directly. Do not let polished prose substitute for a verified measurement.
This tutorial therefore focuses on an architecture rather than claiming a particular SDK, model, weather provider, framework version, or endpoint contract. Before implementing any code, verify current vendor documentation for your chosen Next.js release, OpenAI API, weather-data provider, authentication system, deployment environment, and applicable organisational requirements.
What you are designing
The finished pattern has five clear responsibilities. The browser collects a user question. A server-side route accepts only a constrained request shape. A language model may decide that an approved weather capability is needed. The server validates that proposed capability call, invokes a trusted weather-data service, verifies the returned result, and gives a small structured result back to the model. Finally, the model produces an explanation based on that verified result.
The central rule is simple: the model may request an approved tool, but it must not receive authority to define the tool, choose arbitrary network destinations, alter authorization, or invent measurements when a tool fails.
- User interface: collects the question and displays an answer or a clear retrieval failure.
- Server-owned controller: owns policies, credentials, request limits, tool allowlists, logs, and error handling.
- Language model: interprets the request and decides whether an approved tool is relevant.
- Weather tool: queries a selected data source using only validated, bounded parameters.
- Verification layer: checks the returned structure, date, units, location match, and freshness rules before data can be reported.
This separation also makes the design useful beyond weather. The same pattern can support controlled access to internal data, forecasting solvers, analytics systems, and business workflows. In every case, the application—not the model—remains responsible for the action boundary.
Step 1: Write concrete policies first
Do not start with a broad prompt such as “help users with weather.” Start with a policy that an engineer can implement and test. This is important because the verified symbolic-guardrails research found that 85% of reviewed agent safety and security benchmarks lacked concrete policies. High-level goals and common sense are not precise enough for reliable enforcement.
For a read-only weather assistant, a practical policy could state the following:
- The assistant may retrieve weather only through a server-approved weather capability.
- The only accepted tool inputs are a location identifier or city query and an optional calendar date in a defined format.
- The server must resolve ambiguous place names through the selected trusted provider or ask the user for clarification.
- The server must reject arbitrary URLs, headers, SQL, shell commands, access tokens, account identifiers, and provider-selection instructions from model-generated arguments.
- The assistant may report temperatures, precipitation, wind, conditions, and dates only after the returned data matches the requested location and requested date.
- If retrieval or verification fails, the answer must say that live data could not be confirmed. It must not estimate or fabricate a forecast.
- The system must impose a maximum number of tool attempts and a bounded request duration.
These are not merely prompt instructions. Convert them into deterministic checks in server code. The symbolic-guardrails study reports that 74% of specified policy requirements can be enforced by symbolic guardrails, often with simple, low-cost mechanisms. An allowlist, schema validator, date parser, maximum-call counter, and field-level verifier are examples of straightforward controls that do not rely on the model obeying prose.
Step 2: Define a narrow weather capability
A narrow tool contract is easier to authorize and verify than a universal network tool. Your weather capability should express the smallest useful action: retrieve a forecast for one resolved location and one date. It should not accept a raw URL or a generic request method. It should not accept arbitrary headers. It should not allow the model to select a data provider.
At a conceptual level, the input contract contains a city or location query and an optional date. The output contract contains only the fields your answer needs: a canonical location name, a country or region when available, the forecast date, weather condition, temperature, precipitation information, wind information, units, source timestamp or freshness metadata where the provider supplies it, and a verification status.
Keep the raw provider response inside the tool implementation. Returning an entire external payload to the model is unnecessary and expands the chance that unexpected text or fields influence the assistant. Instead, normalize the source response into a small data object. Treat all tool output as untrusted input until your verification layer has checked it.
For example, if the question is “Will it rain in Dubai tomorrow?”, a suitable internal result is not a paragraph. It is a structured record indicating the resolved location, the relevant local date, precipitation information, units, and whether the record passed verification. The model can then transform that record into a concise answer without being asked to calculate or guess the underlying values.
Step 3: Build a server-owned agent loop
The application should run the loop on the server. The browser should send a limited conversation representation to your own endpoint, not provider credentials, model configuration, tool definitions, or previous tool outputs. The server creates the system instructions, selects the approved model and tools, and applies policy checks.
A safe loop follows this sequence:
- Validate the incoming request: limit message count, role values, character length, and total request size.
- Add server-controlled instructions describing the assistant’s role and the requirement to use approved tools for factual weather claims.
- Ask the model for a response with only the approved weather capability available.
- If the model returns ordinary text and no factual weather data is required, return the text after applying your response policy.
- If it requests the approved weather capability, parse the proposed arguments defensively and validate them against the server schema.
- Execute the fixed server implementation only when the capability name and arguments pass policy.
- Normalize and verify the provider result before it becomes available to the model.
- Return the verified result to the model as data, then request a final user-facing answer.
- Stop when the assistant has an answer or when the configured execution budget is exhausted.
Do not allow recursive execution without limits. Bound the number of tool calls, total elapsed time, request size, and any cost-related budget your deployment can measure. A limit turns an unexpected chain of requests into a controlled failure instead of an open-ended operational event.
When a request fails, return a useful user message such as “I could not confirm live weather data for that location and date.” Keep detailed operational information in protected server-side logs, with a request identifier and appropriate redaction. Do not return provider secrets, internal stack traces, or raw upstream payloads to the browser.
Step 4: Verify before reporting a result
Tool use alone is not enough. A tool can fail, return incomplete data, resolve the wrong city, return stale records, or provide values in a unit the application does not expect. The solver-grounded principle requires an explicit verification step between retrieval and reporting.
Your verifier should check at least the following conditions:
- The tool call used an approved capability and a server-selected provider.
- The location resolution is sufficiently specific for the user’s question. If “Springfield” is ambiguous, ask for a country or region instead of silently selecting one.
- The response contains the requested date and the date matches the intended local calendar date.
- Required numeric fields are present, finite, and associated with known units.
- The data source response indicates a successful retrieval according to your integration’s verified contract.
- The record is fresh enough for the use case under a documented caching and freshness policy.
- The output contains data, not executable instructions. Any instructions embedded in an external response must be ignored.
If any critical check fails, do not pass a “best effort” measurement to the model. Pass a structured failure result instead. The final answer can explain the limitation and request a more specific city or date. This is more trustworthy than a fluent answer built on incomplete or mismatched data.
Step 5: Make the interface honest about live retrieval
The user experience should reflect the actual state of the system. While the server is retrieving and verifying data, show a loading state such as “Checking forecast data.” Disable duplicate submissions for a single ordered conversation, or deliberately implement request IDs and reconciliation rules if your product supports parallel questions.
Label the assistant as a weather information interface rather than implying direct observation. Show the resolved place and forecast date in the final answer whenever the data is available. If the system cannot verify live data, show an error state rather than leaving a blank response or presenting generic weather advice as a current forecast.
For audiences in Saudi Arabia, the UAE, and the wider GCC, localisation should be a product decision backed by verified requirements: clarify place names, time zones, date formats, languages, units, accessibility needs, retention rules, and operational ownership before launch. Do not make data-residency, regional-cloud, or government-initiative claims unless they are supported by current authoritative sources and your actual deployment configuration.
Step 6: Test the invariants, not model wording
Testing a tool-calling agent should focus on what must always remain true regardless of model output. A model may phrase a correct answer in many ways, so sentence matching is not the core safety test. Instead, create tests around policy enforcement, tool validation, verification, and failure handling.
- Reject a browser request that attempts to set server instructions or submit fabricated tool results.
- Reject malformed, oversized, or unsupported tool arguments.
- Reject any requested capability outside the weather allowlist.
- Confirm that a missing or ambiguous location produces clarification or a controlled failure.
- Confirm that an upstream timeout, invalid payload, or incomplete record never becomes a numerical weather claim.
- Confirm that a date mismatch, unknown unit, or failed freshness check blocks reporting.
- Confirm that the loop stops at the configured tool and time limits.
- Confirm that external text cannot override server policy or cause a second unapproved action.
Use mocked provider responses for these cases. This keeps tests deterministic and lets you model outages, malformed data, ambiguous locations, and unexpected tool output without depending on a live external service. Maintain a versioned evaluation set containing normal weather questions, vague place names, invalid dates, adversarial instructions, and multi-turn requests.
Deployment checklist
Before publishing, verify current official documentation for every concrete library and provider used in your implementation. Store secrets only in server-side deployment configuration. Apply authentication and appropriate quotas when the endpoint is not a private demo. Use protected logging, set clear retention rules, monitor tool failures and latency, and maintain an incident process for upstream weather-data failures.
Most importantly, preserve the architectural boundary as the system grows. A model can identify that a trusted capability is useful. The server decides whether the capability is allowed, validates inputs, performs the request, verifies the result, and records the outcome. That is the foundation for a weather agent that is helpful without treating model-generated text as a substitute for verified external facts.
Key takeaway
A reliable Next.js OpenAI weather agent is not defined by a chat box or a single tool call. It is defined by a solver-grounded workflow: trusted tools produce factual values, explicit checks verify those values, and the language model explains only what the verified workflow permits it to explain. This pattern gives teams a durable starting point for weather experiences and for more consequential agentic applications.
Sources: LLMs and Agentic AI Systems for Smart Grids: A Tutorial on Architectures and Applications; Symbolic Guardrails for Domain-Specific Agents.
Top comments (0)