使用RAGFlow+iText2KG针对文档进行搜索与知识图片生成(一)

RAG跟知识图谱

1、RAGFlow 的使用指南

RAGFlow 是一个基于对文档的深入理解的开源 RAG(检索增强生成)引擎。它为任何规模的企业提供了简化的 RAG 工作流程,结合了 LLM(大型语言模型)以提供真实的问答功能,并以来自各种复杂格式数据的有根据的引文为后盾。

demo链接:RAGFlow

特点:

1、有一定的数据质量保证,能从复杂的非结构化数据中提取基于文档理解的深度知识。

2、内置模板,可以基于模板形成知识库;文档分块可以实现人工干预,提高文档质量;

3、可以兼容异构数据源,支持 Word、幻灯片、excel、txt、图像、扫描副本、结构化数据、网页等。

4、 自动化且轻松的 RAG 工作流程

  • 简化的 RAG 编排同时满足了个人和大型企业的需求。
  • 可配置的 LLM 以及嵌入模型。
  • 多重召回与融合的重新排名配对。
  • 直观的 API,可与业务无缝集成。
    RAGFlow架构图

部署要求:

  • CPU >= 4 cores
  • RAM >= 16 GB
  • Disk >= 50 GB
  • Docker >= 24.0.0 & Docker Compose >= v2.26.1

启动 服务器

  1. 确保 >= 262144:vm.max_map_count要检查 的值 :vm.max_map_count$ sysctl vm.max_map_count如果不是,则重置为至少 262144 的值。vm.max_map_count
  1. # In this case, we set it to 262144:$ sudo sysctl -w vm.max_map_count=262144此更改将在系统重启后重置。为了确保您的更改保持永久,请相应地在 /etc/sysctl.conf 中添加或更新该值:vm.max_map_count
  2. vm.max_map_count=262144
  3. 克隆存储库:$ git clone https://github.com/infiniflow/ragflow.git构建预构建的 Docker 镜像并启动服务器:
  4. 以下命令下载 RAGFlow slim () 的开发版本 Docker 映像。请注意,RAGFlow slim Docker 映像不包括嵌入模型或 Python 库,因此大小约为 1GB。dev-slim$ cd ragflow/docker$ docker compose -f docker-compose.yml up -d注意:包含嵌入模型和 Python 库的 RAGFlow Docker 映像的大小约为 9GB,加载时间可能要长得多。
    • 要下载特定版本的 RAGFlow slim Docker 镜像,请将 docker/.env 中的变量更新为所需版本。例如。进行此更改后,请重新运行上述命令以启动下载。RAGFlow_IMAGERAGFLOW_IMAGE=infiniflow/ragflow:v0.12.0-slim
    • 要下载 RAGFlow Docker 映像的开发版本(包括嵌入模型和 Python 库),请将 docker/.env 中的变量更新为 。进行此更改后,请重新运行上述命令以启动下载。RAGFlow_IMAGERAGFLOW_IMAGE=infiniflow/ragflow:dev
    • 要下载特定版本的 RAGFlow Docker 映像(包括嵌入模型和 Python 库),请将 docker/.env 中的变量更新为所需的版本。例如。进行此更改后,请重新运行上述命令以启动下载。RAGFlow_IMAGERAGFLOW_IMAGE=infiniflow/ragflow:v0.12.0
  5. 在服务器启动并运行后检查服务器状态:$ docker logs -f ragflow-server以下输出确认系统已成功启动:
  6. ____ ___ ______ ______ __
    / __ \ / | / ____// ____// /____ _ __
    / /_/ // /| | / / __ / /_ / // __ \| | /| / /
    / _, _// ___ |/ /_/ // __/ / // /_/ /| |/ |/ /
    /_/ |_|/_/ |_|\____//_/ /_/ \____/ |__/|__/

    * Running on all addresses (0.0.0.0)
    * Running on http://127.0.0.1:9380
    * Running on http://x.x.x.x:9380 INFO:werkzeug:Press CTRL+C to quit如果您跳过此确认步骤并直接登录 RAGFlow,您的浏览器可能会提示错误,因为此时您的 RAGFlow 可能没有完全初始化。network abnormal
  1. 在您的 Web 浏览器中,输入服务器的 IP 地址并登录 RAGFlow。使用默认设置时,您只需输入 (sans port number) 作为使用默认配置时可以省略默认 HTTP 服务端口。http://IP_OF_YOUR_MACHINE80
  2. 在 service_conf.yaml 中,选择所需的 LLM 工厂,并使用相应的 API 密钥更新字段。user_default_llmAPI_KEY有关更多信息,请参阅 llm_api_key_setup。

