链载Ai

标题: OpenIM Bot已经在OpenIM官网上线了,欢迎大家使用 [打印本页]

作者: 链载Ai    时间: 昨天 10:19
标题: OpenIM Bot已经在OpenIM官网上线了,欢迎大家使用

背景

随着OpenIM的发展,技术和产品的咨询支持对国内、外的用户变得越来越重要。用户数量的迅速增加,使得OpenIM团队的支持人员面临巨大压力,因为支持人员的数量并没有同步增长。因此,找到一种高效的方法来服务用户成为团队当前迫切需要解决的问题。

通过分析几十个微信群、Slack社区以及Gmail邮箱中收集到的用户问题,发现接近一半的问题其实可以在OpenIM官网的文档中找到答案。然而,由于官网文档内容庞大,目前已经积累了800+网页,用户往往难以快速定位所需信息。因此,构建一个智能客服系统,包含OpenIM官网所有文档的知识库,可以帮助全球用户更便捷地获取信息,更好地了解和使用OpenIM。这个智能客服不仅能减轻支持团队的负担,还能提升用户体验,提高问题解决效率。

技术调研

自从ChatGPT横空出世以来,其自然、流畅的对话引起了全球的瞩目。基于大语言模型(LLM)搭建的AIGC应用如雨后春笋般涌现,掀起了这波AI新浪潮。对于个人用户来说,ChatGPT文心一言以及豆包等LLM应用可以直接使用,并能帮忙解决很多问题。然而,对于企业应用来说,情况要复杂得多。实效性、私有数据的处理、幻觉现象和数据安全等问题,都可能成为潜在的隐患。

LLM问题

在明确需求后,我们需要了解大语言模型(LLM)的特性和限制,以确定其在OpenIM Bot建设中的可行性。仅依靠LLM会面临多种限制,以下四点是最主要的:

RAG方案

RAG(检索增强生成,Retrieval-Augmented Generation)是一种结合搜索技术和LLM生成能力的方法。其核心理念是通过从数据源中检索相关信息,并将这些信息作为生成答案的基础。具体而言,RAG通过搜索算法找到与查询相关的内容,并将这些内容作为上下文整合到传递给LLM的提示中,进而生成更准确和详细的回答。

随着LLM的广泛应用,RAG架构迅速成为热门技术。许多产品和服务依赖于RAG架构,从结合网络搜索引擎和LLM的问答系统,到各种数据交互应用程序,RAG架构的应用范围越来越广泛。这种方法不仅提升了回答的准确性,还极大地扩展了LLM的功能和应用场景。

OpenIM Bot的需求

针对OpenIM的业务场景,我们希望LLM能够实现以下需求:

通过满足这些需求,OpenIM Bot将能够有效地提供技术支持和产品咨询,提升用户体验。

落地实践

向量存储

向量存储本质上是专门设计用于高效存储和管理向量的数据库,这些向量是由文本Embedding模型(例如OpenAI的text-embeddingAPI)生成的高维数组。

在OpenIM Bot中,向量存储在增强LLM的能力方面发挥了关键作用。以下是详细的过程:

  1. 向量生成:每当与OpenIM相关的新内容引入或现有内容更新时,我们使用文本Embedding模型将这些文本信息转换为向量。每个向量都像是其对应文本的唯一指纹,在高维空间中封装其意义。

  2. 相似性搜索:存储这些向量的核心用途在于当我们需要找到与用户查询相关的信息时。通过使用相同的Embedding模型将用户的问题转换为向量,我们可以在向量存储中执行相似性搜索。此搜索通过在Embedding空间中计算向量之间的距离来识别与查询最接近的向量(及文档)。

  3. 上下文检索和增强:通过相似性搜索检索到的文档是有助于语言模型生成相关答案的相关信息。通过提供这些上下文,我们使语言模型能够生成不仅准确且由我们数据库中最新的、最相关的信息支持的响应。

OpenIM官网知识库建设

我们需要将https://www.openim.io/https://docs.openim.io/这两个域名下的所有官方文档导入到向量数据库中。

