天气预报系统

一个基于模型上下文协议(MCP)集成地理空间工具、实时天气数据和AI推理的孟加拉国天气预报系统。

  • by Sgt-Hashtag
  • Python
  • 本地部署
  • 更新于
在 GitHub 查看 Sgt-Hashtag/weather-forecast-mcp

使用说明

天气预报MCP系统

孟加拉国生产就绪的天气预报系统,利用 模型上下文协议(MCP) 整合地理空间工具、实时天气数据和人工智能推理。

🌟 特性

  • 基于地区的天气匹配:将用户查询与BMD WRF表中的孟加拉国地区名称直接匹配
  • 上下文感知响应:通过量身定制的建议区分农民和公民的情况
  • 真实BMD数据集成:取消孟加拉国气象局的实时天气预报
  • MCP架构:为天气操作实施自定义MCP服务器
  • Gemini AI集成:使用谷歌的Gemini 1.5 Flash进行自然语言解释
  • 孟加拉语/英语支持:无缝处理孟加拉语和英语地区名称

🏗️ 系统架构

User Query → LLM Agent → District Extraction → Weather MCP → BMD Scraping → Response
     ↑          ↓             ↑                   ↑              ↓
   Frontend ← Mapbox       Custom MCP        BAMIS.gov.bd    Explanation

核心组件

  1. 大语言模型智能体 (services/agent/)

    • 使用Google Gemini处理用户查询
    • 检测背景(农民与公民)
    • 提取地区名称和预测天数
    • 生成自然语言解释
  2. 自定义MCP服务器 (services/agent/mcp_weather/)

    • retrieve_weather_forecast_by_district:按地区名称删除BMD WRF表
    • 处理孟加拉语和英语地区名称
    • 返回具有3个以上参数的结构化天气数据
  3. 前端 (frontend/)

    • React+Mapbox GL JS接口
    • 自然语言查询输入
    • 可视化预测显示

🚀 快速开始

先决条件

设置

  1. 克隆存储库

    git clone https://github.com/Sgt-Hashtag/weather-forecast-mcp.git
    cd weather-forecast-mcp
    
  2. 配置环境变量

    cp .env.example .env
    # Edit .env with your API keys
    nano .env
    
  3. 构建和启动服务

    docker compose up --build -d
    
  4. 访问应用程序 打开 http://localhost:3000 在浏览器中

🧪 查询示例

查询 上下文 天数 地区
“达卡三天后会下雨吗?” 公民 3 达卡
“我是吉大港附近的一名农民。5天内雨水够吗?” 农民 5 吉大港
“明天帕布纳的天气预报” 未知 1 帕布纳
“科克斯巴扎尔7天天气预报” 未知 7 科克斯巴扎尔

🌊 Prithvi 2.0洪水分割

Docker代理镜像包括本地洪泛分割堆栈 ibm-nasa-geospatial/Prithvi-EO-2.0-300M-TL-Sen1Floods11.期间 docker compose build agentDocker预取拥抱脸 config.yaml 并对检查点进行了微调 /app/models/huggingface,因此推理可以运行 而无需在第一次执行时等待1.28GB的模型下载。

洪水管道位于 scripts/prithvi_flood_seg/.组合支架 ./scripts 到 /app/scripts,因此容器输出文件显示在主机上。

构建

CPU构建:

docker compose build agent

GPU构建:

docker compose -f docker-compose.yml -f docker-compose.gpu.yml build agent

要在构建过程中跳过Prithvi2模型预取:

DOWNLOAD_PRITHVI2_MODEL=false docker compose build agent

运行Prithvi2推理

首先创建Sentinel-2 GeoTIFF输入:

docker compose run --rm agent python /app/scripts/prithvi_flood_seg/copernicus_flood_segmentation.py

然后运行Prithvi-EO-2.0 Sen1Wloods11:

docker compose run --rm agent python /app/scripts/prithvi_flood_seg/prithvi2_flood_inference.py --device auto

预期产出:

scripts/prithvi_flood_seg/prithvi2_flood_prediction.tif
scripts/prithvi_flood_seg/prithvi2_flood_prediction_preview.png

对于全自动流程,包括植被/水后处理:

docker compose run --rm agent bash /app/scripts/prithvi_flood_seg/run_flood_detection_pipeline.sh

有关更多详细信息和阈值调整,请参阅 docs/flood-detection-flow.md.

🔧 技术细节