部署完成后,还需要对RAGFlow进行配置,需要关注以下几点:

  • .env:保留系统的基本设置,例如SVR_HTTP_PORTMYSQL_PASSWORDMINIO_PASSWORD
  • service_conf.yaml:配置后端服务。
  • docker-compose.yml:系统依赖 docker-compose.yml 启动。

您必须确保对 .env 文件的更改与 service_conf.yaml 文件中的更改一致。

./docker/README 文件提供了环境设置和服务配置的详细描述,您需要确保 ./docker/README 文件中列出的所有环境设置都与 service_conf.yaml 文件中的相应配置保持一致。

要更新默认 HTTP 服务端口 (80),请转到 docker-compose.yml 并更改为 。80:80<YOUR_SERVING_PORT>:80

对上述配置的更新需要重启所有容器才能生效:

$ docker compose -f docker/docker-compose.yml up -d

🔧 在不嵌入模型的情况下构建 Docker 镜像

此映像的大小约为 1 GB,依赖于外部 LLM 和嵌入服务。

git clone https://github.com/infiniflow/ragflow.git
cd ragflow/
pip3 install huggingface-hub nltk
python3 download_deps.py
docker build -f Dockerfile.slim -t infiniflow/ragflow:dev-slim .

🔧 构建包含嵌入模型的 Docker 镜像

此映像的大小约为 9 GB。由于它包括嵌入模型,因此它仅依赖于外部 LLM 服务。

git clone https://github.com/infiniflow/ragflow.git
cd ragflow/
pip3 install huggingface-hub nltk
python3 download_deps.py
docker build -f Dockerfile -t infiniflow/ragflow:dev .

🔨 从源头启动服务进行开发

  1. 安装 Poetry,如果已安装,请跳过此步骤:curl -sSL https://install.python-poetry.org | python3 –
  2. 克隆源码并安装 Python 依赖项:git clone https://github.com/infiniflow/ragflow.git
    cd ragflow/
    export POETRY_VIRTUALENVS_CREATE=true POETRY_VIRTUALENVS_IN_PROJECT=true
    ~/.local/bin/poetry install –sync –no-root # install RAGFlow dependent python modules
  3. 使用 Docker Compose 启动依赖服务(MinIO、Elasticsearch、Redis 和 MySQL):docker compose -f docker/docker-compose-base.yml up -d
  4. 添加以下行以将 docker/service_conf.yaml 中指定的所有主机解析为:/etc/hosts127.0.0.1
  1. 127.0.0.1 es01 mysql minio redis
  2. 在 docker/service_conf.yaml 中,将 mysql 端口更新为 ,将 es 端口更新为 ,如 docker/.env 中指定。54551200
  1. 如果无法访问 HuggingFace,请将环境变量设置为使用镜像站点:HF_ENDPOINTexport HF_ENDPOINT=https://hf-mirror.com启动 backend service:
  2. source .venv/bin/activate
    export PYTHONPATH=$(pwd)bash docker/launch_backend_service.sh
  3. 安装前端依赖项:
  4. cd webnpm install –force
  5. 将前端配置为在 .umirc.ts 更新为:proxy.targethttp://127.0.0.1:9380

启动前端服务:

npm run dev 以下输出确认系统已成功启动完成。



1、Text2KG 的使用



Text2KG是一个开源项目,能够利用大型语言模型(zero-shot)跨领域从文本中提取实体和关系,自动构建和更新知识图谱,并通过Neo4j进行可视化。

