文章目录
- 博客详细讲解视频
- 点击查看高清脑图
- 1. 搭建天气查询http服务
- 1.1. flask代码
- 1.2. 接口优化方法
- 2. 生成openapi json schema
- 2.1. 测试接口
- 2.2. 生成openapi schema
- 3. 在dify中创建自定义工具
- 3.1. 导入schema
- 3.2. 设置工具认证信息
- 3.3. 测试工具
- 4. 调用工具
- 4.1. Agent应用中调用工具
- 4.1.1. 创建agent应用
- 4.1.2. 添加工具
- 4.1.3. 测试工具
- 4.2. 聊天助手工作流中调用工具
- 4.2.1. 创建工作流应用
博客详细讲解视频
点击查看高清脑图
我们以一个天气查询工具为例子,介绍如何在dify平台创建自定义工具
1. 搭建天气查询http服务
1.1. flask代码
我们使用flask搭建简单的http服务,代码如下
from flask import Flask, request, jsonify
import randomapp = Flask(__name__)@app.route('/weather', methods=['POST'])
def get_weather():auth_header = request.headers.get('Authorization')if auth_header != 'Bearer hanfangyuan':return {"msg": "Invalid Authorization header"}, 403city = request.json.get('city', None)if city is None:return jsonify({'status': 'error','errorInfo': 'No city provided','data': None})# 随机生成温度,风速和风向temperature = f'{random.randint(10, 20)}℃'windspeed = f'{random.randint(1, 5)}级' winddirect = random.choice(['北风', '南风', '西风', '东风']) # 随机选择风向# 返回JSON格式的响应# return jsonify({# 'status': 'OK',# 'errorInfo': None,# 'data': {# 'city': city,# 'temp': temperature,# 'windspeed': windspeed,# 'winddirect': winddirect# }# })# 返回对LLM友好的字符串格式的响应return f"{city}今天是晴天,温度{temperature}, 风速{windspeed}, 风向{winddirect}"if __name__ == '__main__':app.run(host='0.0.0.0',debug=False, port=4397)
1.2. 接口优化方法
在编写工具的http服务时我们有2个优化方向,即LLM调用友好和LLM理解友好,我在之前写的文章【LLMOps】如何借助AI实现智能客服有过介绍,下面我重新写一下:
LLM调用友好:多步骤整合
我们知道,调用哪些工具,以及根据工具的返回结果回答客户问题完全是依靠模型实现的。工具越多,工具调用的步骤越复杂,工具返回的结果越复杂,模型可能会出错。为了降低这个错误率,对模型的能力要求就会更高,同时模型的使用成本也会更高。为了避免这种情况,我们可以把多步骤的接口合并成一个,让AI模型直接调用。比如查询天气可能需要调用3个接口:鉴权、订阅、查询天气,如果直接让AI使用这三个工具,AI需要三个步骤才能获取到订单数据,对模型的要求就会升高,问题回答速度也会变慢。我们就可以把这三个接口合并成一个接口,对外提供服务。大多数情况,为了不影响原来的业务,我们可能无法改动这三个接口,所以我们可以专门做一个接口整合的服务,去中转这些复杂的接口,只提供给模型易用的接口。
LLM理解友好:自然语言式的返回结果
另外一个优化的方向是工具返回的结果,还是以天气查询接口为例,如果接口直接返回一个json结构,而且字段中都是英文缩写,AI可能根本无法理解这些字段的含义。一种方法是我们可以在提示词中预先告诉模型每个字段的含义,但是这样不够方便。最直接的方法是我们把接口返回的信息翻译成模型容易理解的文字,这样模型更容易理解这个结果。
2. 生成openapi json schema
2.1. 测试接口
在运行上述代码,搭建好天气查询服务后,我们首先需要测试一下这个接口,保证能够调通这个接口,可以利用ApiFox进行测试。
我首先把代码部署到我的服务器上,地址为https://weather.hanfangyuan.cn/weather,然后测试接口。
首先填写请求方法和地址,然后不要忘记填写认证的Authorization header
然后填写body,发送请求,确认接口正确返回数据
2.2. 生成openapi schema
- 接口测试无误后,我们按照下图方式导出接口curl命令
- 复制curl请求代码
- 利用gpt4把curl命令转为openapi schema
提示词如下
请把curl请求命令转成openapi 3.1.0 版本的json schema
<curl>
curl --location --request POST 'https://weather.hanfangyuan.cn/weather' \
--header 'Authorization: Bearer hanfangyuan' \
--header 'User-Agent: Apifox/1.0.0 (https://apifox.com)' \
--header 'Content-Type: application/json' \
--data-raw '{"city": "上海"
}'
</curl>
json schema请参照下面的例子
<json-schema>
{"openapi": "3.1.0","info": {"title": "Get weather data","description": "Retrieves current weather data for a location.","version": "v1.0.0"},"servers": [{"url": "https://weather.example.com"}],"paths": {"/location": {"get": {"description": "Get temperature for a specific location","operationId": "GetCurrentWeather","parameters": [{"name": "location","in": "query","description": "The city and state to retrieve the weather for","required": true,"schema": {"type": "string"}}],"deprecated": false}}},"components": {"schemas": {}}}
</json-schema>
生成的json结果如下
{"openapi": "3.1.0","info": {"title": "Weather Service API","description": "API for retrieving weather data for a specified city.","version": "1.0.0"},"servers": [{"url": "https://weather.hanfangyuan.cn"}],"paths": {"/weather": {"post": {"description": "Retrieve weather data for a specific city","operationId": "getWeatherData","requestBody": {"description": "City for which to fetch weather","required": true,"content": {"application/json": {"schema": {"type": "object","properties": {"city": {"type": "string","description": "Name of the city"}},"required": ["city"]}}}},"responses": {"200": {"description": "Successful response","content": {"application/json": {"schema": {"type": "object","properties": {"temperature": {"type": "number","description": "Current temperature in Celsius"},"description": {"type": "string","description": "Weather condition description"}}}}}}},"security": [{"bearerAuth": []}]}}},"components": {"securitySchemes": {"bearerAuth": {"type": "http","scheme": "bearer","bearerFormat": "JWT"}}}
}
这个open api schema包含了天气工具的作用、url地址、请求参数、参数的描述等信息,利用这些信息能够正确创建http请求,并且能够提供模型这个工具的作用,指导模型什么时候应该调用这个工具。
3. 在dify中创建自定义工具
3.1. 导入schema
- 进入dify工具页面
- 创建自定义工具
- 填写名称
- 填写生成的open api json schema
3.2. 设置工具认证信息
- 点击设置鉴权方法
- 鉴权类型 API Key
- 头部Bearer
- 键 Authorization
- 值 hanfangyuan
配置上面认证方法的依据是,我们在1.1 flask 的代码设置了鉴权,具体代码如下
def get_weather():auth_header = request.headers.get('Authorization')if auth_header != 'Bearer hanfangyuan':return {"msg": "Invalid Authorization header"}, 403
3.3. 测试工具
- 点击测试
- 填写参数值上海
- 点击测试
- 确认正常返回
测试正常后不要忘了点击右下角保存
4. 调用工具
4.1. Agent应用中调用工具
4.1.1. 创建agent应用
在工作室页面按照如下步骤创建agent类型应用
4.1.2. 添加工具
创建成功后按照如下步骤添加工具
4.1.3. 测试工具
工具添加完毕后,发送问题今天上海天气如何,可以看到成功调用工具,并返回结果。
4.2. 聊天助手工作流中调用工具
4.2.1. 创建工作流应用
- 工作室页面
- 创建空白应用
- 选择聊天助手
- 选择工作流编排
- 输入名称,工具调用-工作流
创建聊天工作流,在聊天工作流中调用工具