AI Agent(七)- Dify 自定义工具实战 - 云南省历史天气查询助手

文章目录

  • 前言
  • 一、实战背景与整体架构
    • [1.1 需求场景](#1.1 需求场景)
    • [1.2 整体技术架构](#1.2 整体技术架构)
  • 二、数据集与数据库准备
    • [2.1 数据集字段说明](#2.1 数据集字段说明)
    • [2.2 SQLite数据库存储](#2.2 SQLite数据库存储)
  • 三、FastAPI接口开发:提供数据查询能力
    • [3.1 接口核心设计思路](#3.1 接口核心设计思路)
    • [3.2 完整接口代码(selectapi.py)](#3.2 完整接口代码(selectapi.py))
    • [3.3 接口启动与测试](#3.3 接口启动与测试)
      • [3.3.1 接口启动](#3.3.1 接口启动)
      • [3.3.2 接口文档](#3.3.2 接口文档)
      • [3.3.3 接口测试](#3.3.3 接口测试)
  • 四、OpenAPI规范编写:对接Dify自定义工具
    • [4.1 完整OpenAPI配置(openapi.json)](#4.1 完整OpenAPI配置(openapi.json))
    • [4.2 OpenAPI配置解释](#4.2 OpenAPI配置解释)
      • [4.2.1 顶层基础信息](#4.2.1 顶层基础信息)
      • [4.2.2 `info` 对象详情](#4.2.2 info 对象详情)
      • [4.2.3 `servers` 数组详情](#4.2.3 servers 数组详情)
      • [4.2.4 `paths` 对象详情](#4.2.4 paths 对象详情)
      • [4.2.5 `parameters` 数组中的参数详情](#4.2.5 parameters 数组中的参数详情)
      • [4.2.6 `responses` 对象详情](#4.2.6 responses 对象详情)
      • [4.2.7 `components` 对象详情](#4.2.7 components 对象详情)
  • 五、内网穿透:贝锐花生壳实现外网访问
    • [5.1 下载并安装贝锐花生壳客户端](#5.1 下载并安装贝锐花生壳客户端)
      • [5.1.1 下载贝锐花生壳](#5.1.1 下载贝锐花生壳)
      • [5.1.2 安装贝锐花生壳](#5.1.2 安装贝锐花生壳)
    • [5.2 新增映射](#5.2 新增映射)
    • [5.3 验证外网访问](#5.3 验证外网访问)
  • 六、Dify自定义工具与Agent配置
    • [6.1 创建自定义工具](#6.1 创建自定义工具)
    • [6.2 配置AI Agent](#6.2 配置AI Agent)
      • [6.2.1 新建Agent](#6.2.1 新建Agent)
      • [6.2.2 设置系统提示词](#6.2.2 设置系统提示词)
      • [6.2.3 添加工具](#6.2.3 添加工具)
      • [6.2.4 Agent测试](#6.2.4 Agent测试)
      • [6.2.5 发布](#6.2.5 发布)

前言

在AI Agent的落地实践中,自定义工具是核心能力之一------通过对接自有数据和业务接口,能让Agent具备解决特定场景问题的能力。本文将以「云南省历史天气查询助手」为例,完整讲解如何基于Dify平台开发自定义工具,对接FastAPI开发的天气查询接口,最终实现一个能精准查询云南各城市历史天气的AI Agent。

一、实战背景与整体架构

1.1 需求场景

我们拥有2015-2025年云南省各城市的历史天气数据集(包含城市、日期、昼夜天气状况、气温、风向风力等维度),需要基于该数据搭建AI Agent,让用户能通过自然语言查询任意城市、任意时间段的历史天气数据。

1.2 整体技术架构

整个实战流程分为5个核心环节:

  1. 数据集准备:基于SQLite存储结构化天气数据;
  2. 接口开发:FastAPI开发天气查询接口,提供精准的数据查询能力;
  3. 自定义工具:在Dify中基于OpenAPI规范创建「云南历史天气查询」工具;
  4. 内网穿透:通过贝锐花生壳实现内网接口的外网访问;
  5. Agent配置:组合工具、Prompt,测试并发布可用的AI Agent。

二、数据集与数据库准备

2.1 数据集字段说明

本次使用的云南省历史天气数据集(云南天气数据.csv)包含以下核心字段,覆盖天气核心维度:

字段名 字段说明 示例值
city 城市名称 昆明市
date 日期 2025年06月24日
type_day 白天天气状况
type_night 夜晚天气状况 多云
max_temperature 当日最高气温 28℃
min_temperature 当日最低气温 18℃
direction_day 白天风向 南风
wind_force_day 白天风力 3级
direction_night 夜晚风向 东南风
wind_force_night 夜晚风力 2级

2.2 SQLite数据库存储

将上述结构化数据导入SQLite数据库,数据库文件路径为 D:\ProjectCode\yunnan-weather-data-analysis\db\weather.db,数据表名定义为 original_weather_data。SQLite无需额外部署服务,轻量且适配小型数据集的查询需求。

python 复制代码
import pandas as pd
from sqlalchemy import create_engine

# 1. 读取 CSV 文件
df = pd.read_csv("../data/云南天气数据.csv", encoding='utf-8-sig')

# 2. 创建 SQLite 数据库连接引擎
# 如果数据库文件不存在,会自动创建;'weather.db' 是数据库文件名
engine = create_engine('sqlite:///../db/weather.db')

# 3. 将 DataFrame 保存到 SQLite 数据库中
df.to_sql(
    name='original_weather_data',  # 数据库中的表名
    con=engine,  # 数据库连接引擎
    if_exists='replace',  # 如果表已存在:'replace'(替换), 'append'(追加), 'fail'(报错)
    index=False  # 不将 DataFrame 的索引作为数据库表的一列
)

print("数据已成功保存到 SQLite 数据库!")

保存后的数据如下图所示:

三、FastAPI接口开发:提供数据查询能力

3.1 接口核心设计思路

接口需满足两种查询模式,且保证参数合法性:

  • 精确多日期查询:传入单个/多个具体日期,查询指定日期的天气;
  • 日期区间查询:传入起止日期,查询区间内所有天气数据;
  • 接口鉴权:通过API Key校验,防止接口被非法调用;
  • 参数互斥校验:两种查询模式不可同时使用,且必须传入日期相关参数。

3.2 完整接口代码(selectapi.py

python 复制代码
# 导入类型注解工具
from typing import List, Union, Optional

# 导入FastAPI核心组件
from fastapi import FastAPI, Query, HTTPException, Depends
# 导入SQLAlchemy数据库操作相关
from sqlalchemy import create_engine, text
from sqlalchemy.orm import sessionmaker, Session

# ===================== 项目配置区 =====================
# SQLite数据库本地文件绝对路径
DB_PATH = r"D:\ProjectCode\yunnan-weather-data-analysis\db\weather.db"
# 构造SQLite数据库连接地址
engine = create_engine(f"sqlite:///{DB_PATH}", connect_args={"check_same_thread": False})
# 创建数据库会话工厂,用于生成数据库连接会话
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
# 接口访问密钥,请求时必须携带正确key才能调用
VALID_API_KEY = "weather123456"
# 数据库中存储天气数据的表名
TABLE_NAME = "original_weather_data"

# 实例化FastAPI应用,配置接口文档标题、版本
app = FastAPI(title="云南天气查询接口", version="1.0")


# ===================== 数据库公共依赖函数 =====================
def get_db() -> Session:
    """
    获取数据库会话依赖
    每次接口请求自动创建数据库连接,请求结束自动关闭连接,避免连接泄漏
    """
    # 创建数据库会话
    db = SessionLocal()
    try:
        # 将会话提供给接口使用;暂停,把db交给接口使用
        # 返回数据 → 函数暂停,保存当前状态;等外部逻辑执行完,再回到 yield 之后继续运行代码
        yield db
    finally:
        # 请求执行完毕后关闭数据库会话
        db.close()


# ===================== 接口鉴权依赖函数 =====================
# ...表示标记该查询参数为必填项,缺失直接拦截请求。
# Query 是 FastAPI 提供的类,用来声明URL 查询参数(就是地址里 ?key=xxx 这部分参数)。
def check_key(api_key: str = Query(...)):
    """
    全局接口鉴权校验依赖
    从请求参数中读取api_key,校验密钥合法性,非法密钥直接抛出401错误
    :param api_key: 请求传入的访问密钥,必填参数
    """
    if api_key != VALID_API_KEY:
        # 密钥不匹配,抛出未授权异常
        raise HTTPException(status_code=401, detail="无效api_key,禁止访问")


# ===================== 天气数据查询主接口 =====================
@app.get("/api/weather/query")
def query_weather(
        # Depends() 是 FastAPI 的依赖注入工具。
        # 简单说:把一段通用逻辑抽成单独函数,接口函数不用自己写一遍,用 Depends 自动执行、自动传参。
        # 依赖鉴权函数,接口调用前先校验api_key
        _key: None = Depends(check_key),
        # 依赖数据库会话,提供数据库操作对象
        db: Session = Depends(get_db),
        # 查询城市名称,必填,需与数据库内城市名称完全一致
        city: str = Query(..., description="云南省城市名称,需与数据库数据完全匹配"),
        # 多日期精确查询参数,支持单个/多个日期,格式:xxxx年xx月xx日
        date: Optional[Union[str, List[str]]] = Query(None,
                                                      description="指定单个或多个精确日期,格式示例:2026年06月24日,多日期重复传参"),
        # 日期区间起始日期,和date参数互斥,不可同时使用
        start_date: Optional[str] = Query(None, description="日期区间起始时间,格式xxxx年xx月xx日,与date参数二选一"),
        # 日期区间结束日期,和date参数互斥,不可同时使用
        end_date: Optional[str] = Query(None, description="日期区间结束时间,格式xxxx年xx月xx日,与date参数二选一")
):
    """
    天气数据查询接口
    两种查询模式二选一,不可混合传参:
    1. 精确多日期查询:传递date参数,可传多个日期值
    2. 日期范围区间查询:传递start_date + end_date,查询区间内全部天气数据
    日期统一格式:xxxx年xx月xx日,必须和数据库存储格式完全一致
    """
    # 判断是否传入多日期参数
    has_date_list = date is not None
    # 判断是否完整传入起止日期区间参数
    has_range = start_date is not None and end_date is not None

    # 规则1:两种查询方式不能同时传入,参数冲突报错
    if has_date_list and has_range:
        raise HTTPException(status_code=400, detail="仅支持【多日期】或【起止日期区间】其中一种查询方式,不可同时传入")
    # 规则2:必须传入日期相关参数,否则无法查询
    if not has_date_list and not has_range:
        raise HTTPException(status_code=400, detail="必须传入date列表 或 start_date+end_date日期区间")

    # 分支1:多精确日期 IN 查询逻辑
    if has_date_list:
        # 统一转为列表,兼容单日期/多日期传参
        date_list = date if isinstance(date, list) else [date]
        # 拼接SQL占位符,动态适配不定数量的日期
        placeholders = ",".join([f":d{i}" for i in range(len(date_list))])
        # 构造查询SQL语句
        sql = text(f"SELECT * FROM {TABLE_NAME} WHERE city = :city AND date IN ({placeholders})")
        # 组装SQL参数
        params = {"city": city}
        params.update({f"d{i}": v for i, v in enumerate(date_list)})
        # 执行SQL并获取全部查询结果
        rows = db.execute(sql, params).fetchall()
    # 分支2:日期区间 BETWEEN 查询逻辑
    else:
        # 区间查询SQL,匹配起止日期内所有数据
        sql = text(f"SELECT * FROM {TABLE_NAME} WHERE city = :city AND date BETWEEN :s AND :e")
        # 组装城市、起始、结束日期参数
        params = {"city": city, "s": start_date, "e": end_date}
        # 执行SQL并获取全部查询结果
        rows = db.execute(sql, params).fetchall()

    # 校验:无匹配数据时返回404提示
    if not rows:
        raise HTTPException(status_code=404, detail=f"{city} 指定日期无天气数据")

    # 将数据库行对象转换为标准字典列表,接口自动返回JSON格式
    result = []
    for row in rows:
        result.append({
            "city": row.city,  # 城市名称
            "date": row.date,  # 日期(xxxx年xx月xx日)
            "type_day": row.type_day,  # 白天天气状况
            "type_night": row.type_night,  # 夜晚天气状况
            "max_temperature": row.max_temperature,  # 当日最高气温
            "min_temperature": row.min_temperature,  # 当日最低气温
            "direction_day": row.direction_day,  # 白天风向
            "wind_force_day": row.wind_force_day,  # 白天风力
            "direction_night": row.direction_night,  # 夜晚风向
            "wind_force_night": row.wind_force_night  # 夜晚风力
        })
    # 返回处理完成的天气数据列表
    return result


# ===================== 服务启动入口 =====================
if __name__ == "__main__":
    import uvicorn

    """
    启动uvicorn服务
    selectapi:app:当前文件名为selectapi.py,app为FastAPI实例对象
    host=0.0.0.0:允许局域网、本地访问接口
    port=8000:服务占用端口8000
    reload=True:开启热重载,代码修改自动重启服务(开发环境使用)
    """
    uvicorn.run("selectapi:app", host="0.0.0.0", port=8000, reload=True)

3.3 接口启动与测试

3.3.1 接口启动

运行 selectapi.py 启动FastAPI服务,服务默认监听 0.0.0.0:8000,如下图所示。

3.3.2 接口文档

访问 http://127.0.0.1:8000/docs 查看自动生成的Swagger文档,如下图所示。

Swagger文档支持接口在线调试,如下图所示。

测试结果如下图所示,从图中可以看到已经成功获取到数据。

3.3.3 接口测试

  • 测试示例(精确日期查询):

    复制代码
    http://localhost:8000/api/weather/query?api_key=weather123456&city=昆明&date=2025年06月25日
  • 测试示例(区间查询):

    复制代码
    http://localhost:8000/api/weather/query?api_key=weather123456&city=昆明&start_date=2025年06月01日&end_date=2025年06月10日

四、OpenAPI规范编写:对接Dify自定义工具

为了让Dify能识别并调用上述接口,需要编写符合OpenAPI 3.1.0规范的配置文件(openapi.json),核心是定义接口路径、参数、响应格式等信息。

4.1 完整OpenAPI配置(openapi.json)

json 复制代码
{
  "openapi": "3.1.0",
  "info": {
    "title": "云南天气查询接口",
    "version": "1.0"
  },
  "servers": [
    {
      "url": "http://7ep38004bq85.vicp.fun:39972"
    }
  ],
  "paths": {
    "/api/weather/query": {
      "get": {
        "summary": "Query Weather",
        "description": "天气数据查询接口\n两种查询模式二选一,不可混合传参:\n1. 精确多日期查询:传递date参数,可传多个日期值\n2. 日期范围区间查询:传递start_date + end_date,查询区间内全部天气数据\n日期统一格式:xxxx年xx月xx日,必须和数据库存储格式完全一致",
        "operationId": "query_weather_api_weather_query_get",
        "parameters": [
          {
            "name": "city",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "description": "云南省城市名称,需与数据库数据完全匹配",
              "title": "City"
            },
            "description": "云南省城市名称,需与数据库数据完全匹配"
          },
          {
            "name": "date",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                },
                {
                  "type": "null"
                }
              ],
              "description": "指定单个或多个精确日期,格式示例:2026年06月24日,多日期重复传参",
              "title": "Date"
            },
            "description": "指定单个或多个精确日期,格式示例:2026年06月24日,多日期重复传参"
          },
          {
            "name": "start_date",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "日期区间起始时间,格式xxxx年xx月xx日,与date参数二选一",
              "title": "Start Date"
            },
            "description": "日期区间起始时间,格式xxxx年xx月xx日,与date参数二选一"
          },
          {
            "name": "end_date",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "日期区间结束时间,格式xxxx年xx月xx日,与date参数二选一",
              "title": "End Date"
            },
            "description": "日期区间结束时间,格式xxxx年xx月xx日,与date参数二选一"
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {

                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "HTTPValidationError": {
        "properties": {
          "detail": {
            "items": {
              "$ref": "#/components/schemas/ValidationError"
            },
            "type": "array",
            "title": "Detail"
          }
        },
        "type": "object",
        "title": "HTTPValidationError"
      },
      "ValidationError": {
        "properties": {
          "loc": {
            "items": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "integer"
                }
              ]
            },
            "type": "array",
            "title": "Location"
          },
          "msg": {
            "type": "string",
            "title": "Message"
          },
          "type": {
            "type": "string",
            "title": "Error Type"
          }
        },
        "type": "object",
        "required": [
          "loc",
          "msg",
          "type"
        ],
        "title": "ValidationError"
      }
    }
  }
}

4.2 OpenAPI配置解释

4.2.1 顶层基础信息

键名 (Key) 值/类型 解释说明
openapi 3.1.0 声明当前文档遵循的 OpenAPI 规范版本号。
info Object 包含 API 的元数据(如标题、版本等)。
servers Array 提供 API 服务器的基础 URL 列表,客户端请求时会拼接此地址。
paths Object 核心部分。定义 API 的所有可用端点(路由)及其对应的 HTTP 方法。
components Object 存放可复用的组件(如数据模型/Schema、安全方案等),避免在 paths 中重复定义。

4.2.2 info 对象详情

键名 (Key) 值/类型 解释说明
title 云南天气查询接口 API 的名称。
version 1.0 API 的版本号。

4.2.3 servers 数组详情

键名 (Key) 值/类型 解释说明
url http://7ep38004bq85.vicp.fun:39972 该天气查询 API 的实际服务地址。

4.2.4 paths 对象详情

键名 (Key) 值/类型 解释说明
/api/weather/query Object 具体的请求路径(Endpoint)。
get Object 该路径支持的 HTTP 方法(此处为 GET 请求)。
summary Query Weather 接口的简短摘要。
description 天气数据查询接口... 接口的详细描述,说明了两种查询模式及日期格式要求。
operationId query_weather_api_weather_query_get 用于代码生成工具的唯一操作 ID,通常作为生成函数的名称。
parameters Array 定义该接口接收的所有请求参数(Query 参数)。
responses Object 定义该接口可能返回的 HTTP 状态码及对应的数据结构。

4.2.5 parameters 数组中的参数详情

键名 (Key) 值/类型 解释说明
name city / date / start_date / end_date 参数的名称。
in query 参数传递的位置,这里表示通过 URL 的查询字符串(?key=value)传递。
required true / false 该参数是否为必填项(如 city 必填,日期参数选填)。
schema Object 定义参数的数据类型(如 string, array, null)及格式要求。
description 云南省城市名称... 对该参数具体含义和格式要求的补充说明。

4.2.6 responses 对象详情

键名 (Key) 值/类型 解释说明
200 Object 表示请求成功时的响应定义。
422 Object 表示请求参数校验失败(Unprocessable Entity)时的响应定义。
description Successful Response / Validation Error 响应状态的文字描述。
content Object 定义响应体的数据格式(如 application/json)及对应的数据结构(schema)。

4.2.7 components 对象详情

键名 (Key) 值/类型 解释说明
schemas Object 存放可复用的数据模型定义。
HTTPValidationError Object 定义 422 错误时的返回结构,包含一个 detail 数组。
ValidationError Object 定义单个校验错误的具体结构。
detail Array 包含一个或多个 ValidationError 对象的列表。
loc Array 错误发生的位置(如哪个参数出了问题)。
msg String 具体的错误提示信息。
type String 错误的类型标识。
properties Object 定义该模型包含的所有字段及其类型。
required Array 列出该模型中必须存在的字段名。
title String 模型的显示名称。
$ref String JSON 引用语法,指向 components/schemas 中定义的另一个模型,实现复用。

五、内网穿透:贝锐花生壳实现外网访问

由于FastAPI服务部署在内网,Dify平台无法直接访问,需通过贝锐花生壳实现内网穿透:

5.1 下载并安装贝锐花生壳客户端

5.1.1 下载贝锐花生壳

打开浏览器访问贝锐花生壳官方下载地址 https://hsk.oray.com/download,页面自动展示适配Windows系统的花生壳9客户端,直接点击红色「免费下载」按钮获取安装包,安装登录后即可配置内网穿透映射,将本地8000端口的FastAPI服务暴露至公网供Dify调用。

5.1.2 安装贝锐花生壳

下载完成后在浏览器下载目录找到安装包 HskDDNS_9.4.0.1320.exe,双击该应用程序文件,跟随安装向导完成花生壳客户端本地安装。

5.2 新增映射

登录花生壳客户端并切换至「内网穿透」页面,在自定义映射区域点击右上角加号按钮,打开新增映射配置页面,用于创建FastAPI服务对应的外网穿透规则。

在映射配置页面填写参数:内网主机填写本机局域网IP、内网端口填写FastAPI服务端口8000,映射协议选择HTTP,自定义外网域名与端口,映射名称填写「云南历史天气查询」,全部参数填写完成后点击确定保存映射规则。

保存配置后返回内网穿透首页,开启映射开关,右侧诊断信息全部显示连接、解析成功,代表内网8000端口的天气接口已成功映射为公网地址,可在外网环境访问接口。

5.3 验证外网访问

通过外网地址访问接口文档 http://设置的外网地址/docs,能正常打开则说明穿透成功。

六、Dify自定义工具与Agent配置

6.1 创建自定义工具

进入Dify自定义工具创建页面,工具名称填写「云南历史天气查询」,粘贴完整openapi.json规范文本;点击鉴权配置按钮,鉴权类型选择查询参数,参数名填写api_key、值填入接口密钥weather123456并保存;随后打开工具测试面板,输入城市与目标日期参数,点击测试按钮,页面成功返回对应历史天气数据,代表自定义工具对接接口正常可用。

6.2 配置AI Agent

6.2.1 新建Agent

6.2.2 设置系统提示词

复制代码
【角色设定】
你是一位专业、严谨且亲切的"云南省历史天气查询助手"。你精通云南省各城市的气象历史数据,能够准确理解用户的自然语言查询需求,并将其转化为对底层天气查询接口的精准调用。你的核心使命是为用户提供准确、清晰、结构化的历史天气信息,并在必要时提供友好的引导与异常处理。
【任务指令】
意图识别与参数提取:仔细分析用户的输入,提取出关键查询要素,包括"城市名称"和"日期/日期范围"。
城市名称:城市名词不包含"市",例如:用户输入"昆明市",应转为"昆明"。
日期格式转换:将用户口语化或多样化的日期表达(如"去年五一"、"上个月15号"、"最近三天"等)统一转换为接口要求的标准格式:"xxxx年xx月xx日"。若用户未提供具体日期,默认查询今天。若格式不是标准的"xxxx年xx月xx日",你需要自动转为标准格式;例如:2020年1月1日应转为2020年01月01日。
智能选择查询模式:根据提取到的日期信息,严格遵守以下两种查询模式的互斥规则:
精确多日期查询:当用户指定了具体的、不连续的多个日期时,仅传递 date 参数(支持数组形式)。
日期范围区间查询:当用户查询一个连续的时间段时,仅传递 start_date 和 end_date 参数。
绝对禁止同时传递 date 与 start_date/end_date 参数。
工具调用:根据上述逻辑,构造并执行 query_weather_api_weather_query_get 接口调用。
信息整合与回复:获取接口返回的天气数据后,结合用户的原始问题,生成易于阅读、信息完整的自然语言回复。
【限制要求】
地域限制:本助手仅支持查询云南省内的城市天气。若用户查询非云南省城市,需礼貌告知并说明服务范围。
参数格式限制:所有日期参数必须严格遵循"xxxx年xx月xx日"的格式,任何偏差都可能导致接口报错。
查询模式限制:必须严格遵守 date 与 start_date+end_date 二选一的规则,不可混合传参。
异常处理:
若接口返回 422 Validation Error,应检查参数格式或查询模式是否正确,并尝试修正后重新调用。若仍失败,向用户说明查询失败的原因。
若用户提供的城市名称不精确(如"大理"而非"大理白族自治州"),应尝试模糊匹配或引导用户提供更准确的名称。
若查询结果为空,应告知用户未找到相关历史记录。
回答边界:仅基于接口返回的天气数据进行回答,不编造、不推测任何未提供的信息。对于超出天气查询范畴的问题,应礼貌拒绝并重申自身功能。
【输出格式】
结构化呈现:回复内容应条理清晰,推荐使用列表或表格形式展示多日天气数据。
核心信息包含:每次回复必须包含以下要素:
查询的城市名称。
查询的日期或日期范围。
天气状况(如:晴、多云、小雨等)。
气温范围(最高温/最低温)。
友好提示:在回复末尾,可根据天气情况提供一句简短的、基于历史数据的温馨提示(例如:"历史数据显示该日温差较大,请注意增减衣物。")。
格式示例:
为您查询到 昆明市 在 2025年06月20日 的历史天气如下:
天气状况:多云转晴
气温范围:18℃ ~ 26℃
温馨提示:当日天气较为舒适,但早晚温差明显,外出建议备一件薄外套。

6.2.3 添加工具

6.2.4 Agent测试

6.2.5 发布