iText2KG由四个主要模块组成:文档提取器、增量实体提取器、增量关系提取器、图形集成器和可视化。它们协同工作,从非结构化文本构建和可视化知识图谱。

  • 文档提取器(Document Distiller):该模块处理原始文档,并根据用户定义的模式将其重新表述为语义块。它通过关注相关信息并以预定义的格式对其进行结构化来提高信噪比。
  • 增量实体提取器(Incremental Entity Extractor):此模块从语义块中提取唯一实体并解决歧义以确保每个实体都有明确定义。它使用余弦相似度度量将局部实体与全局实体进行匹配。
  • 增量关系提取器(Incremental Relation Extractor):此模块识别提取实体之间的关系。它可以以两种模式运行:使用全局实体丰富图形中的潜在信息,或使用局部实体建立更精确的关系。
  • 图形集成器和可视化(Graph Integrator and Visualization):此模块将提取的实体和关系集成到 Neo4j 数据库中,提供知识图谱的可视化表示。它允许对结构化数据进行交互式探索和分析。

四个模块中,增量实体提取器与增量关系提取器最为关键,采用大模型来实现LLM提取代表一个唯一概念的实体,以避免语义混合的实体。显示了使用 Langchain JSON 解析器的实体和关系提取prompt。分类如下:蓝色 – 由 Langchain 自动格式化的prompt;常规 – iText2KG设计的prompt;斜体 – 专门为实体和关系提取设计的prompt。(a)关系提取prompt和(b)实体提取prompt。

为了说明知识图谱构建的结果,在三种不同场景下,将基线方法与iText2KG进行了比较:

  • 基线方法在所有三种知识图谱构建场景中都揭示了存在没有关系的孤立节点。这种现象可能归因于实体提取和关系提取的同时执行,这可能会在语言模型中引起幻觉效应,导致“遗忘”效应,即分离实体和关系提取的过程可以提高性能。
  • 在“网站到知识图谱”的场景中,输入文档数量的增加与图中噪声节点的出现有关。这强调了对文档进行有效精炼和蒸馏的模块1的关键需求。
  • iText2KG方法在三种知识图谱构建场景中展示了改进的实体和关系解析能力。当输入文档较少且由简单、非复杂短语组成时,语言模型在实体和关系解析方面表现出高效率,如“简历到知识图谱”过程中所证明的。相反,随着数据集变得更加复杂和庞大,挑战也随之增加,如“网站到知识图谱”场景所示。此外,重要的是要强调输入文档的分块大小和阈值对知识图谱构建的影响。文档分馏器的输入文档可以是独立的文档或分块。如果分块大小较小,则语义块将从文档中捕获更具体的详细信息,反之亦然

一种由 LLM 驱动的零样本方法,使用大型语言模型构建增量知识图谱(KG)

iText2KG 是一个 Python 包,通过利用大型语言模型从文本文档中提取实体和关系,逐步构建具有已解析实体和关系的一致知识图谱。

它具有零样本能力,无需专门的训练即可跨各个领域提取知识。

它包含四个模块:文档提炼器、增量实体提取器、增量关系提取器和图形集成器与可视化。

  • 文档提取器:此模块将原始文档重新表述为预定义的语义块,并由指导 LLM 提取特定信息的模式引导。
  • 增量实体提取器:此模块识别并解析语义块内的唯一语义实体,确保实体之间的清晰度和区别。
  • 增量关系提取器:此组件处理已解析的实体以检测语义上唯一的关系,解决语义重复的挑战。
  • Neo4j 图形集成器:最后一个模块以图形格式可视化关系和实体,利用 Neo4j 进行有效表示。

对于我们的 iText2KG 它包含了两大特点

  • 增量构建:iText2KG 允许增量构建 KG,这意味着它可以在新数据可用时不断更新和扩展图,而无需进行大量重新处理。
  • 零样本学习:该框架利用 LLM 的零样本功能,使其无需预定义集或外部本体即可运行。这种灵活性使其能够适应各种 KG 构建场景,而无需进行大量训练或微调。

一 、设置模型

在运行 iText2KG 之前,我们先设置好大模型,我这里选择的是 OpenAi 的模型以及 HuggingFace 的 bge-large-zh embedding 模型。这么选择也是考虑到构建 KG 的准确度。

