咱 web 端也能跑本地知识库,RAG(傲娇)-篇章 1-核心技术方案

2 天前
 doujiangjiyaozha

核心技术方案如下

transfomerjs + indexdb

知识库与 RAG 介绍

可能有些小伙伴对这两玩意不太清楚,大致介绍下

知识库(偏狭义上或特定领域下的知识库)

知识库我觉得算是一个赛道方向,现在有很多家如 dify,openai 等等,包括阿里等平台,都有提供这类功能服务,通过将用户文本向量化(将文本变成数字),存储到数据库中,最后在搜索时,可通过文本再向量化,达到语义化搜索(向量相似度计算),最后将相应匹配的文本交给 AI 回答.

这样做的好处就是,当你存储的文本如果是 "我想吃苹果", 而你搜索的文本是"我吃苹果"或者"我超级 tm 的想吃苹果"时,是能够搜索到的.

RAG

而 RAG,则是实现这样知识库的一个手段,如向量化,分片文本,文本预处理,巴拉巴拉的

划重点,圈起来,要考的地方

向量化,向量化,向量化

回归正题

向量化

通过 transfomerjs 来处理文本向量化,这样咱就完成了最基础也是最核心的地方,参考代码如下

import { env, pipeline } from '@huggingface/transformers';
// Create a pipeline for feature extraction, using the full-precision model (fp32)
const pipe = await pipeline('feature-extraction', 'your-model-name', {
    dtype: "fp32",
});
const output = await pipe(inputTexts, { pooling: 'mean', normalize: true })

文档链接: https://huggingface.co/docs/transformers.js/pipelines

存储与搜索

而由于是在 web 端,要能存储大量数据的方案,也只有 indexdb 了(好像是可以存储电脑总硬盘量百分之五十哦,记不太清楚了)

但这有个问题,向量化的数据怎么存储到 indexdb 并保证搜索呢???

要知道,大部分服务端存储向量数据方案,是有专门的向量数据库的,而 indexDB 是类似于 Mongodb 的 JSON 存储,这咋玩???

咱们不妨把心思放野一点, 自己实现个最基础的向量数据库试下呢

思路也有,而我,采用了 LSH 方案,细节太多了,后续可以单开篇章来讲,感兴趣的可以直接看源码

啥,你觉得这个技术栈不靠谱,看下面!!!

成果

代码已开源

github.com/Yoan98/Ncurator

想看实际演示?这里

www.ncurator.com

有啥能证明这个玩意靠谱呢?这里

1.上了阮一峰的周刊 科技爱好者周刊(第 337 期):互联网创业几乎没了

2.上了 DeepSeek 的集成推荐 https://github.com/deepseek-ai/awesome-deepseek-integration

1012 次点击
所在节点    程序员
13 条回复
musi
2 天前
仅靠向量实现 RAG 不是早就被证伪了么,做 demo 可以,落地不行
doujiangjiyaozha
2 天前
@musi 额 我不知道哪有被证伪了;但是呢,仅靠向量肯定是不行的,而没有向量也是肯定不行的;
NjcyNzMzNDQ3
1 天前
向量化到本地思路挺好啊,类似输入法选特定领域的提示词,让用户自己选
ovate
1 天前
@musi 您好能具体讲讲落地的困境么?或者可否分享下相关文章
doujiangjiyaozha
1 天前
@NjcyNzMzNDQ3 是的 随着后期设备性能普遍增强 即使只是 cpu ,在客户端向量化且面对数据不是特别大,或者允许时间延长,也将是不错的方案
musi
1 天前
@ovate 依靠 LLM 向量检索在文本转向量期间还是会受到 LLM 窗口大小的制约,所以需要对源文档进行拆分。所以引入第一个问题:
一、怎么拆分文档?
1. 根据 LLM 窗口大小进行自动化拆分?
最开始的方法,因为拆分文档就是因为 LLM 窗口限制,所以自然而然的想到根据窗口大小进行拆分。但是在实践中发现,直接根据窗口大小不会联系上下文,同样的一个词在不同的上下文中的意思差别很大
2. 根据上下文拆分?
如何保证拆分的每一段文档都处于一个上下文中?上下文很大要怎么处理?