在此过程中,需要注意以下几点:

class MarkdownTextSplitter(RecursiveCharacterTextSplitter):
def __init__(self,
separators: Optional[List[str]] = None,
keep_separator: bool = True,
is_separator_regex: bool = True,
is_remove_empty_line: bool = True,
**kwargs: Any,
) -> None:
"""Create a new TextSplitter."""
super().__init__(keep_separator=keep_separator, **kwargs)
self._separators = separators or [
"\n\n",
"\n",
"。|!|?",
"\.\s|\!\s|\?\s",
";|;\s",
",|,\s"
]
self._is_separator_regex = is_separator_regex
self._is_remove_empty_line = is_remove_empty_line

通过以上步骤,我们可以确保知识库中的文档高质量、格式统一,并且适合LLM处理,从而为 OpenIM Bot 提供准确可靠的知识基础。

在实际操作过程中,我们积累了一些有价值的经验教训。通过爬虫抓取网页后,将其中的文本内容抽取并转换为Markdown格式https://docs.openim.io/的每个网页都有一个导航目录。在最初的尝试中,我们没有对这部分内容进行特殊处理,而是尽可能地保留网页上的所有文本信息。然而,在测试过程中我们发现,对于某些查询,召回的文档几乎全部是这些导航目录的内容,导致 LLM 无法根据这些内容生成有效的答案。

例如,网页https://docs.openim.io/sdks/api

对应的部分 chunk 信息。这些 chunk 没有实际用途,但会干扰检索召回,并占用向量数据库的存储资源。

为了解决这个问题,我们在处理网页抓取内容时进行了清洗操作。具体方法如下:

async def parse_content(self, html_text: str, url: str) -> List[str]:
logger.info(f"[CRAWL_CONTENT] parse_content, url: '{url}'")
try:
# Use BeautifulSoup to parse HTML content
soup = BeautifulSoup(html_text, 'html.parser')

# Remove all the tags that are not meaningful for the extraction
SCAPE_TAGS = ["nav", "footer", "aside", "script", "style"]
[tag.decompose() for tag in soup.find_all(SCAPE_TAGS)]

通过移除网页中的nav等标签内容,向量数据库的大小从123M减少到50M,大幅提升了检索效率和存储利用率。

这一经验表明,在抓取和处理网页内容时,对无用信息进行清洗是非常必要的。这不仅可以提升向量数据库的存储效率,还能显著提高检索结果的质量。

检索

在LLM应用技术架构中,通过检索上下文来回答用户的问题,是解决大模型“幻觉”问题的有效方案。RAG在LLM中的地位愈发重要,检索召回的质量和用户query的质量直接影响到大模型生成结果的准确性。

随着向量数据库的广泛应用,单纯依靠语义搜索已不能完全满足企业需求。传统的搜索技术(如基于关键词和词频的搜索)再度显示出其价值。因此,混合检索成为RAG中的主流。混合检索结合了多种搜索技术的优点,能够在不同的业务场景中灵活应用,形成互补,满足多样化的需求,是RAG中关键的一环。

混合检索结合了以下两种主要搜索技术:

  1. 文本搜索:基于BM25和TF-IDF算法进行的文本匹配搜索。它在处理特定术语(如产品名称或专业术语)时效果显著,但对拼写错误和同义词较为敏感,可能忽略一些重要的上下文信息。

  2. 语义搜索:使用向量的KNN算法进行的语义搜索。该方法能基于query的语义含义进行多语言、多模态的检索,对拼写错误具有较好的容错性,但有时可能忽视关键字的精确匹配,其效果依赖于向量嵌入的质量,对非专业领域的术语较为敏感。

混合检索的优势

混合检索结合了相关性搜索和语义搜索的优势,具体表现为:

主流向量数据库介绍

不同的向量数据库在功能和应用场景上有各自的特点,以下是一些主要的向量数据库及其支持的检索类型:

  1. Chroma






欢迎光临 链载Ai (https://www.lianzai.com/) Powered by Discuz! X3.5