from langchain_openai import ChatOpenAI, OpenAIEmbeddings
import os
os.environ["OPENAI_API_KEY"] = "*****"
openai_api_key = os.environ["OPENAI_API_KEY"]
openai_llm_model = llm = ChatOpenAI(
model="gpt-4o-mini",
temperature=0,
max_tokens=None,
timeout=None,
max_retries=2,
)
messages = [
(
"system",
"You are a helpful assistant that translates English to French. Translate the user sentence.",
),
("human", "I love programming."),
]

ai_msg=openai_llm_model.invoke(messages)

开始部署我们的 Embedding 模型:

from langchain_huggingface.embeddings import HuggingFaceEmbeddings
openai_embeddings_model = HuggingFaceEmbeddings(model_name="BAAI/bge-large-zh-v1.5")
text = "This is a test document."
query_result = openai_embeddings_model.embed_query(text)
query_result[:3]
doc_result = openai_embeddings_model.embed_documents([text])

二 、使用 iText2KG 构建 KG

我们这里的场景是,给出一篇简历,使用知识图谱将在线职位描述与生成的简历联系起来。

设定目标是评估候选人是否适合这份工作。

我们可以为 iText2KG 的每个模块使用不同的 LLM 或嵌入模型。但是,重要的是确保节点和关系嵌入的维度在各个模型之间保持一致。

如果嵌入维度不同,余弦相似度可能难以准确测量向量距离以进行进一步匹配。

我们的简历放到根目录,加载简历:

from langchain.document_loaders import PyPDFLoader
loader = PyPDFLoader(f"./CV_Emily_Davis.pdf")
pages = loader.load_and_split()

初始化 DocumentDistiller 引入 llm :

from itext2kg.documents_distiller import DocumentsDisiller, CV
document_distiller = DocumentsDisiller(llm_model = openai_llm_model)

信息提炼:

IE_query = '''
# DIRECTIVES :
- Act like an experienced information extractor.
- You have a chunk of a CV.
- If you do not find the right information, keep its place empty.
'''
# 使用定义好的查询和输出数据结构提炼文档。
distilled_cv = document_distiller.distill(documents=[page.page_content.replace("{", '[').replace("}", "]") for page in pages], IE_query=IE_query, output_data_structure=CV)

将提炼后的文档格式化为语义部分。

semantic_blocks_cv = [f"{key} - {value}".replace("{", "[").replace("}", "]") for key, value in distilled_cv.items() if value !=[] and value != ""  and value != None]

我们可以自定义输出数据结构,我们这里定义了4种,工作经历模型,岗位,技能,证书。

from pydantic import BaseModel, Field
from typing import List, Optional

class JobResponsibility(BaseModel):
description: str = Field(..., description="A specific responsibility in the job role")

class JobQualification(BaseModel):
skill: str = Field(..., description="A required or preferred skill for the job")

class JobCertification(BaseModel):
certification: str = Field(..., description="Required or preferred certifications for the job")

class JobOffer(BaseModel):
job_offer_title: str = Field(..., description="The job title")
company: str = Field(..., description="The name of the company offering the job")
location: str = Field(..., description="The job location (can specify if remote/hybrid)")
job_type: str = Field(..., description="Type of job (e.g., full-time, part-time, contract)")
responsibilities: List[JobResponsibility] = Field(..., description="List of key responsibilities")
qualifications: List[JobQualification] = Field(..., description="List of required or preferred qualifications")
certifications: Optional[List[JobCertification]] = Field(None, description="Required or preferred certifications")
benefits: Optional[List[str]] = Field(None, description="List of job benefits")
experience_required: str = Field(..., description="Required years of experience")
salary_range: Optional[str] = Field(None, description="Salary range for the position")
apply_url: Optional[str] = Field(None, description="URL to apply for the job")

定义一个招聘工作需求的描述:

