
本文首发个人博客:llm与RAG的学习与优化 - 黑白の世界
欢迎点击,评论
这是一篇拖延了半年的文章。
年初有计划做一下基于LLM大模型的应用,正好公司有业务需求,于是学习了一下RAG的相关知识,一边看字节开源的 eino 框架学习开发,一边补充这 agent,mcp,rag相关的知识。
当时就计划写一篇总结的文章,不过之后事情太多有些搁置。今天终于是打算拿出来,总结一番。
笔者也是探索中学,如果读者有更好的建议,可以直接在评论区留言。
如果是一位没有接触过AI开发,只局限于使用AI工具的朋友。
可能会对提及的这些名词有些疑惑,可能经常看到一些新闻携带这些名词。
对于 AI应用开发。对于模型的调用方法多种多样,不同家有不同的标准
而我们最常用,也就是各种大模型平台最经常提供的接入方式就是OpenAI标准。
下面是一个使用curl调用OpenAI chat/completions接口的示例:
curl https://api.openai.com/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $OPENAI\_API\_KEY" \
-d '{
"model": "gpt-4",
"messages": [
{
"role": "system",
"content": "你是一个乐于助人的助手。"
},
{
"role": "user",
"content": "你好!"
}
],
"stream": false,
"temperature": 0.7
}'关键参数说明:
model: 指定使用的模型,例如 gpt-4, gpt-3.5-turbo。messages: 一个消息列表,用于驱动对话。role: 角色,可以是 system (设定助手行为), user (用户提问), 或 assistant (模型之前的回复)。content: 消息的具体内容。stream: 是否使用流式传输。如果为 true,服务器会分块发送数据,实现打字机效果。temperature: 控制输出的随机性。值越高(如 0.8),输出越随机;值越低(如 0.2),输出越确定。Authorization: 你的API密钥,通常从环境变量 $OPENAI\_API\_KEY 中获取。RAG 检索增强生成(Retrieval Augmented Generation)
RAG的提出是因为大模型存在幻觉问题,大预言模型虽然看上去万能,但其实很多时候会一本正经的胡说八道,如果是编程开发中出现这种问题,问题不大,大不了跑一下发现编译不通过重新编码
但是在医生,律师等行业如果出现这种现象,那么就会导致严重的问题。为了解决这个问题,业界提出了RAG方法 Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks。
最初的版本就是,在与AI交互的过程中,在prompt中,尤其是 role 中的 system中,写入相关知识内容,防止AI胡编乱造,
简单来说,向量就是一串数字,它像一个‘语义坐标’,代表了文本在多维空间中的位置。意思相近的文本,它们的‘坐标’在空间中也会靠得很近。
但是当相关知识内容变得庞大后,单纯的在prompt中内置全部资料的方法就失效了。
一是模型存在上下文token限制,过多的资料反而会导致它出现幻觉
二是出于成本考虑,如果塞入过多的资料,但是实际只用到其中的一点,那就会导致token浪费,开销过高
然后就有人提出,将不同的资料都存入向量数据库。在AI需要的时候,根据我们的描述内容的向量结果去匹配数据库中符合的向量。
将符合的top k 都视为匹配的数据给到 llm模型 就好。这样节省了token开销,而且还能保证资料可靠
在向量搜索领域,主流的匹配方式分为两大流派,它们分别解决了不同类型的问题:
本来想写一节谈论向量匹配的方法,比如余弦相似度,欧氏距离,点积之类的,不过本文更多是面向开发者,所以就不多谈了,还是聊一聊开发技术选型强关联的内容
向量索引,也可是一种数据库索引。不过它有很多类型
pgvector 插件)**pgvector 插件可以为 PG 提供向量检索能力。基础的RAG流程很简单:
sequenceDiagram
participant 用户
participant RAG程序
participant 嵌入式模型
participant 向量数据库
participant LLM模型
用户->>RAG程序: 1. 提问
RAG程序->>嵌入式模型: 2. 将问题文本向量化
嵌入式模型-->>RAG程序: 返回问题向量
RAG程序->>向量数据库: 3. 使用问题向量进行搜索
向量数据库-->>RAG程序: 返回Top-K相似文档
RAG程序->>LLM模型: 4. 构造Prompt(相似文档 + 原始问题)
LLM模型-->>RAG程序: 生成最终答案
RAG程序-->>用户: 5. 返回答案这是一个需要注意的点。刚开始接触RAG系统的人(就是本人),往往会因为一开始小数据量的成功匹配,将向量匹配当成问答系统了。
明明向量是由数据向量出来的,却用问题的向量去匹配
如:
向量内容: 岗位名称:go开发工程师
提问: 我这里有一个简历,它的内容是 1.预期岗位go .....
这样或许也可以匹配到,但是基本匹配系数比较低,当数据量增大后,容易匹配出一些奇怪的数据
基础的RAG流程虽然简单,但在实际应用中,召回的上下文质量直接决定了LLM生成答案的优劣。为了从“能用”到“好用”,我们需要一系列的调优手段来优化召回效果。RAG的调优可以分为三个核心阶段:**预处理(Pre-processing)**、**检索(Retrieval)** 和 **后处理(Post-processing)**。
将文档切分成合适的、独立的语义单元是RAG中最关键的第一步。分块的质量直接影响向量的质量和检索的精度。
\n\n, \n, )递归地分割文本,尽可能保持段落和句子的完整性。这是 LangChain 等框架中默认且推荐的方式。eino 框架的社区扩展eino-ext中,这是一种看上去就最很好用的方法(除了token开销更大)。而通过源码查看,它的开头处理也是递归分割,只是将分割后的每个片段来做余弦相似度对比,获得最符合语义的片段。通常,我们存储的不仅仅是文本块的向量,还会附带**元数据(Metadata)**,比如文档来源,这段记录对应的实际意义。不但可以用于知识库,还可以用于各种场景类向量数据库的优化。
type为帽子的结果。用户的原始问题可能与文档中的表述存在语义鸿沟。查询转换的目的就是通过改写或扩展用户的查询,来提升召回率。
还有一种最简单的优化方法。用户提问都过一遍LLM大模型,让他标准化一些。
向量搜索(召回/Retrieval)追求的是“快”和“广”,可能会包含一些不那么相关的结果。重排序则是在召回之后、生成之前,引入一个更“精”的模型,对初步召回的Top-K个结果进行二次排序。
以上内容大概就是笔者最近在大模型学习,RAG开发与特定领域向量数据库构建业务中的一些总结与优化心得。
同时不禁感叹,大模型从22年到如今的发展迅速。在去年的时候,更多还只是用于提示词和问答,而现在以及可以真的用于实际开发之中了。
从GitHub copilot 到 cursor 到claude code。各种工具越来越可靠,越来越现代化。
但是也有些养懒了大脑
同时在写文档中也有了很多帮助。 可以看到本文在谈到RAG调优的格式突然有些变化。因为到这里笔者有些懒了,手写了思路与大纲后,直接让AI优化,然后再手改一番。
本文还只是单纯的 RAG知识库,或者说向量数据库的相关技术点。下一篇就谈一谈 ai agent 与 mcp 吧
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。