使用说明
天气预报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
核心组件
-
大语言模型智能体 (
services/agent/)- 使用Google Gemini处理用户查询
- 检测背景(农民与公民)
- 提取地区名称和预测天数
- 生成自然语言解释
-
自定义MCP服务器 (
services/agent/mcp_weather/)retrieve_weather_forecast_by_district:按地区名称删除BMD WRF表- 处理孟加拉语和英语地区名称
- 返回具有3个以上参数的结构化天气数据
-
前端 (
frontend/)- React+Mapbox GL JS接口
- 自然语言查询输入
- 可视化预测显示
🚀 快速开始
先决条件
设置
-
克隆存储库
git clone https://github.com/Sgt-Hashtag/weather-forecast-mcp.git cd weather-forecast-mcp -
配置环境变量
cp .env.example .env # Edit .env with your API keys nano .env -
构建和启动服务
docker compose up --build -d -
访问应用程序 打开 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+所需参数:
- 温度:最低/最高摄氏度
- 降水:概率下的降雨量(单位:毫米)
- 湿度:百分比值
🧪 测试
运行端到端测试:
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%,适合日常活动。”
🛠️ 故障排除
常见问题
-
“NoneType对象不可下标”
- 原因:Mapbox MCP工具名称不匹配
- 解决方案:系统现在使用直接区域提取(无Mapbox依赖性)
-
BMD刮除失败
- 原因:SSL证书问题或URL格式
- 解决方案:用途
verify=False以及正确的URL格式
-
未找到地区
- 原因:拼写变化(吉大港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模式
要求:
- 配备CUDA 12.x驱动程序的NVIDIA GPU
- NVIDIA 容器工具包 已安装在主机上
步骤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