拆分完文档转向量入库这一步是最简单的,选取一个支持向量存储的数据库然后调用 API 就可以

入库完之后需要检索,这就是第二个问题:
二、如何检索?
直接通过余弦相似度计算向量?查出来有多个结果应该取哪个?相似度越高真的就越符合原问题吗?
musi
1 天前
@musi #6

依靠向量的 RAG 整体流程一般就是
1. 拆分文档
2. 文档转向量
3. 向量入库
4. 向量检索
5. LLM 根据检索到的数据进行生成

其中 1 4 的准确性都会影响到 5 的结果,加上 LLM 本身存在的幻觉,导致最终结果更加不可控
visper
1 天前
@musi 是的。知识文档的拆分才是重点。这才是最难的。除非他们的知识文档刚好一自然分段得很好。否则不管使用哪种分段方式,总可能会是不怎么合适。可能可以试下一开始建的时候用超长上下文的模型把知识文档整理成合适的问题和回答列表之类的。还有些自动用模型来整理实体关系来做知识图谱,不过感觉起来还是会有这个准确性的问题。
EspoirBao
1 天前
@musi #7 遇到个跟你说的一摸一样的问题, 现在的解决办法是将业务逻辑结合在文档拆分的那一步,但问题是跟传统开发也没有什么本质区别了,只能说大模型解决了之前没办法用纯编程来处理语义化的内容,不知道还有没有别的好的思路
llzzll1234
1 天前
@musi 现在我也在做企业知识库,目前发现最大的问题就是你说的拆分文档。
而且我们还遇到了另外两个问题:
1.问的问题本身在库里向量检索时不一定能匹配,但是对人来说这个问题和库中的文档又是有联系的,举个例子,库中有一篇做好了分段的年报,然后用户问“把年报中的一级标题都提取出来”,这句话对于 RAG 框架来说是几乎无法匹配的,但如果真把全文扔给人类或者大模型又是能做到的。
2.有个落地场景是规范标准,工艺工法的检索,但是这类文档里会经常出现类似“计算方法参见《 XXX 标准》第 3 章第 2 条”这样的和其他文档或者分段有关联的内容,而知识库是做不到这种多文档关联的查询的(得上知识图谱或者 GRAG 之类的,但目前看来好像也不是很成熟的样子)。

目前以上两个事情,包括文档拆分导致上下文断层的问题在我这几乎无解,所以不知道各位大佬有什么好的解决方案。
doujiangjiyaozha
1 天前
@llzzll1234 我的项目是直接使用 langchain 的分片的,看下对你是否有帮助,这是文档;我记得有个最屌的办法,就是用 ai 去分片,而不是纯靠代码逻辑
https://js.langchain.com/docs/concepts/text_splitters/#text-structured-based
llzzll1234
1 天前
@doujiangjiyaozha 您怕是完全没看我的问题吧?真正落地的时候会发现很多问题除非把全文都丢给知识库不然几乎无解,分片分出花来也只能解决上下文窗口的问题,而无法解决检索和内容跳转以及对全文理解的问题。
doujiangjiyaozha
1 天前
@llzzll1234 大哥,不是你开头说的目前发现最大的问题是拆分文档的问题吗,我理解的不就是文本分片,预处理吗?
你说的另两个问题,这本就是 rag 的弊端
我看到的落地方案,都是在建立在 RAG 之上,针对特定业务,将数据按照该业务特性,划分纬度拆分去搜索,或者是预处理文本拆分成小词,通过关键词搜索,从而扩大搜索范围,最终将多种结果优化排序,再通过意图分析,即便一次无法匹配完内容,通过让 ai 引导用户来尝试更精准与下一次的搜索

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://yangjunhui.monster/t/1129675

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX