Dify如何调用工具

Dify如何调用工具

1.Function Call介绍

2023年6月13日OpenAI公布了Function Call(函数调用)功能,该功能指的是在语言模型中集成外部功能或API的调用能力,这意味着模型可以在生成文本的过程中调用外部函数或服务,获取额外的数据或执行特定的任务。

2.为什么需要应用插件工具

  • 信息的实时性

  • 数据局限性

  • 功能扩展性

3.Function Call的应用

(1)方法一:第三方插件——时间

可以自己在Dify市场下载需要的工具

①先创建一个Agent

②添加工具

当直接问大模型时间时,大模型不能给出答案。

这时需要添加第三方插件时间,并且选择获取当前时间

然后设置添加的工具选择时区,就能获取准确的时间了。

(2)方法二:自定义插件——天气查询
①Fast API服务搭建

安装依赖

# 安装依赖 pip install fastapi uvicorn requests

天气查询工具的完整代码

from fastapi import FastAPI, Request, HTTPException from pydantic import BaseModel import requests ​ app = FastAPI() ​ # 身份验证令牌(个人使用,简单安全) VALID_TOKEN = "difyweather" ​ # 城市编码数据(直接硬编码,无需外部文件) CITY_CODES = { "北京": "101010100", "上海": "101020100", "广州": "101280101", "深圳": "101280601", "杭州": "101210101", "成都": "101270101", "武汉": "101200101", "西安": "101110101", "南京": "101190101", "重庆": "101040100", "天津": "101030100", "苏州": "101190401", "郑州": "101180101", "长沙": "101250101", "青岛": "101120201", "大连": "101070201", "宁波": "101210401", "厦门": "101230201", "福州": "101230101", "济南": "101120101", "合肥": "101220101", "南昌": "101240101", "昆明": "101290101", "南宁": "101300101", "贵阳": "101260101", "哈尔滨": "101050101", "长春": "101060101", "沈阳": "101070101", "石家庄": "101090101", "太原": "101100101", "呼和浩特": "101080101", "乌鲁木齐": "101130101", "拉萨": "101140101", "兰州": "101110501", "西宁": "101150101", "银川": "101170101", "海口": "101310101", "三亚": "101310201" } ​ class WeatherRequest(BaseModel): location: str ​ @app.post("/weather") def get_current_weather(request: Request, body: WeatherRequest): """ 天气查询接口 - 需要Authorization头认证 - 返回自然语言格式的天气信息 """ # 1. 验证身份 auth_header = request.headers.get("Authorization") if auth_header != f"Bearer {VALID_TOKEN}": raise HTTPException(status_code=403, detail="Invalid Authorization header") location = body.location # 2. 查找城市编码 city_code = CITY_CODES.get(location) if not city_code: return { "status": "error", "message": f"请提供{location}对应的编码方可查询,目前支持的城市:{','.join(CITY_CODES.keys())}" } # 3. 调用天气API url = f"http://t.weather.itboy.net/api/weather/city/{city_code}" try: response = requests.get(url, timeout=10) response.raise_for_status() data = response.json() except Exception as e: return {"status": "error", "message": f"天气服务请求失败: {str(e)}"} # 4. 解析天气数据 try: forecast = data["data"]["forecast"][0] weather_type = forecast["type"] high = forecast["high"].replace("高温 ", "") low = forecast["low"].replace("低温 ", "") temperature = f"{high}/{low}" # 5. 返回自然语言格式 return f"{location}今天是{weather_type},温度{temperature}" except (KeyError, IndexError) as e: return {"status": "error", "message": f"天气数据解析失败: {str(e)}"} ​ # 启动入口 if __name__ == "__main__": import uvicorn uvicorn.run(app, host="0.0.0.0", port=8081)

✅ 预期输出:

INFO:Uvicorn running on http://0.0.0.0:8081 (Press CTRL+C to quit)

②公网穿透配置

安装Node.js

https://nodejs.org/

安装 localtunnel

# 全局安装 npm install -g localtunnel

启动穿透服务

# 新开一个终端窗口 lt --port 8081

✅ 预期输出:

your url is: https://cold-sheep-smoke.loca.lt

⚠️重要:保持这个终端窗口开启,关闭后链接失效

③服务测试验证

Postman 测试

1.创建 POST 请求 2.URL: https://cold-sheep-smoke.loca.lt/weather 3.Headers: Authorization: Bearer itcast Content-Type: application/json 4.Body (raw, JSON): {"location": "成都"}

④Dify插件配置

url修改成自己的

{ "openapi": "3.1.0", "info": { "title": "天气查询API", "description": "查询中国城市当前天气信息", "version": "v1.0.0" }, "servers": [ { "url": "https://cold-sheep-smoke.loca.lt" } ], "paths": { "/weather": { "post": { "summary": "查询城市天气", "security": [ { "BearerAuth": [] } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "properties": { "location": { "type": "string", "description": "城市名称", "example": "北京" } }, "required": ["location"] } } } }, "responses": { "200": { "description": "成功获取天气信息" } } } } }, "components": { "schemas": {}, "securitySchemes": { "BearerAuth": { "type": "http", "scheme": "bearer" } } } }

点击授权方法——鉴权类型(请求头)——鉴权头部前缀(Bearer)——值(difyweather)——保存

点击测试输入城市名称查看测试结果,并把标签改成天气,最后保存就ok

创建支持天气查询的Agent

⑤故障排除指南

常见问题及解决方案

问题现象原因分析解决方案
Reached maximum retriesDify无法访问localhost必须使用公网URL,不能用localhost
{"detail":"Not Found"}路由路径错误检查代码中是@app.post("/weather")
403 Forbiddentoken不匹配确认VALID_TOKEN = "itcast"和Dify配置一致
连接超时localtunnel断开重启lt --port 8081,更新Dify中的URL
城市未找到城市不在CITY_CODES中在代码中添加该城市编码

快速诊断命令

# 1. 检查服务是否运行 lsof -i :8081 # Mac/Linux netstat -ano \| findstr 8081 # Windows ​ # 2. 检查公网可达性 curl -I https://your-url.loca.lt ​ # 3. 完整测试命令 curl -X POST https://your-url.loca.lt/weather \ -H "Authorization: Bearer itcast" \ -H "Content-Type: application/json" \ -d '{"location": "杭州"}'
⑥维护与优化建议

临时方案(日常使用)

  • 保持终端开启:两个终端(FastAPI + localtunnel)需要一直运行

  • 每日重启:local tunnel 链接24小时后可能失效,每天重启一次

  • 快速更新URL:创建一个脚本自动更新Dify配置

永久方案(推荐升级)

# 部署到免费云服务(Render.com示例) # 1. 创建render.com账号 # 2. 创建Web Service # 3. 连接GitHub仓库 # 4. 设置环境变量(如果需要) # 5. 部署完成,获取永久URL

功能扩展

  • 添加更多城市:在CITY_CODES字典中添加新城市

  • 丰富天气信息:返回湿度、风力等更多字段

  • 错误重试机制:添加请求重试逻辑

  • 缓存机制:避免频繁请求天气API