用 Codex Sites 搭一个能调用 QVeris 的天气网站
很多工具演示站的问题,不是页面不够漂亮,而是只能看,不能真正使用。用户面对一张精致的仪表盘,却不知道数据从哪里来、工具为什么这样选,失败后又会发生什么。
这次我把演示往前推进了一步:让 Codex Sites 负责生成网站,让 QVeris 负责能力发现和工具调用,做一个可以查询城市天气、空气质量和未来预报的交互式网站。页面只是最终呈现,真正值得验证的是从需求到工具执行的完整链路。

先看网站
演示网站地址:
https://city-weather-lab-qveris.ax2675996.chatgpt.site
**访问前提:**这个网站由 OpenAI Codex Sites 托管在
chatgpt.site。访问它的网络环境必须能够正常连接 ChatGPT/OpenAI;即使可以访问其他海外网站,也不代表一定能访问chatgpt.site。部分网络出口还可能被 Cloudflare 风控拦截。
我在 2026 年 7 月 11 日从当前自动化测试环境访问时,Cloudflare 返回了 403 Sorry, you have been blocked。这不代表网站已经删除,而是说明公开分享和“任何网络都能打开”不是一回事。如果浏览器打不开,先确认同一网络能否正常访问 ChatGPT,再尝试更换网络出口或稍后重试。

网站已在 Codex Sites 中设置为“互联网上的任何人”可访问。这个设置解决的是登录权限,不能绕过访问者所在地的网络限制和 Cloudflare 安全策略。
目前公开站点使用的是 Demo 测试数据,没有配置真实的 QVERIS_API_KEY。这样做是为了避免公开演示被大量调用后持续消耗积分。要切换到真实数据,需要在 Sites 的服务端环境变量中配置密钥,并重新部署;密钥不能写进前端源码。
为什么用天气做演示
天气数据几乎不需要解释。当前温度、未来七天预报、24 小时趋势和空气质量,也天然适合卡片、曲线、柱状图和对比表格。
但“输入北京,显示天气”背后并不简单:
- 工具可能接受城市名,也可能只接受经纬度。
- 城市名不能直接使用时,要先调用地理编码工具。
- 当前天气、未来预报和空气质量可能来自不同供应商。
- 三类能力应当能够独立成功或失败。
- 不同工具返回的字段结构需要在服务端统一。
- 演示网站公开后,API Key 绝不能进入浏览器。
这些问题正好覆盖 Agent 调用外部工具时最常见的边界,比写死一个天气接口更适合展示 QVeris。
Codex Sites 和 QVeris 怎么分工
Codex Sites 接收的不是一句“帮我做个天气网站”,而是一份接近产品需求文档的指令。页面结构、交互状态、响应式布局、数据模型、安全边界和验收条件都需要说清楚。要求越具体,生成结果越接近可继续开发的产品,而不是一次性页面样稿。
QVeris 负责另一部分:根据能力描述动态发现工具,读取真实参数定义,再执行合适的候选工具。网站服务端完成工具选择和字段适配,浏览器只接收统一后的天气数据与脱敏调用摘要。

完整链路可以拆成六步:
- 浏览器提交城市和所需能力。
- 服务端调用 QVeris
/search动态发现工具。 - 根据参数适配度、成功率、响应时间和返回结构筛选候选。
- 携带发现阶段返回的
search_id执行工具。 - 服务端把不同供应商结果转换成统一数据模型。
- 浏览器显示结果和脱敏后的工具调用轨迹。
这条链路不把 tool_id 永久写死。首选工具失败时,服务端可以修正参数或尝试下一个候选;前端也不需要理解供应商各不相同的字段结构。
生成出来的网站
网站打开后直接进入数据看板,没有营销式的大 Hero。桌面端由城市列表、天气主区域、空气质量和工具状态组成,移动端改成单列布局。

页面覆盖了当前天气、小时趋势、未来预报、空气质量、城市收藏和中英文切换。城市对比最多放入四个城市,表格下面再用图表强化温度和空气质量差异。

演示站还提供了一个“工具调用”抽屉。它展示能力描述、discover query、候选数量、选中的 tool_id、工具质量、执行耗时、参数摘要和 Demo 状态,但不展示 API Key、Authorization Header、Cookie 或完整敏感响应。

