在第五节我们只介绍了RAG中向量数据库的创建,但是没有说如何检索?
这里先说好,前提环境还是和之前一样
- 初始化好一个LLM大模型 ×1
- Embeddings模型 ×1
- vectorstore(向量数据库)×1
-
好啦,我们有上面那三个,那我们现在想要实现的就是,在我们提问大模型的时候,程序会带着问题去检索向量数据库找到最相似的片段,然后喂给大模型。
你可能会想,是不是还得手动实现vectorstore向量库搜索,什么相似度分析,然后再手动分析?但不是的哦。Langchain都实现了自动化,我们需要用到一个很重要的东西就是retriever,我们需要把vectorstore变成这玩意才能给大模型用哦(但你不嫌麻烦手写也是可以的)
1.第一步 转换格式
1 | retriever = vectorstore.as_retriever() |
2.第二步 设计一个rag提示词
我这里用的是hub的提示词,从from langchain import hub。这个其实就是约束大模型根据我们rag检索到数据库的知识回答减少产生幻觉 过后面主播发现这个库已经废弃了。。
就直接用模板提示词了
1 | # Prompt |
rlm/rag-prompt的中文翻译版
1 | 您是问答任务的助手。请使用以下检索到的上下文信息来 回答问题。 |
3.构造链
1 | rag_chain=( |
这边用到了一个函数哈,因为链条需要的是字符穿,直接检索给的是Liat[Document]这不中
1 | def format_function(docs): |
4.调用
这边别传字典啊。主播犯了一个很蠢的错误。。。因为第一个链的话,会把字典也传给检索器导致报错。
1 | rag_chain.invoke('what is Task Decomposition') |
总结
这边总结一下简单RAG使用吧
- 1 先加载数据。langchain提供了不同的loader,从from langchain_community.document_loaders这个库引入就好了,比如txt ,csv html.doc都可以。
- 2 加载文档doc=loader.load(),这里可以选择load_lazy()懒加载应对文本数量多的时候
- 3 定义文本切割器。使用的是RecursiveCharacterTextSplitter,里面需要传递的是切片Chunk的大小和重叠度。ps;这里得到的是List[Document]
- 4 进行切割 chunks=text_splitter.split_documents(doc),ps;这里得到的还是List[Document]。只不过是小份的
- 5 初始化Embeddings模型
- 6 初始化向量数据库,必须传递的是Embeddings模型,切片好的list[Document]
- 7 设置rag提示词,和对应的链条