数据源

  • 天气数据: BMD WRF表
  • 地理编码:从查询文本中提取地区名称(不需要外部API)
  • AI模型:谷歌双子座2.5 Flash

已实施MCP工具

工具 参数 说明
retrieve_weather_forecast_by_district district_name, forecast_days, parameters 删除特定地区的BMD WRF表

地区名称处理

系统同时支持这两种功能 孟加拉语 和 英语 地区名称:

孟加拉语 英语
找不到 Pabna
达卡 Dhaka
Chattogram Chattogram
考克斯集市 Cox's Bazar

BMD表结构

BMD WRF表提供了以下列的综合天气数据:

  • 温度:最小值、平均值、最大值(°C)
  • 湿度:最小值、平均值、最大值(%)
  • 土壤湿度:最小值、平均值、最大值(%)
  • 降雨:总计(mm)-在表格中出现两次
  • 风:速度最小、平均、最大(km/h)和方向最小、平均和最大(°)
  • 云:分数高、低、中(八)

📊 天气参数

每个预测包括 3+所需参数:

  1. 温度:最低/最高摄氏度
  2. 降水:概率下的降雨量(单位:毫米)
  3. 湿度:百分比值

🧪 测试

运行端到端测试:

python scripts/test_e2e.py

API手动测试:

curl -X POST http://localhost:8000/query \
  -H "Content-Type: application/json" \
  -d '{"query": "Will it rain in Pabna in 3 days?"}'

📈 情境感知解释

农民背景

“对于帕布纳附近的农民来说,预测显示降雨量为8毫米(40%的可能性),气温为24-32°C。降雨量对作物生长有利——此时不需要额外的灌溉。75%的湿度水平可能会影响作物健康——如果超过70%,可以考虑采取真菌病预防措施。”

公民背景

“帕布纳的天气预报:预计降雨量为8毫米(40%的可能性),气温为24-32°C。上下班和户外活动时请携带雨伞。湿度为75%,适合日常活动。”

🛠️ 故障排除

常见问题

  1. “NoneType对象不可下标”

    • 原因:Mapbox MCP工具名称不匹配
    • 解决方案:系统现在使用直接区域提取(无Mapbox依赖性)
  2. BMD刮除失败

    • 原因:SSL证书问题或URL格式
    • 解决方案:用途 verify=False 以及正确的URL格式
  3. 未找到地区

    • 原因:拼写变化(吉大港vs聊天程序)
    • 解决方案:孟加拉语/英语综合地图

调试命令

# Check agent logs
docker compose logs agent

# Test BMD scraping directly
python services/agent/scripts/test_bmd_scraping.py

# Verify district extraction
python -c "from mcp_client import MCPClientManager; print(MCPClientManager()._extract_district_from_query('I am in pabna'))"

🙏 致谢

  • 孟加拉国气象局 提供开放的天气数据
  • 谷歌人工智能 为双子星API
  • Mapbox 用于映射基础设施
  • 模型上下文协议 实现工具互操作性的规范

建于❤️ 孟加拉国的农业和城市社区 🌾🏙️


农田边界划定(农业边界)

农田边界划定作为可选的管道步骤实施,由 农业用地 以及谷歌地球引擎。

运作原理

User query with coordinates
        ↓
GEE downloads Sentinel-2 composite (full-year median, 10m, cloud-masked)
        ↓
Step 1 — DelineateAnything (YOLO instance segmentation) → field polygons GeoJSON
        ↓
Step 2 — FTW / Fields of the World (semantic segmentation) → refines boundaries
        ↓
LULC filter — Google Dynamic World crop probability > 0.3 (removes non-agricultural detections)
        ↓
GeoJSON output + map overlay

重要提示: 步骤1和步骤2都是字段 边界 仅检测——不进行作物类型分类。这 crop_type 输出中的字段将始终为 "Unknown".

附加先决条件

  • GEE项目ID:已注册的谷歌地球引擎项目
  • 服务帐户凭据:具有GEE访问权限的JSON密钥文件
  • 英伟达GPU (推荐):配备CUDA 12.x驱动程序的RTX级GPU。CPU回退工作正常,但速度较慢。

凭据设置

将您的GEE服务帐户JSON放在以下任一位置:

secrets/credentials.json
secrets/service-account.json

这 secrets/ 目录以只读方式装载到容器中 /app/secrets/.

环境变量

添加到您的 .env:

GEE_PROJECT_ID=your-gee-project-id

触发字段划分