截图中的 demo-weather-current、demo-weather-forecast-7d 和 demo-air-quality 明确属于 Demo 模式,不应当被理解为已经完成真实 QVeris 调用。公开演示最忌讳把测试数据包装成生产结果。
交给 Codex Sites 的 Prompt
下面是本次 Prompt 的主体。它不只描述视觉风格,也约束了 QVeris 接入、缓存、错误状态、凭证保护和验收方式。
请生成一个完整、可运行、响应式的网站,名称为:
「城市气象观察站 / City Weather Lab」
网站用途:
演示如何使用 QVeris 发现并调用天气、空气质量、地理编码等工具。
网站不是产品宣传页,打开后直接进入可操作的数据看板。
一、技术要求
1. 使用 React + TypeScript。
2. 使用 Tailwind CSS。
3. 图标使用 Lucide,不要手绘 SVG。
4. 图表使用 Recharts 或 ECharts。
5. 支持桌面端和移动端。
6. 不要把 QVERIS_API_KEY 写入前端代码或 Git 仓库。
7. 使用服务端 API Route 代理 QVeris 请求,从环境变量读取 QVERIS_API_KEY。
8. 提供 .env.example,但不提供真实密钥。
9. 如果 Sites 环境不支持服务端 API Route,保留完整客户端接口并明确进入 Demo 模式。
二、QVeris 接入
API Base URL:
https://qveris.ai/api/v1
服务端请求头:
Authorization: Bearer ${QVERIS_API_KEY}
Content-Type: application/json
不要硬编码 tool_id。首次调用某项能力时,通过 POST /search 动态发现工具,
并在服务端会话中缓存选中的工具。
分别发现以下能力:
- weather forecast current conditions API
- multi day weather forecast API
- air quality pollution index API
- city geocoding latitude longitude API
选择工具时综合判断:
- 参数是否支持城市名、经纬度或标准地点;
- success_rate 是否较高;
- 参数描述和样例是否完整;
- 平均响应时间;
- 返回结果是否为结构化数据。
执行接口:
POST /tools/execute?tool_id=<tool_id>
请求体包含 discover 返回的 search_id、按真实参数定义生成的 parameters,
以及 max_response_size。不得假设所有天气工具都接受 city 参数。
失败时先修正参数,仍失败再切换候选工具。
不得向浏览器返回 API Key、Authorization Header、敏感错误堆栈或用户唯一标识。
三、页面与功能
页面打开后直接显示数据看板,不做营销落地页或巨大 Hero。
桌面布局:顶部应用栏、左侧城市列表、中间天气区域、右侧空气质量和工具状态。
移动端改为单列,城市列表使用抽屉。
顶部包括城市搜索、定位、中英文切换、明暗模式、刷新和设置。
支持北京、上海、新加坡、Tokyo、London、New York。
如果天气工具不支持城市名称,先做地理编码。
当前天气显示温度、体感、高低温、湿度、风速风向、降水概率、
能见度、气压、紫外线指数和更新时间。
未来预报显示七天卡片、温度趋势和降水概率。
24 小时趋势可切换温度、体感温度和降水概率。
空气质量显示 AQI、PM2.5、PM10、CO、NO2、SO2 和 O3,
只给谨慎的活动建议,不做医疗诊断。
城市对比最多选择四个城市,比较温度、体感、湿度、风速、
降水概率、AQI 和 PM2.5。表格在移动端允许横向滚动。
四、工具调用抽屉
展示用户请求能力、discover query、候选数量、最终 tool_id、工具名称、
success_rate、平均耗时、本次耗时、参数摘要、返回字段摘要、
是否切换候选以及是否使用 Demo 数据。
不展示 API Key、Authorization Header、Cookie、完整敏感响应或用户身份。
五、统一数据模型
服务端把不同工具结果统一为 WeatherViewModel:
- location:城市、国家、经纬度、时区和当地时间;
- current:天气、温度、体感、湿度、风、降水、能见度、气压和 UV;
- hourly:时间、温度、体感和降水概率;
- daily:日期、天气、高低温、降水和风速;
- airQuality:AQI 和主要污染物;
- source:toolId、toolName、更新时间、耗时和 demoMode。
缺失数据统一显示“暂无数据”,不能显示 0 或编造数值。
六、状态与缓存
实现首次加载、搜索中、骨架屏、部分成功、城市不存在、认证失败、
调用超时、字段缺失、空气质量不可用、Demo 提示、手动重试,
并保留最近一次成功数据。
工具发现缓存 24 小时,天气缓存 10 分钟,空气质量缓存 15 分钟。
用户主动刷新可绕过结果缓存,但不要重复执行工具发现。
防止同一城市的并发请求造成重复调用。
七、验收
1. 北京、新加坡和伦敦至少能够查询。
2. 必要时自动先做地理编码。
3. 当前天气、预报和空气质量可以独立失败。
4. 页面显示实际 tool_id 和执行耗时。
5. API Key 不出现在浏览器、响应或构建产物中。
6. 1440px 桌面端显示完整。
7. 390px 移动端无重叠和横向溢出。
8. 明暗模式、中英文切换和收藏持久化可用。
9. 运行 lint、类型检查和生产构建。
10. 使用 Playwright 检查桌面和移动端页面。
请直接生成完整网站、API Route、环境变量样例、README 和必要测试,
不要只生成静态设计稿。
从 Demo 切到真实调用
公开版本现在还不能作为真实数据验证结果。要切换到 QVeris,需要完成以下工作:
- 在 Sites 服务端环境中设置
QVERIS_API_KEY。 - 确认密钥只在服务端 API Route 中读取。
- 重新部署后查询北京、新加坡和伦敦。
- 在工具抽屉确认
demoMode已变为false。 - 检查实际
tool_id、参数摘要和执行时间。 - 搜索浏览器源码、响应和构建产物,确认没有密钥。
- 分别制造天气、预报和空气质量失败,确认页面可以局部降级。
如果 Sites 当前不支持所需的服务端运行环境,正确做法是保留清晰的 Demo 标识,把 API Route 部署到受控后端,而不是把 Key 塞进前端临时解决。
还能扩展成什么
天气只是一个容易理解的入口。保留“能力描述、动态发现、参数适配、服务端调用、统一模型、结果可视化”这条主线,可以快速替换成其他主题:
- 体育赛事:赛程、积分榜、球队状态和球员数据。
- 金融市场:行情、公告、资金流向和公司基本面。
- 科研助手:论文检索、引用关系、主题聚类和摘要。
- 城市生活:天气、空气质量、路线和周边服务。
- 内容处理:网页提取、PDF、OCR、翻译和语音合成。
Codex Sites 降低了把需求做成网站的门槛,QVeris 则提供真实、可选择、可替换的外部能力。两者结合的价值,不是再生成一张更漂亮的界面,而是把“找工具、用工具、处理失败、解释结果”放进同一个可以操作的产品里。
微信公众号
欢迎关注「字与码」
如果这篇文章对你有用,也欢迎在微信里继续关注后续更新。
X / Twitter
关注 @ax2_zicode
更即时的技术观察、新文章提醒和一些短想法会发在 X 上。