Skip to content

09 概念详解:如何根据元数据高效检索知识?

你好,我是叶伟民。

上一节课我们提到,如果我们想查看前天的CNET新闻,我们会问RAG应用:前天的CNET新闻有哪些?

这时候RAG应用就需要根据 创建日期 这个元数据去知识库里面搜索相关知识了。那究竟什么是元数据呢?这节课我就带你深入了解元数据这个基础概念。

什么是元数据?

元数据,英文叫Metadata,是一个广泛的概念,它指的是 “数据的数据”,即描述其他数据的属性、特征或上下文信息的数据。元数据通常用于帮助我们组织、搜索、访问和管理数据。元数据是关于数据的信息,它描述了数据的属性、结构、内容、来源、格式、质量、关联性等。

元数据分为以下四个类型。

  1. 描述性元数据:提供数据内容的描述,例如实战案例2中的文章标题、作者、发布日期等等。

  2. 结构性元数据:描述数据的组织结构,如文章的章节、表格的列和行等等。

  3. 管理性元数据:涉及数据的管理和维护,如文章的版权信息、存储位置、访问权限等等。

  4. 参考性元数据:提供数据之间关系的描述,如文章的链接、引用、分类等等。

这里我想重点讲一下 访问权限 这个元数据。

就像我们用到的MIS系统一样,在日常工作的RAG应用中,特别是企业里面的RAG应用,绝大部分都会用到访问权限。其机制与MIS系统是一样的。相对于其他类型的元数据,访问权限这个元数据使用频率是相当高的。

具体来说,以实战案例1为例,在首页的提问输入框输入问题之后,系统应该只检索当前用户具有访问权限的数据,而不是从所有数据中检索。

那么,我们如何获取元数据呢?

如何获取元数据?

获取元数据的方式有很多种,包括:

  • 原始数据:直接从数据源中提取,如数据库、文件系统、网络资源等。

  • 用户输入:用户在创建或编辑数据时提供的描述性信息。

  • 自动化工具:通过软件工具自动生成,如文件的创建时间、修改时间等。

  • 第三方服务:从外部API或数据提供商获取,如社交媒体元数据、地理信息系统元数据等。

在实战案例2里,我们的元数据来自于RSS API。

比较特殊的是访问权限这个元数据。访问权限元数据与MIS系统里面的访问权限类似,甚至可以直接沿用MIS系统里面的权限管理模块。因此访问权限元数据是需要自定义的,而不是像实战案例2那样直接取自RSS API。

那么,获取了元数据之后,如何保存呢?

如何保存元数据?

一般来说,我们可以使用数据库来保存元数据。因此,我们需要针对元数据的结构来建立对应的元数据表。以下是实战案例2中的元数据表结构。

那么加了访问权限元数据之后应该如何设计表结构呢?这个要简单可以很简单,要复杂可以很复杂。

表结构设计

我们先看看简单的方式。首先需要在前面的表加一个权限字段。于是表结构就变成了:

之后我们要在权限这一列设置值为readnews,也就是可以阅读新闻的意思。

然后新建一个用户权限表。这个表只包含两个字段,用户名和权限。

然后在这个表新增一行,用于存储用户名和对应的权限readnews。

如果同学们觉得以上这么简单的表结构满足不了你的需求,还有一种复杂些的方法,我们可以参考RBAC来设计表结构。

RBAC

RBAC是角色基于访问控制的英文缩写。RBAC是一种常见的安全策略,它通过定义角色和权限来管理对资源的访问。

RBAC 的核心概念包括角色、权限、用户和会话。

  1. 角色(Role):角色是一组权限的集合,它代表了在组织中执行特定任务所需的访问级别。例如,一个组织可能会有“管理员”“编辑”和“访客”等角色。

  2. 权限(Permission):权限是允许或拒绝执行特定操作的能力。权限可以是查看、编辑、删除或访问特定资源的能力。

  3. 用户(User):用户是系统中的一个实体,可以是个人或系统账户。用户被分配一个或多个角色,通过这些角色获得相应的权限。

  4. 会话(Session):会话是用户登录系统后与系统交互的时间段。在会话期间,用户的权限由其角色决定。

