
Dify 知识库外接 RAGFlow 喂饭教程!附避坑指南 原创
背景
在我们之前的文章中,我们对比了dify,ragflow和n8n这三个工具的使用场景及其差异。实际上,在企业中,这些工具通常会被结合起来使用,以便充分发挥各自的优势。例如,尽管ragflow也具备一些智能功能,但是与dify相比,它在这方面的表现力还有待提高。然而,当谈到解析和检索的能力时,ragflow却显著超过了dify。在今天的文章中,我们将探讨如何有效地将这两个工具结合使用。
RAGFlow
核心功能
我觉得 RAGflow 最大的一个亮点就是支持各种基于模板的解析模式和多样的模型支持,这主要是通过deepdoc
模块实现。这种灵活性使得 RAGflow 能够适应不同类型的文档和数据结构,从而提高解析的准确性和效率。在RAGFlow刚出来的时候,我们就开始利用其deepdoc模块帮我们做文档解析,效果比langchain内置的pymupdf效果要好很多。
具体来说,RAGflow 提供了以下几种解析模式和模型支持:
- 基于规则的解析:适用于结构化程度较高的文档
- 基于典型数据结构的解析:例如 Paper, Table 等类型的数据
- 基于 Graph 的解析:参考 GraphRAG 构建知识集的 Knowledge Graph 知识图谱
安装要求
硬件指标:
- CPU >= 4 cores
- RAM >= 16 GB
- Disk >= 50 GB
- Docker >= 24.0.0 & Docker Compose >= v2.26.1
内存映射:
sudo sysctl -w vm.max_map_count=262144
ragflow 依赖 Elasticsearch,Elasticsearch 官方建议将其调整为262144值
值得一提的是,RAGFlow 对于硬件的要求还是挺高的,我在一台只剩不到7个G内存的服务器上运行ragflow,明显能感觉到卡顿,一看内存就剩100多M了!
知识库
官方说 RAGFlow的知识库提供多个分块模板供用户选择,方便分块不同布局的文件,尽可能地确保语义完整性。在分块方法中,我们可以选择适合文件布局和格式的默认模板。下表显示了每个支持的块模板的描述和兼容的文件格式.
模板 | 文件格式 |
General | DOCX、EXCEL、PPT、PDF、TXT、JPEG、JPG、PNG、TIF、GIF |
Q&A | EXCEL、CSV/TXT |
Manual | |
Table | EXCEL、CSV/TXT |
Paper | |
Book | DOCX、PDF、TXT |
Laws | DOCX、PDF、TXT |
Presentation | PDF、PPTX |
Picture | JPEG、JPG、PNG、TIF、GIF |
One | DOCX、EXCEL、PDF、TXT |
我们还可以在创建并配置完知识库之后,在知识库的数据集页面上更改特定文件的块模板之后再执行文档的解析。
Dify接入RAGFlow
虽然dify自身的文档解析能力相对较弱,但ragflow在这方面却表现出色。那么我们是否可以利用dify去接入ragflow的知识库呢?实际上,ragflow确实支持这种功能,并专门为dify提供了一个单独的API,使其可以从ragflow的知识库中进行检索。
我们可以从源码中找到对应的接口及代码:
从这个api 可以看到,请求体的json应该长这样:
{
"query": "what is meme?",
"knowledge_id": "xxxx",
"use_kg": false,
"retrieval_setting": {"score_threshold": 0.0, "top_k": 1024}
}
有一点很重要,那就是在调用ragflow的API之前,你需要进行身份验证。所以,我们首先需要申请一个密钥(key)。
从RAGFlow的认证代码不难看出,我们只需要把key放在请求的header中即可。
def apikey_required(func):
@wraps(func)
def decorated_function(*args, **kwargs):
token = flask_request.headers.get("Authorization").split()[1]
objs = APIToken.query(token=token)
if not objs:
return build_error_result(message="API-KEY is invalid!", code=settings.RetCode.FORBIDDEN)
kwargs["tenant_id"] = objs[0].tenant_id
return func(*args, **kwargs)
return decorated_function
在我们成功申请到API密钥后,我们可以先使用curl命令来调试接口。首先,我们需要找到知识库的ID,并将其用作knowledge_id
。
curl --request POST \
--url http://192.168.35.16:8080/api/v1/dify/retrieval \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer ragflow-dmN2M4ZTUyNDgyYTExZjA5MWZmMDI0Mm' \
--data '
{
"query": "If you donot have the invitation code you can go to",
"knowledge_id": "b4bc18a6482211f0920a0242ac1c0006",
"use_kg": false,
"retrieval_setting": {"score_threshold": 0.45, "top_k": 5}
}'
得到的结果如下:
{"records":[{"content":"completetaskstoreceive theinvitation code.\nclick on the campaign button, which will take you to a screen where you must\nNote: If you don't have the invitation code you can go to http://quest.sending.me then,\nInvitation Code\nSendingMe\nSending You to the Free World\n Personal Signing\nCancel\nConfirm\nWhere can I get it?\nlog in instantly.","metadata":{},"score":0.487319856762247,"title":"Getting Started _ SendingMe User Manual.pdf"}]}
在api 验证通过之后,我们就可以在dify外接知识库连接到ragflow了。
我们需要将端点(endpoint)设置为本地IP地址,并加上/api/v1/dify
作为后缀。然后,dify会在应用程序中自动添加retrieval
,从而形成完整的路径/api/v1/dify/retrieval
:
// api/services/external_knowledge_service.py
def fetch_external_knowledge_retrieval(
tenant_id: str,
dataset_id: str,
query: str,
external_retrieval_parameters: dict,
metadata_condition: Optional[MetadataCondition] = None,
) -> list:
...
request_params = {
"retrieval_setting": {
"top_k": external_retrieval_parameters.get("top_k"),
"score_threshold": score_threshold,
},
"query": query,
"knowledge_id": external_knowledge_binding.external_knowledge_id,
"metadata_condition": metadata_condition.model_dump() if metadata_condition else None,
}
response = ExternalDatasetService.process_external_api(
ExternalKnowledgeApiSetting(
url=f"{settings.get('endpoint')}/retrieval",
request_method="post",
headers=headers,
params=request_params,
),
None,
)
...
接着我们可以在dify测试一下从ragflow的数据召回情况:
当检索召回成功之后,说明整个流程已经跑通了,我们就可以在问答或者工作流中使用这个外部知识库了。
注意事项
- 当dify和ragflow配置在同一台服务器,端口会有冲突,修改ragflow/docker/docker-compose.yml 中ragflow-server的端口即可
- dify配置的ragflow的端口地址,除了可以使用映射的80端口之外,也可以使用SVR_HTTP_PORT(默认值是9380)
- 上述使用的dify版本Version 1.4.1,ragflow的版本v0.19.0,其他版本没测试过
本文转载自AI 博物院 作者:longyunfeigu