job_offer = """
About the Job Offer
THE FICTITIOUS COMPANY

FICTITIOUS COMPANY is a high-end French fashion brand known for its graphic and poetic style, driven by the values of authenticity and transparency upheld by its creator Simon Porte Jacquemus.

Your Role

Craft visual stories that captivate, inform, and inspire. Transform concepts and ideas into visual representations. As a member of the studio, in collaboration with the designers and under the direction of the Creative Designer, you should be able to take written or spoken ideas and convert them into designs that resonate. You need to have a deep understanding of the brand image and DNA, being able to find the style and layout suited to each project.

Your Missions

Translate creative direction into high-quality silhouettes using Photoshop
Work on a wide range of projects to visualize and develop graphic designs that meet each brief
Work independently as well as in collaboration with the studio team to meet deadlines, potentially handling five or more projects simultaneously
Develop color schemes and renderings in Photoshop, categorized by themes, subjects, etc.
Your Profile

Bachelor’s degree (Bac+3/5) in Graphic Design or Art
3 years of experience in similar roles within a luxury brand's studio
Proficiency in Adobe Suite, including Illustrator, InDesign, Photoshop
Excellent communication and presentation skills
Strong organizational and time management skills to meet deadlines in a fast-paced environment
Good understanding of the design process
Freelance cont

继续使用上面方法做信息提炼:

IE_query = '''
# DIRECTIVES :
- Act like an experienced information extractor.
- You have a chunk of a job offer description.
- If you do not find the right information, keep its place empty.
'''
distilled_Job_Offer = document_distiller.distill(documents=[job_offer], IE_query=IE_query, output_data_structure=JobOffer)
print(distilled_Job_Offer)
semantic_blocks_job_offer = [f"{key} - {value}".replace("{", "[").replace("}", "]") for key, value in distilled_Job_Offer.items() if value !=[] and value != "" and value != None]

到这里准备工作完成,简历和工作需求都已经提炼完毕,然后正式开始构建 graph,我们将简历的所有语义块作为一个块传递给了 LLM

也将工作需求作为另一个语义块传递,也可以在构建图时将语义块分开。

我们需要注意每个块中包含多少信息,然后好将它与其他块连接起来,我们在这里做的就是一次性传递所有语义块。

from itext2kg import iText2KG
itext2kg = iText2KG(llm_model = openai_llm_model, embeddings_model = openai_embeddings_model)

global_ent, global_rel = itext2kg.build_graph(sections=[semantic_blocks_cv], ent_threshold=0.6, rel_threshold=0.6)

global_ent_, global_rel_ = itext2kg.build_graph(sections=[semantic_blocks_job_offer], existing_global_entities = global_ent, existing_global_relationships = global_rel, ent_threshold=0.6, rel_threshold=0.6)

iText2KG 构建 KG 的过程我们看到有很多参数,下面分贝是对每个参数的表示做一些解释:

  • llm_model:用于从文本中提取实体和关系的语言模型实例。
  • embeddings_model:用于创建提取实体的向量表示的嵌入模型实例。
  • sleep_time (int):遇到速率限制或错误时等待的时间(以秒为单位)(仅适用于 OpenAI)。默认为 5 秒。

iText2KG 的 build_graph 参数:

  • sections (List[str]):字符串(语义块)列表,其中每个字符串代表文档的一部分,将从中提取实体和关系。
  • existing_global_entities (List[dict], optional):与新提取的实体进行匹配的现有全局实体列表。每个实体都表示为一个字典。
  • existing_global_relationships (List[dict], optional):与新提取的关系匹配的现有全局关系列表。每个关系都表示为一个字典。
  • ent_threshold (float, optional):实体匹配的阈值,用于合并不同部分的实体。默认值为 0.7。
  • rel_threshold (float, optional):关系匹配的阈值,用于合并不同部分的关系。默认值为 0.7。

从图中结果看到我们构建过程中的实体,和关联关系。

最后使用 GraphIntegrator 对构建的知识图谱进行可视化。

使用指定的凭据访问图形数据库 Neo4j,并对生成的图形进行可视化,以提供从文档中提取的关系和实体的视觉表示。

from itext2kg.graph_integration import GraphIntegrator
URI = "bolt://3.216.93.32:7687"
USERNAME = "neo4j"
PASSWORD = "selection-cosal-cubes"
new_graph = {}
new_graph["nodes"] = global_ent_
new_graph["relationships"] = global_rel_
GraphIntegrator(uri=URI, username=USERNAME, password=PASSWORD).visualize_graph(json_graph=new_graph)

打开我们的 Neo4j 图形数据库:

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注