RBAC 的设计通常遵循以下几个步骤:

  • 角色定义:根据组织的需求和职责,定义不同的角色。每个角色应该清晰地定义其职责范围和所需的权限。

  • 权限分配:为每个角色分配所需的权限。这通常涉及到对资源的访问控制,例如文件、数据库记录或系统功能。

  • 用户角色分配:将用户分配到一个或多个角色。用户通过其角色获得相应的权限。

  • 最小权限原则:确保用户只拥有完成其工作所必需的最小权限集,这有助于减少安全风险。

  • 权限审查和更新:定期审查角色和权限的分配,确保它们仍然符合组织的安全策略和业务需求。根据需要更新角色和权限。

  • 会话管理:管理用户的登录和登出过程,确保在会话期间用户只能访问其角色允许的资源。

RBAC 模型的优势是灵活、可扩展。它允许组织根据变化的业务需求快速调整角色和权限,同时通过集中管理角色和权限简化了安全策略的实施。然而,RBAC 也需要仔细地设计和管理,以避免权限过度集中或不当分配,这可能会导致安全漏洞。

那么,保存了元数据之后,如何根据元数据检索知识呢?

如何根据元数据检索知识?

根据元数据检索知识,主要包括两部分主要工作。

  1. 根据用户提问判断是否需要检索元数据。

  2. 根据用户权限在有权限的知识里面检索

例如,用户提问:前天的CNET新闻有哪些?那么系统就应该识别出从CNET新闻表里面按照创建时间和当前用户权限来检索知识。

那么系统如何识别出应该从CNET新闻表里面按照创建时间和当前用户权限来检索知识呢?

是直接让系统返回查询的SQL语句吗?这样做不是很稳定,特别是使用免费的、性能较差的大模型。

这时候,我们就可以使用实战案例1里面的知识点了。我们基于第5节课的代码改造一下。

我们首先多添加一个序号,从CNET新闻表里面检索知识。

然后再添加一个示例,当用户提问:

前天的CNET新闻有哪些

这时应该返回序号、日期。

修改之后,我们就得到了后面的代码。

def 构造解析用户输入并返回结构化数据用的messages(用户输入):
  messages=[
  {"role": "user", "content": f"""
  请根据用户的输入返回json格式结果,除此之外不要返回其他内容。注意,模块部分请按以下选项返回对应序号:
   1. 销售对账
   2. 报价单
   3. 销售订单
   4. 送货单
   5. 退货单
   6. 从CNET新闻表里面检索知识
   7. 其他

  示例1:
  用户:客户北京极客邦有限公司的款项到账了多少?
  系统:
  {{'模块':1,'客户名称':'北京极客邦有限公司'}}

  示例2:
  用户:你好
  系统:
  {{'模块':7,'其他数据',None}}

  示例3:
  用户:最近一年你过得如何?
  系统:
  {{'模块':7,'其他数据',None}}

  示例4:
  用户:前天的CNET新闻有哪些?
  系统:
  {{'模块':6,'日期',-3}}

  用户:{用户输入}
  系统:
  """},
  ]
  return messages

然后,我们再根据系统的回答调用对应的知识检索函数,例如 根据用户和查询条件来检索CNET新闻 函数。

进行到这里,我们就可以根据元数据来检索知识了。

小结

好了,今天这一讲到这里就结束了,最后我们来回顾一下。这一讲我们学会了三件事情。

第一件事情是什么是元数据。元数据是指“数据的数据”,具体包括文章标题、作者、发布日期、访问权限等等。

第二件事情是如何获取和保存元数据。我们可以通过API等方式获取元数据,然后将元数据保存到数据库里面。一般来说,元数据的表结构都很简单,只是访问权限元数据表结构会复杂一点。

第三件事情是如何根据元数据检索知识。主要工作有两部分:第一,根据用户提问判断是否需要检索元数据。第二,根据用户权限在有权限的知识里面检索。

思考题

前面我们添加了一个示例,当用户提问:前天的CNET新闻有哪些?应该返回序号、日期。那么如果用户提问:最近一周的CNET新闻有哪些?这时应该如何处理呢?

欢迎你在留言区和我交流互动,如果这节课对你有启发,也推荐分享给身边更多朋友。