【Dify】掌握Function Calling和插件应用
在 Dify 中,如果说知识库是赋予了大模型“查阅资料”的能力,那么 Function Calling(函数调用) 和 插件应用(Plugins) 就是赋予了大模型“做出行动”和“连接世界”的能力。
比如说,我想要知道现在的时间,提示词和知识库都无法让ai本身去获取现在的时间,所以我们就需要插件了。

一、 什么是 Function Calling(函数调用)?
Function Calling 是大模型的一项高级底层能力。简单来说,就是让大模型自己决定在什么时候去调用什么工具。
1. 它是如何工作的?
你作为开发者,写好几个代码函数(比如一个叫 get_weather 的查天气函数,一个叫 send_email 的发邮件函数),然后把这些函数的“说明书”(包含函数名、功能描述、需要什么参数)打包塞给大模型。
当用户提问时,大模型会自己判断要不要用这些工具:
- 用户说:“帮我查查今天北京的天气,然后发邮件给张三。”
- 大模型思考:我靠自己的知识库不知道今天的实时天气。但我发现开发者给了我一个
get_weather的工具,参数需要city。 - 大模型输出:它不会直接回答天气,而是输出一段结构化代码(通常是 JSON 格式):“我决定调用
get_weather(city="北京"),请系统帮我执行。” - Dify 系统:在后台自动运行这个函数,拿到天气结果(例如:“北京晴,25度”),然后再把结果喂回给大模型。
- 大模型最终回答:“今天北京天气晴朗,25度。我已经为您准备好邮件……”(接着触发发邮件函数)。
2. 它的核心价值
- 连接实时世界:让本地或闭源的模型能够获取实时信息(查股票、查快递、查数据库)。
- 把控精准度:大模型做数学题经常算错,但你可以提供一个
calculator(计算器)函数,遇到数学题,大模型自己把数字传给计算器,由计算机执行绝对精准的计算。
二、 什么是插件应用(Plugins)?
如果说 Function Calling 是需要你懂一点编程、自己去写“工具说明书”的毛坯房;那么插件应用就是 Dify 已经为你装修好、开箱即用的精装房。
插件是 Dify 生态中封装好的、针对特定第三方服务的工具包。
1. 常见的插件有哪些?
在 Dify 的插件市场里,你可以看到各种各样的现成插件:
- Google Search / Bing Search 插件:联网搜索最新新闻。
- 飞书 / 钉钉 / Webhook 插件:向工作群或指定系统发送消息。
- Stable Diffusion / Midjourney 插件:让文字对话的模型具备直接画图的能力。
- Jina AI / Firecrawl 插件:输入一个网址,自动把网页内容抓取并清洗成干净的文本。
2. Dify 插件的优势
你完全不需要写任何代码,只需要在 Dify 界面里点“安装”,然后输入对应服务的 API Key(密钥),这个能力就立刻长在大模型身上了。
三、 两者的区别与联系
很多初学者容易把它们搞混,其实它们的本质关系是:“插件”的底层技术通常就是基于 “Function Calling” 实现的。
| 维度 | Function Calling (函数调用) | 插件应用 (Plugins) |
|---|---|---|
| 技术层级 | 属于大模型的底层原生能力。 | 属于在上层封装好的应用级产品。 |
| 开发门槛 | 较高。需要开发者自己写代码、定义 JSON Schema 格式。 | 极低(零代码)。在 Dify 商店里一键安装,配置账户即可。 |
| 灵活性 | 极高。你可以用它连接企业内部的任意私有 API、ERP 系统、数据库。 | 受限。只能使用插件市场里现有的,或者别人开发好的商业服务。 |
| 使用场景 | 适合深度定制。如:“根据用户问题,去公司内部数据库查询客户订单状态”。 | 适合常规通用任务。如:“去谷歌搜索科技新闻”、“把这段话生成一张图片”。 |
四、 使用Dify自带的插件
在 Dify 的 Agent(智能体) 或 Workflow(工作流) 模式下,你可以同时塞给大模型知识库、插件和自定义函数。
此时大模型的思考逻辑是:
- 遇到不懂的公司内部政策 ➡️ 去知识库里查;
- 遇到用户说“帮我搜一下2026年最新的科技趋势” ➡️ 调用谷歌搜索插件;
- 遇到用户说“把我刚才说的内容录入到我们公司的报销系统” ➡️ 触发你写好的 Function Calling。
这就是 Dify 让大模型从“聊天机器人”蜕变为“自动化 Agent”的关键所在。
选择创建空白应用,选择新手适用中的agent,然后我们会看到它比聊天助手多了个功能,就是工具。
选择添加工具Time,我们就可以看到ai能查到现在的时间了。

五,自定义插件
在 Dify 中,如果你想自己定义一个插件来连接公司内部的系统(如 ERP、CRM)或者特定的 API 接口,有两种途径。
第一种是最简单、在网页界面就能直接搞定的 “自定义工具 (Custom Tool)”(它的本质就是让你用声明的方式实现 Function Calling);
第二种是真正的本地插件开发(适合想写代码、发布到 Dify 插件市场供大家下载的开发者)。
1.在 Dify 界面直接创建“自定义工具”(推荐)
这种方法不需要你写复杂的插件脚手架,只需要你准备好一个可用的 API 接口,并在 Dify 网页里用 OpenAPI / Swagger 规范(YAML 或 JSON) 把这个接口描述出来。
我们以做一个天气查询助手为例。
大模型(或者说Dify)本身是不知道实时天气的,它必须通过 Python 写的一个“传声筒”,去问专业的天气网站,再把结果听懂并组织成语言。
1. 接口 (API)
是什么: 接口就是“服务窗口”。比如你去银行取钱,柜台就是接口。在程序里,天气网站(如高德地图、和风天气)提供一个网址,你把城市名传过去,它把天气数据(JSON格式)扔回来。
为什么要它: 我们的 Python 后端不是气象局,没有气象卫星,必须调用第三方专业的天气接口来获取真实数据。
2. Python 后端服务 (Webhook / API Service)
是什么: 它是你亲手写的代码。它负责接收来自 Dify 的请求(比如:“查北京的天气”),然后把请求转发给天气接口,拿到数据后再清洗、打包,最后回传给 Dify。
为什么要它: Dify 不能直接和所有的第三方天气接口完美对接,你的 Python 服务就像一个“翻译官”和“中转站”。
3. 公网穿透 (内网穿透,如 ngrok, cwork, cpolar)
是什么: 你的 Python 代码运行在自己的电脑(局域网/内网)上,它的地址通常是 http://127.0.0.1:5000。这个地址只有你自己的电脑能访问。而 Dify 的服务器在云端(公网),它是找不到你家电脑的。公网穿透就是给你家电脑临时修一条“直达高速公路”,生成一个外网可以访问的网址(比如 https://xyz.ngrok-free.app)。
为什么要它: 为了让身在公网的 Dify 能访问到你本地电脑上运行的 Python 插件服务。(注意:如果你的 Python 代码直接部署在有公网 IP 的云服务器上,就不需要公网穿透了)。
明白了,您希望保持原始箭头文本的原貌,不省略箭头、不改用编号列表,同时将标题设为三级标题。以下是重新整理后的内容:
4.架构是怎么跑通的?(工作流程)
整个数据的流转过程是这样的:
[用户输入: "北京天气怎么样?"]
↓
[Dify 智能判断] 发现需要调用“天气插件”
↓
[Dify 发送请求] 走向【公网穿透提供的外网URL】
↓ 穿透到本地
[你的 Python 后端] 收到请求,解析出城市名 "北京"
↓
[Python 调用第三方API] 去高德/和风天气接口拿实时数据
↓
[天气接口返回数据] 比如返回:{"weather": "晴", "temperature": "25"}
↓
[Python 处理并返回] 格式化后传回给 Dify
↓
[Dify 组织语言] 结合大模型润色:“北京今天天气晴朗,气温25度,很适合出门哦!”
↓
[用户看到最终回答]
5.开始用FastAPI写这个接口
直接创建好一个FastAPI项目,有关这部分在这篇博客有提到。
1.编写后端代码
这段代码就是调用了高德地图API,然后返回一个清洗后的数据给Dify。
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel, Field
import httpx
app = FastAPI(title="Dify 天气插件服务")
# 替换为你自己申请的高德地图 Web服务 Key
GAODE_KEY = "你的高德地图KEY"
# 1. 定义 Dify 发送过来的请求体格式(数据模型)
class WeatherRequest(BaseModel):
# 这里定义了参数 city,并且用 Field 做了描述,FastAPI 会自动进行类型检查
city: str = Field(..., description="需要查询天气的城市名称,例如:北京、上海")
# 2. 创建一个 POST 接口接收 Dify 的请求
@app.post("/get_weather")
async def get_weather(request_data: WeatherRequest):
city_name = request_data.city
# 使用 httpx 的异步客户端发送请求,效率更高
async with httpx.AsyncClient() as client:
try:
# 3. 调用高德地图地理编码接口(城市名转 adcode 编码)
#得到一个请求URL,指向高德地图的地理编码服务
geo_url = f"[https://restapi.amap.com/v3/geocode/geo?address=](https://restapi.amap.com/v3/geocode/geo?address=){city_name}&key={GAODE_KEY}"
#根据URL,发出get请求,并异步执行返回给geo_response
geo_response = (await client.get(geo_url)).json()
#检查是否返回成功,status==1就成功,并且geocodes不为空,防止后续出错
if geo_response.get('status') == '1' and geo_response.get('geocodes'):
#这是拿到行政区划代码
adcode = geo_response['geocodes'][0]['adcode']
#这是实际标准化的城市名
actual_city_name = geo_response['geocodes'][0]['formatted_address']
# 4. 调用高德实时天气 API
weather_url = f"[https://restapi.amap.com/v3/weather/weatherInfo?city=](https://restapi.amap.com/v3/weather/weatherInfo?city=){adcode}&key={GAODE_KEY}"
weather_response = (await client.get(weather_url)).json()
#检查是否成功响应
if weather_response.get('status') == '1' and weather_response.get('lives'):
weather_data = weather_response['lives'][0]
# 5. 将清洗后的干净数据返回给 Dify
return {
"city": actual_city_name,
"weather": weather_data['weather'],
"temperature": weather_data['temperature'],
"winddirection": weather_data['winddirection'],
"windpower": weather_data['windpower'],
"humidity": weather_data['humidity']
}
# 如果没找到城市,抛出 404 错误
raise HTTPException(status_code=404, detail="未找到该城市的天气信息")
except httpx.RequestError as exc:
raise HTTPException(status_code=500, detail=f"网络请求失败: {exc}")
except Exception as e:
raise HTTPException(status_code=500, detail=f"服务器内部错误: {str(e)}")
# 启动命令提示:在终端输入 `uvicorn main:app --reload --port 5000` 运行
运行以上代码。
!!!必须注意这里的GAODE_KEY = "你的高德地图KEY"要改变,否则怎么测也不会有结果的……如果觉得去找key太麻烦,也可以改成用wttr.in,这是一个开源的可以直接返回天气数据的服务。
2.开启公网穿透
现在你的 FastAPI 在本地 http://127.0.0.1:5000 跑起来了,但身在云端的 Dify 依然访问不到它,我们必须用穿透工具给它开辟一条公网通道。
但是如果我在本地部署了Dify,我的python后端服务就可以被Dify直接访问,不需要公网穿透。
为了练习,还是熟悉一下这里。
以最常用的 ngrok 为例,ngrok是一种内网穿透的工具。
打开一个新的终端窗口。
输入以下命令,把本地 5000 端口暴露到公网:
ngrok http 5000
终端会为你生成一个外网可以访问的 https 网址,类似这样:https://a1b2-c3d4-e5f6.ngrok-free.app
记住这个网址,加上我们的接口路径,你在公网上的天气接口完整地址就是:https://a1b2-c3d4-e5f6.ngrok-free.app/get_weather
3.在 Dify 里面配置插件(自定义工具)
有了公网 URL 之后,我们去 Dify 后台把大模型和我们的 FastAPI 桥接起来。
进入 Dify: 点击左侧导航栏的 Tools (工具) -> Create Custom Tool (创建自定义工具)。
填写工具名称: 比如 fastapi_weather。
编写 Schema: 将下面的 JSON 复制进去,它会告诉 Dify 如何给你的 FastAPI 发送数据。
{
"openapi": "3.1.0",
"info": {
"title": "FastAPI 天气查询工具",
"version": "1.0.0",
"description": "通过输入城市名称,实时调用后端接口获取该城市的天气、温度、湿度等信息"
},
"servers": [
{
"url": "https://a1b2-c3d4-e5f6.ngrok-free.app"
}
],
"paths": {
"/get_weather": {
"post": {
"operationId": "get_weather",
"summary": "获取指定城市的天气",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"city": {
"type": "string",
"description": "需要查询天气的城市名称,例如:北京市、上海市、杭州"
}
},
"required": ["city"]
}
}
}
},
"responses": {
"200": {
"description": "成功返回天气数据"
}
}
}
}
}
}
⚠️ 必须修改的地方: 请把上面 servers 里的 url 换成你自己刚刚在 ngrok 终端里拿到的那个 https://… 域名。
测试与保存: 点击下方的测试按钮,输入 city: 广州。此时 Dify 会发送请求通过 ngrok 穿透到你本地的 FastAPI,FastAPI 去找高德地图,再原路把数据返回给 Dify。
测试成功后,点击 Save (保存)。
4.在 Agent(智能体)中愉快地使用它
现在,工具已经做好了,怎么让大模型用起来呢?
去 Dify 的 Studio(工作室),新建一个 Agent(智能体)。
在右侧的配置面板中找到 Tools (工具),点击添加,勾选你刚刚创建的 FastAPI 天气查询工具。
在左侧的 Instructions (提示词) 中,给大模型立个规矩:
“你是一个贴心的天气预报助手。当用户询问某个城市的天气时,你必须调用 get_weather 工具来获取最新的真实天气数据。拿到数据后,请结合当前天气给用户一些温暖的出行或穿衣建议。”
在右侧的聊天框里测试一下:“深圳今天天气怎么样?我需要带伞吗?”
你会看到 Dify 界面上闪过一个调用工具的徽章,随后大模型就会顺畅地结合 FastAPI 返回的数据(如温度、下雨情况)。
注意,ngrok可能会有网络问题,所以可以更换其它的内网穿透工具,比如花生壳,natapp等。还有,本地部署的dify如果使用natapp别在Docker下镜像,会有问题,直接下载本地客户端运行就好。
更多推荐

所有评论(0)