代理从自然语言中检测描绘意图。始终包含明确的坐标:

"Delineate field boundaries at latitude 30.9 longitude 75.5"
"Show me farm boundaries at lat 23.5 lon 90.3"
"My land at latitude 28.6 longitude 77.2"

使用提供的脚本:

# Edit the coordinates inside the script, then run:
bash scripts/query_field_boundaries.sh
# Output saved to results/result.json

或者直接使用curl:

curl -X POST http://localhost:8000/query \
  -H "Content-Type: application/json" \
  -d '{"query": "Delineate field boundaries at latitude 30.9 longitude 75.5"}'

始终提供明确的坐标。 如果没有它们,代理会对位置名称进行地理编码,如果该区域在谷歌动态世界中的裁剪概率较低(阈值:0.3),则可能返回0个结果。

GPU与CPU模式

GPU推理是可选的。基础 docker-compose.yml 完全在CPU上运行,可以在任何机器上工作。一个单独的 docker-compose.gpu.yml 覆盖激活GPU模式。

为什么是两个文件? Docker Compose不支持有条件的YAML块。这 deploy.resources.reservations.devices 保留GPU设备的部分在没有NVIDIA容器工具包的机器上发生硬故障,无论任何环境变量如何。覆盖文件模式是Docker的标准解决方案。

CPU模式(默认,不需要GPU)

docker compose up --build -d

默认情况下安装PyTorch CPU轮。推理在CPU上运行——速度较慢,但在任何地方都能工作。代理构建也会预取Prithvi2洪水模型,除非 DOWNLOAD_PRITHVI2_MODEL=false 已设置。

GPU模式

要求:

步骤1——使用CUDA PyTorch车轮构建:

docker compose -f docker-compose.yml -f docker-compose.gpu.yml build

GPU覆盖默认为 TORCH_INDEX_URL=https://download.pytorch.org/whl/cu128. 对于高龄驾驶者,请覆盖它:

TORCH_INDEX_URL=https://download.pytorch.org/whl/cu121 \
  docker compose -f docker-compose.yml -f docker-compose.gpu.yml build

CPU轮较小;CUDA车轮要大得多。

步骤2——从GPU覆盖开始:

docker compose -f docker-compose.yml -f docker-compose.gpu.yml up -d

这将合并 docker-compose.gpu.yml 在基础文件之上,其中:

  • 集合 GPU_INFERENCE=true → 农业用途 device="auto" (决议给CUDA)
  • 为Docker构建设置CUDA PyTorch轮索引
  • 为容器保留一个NVIDIA GPU

验证GPU是否处于活动状态:

docker exec weather-forecast-mcp-agent-1 python -c "import torch; print(torch.cuda.is_available())"
# Expected: True

在启动时检查代理日志以确认设备:

docker compose logs agent | grep "Inference device"
# Expected: Inference device: auto (GPU_INFERENCE=true)

已知约束

约束 详细信息
AOI大小 点周围0.02°缓冲区(约2.2公里)——FTW 256px补丁要求的最小值
LULC过滤器 如果谷歌动态世界作物概率<0.3,则删除多边形——城市和森林地区将返回0个字段
缓存 Sentinel-2复合缓存在 /tmp/.agribound_cache/;每次运行前清除,以避免结果过时
工人 n_workers=0 是必需的--Docker中的分叉DataLoader进程不能继承CUDA上下文
作物分类 未执行--输出 crop_type 总是 "Unknown"

提取原始卫星复合材料

成功描绘后,Sentinel-2复合体保存在容器内:

/tmp/patches/{lat}_{lon}/sentinel2_composite.tif   ← GeoTIFF with CRS + transform
/tmp/patches/{lat}_{lon}/sentinel2_composite.npy   ← numpy array, shape (12, H, W), float32

复制到主机:

./get_patches.sh              # copies to ./patches/
./get_patches.sh ~/my_patches # custom output dir

在Python中加载:

import rasterio, numpy as np

# With spatial metadata (CRS, pixel size, bounding box)
with rasterio.open("patches/30.900000_75.500000/sentinel2_composite.tif") as src:
    arr = src.read()        # shape: (12, H, W) — S2 bands B1..B12
    transform = src.transform

# Plain numpy
arr = np.load("patches/30.900000_75.500000/sentinel2_composite.npy")

Sentinel-2波段(按顺序):B1、B2、B3、B4、B5、B6、B7、B8、B8A、B9、B11、B12