☰
玩转Vibe Coding:用Qoder零代码开发天气预报智能体,一键部署到ModelScope创空间
2026/10/15 19:11:57 网站建设 项目流程

1. 从一句需求到线上应用:Vibe Coding 到底能做什么

Vibe Coding 这个词最近在开发者圈子里出现得越来越频繁,它的核心思路很简单:你用自然语言描述想要什么,AI 帮你把代码写出来,你负责判断和调整方向。听起来像是“许愿式编程”,但实际用下来,它确实能把一个想法从零到可访问的线上 Demo 压缩到一两个小时以内。

这篇文章要做的,是一个天气预报智能体。它能做什么?你用中文问“上海明天天气怎么样”,它会自动把城市名转成英文、调用地理编码接口拿到经纬度、再请求天气 API 取回温度湿度和降水概率,最后用自然语言把结果整理给你。适合谁?适合想快速验证 AI 应用想法、又不想从零手写前后端和工具调用逻辑的开发者,也适合刚接触 MCP 协议、想找一个完整可跑案例来理解“大模型怎么调工具”的朋友。

整个流程分四段:在 Qoder 里用自然语言生成 Gradio 界面和 MCP 工具调用逻辑,本地跑通验证,然后部署到 ModelScope 创空间,最后拿到一个公网可访问的链接。我会把每一步的提示词、配置文件、部署参数都写清楚,你跟着做就能复现。

技术栈方面,界面用 Gradio 5.x,大模型走 ModelScope 的推理 API(Qwen3-Next-80B-A3B-Instruct),工具调用协议用 MCP,天气数据源用 Open-Meteo 的免费接口,异步请求用 httpx。Python 版本建议 3.11,操作系统 Windows / macOS / Linux 都行。

有一点需要提前说明:MCP 在这里的角色是“标准化工具调用协议”。你可以把它理解成一个插座标准——大模型不需要知道天气 API 的具体 URL 和参数格式,它只需要知道“有一个叫 get_hourly_forecast_by_datetime_range 的工具,接受经纬度和日期范围”,MCP 服务端负责把参数翻译成实际的 HTTP 请求。这样换数据源的时候,只需要改服务端,客户端和提示词都不用动。

2. 前置准备:Qoder 项目初始化与 ModelScope API Key 获取

2.1 环境检查

在开始之前,确认你的开发环境满足以下条件:

项目要求
Python 版本3.11(3.10 也可,但 3.11 对 asyncio 支持更好)
操作系统Windows / macOS / Linux
必需工具Qoder IDE
网络要求能访问 ModelScope API 和 Open-Meteo API
依赖包gradio、openai、mcp、httpx

如果你还没有 Qoder,去官网下载安装即可。安装完成后打开,点击“打开项目”,在本地新建一个目录(比如weather-agent),用 Qoder 打开这个空目录。

2.2 获取 ModelScope API Key

大模型调用需要 ModelScope 的访问令牌。操作路径:

  1. 登录 ModelScope 账号
  2. 访问https://www.modelscope.cn/my/myaccesstoken
  3. 复制你的 Access Token(格式类似ms-xxxxxxxx)

这个 Token 后面会用在两个地方:本地client.py里的api_key参数,以及创空间的环境变量MODELSCOPE_API_KEY。注意不要把它硬编码到会公开的代码里,后面部署那一步我会讲怎么用环境变量替代。

2.3 创建项目文件

在 Qoder 左侧资源管理器里新建三个文件:server.py、client.py、app.py。前两个是 MCP 服务端和客户端,第三个是 Gradio 应用入口。

server.py负责定义 MCP 工具,核心是三个@mcp.tool装饰的函数:

  • get_all_coordinates(city):调 Open-Meteo 地理编码 API,把城市名转成经纬度
  • get_hourly_forecast_by_datetime_range(...):调预报 API 拿指定日期范围的逐小时天气
  • get_hourly_observe_by_datetime_range(...):调历史 API 拿实况天气

每个工具都用Annotated和Field标注参数说明,这些说明会直接暴露给大模型,所以写清楚很重要。比如city参数要注明“非英文名称要转换为英文”,否则模型可能直接把“北京”传给 API 导致查不到。

