type
status
date
slug
summary
tags
category
icon
password
大家好,我是鹤涵。
最近一直在给一些企业做 AI 知识库的落地的工作,有了一定的收入。但是在期间发现了一些不足和改进点,做一个整理复盘。
一、大模型的不足
以 ChatGPT 为首的大模型的,让我们看到了生产力再一次飞跃。
ChatGPT 可以在很多工作场景中提高效率:
辅助编程: 使用 AI 来提高编程效率,帮助编写代码。
辅助文章输出:可以通过翻译、总结、头脑风暴等方式生成深度文章,帮助快速产出内容。
智能客服:可以用来支持客服工作,回答常见问题或提供相关建议。
自媒体:可用于撰写短视频脚本、文案创作、内容批量生成等,助力自媒体创作。
爆文写作:使用 ChatGPT 来撰写引人入胜的文章,吸引更多读者关注。
看起来能用到AI的地方有很多,但是每个垂直方向在实际操作落地的时候会感觉「十八般武艺,样样稀松」。
好像它什么都会,但是产出的内容直接用在复杂的生产环境上,总好像差点意思。
一)局限性
1、领域信息不足
虽然 LLM 仅基于公开数据集进行训练,但这也意味着它缺乏领域特定或专有等非公开的信息。这可能导致在某些情况下, LLM 无法提供更准确或更全面的回答。
2、有可能产生误导
尽管 LLM 尽力根据已有的数据提供信息和答案,但在超出其范围的情况下,它可能会给出不正确或是虚构的信息。这是因为 LLM 无法直接获取新的信息或与实时数据同步。
3、无法获取实时信息
由于 LLM 的训练成本非常高,它无法实时更新其知识库。因此,LLM 可能无法提供最新的信息或跟上快速变化的情况。
4、预训练数据不可更改
LLM 使用的预训练数据可能包含错误或过时的信息,并且无法进行更正或删除。这意味着 LLM 可能会基于不准确或过时的数据进行回答。
5、缺乏长期记忆
LLM 设计的目标是根据输入的数据给出准确的回答,但它没有真正的长期记忆能力。这意味着 LLM 可能在处理复杂的问题或需要上下文理解的情况下表现不佳。
二)改进点
1、领域信息不足
1)嵌入(Embedding)+向量数据库建立知识库,拓展认知边界
把私有数据进行切分,Embedding转成向量,存入向量库中。这样就可以通过向量搜索给大模型加上私有数据了。
2)微调(Fine-tuning) 针对专业领域进行特定训练
Fine-tuning 就是在大模型的基础上投喂自己的私有数据,从而生成一个新的模型。然后使用新的模型就可以使用到投喂的私有数据。
它确实可以解决领域信息不足的问题,但是他的缺点也非常多。
需要大量标注数据: Fine-tuning 需要大量标注的数据才能在特定任务上取得好的效果。如果标注数据有限,可能会导致性能下降。
准确性难以保证:Transformer 本质上是基于“单词接龙”,无法基于领域私有数据进行准确输出。
修改困难:如果想对 LLM 中的数据是不能直接修改的,只能重新训练。就像一个人已经形成习惯了再去修改是很难的。
2、有可能产生误导
1)使用提示词工程 Prompt-Engineering 规定限制
比如使用如下提示词,让 LLM 只从我们提供的信息中查找,不会自己随意发挥。
2)增加更多的上下文信息
通过增加向量检索结果的 context 条数以降低误导的风险
3、无法获取实时信息
1)利用向量数据库为大模型建立记忆,及时更新
导入到向量库中的数据是可以随意增删改的,相比微调灵活性高狠多。
2)结合实时数据源,确保信息的时效性
可以定期的导入增量数据,从而提高数据时效性。
当然也可以接入联网搜索API(google, bing 等等),那这就是另一个话题了。
4、不变的预训练数据
1)RLHF(Reinforcement learning from human feedback) 人工纠正再次微调
2)从向量库中剔除无效信息
5、缺乏长期记忆
利用向量数据库建立知识库,存储超长上下文。
由于 LLM 有最大 Token 数量的限制,只能使用 few-shot 的形式进行简单的数据投喂。
使用向量库就可以支持超大上下文(一本书,文献,课程等)的导入和读取。
二、向量库改进大模型
Embedding 和 Fine-tuning 对比下来还是使用 Embedding+向量库的方式更适合做知识库。
Embedding | Fine-tunine |
易于管理 | 适用于较小的知识库 |
更精确和具有上下文的答案 | 没有知识的访问控制 |
高度适应性和灵活性 | 高前期成本,高维护成本 |
更好的模糊搜索能力 | 知识不是最新的 |
一)什么是 Embedding?
Embedding 度量了文本字符串之间的相关性。Embedding 通常用于:
搜索(根据与查询字符串的相关性对结果进行排序)
聚类(将文本字符串按相似性分组)
推荐(推荐具有相关文本字符串的项目)
异常检测(识别与相关性较低的异常值)
多样性测量(分析相似性分布)
分类(根据最相似的标签对文本字符串进行分类)
Embedding 是一个浮点数向量(列表)。两个向量之间的距离测量它们的相关性。较小的距离表示高相关性,较大的距离表示低相关性。
调用 OpenAI 的
text-embedding-ada-002
看下向量到底是什么玩意?请求:
响应:
通过使用 Embedding 接口,我们将输入的文字转换成了一个浮点数数组的多维向量表示。这个多维向量表示了输入文字的语义信息,并且可以用于各种自然语言处理任务,如文本分类、信息检索和机器翻译等。使用 Embedding 接口可以帮助我们更好地理解和处理文字数据,提高我们的文本处理效果。
二)什么是向量库?
向量库是一个用于存储向量数据的数据库。它可以将文本、图像或其他类型的数据转换成向量形式,并将这些向量存储在数据库中。向量库的主要目的是支持向量检索,即根据查询向量的相似性,在数据库中找到最相似的向量。
简单来说就是存储向量的,把我们 Embedding 的结果存入向量库,从而构建知识库。
三)向量检索好在哪?
当搜索一个词或短语时,通过计算你的搜索词与数据库里每个项目的向量相似度,返回最相似的结果。
与传统的分词搜索相比,向量检索有以下优点:
更好的理解语义:向量检索能够更好地理解词语或句子的意思,因为它不仅仅是基于关键词匹配。
处理同义词:它可以识别不同词语之间的相似性,比如“手机”和“移动电话”。
跨语言搜索:向量检索可以更容易地进行不同语言之间的搜索。
简单来说,向量检索可以通过语义进行搜索,不像传统搜索需要关键词完全匹配,更像跟一个真实的人在对话。
三、CVP 技术栈落地
一)CVP 详解
ChatGPT /LLM: 大模型是大脑,用于总调度。
Vector database: 向量库是记忆,存储超大上下文
Prompt-as-code:Prompt 是逻辑能力,用来调整问答质量。
二)核心流程
1、把私有数据进行切分后,使用模型进行向量化,然后存储到向量库中。
2、用户提问时先在向量库中进行向量搜索,匹配相关联的n条数据。
3、把用户的问题和向量库匹配结果格式化成一个 Prompt,发送给大模型,得到最终结果。
三)FastGPT 技术栈落地
强烈推荐一个 CVP 的开源技术方案「FastGPT」,我也作为 FastGPT 的 Contributor 贡献过一些代码。
除了支持 CVP 的能力,还支持“高级编排”,可以自定义很多复杂的应用。
项目技术栈: NextJs + TS + ChakraUI + Mongo + Postgres(Vector 插件)
四)系统搭建
使用
docker-compose
一键启动1、安装Docker
Docker 安装:https://www.docker.com/
Docker-compose 安装:https://docs.docker.com/compose/install/
2、创建配置文件
在 fastgpt 目录下创建
config.json
文件在 fastgpt 目录下创建
docker-compose.yml
文件修改上面配置文件中的 OPENAI_BASE_URL,CHAT_API_KEY 替换成自己的 key。
3、启动脚本
4、访问网站
目前可以通过
ip:3000
直接访问(注意防火墙)。登录用户名为 root
,密码为 docker-compose.yml
环境变量里设置的 DEFAULT_ROOT_PSW
。五)知识库搭建
1、创建知识库
默认使用 OpenAI 的 Embedding 模型把文本转成向量(不懂什么是向量也不影响使用哈)。
还可以设置标签,方便知识库进行分类
2、导入私有数据
支持丰富的导入方式。
可以手动输入 QA,也可以从网络/本地文件中提取文本的方式导入
3、测试向量搜索
可以输入文本测试向量库的搜索,下面 0.8884 就是文本和知识库片段的相似度。
六)应用搭建
1、创建应用
我们选知识库+对话引导这个最经典运用到 CVP 技术的场景
2、关联知识库
关联刚创建的知识库,填写自定义 Prompt 控制输出。
3、测试知识库问答
这里就跟我们正常使用 GPT 一样,通过文本的方式对话,也支持聊天上下文。
同时还会显示向量搜索的结果,上下文情况, Token 消耗,完整响应日志,帮助我们优化应用。
虽然可以完成基本的知识库能力,但是效果并不是那么好。会经常出现想要的内容搜不到,不想要的内容却可以搜出来的情况。
这就会导致在对准确度要求严格的场景无法使用。所以要进行召回效果优化。
四、召回效果优化
在互联网业务中常见的推荐、广告、搜索等场景下,召回是指从大规模数据集中快速检索出一些候选项,以便进一步进行排序和筛选。召回阶段的目标是尽可能多地捕捉到用户可能感兴趣的内容,以提供更准确和相关的推荐、广告或搜索结果。
在知识库场景下的召回就是如何找到跟问题最相关的文档片段。
其中重点可优化的点一个是在索引阶段(文档导入),另一个是在召回阶段(文档搜索)。
一)索引阶段
1、优化文档分段模式
文档切分最准确的方式肯定是按照固定的字数(比如600字)切开,但是可能会把语义连贯的文字切分到两个片段造成部分数据缺失。
1)上下文理解
在文档切分的时候使用提示词工程(Prompt Engineering)进行上下文理解,保证连贯语义的上下文不切割。
2)文件格式清洗
由于LLM是文本语言模型,最终得把文件的格式清洗成纯文本再进行投喂。比如 PDF , Word ,网址,都必须通过技术手段最终转化成文本(OCR技术和爬虫技术已经比较成熟了)。
而结构化文本 Markdown ,当然是语料的首选,由于本身就是纯LLM可以很容易的识别出来。
但是如果一个标题下面内容太长了怎么办呢?
比如下面这个Markdown我们可以把标题识别出来放在下面多个文本段前面
before:
after:
这样我们就可以通过标题1,标题2检索到全量内容了。这个代码不难,当然可以直接让 GPT 帮我们去写~
2、切换 Embedding Model
根据文档的特性(语言、内容),选择 Embedding 模型。
不同语言,不同细分领域使用同一个Embedding模型,可能会对某些领域知识不了解,导致转化成的向量不是很精准。而向量生成是第一步,会影响后续的召回。
我们不仅仅可以使用 OpenAI 的
text-embedding-ada-002
,还可以选择 m3e
等等上百种 Embedding Model。3、自动生成QA
将文档转化为问题,并使用问题召回方法
使用提示词工程(Prompt Engineering)把分段后的文本自动切分 Question/Awser ,使用 Question 进行召回。
二)召回阶段
1、参数调整
不断调整相似度,单次搜索上限,温度值,回复上限来测试最佳效果
相似度越高,搜索结果越准确。
单次搜索上限越高,私有数越月丰富,Token消耗越快。
2、Prompt调整
可以通过 Prompt 调整,让知识库只回复私有数据中有的内容,不自己”胡编乱造“
3、用户问题改写
用户的问题可能很不规范,导致召回效果差。同样使用提示词工程对用户问题进行改写,然后再去向量库召回。
4、多路召回
由于向量召回是属于模糊匹配,依赖于 Embedding 是否准确,容易产生幻觉。
所以引入“多路召回”,在使用向量召回的同时,也使用原始的分词召回(如ES)进行精准匹配。
把多路召回的结果合并后继续走后续的流程。
三)召回后排序
当召回出的文档片段数量比较多的时候,只对召回结果通过相似度取 topK 就不够了。
需要对召回结果进一步做粗排,精排,重排,把大的候选集优中选优得到 topK。
五、总结
一)文档的清洗非常重要
整理清洗工作也可以利用人工智能来更快更好地完成。
上面这些优化甚至可以封装成一个智能体 FileAgent 的单独项目来对文档进行清洗,再导入知识库。
二)知识库在企应用非常广
知识库的在企业中的应用场景非常多
智能客服,企业培训,Copilot 助手,数字分身这些场景都需要知识库来提供记忆。
随着时间推移,承接业务越来越复杂,会持续涌现出各种各样的优化。
希望大家可以多多讨论交流,共同进步。
六、联系我
公众号:
微信:
- 作者:鹤涵
- 链接:https://www.hehanwang.com/article/llm-cvp
- 声明:本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。