在 Dify 知识问答系统中,精准限定检索范围是提升回答质量的关键环节。借助元数据标签为文档赋予独特的“身份标识”,并在检索时按标签进行筛选,即可实现“指哪查哪”的精准检索,彻底告别全库扫描带来的冗余信息。本教程将详细演示如何利用 Dify 的元数据功能,结合工作流动态调整检索范围,让知识问答更加高效可控。
一、核心原理概述
元数据精准检索的实现逻辑主要分为以下三个步骤:
- 1️⃣ 标记文档:通过元数据为选定的文档统一添加一个标签(例如一个 UUID)。
- 2️⃣ 检索时筛选:在知识检索节点中配置过滤条件,仅搜索带有该标签的文档。
- 3️⃣ 动态调整:每次提问前先更新标签(生成新的 UUID),从而灵活控制每一次搜索的范围。
二、新建元数据字段
首先,为 Dify 知识库开启元数据功能。进入知识库页面,选择一个知识库并点击进入。以下以“公众号知识库”为例进行说明。

点击页面中的元数据按钮,弹出元数据管理对话框。

点击新建元数据按钮,新增一个名为 query_batch_id 的元数据,类型建议选择“字符串”。
小提示:元数据名称可自定义,但建议使用有意义的英文名称,这样后续在工作流中引用会更加便捷。
三、创建并配置工作流
利用 Dify 的工作流,我们可以通过代码模块动态更新文档的元数据,并在知识检索时按照新标签进行过滤。具体操作步骤如下:
1. 创建应用并添加代码执行节点
在 Dify 中创建一个工作流应用,并添加一个代码执行节点。该节点通过调用 Dify API 更新指定文档的元数据。
在代码执行节点中填入以下 Python 代码(请根据实际情况替换 API 地址和密钥):
import requests
import uuid
def main(dataset_id:str, document_ids:str) -> dict:
document_ids = document_ids.split(",")
url = "api:5001"
api_key = "dataset-sLRzvhU8GzqFd1fjZ1rqZi8o"
## your can get metadata_id from by get method ```GET /datasets/{dataset_id}/metadata```
metadata_id = '43d84af2-40b3-4158-b424-721e6049f1e8'
headers = {
'Authorization': f'Bearer {api_key}',
}
batch_id = uuid.uuid4().hex
json_data = {
'operation_data': [
{
'document_id': document_id,
'metadata_list': [
{
'id': metadata_id,
'value': batch_id,
'name': 'query_batch_id',
"type": "string"
},
],
} for document_id in document_ids
],
}
response = requests.post(f'http://{url}/v1/datasets/{dataset_id}/documents/metadata', headers=headers, json=json_data)
if response.status_code != 200:
return {
"is_success":0,
"err_message":response.text,
"query_batch_id":""
}
return {
"is_success":1,
"err_message":"",
"query_batch_id":batch_id
}
注意:代码中的 metadata_id 需要通过 GET 请求 /datasets/{dataset_id}/metadata 预先获取,请根据你的实际知识库 ID 获取并替换。
2. 配置知识检索节点
在代码执行节点之后添加一个知识检索节点。在该节点的配置中,开启元数据过滤功能,设置过滤条件为:query_batch_id 等于代码节点返回的 batch_id。
具体操作:
- 选择需要检索的知识库。
- 在“元数据过滤”部分,点击添加过滤条件,选择元数据名为
query_batch_id,运算符选“等于”,值设为 {{节点输出变量}}(即代码节点输出的query_batch_id)。
小提示:如果你需要每次检索多个文档,可以在代码节点中传入多个文档 ID(以逗号分隔),它们都会被更新为同一个 batch_id,从而在检索时一并命中。
四、工作流测试验证
完成配置后,我们需要测试效果。假设我们希望只从“毕昇LLMs平台”和“Dolphine-API”两份文档中检索答案。
首先,手动从浏览器中获取这两个文档所属的知识库 ID(dataset_id)和文档 ID(document_id)。然后,在工作流中输入这些参数,开始测试。
测试用例1:询问一个与这两个文档均无关的问题(例如“今天天气如何?”),模型应当提示“未检索到知识”。
测试用例2:询问一个与文档相关的问题(例如“如何调用Dolphine-API?”),模型将正确检索到指定文档中的内容并给出答案。
常见问题:为什么测试时仍然检索到所有文档?请检查代码执行节点是否正确更新了元数据(查看返回的 is_success),以及知识检索节点是否确实开启了元数据过滤并绑定了正确的变量。
五、常见问题(FAQ)
- Q:如何获取 metadata_id?
A:在 Dify 中,可以通过浏览器开发者工具或 Postman 调用GET /datasets/{dataset_id}/metadata接口,返回的元数据列表中包含每个元数据的id。建议在知识库设置中提前创建好元数据并记录其 ID。 - Q:代码中的 api_key 从哪里获取?
A:在 Dify 应用的管理页面中,进入“API 访问”或“密钥管理”生成一个 Dataset 级别的 API Key,注意权限需包含“更新文档元数据”。 - Q:一次可以标记多个文档吗?
A:可以。代码中的document_ids支持传入多个 ID(以逗号分隔),循环更新每个文档的元数据为同一个batch_id,从而实现多文档精准检索。 - Q:每次检索都需要重新生成 UUID,会不会影响性能?
A:不会。UUID 生成极快,且元数据更新属于轻量操作,对整体流程影响很小。
六、总结
通过本文的教程,你已经掌握了利用 Dify 元数据功能实现文档级精准检索的核心方法。从新建元数据、编写代码更新标签,到工作流中设置过滤条件,每一步都清晰可执行。借助动态 UUID 机制,你可以灵活控制每次检索的文档范围,大幅提升知识问答的准确性和效率。现在就去你的 Dify 项目中试试吧!