client.py是 MCP 客户端,负责连接服务端、收集工具列表、把工具定义转成 OpenAI function calling 格式、处理多轮工具调用循环。关键逻辑在process_query方法里:它维护一个messages列表,每次请求后检查message.tool_calls,如果有工具调用就执行、把结果追加到消息里、再次请求模型,直到模型给出最终文本回答。

app.py是 Gradio 界面,把client.py的process_query包装成聊天回调。这部分我建议直接用 Qoder 生成,提示词如下:

请参考 server.py 和 client.py,编写一个 app.py 脚本,利用 Gradio 技术实现一个天气预报智能体。 要求: 1. 使用 gr.Blocks 构建界面,左侧显示功能介绍,右侧是聊天窗口 2. 聊天窗口用 gr.Chatbot,输入框用 gr.Textbox,发送和清空按钮放在同一列 3. 首次查询时自动初始化 MCP 工具连接 4. api_key 从环境变量 MODELSCOPE_API_KEY 读取,默认值留空 5. 支持多轮对话,显示工具调用过程

Qoder 会生成一个完整的app.py,你检查一下api_key那行是不是从环境变量读的,如果不是就手动改一下。

3. 可复制配置:MCP 服务端、客户端与 Gradio 界面参数

3.1 server.py 关键配置

MCP 服务端的核心是工具定义。以下是get_hourly_forecast_by_datetime_range的参数配置片段,你可以直接复制到server.py:

@mcp.tool(description="获取指定经纬度位置在指定日期范围内的预报天气信息") async def get_hourly_forecast_by_datetime_range( latitude: Annotated[float, Field(description="纬度坐标,例如: 31.2304")], longitude: Annotated[float, Field(description="经度坐标,例如: 121.4737")], start_date: Annotated[str, Field(description="开始日期,格式为YYYY-MM-DD")], end_date: Annotated[str, Field(description="结束日期,格式为YYYY-MM-DD")], location_name: Annotated[str, Field(description="位置名称,用于结果展示")] = "", timezone: Annotated[str, Field(description="时区名称,例如: Asia/Singapore")] = "Asia/Singapore", model: Annotated[str, Field(description="天气预报模型,例如: icon_seamless")] = "", weather_variables: Annotated[str, Field( description="要获取的天气要素,用逗号分隔,例如: 'temperature_2m,relative_humidity_2m,precipitation'" )] = "temperature_2m" ) -> Annotated[str, Field(description="给定位置和日期范围内每小时天气数据的摘要。")]:

注意weather_variables的默认值是temperature_2m,如果你想让模型默认返回更多要素,可以改成temperature_2m,relative_humidity_2m,precipitation_probability,weather_code。但不要把所有要素都塞进去,否则返回的 JSON 会很大,模型处理起来慢。

服务端启动方式在文件末尾:

if __name__ == "__main__": mcp.run(transport="stdio")

stdio表示通过标准输入输出通信,适合本地进程间调用。部署到创空间后也是这个模式,Gradio 进程会以子进程方式启动 MCP 服务端。

3.2 client.py 的 API 配置

client.py里需要改两个地方。第一个是 OpenAI 客户端的初始化:

self.client = OpenAI( base_url='https://api-inference.modelscope.cn/v1', api_key='ms-xxx', # 替换为你的 ModelScope Access Token )

第二个是模型名称:

response = self.client.chat.completions.create( model="Qwen/Qwen3-Next-80B-A3B-Instruct", messages=messages, tools=available_tools, stream=False )

如果你用的是其他模型,把model参数换成对应的 Model ID 即可。但要注意,不是所有模型都支持 function calling,选之前确认一下模型卡片里有没有标注工具调用能力。

3.3 app.py 的 Gradio 组件配置

Gradio 界面部分,Qoder 生成的代码结构大概是这样的:

with gr.Blocks(title="天气预报智能体") as demo: with gr.Row(): with gr.Column(scale=1): gr.Markdown(""" # 天气预报智能体 ## 功能特性 - 全球天气查询 - 自然语言交互 - MCP工具调用 ## 使用示例 - "查询北京的天气" - "上海明天的温度和降水概率" """) with gr.Column(scale=2): chatbot = gr.Chatbot(label="对话窗口", height=500) with gr.Row(): with gr.Column(): msg = gr.Textbox(label="输入你的问题", placeholder="例如:查询北京的天气") with gr.Row(): submit_btn = gr.Button("发送", variant="primary") clear_btn = gr.Button("清空对话")

scale=1和scale=2控制左右两栏的宽度比例,左边占 1/3,右边占 2/3。height=500是聊天窗口的固定高度,避免消息多了之后页面被撑得太长。

3.4 requirements.txt

创空间部署需要这个文件来安装依赖:

gradio openai mcp httpx

版本号可以不写,创空间会自动装最新版。但如果遇到兼容性问题,可以锁定版本,比如gradio==5.0.0。

4. 验证请求:本地预览与线上访问的完整步骤

4.1 本地启动

在 Qoder 的终端里运行:

python app.py

如果一切正常,你会看到类似这样的输出:

Running on local URL: http://127.0.0.1:7860

打开浏览器访问这个地址,就能看到 Gradio 界面。首次查询时,系统会初始化 MCP 工具连接,可能需要几秒钟。你可以在输入框里输入“查询北京的天气”,观察右侧聊天窗口的回复。

4.2 验证工具调用是否生效

一个完整的查询流程应该包含以下步骤:

  1. 模型收到“查询北京的天气”
  2. 模型判断需要调用get_all_coordinates,参数city="Beijing"
  3. MCP 服务端请求地理编码 API,返回北京的经纬度(39.9042, 116.4074)
  4. 模型拿到经纬度后,调用get_hourly_forecast_by_datetime_range,传入经纬度和日期
  5. MCP 服务端请求天气 API,返回逐小时数据
  6. 模型把数据整理成自然语言回复

你可以在终端里看到工具调用的日志,比如:

[调用工具 get_all_coordinates,参数: {'city': 'Beijing'}] 工具返回: 找到 1 个坐标结果: 1. Beijing - 纬度: 39.9042, 经度: 116.4074, 国家: China, 省份: Beijing, 时区: Asia/Shanghai

如果日志里只有模型回复、没有工具调用,说明模型没有正确识别工具。检查一下tools参数是不是传进去了,以及工具描述是不是足够清晰。

4.3 部署到 ModelScope 创空间

本地跑通后,就可以部署上线了。步骤如下:

步骤 1:创建创空间

进入 ModelScope 创空间页面,点击右上角“我要创建”。填写基本信息:

  • 空间名称:weatherforecast(建议用英文)
  • 空间标题:天气预报智能体
  • 可见性:公开
  • SDK 类型:Gradio

步骤 2:修改 app.py 适配云端环境

把api_key改成从环境变量读取:

import os api_key = os.getenv('MODELSCOPE_API_KEY', '') self.client = OpenAI( base_url='https://api-inference.modelscope.cn/v1', api_key=api_key, )

步骤 3:准备部署文件

确保项目目录包含以下文件:

  • app.py:主程序
  • client.py:MCP 客户端
  • server.py:MCP 服务端
  • requirements.txt:依赖列表
  • README.md:项目说明

步骤 4:配置 README.md

在README.md头部添加部署配置:

--- deployspec: entry_file: app.py ---

步骤 5:上传文件

在创空间管理页面点击“空间文件”,把所有文件上传上去。

步骤 6:配置环境变量

点击右上角“设置” → “环境变量管理”,添加:

  • 变量名:MODELSCOPE_API_KEY
  • 变量值:你的 ModelScope Access Token
  • 可见性:私有

步骤 7:上线发布

点击“上线”按钮,系统会自动安装依赖、启动应用、分配公网地址。等待几分钟后,你就能通过创空间提供的 URL 访问了。

4.4 线上验证

访问创空间地址,测试几个查询:

  • “查询上海的天气”
  • “纽约2025年11月15日到11月17日的天气预报”
  • “东京明天的温度和降水概率”

如果返回结果正常,说明部署成功。你可以在创空间页面看到访问量统计。

5. 本篇常见错误排查:401、local proxy failed、reading choices 与 OAuth 报错

5.1 401 Unauthorized

报错信息:

openai.AuthenticationError: Error code: 401 - {'error': {'message': 'Invalid API key', 'type': 'invalid_request_error'}}

原因:api_key不对或没传。

排查步骤:

  1. 检查client.py里的api_key是不是ms-开头
  2. 如果部署到创空间,检查环境变量MODELSCOPE_API_KEY是否配置正确
  3. 确认 Token 没有过期,重新生成一个试试

5.2 local proxy failed

报错信息:

httpx.ConnectError: [Errno 111] Connection refused

或者:

openai.APIConnectionError: Connection error.

原因:网络请求被拦截或代理配置有问题。

排查步骤:

  1. 确认本机网络能正常访问api-inference.modelscope.cn
  2. 如果用了系统代理,检查httpx是否走了代理。可以在代码里显式设置:
import httpx async with httpx.AsyncClient(proxy=None) as client: ...
  1. 创空间环境一般不需要代理,如果本地需要,确保代理地址正确

5.3 reading choices 报错

报错信息:

KeyError: 'choices'

或者:

IndexError: list index out of range

原因:模型返回的 JSON 结构不符合预期,通常是 API 返回了错误信息而不是正常的 completion 结果。

排查步骤:

  1. 在response = self.client.chat.completions.create(...)后面加一行print(response),看看实际返回了什么
  2. 如果返回的是错误信息,检查model参数是不是正确的 Model ID
  3. 确认模型支持 function calling,不支持的话tools参数会被忽略或报错

5.4 OAuth 相关报错

报错信息:

openai.BadRequestError: Error code: 400 - {'error': {'message': 'Invalid request format', 'type': 'invalid_request_error'}}

原因:请求格式不对,常见于messages列表结构有问题。

排查步骤:

  1. 检查messages里每条消息是否有role和content字段
  2. 工具调用后追加的assistant消息要包含tool_calls字段
  3. 工具返回的消息要包含tool_call_id和name字段

正确的消息结构:

messages.append({ "role": "assistant", "content": "", "tool_calls": [ { "id": call.id, "type": "function", "function": { "name": call.function.name, "arguments": call.function.arguments } } ] })

5.5 工具调用不生效

现象:模型直接回复“我无法查询天气”,没有调用工具。

排查步骤:

  1. 检查tools参数是不是传进去了
  2. 检查工具描述是不是足够清晰,模型需要知道这个工具能做什么
  3. 在 system prompt 里明确告诉模型“如果是天气相关问题,请调用工具”

5.6 创空间部署后无法访问

现象:上线后页面打不开,或者显示“应用启动失败”。

排查步骤:

  1. 检查README.md里的entry_file是不是app.py
  2. 检查requirements.txt里的依赖是不是都装了
  3. 查看创空间的日志,看看有没有报错信息
  4. 确认环境变量MODELSCOPE_API_KEY配置正确

如果日志里显示ModuleNotFoundError,说明依赖没装全,把缺失的包加到requirements.txt里重新上线。

6. 从本地到云端:把天气智能体接入你的日常工具链

这个天气智能体跑通之后,你可以把它当成一个模板,替换掉天气 API 和工具定义,就能快速做出其他类型的智能体。比如把 Open-Meteo 换成某个数据库查询接口,把 Gradio 换成飞书机器人,核心逻辑不用动。

如果你想让模型调用更稳定,可以在client.py的 system prompt 里加一句“如果用户没有指定日期,默认查询今天和明天”。这样模型就不会因为缺少参数而反复询问。

另外,MCP 服务端的工具描述尽量写详细,包括参数格式、取值范围、默认值。模型看到的信息越完整,调用越准确。我试过把weather_variables的可选值全部列在 description 里,模型就能根据用户问题自动选择合适的要素,比如问“会下雨吗”就只取precipitation_probability,问“冷不冷”就取temperature_2m和apparent_temperature。

部署到创空间后,你可以把公网地址分享给朋友测试。如果访问量不大,免费额度完全够用。需要 GPU 加速的话,创空间也支持付费升级。

最后提醒一点:ModelScope 的 Access Token 不要提交到公开仓库。如果代码要开源,用环境变量或者.env文件管理密钥,.env记得加到.gitignore里。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询