今天尝试跟进知识库的搭建
我这边还是使用的智谱的模型
使用智谱的LLM模型, 需要提前知道langchain目前不支持智谱的模型, 需要通过继承langchain_core.language_models的BaseChatModel来自定义, 其中主要实现两个私有方法即可, 一个是_generate方法, 用来调用智谱的API对喂给LLM的输入进行响应, 生成回答, 另外一个是_stream方法, 通过调用智谱的API返回stream输出, 另外还需要实现一个消息转换的函数, 用于把langchain的消息格式转化为智谱支持的格式, zhipuai_llm的设计思路就是这样
我们继承了langchain_core的BaseChatModel之后, 只需要调用LLM的invoke方法, 输入prompt, 即可让模型做completion
例如:
接下来就要基于上一届中已经搭建的向量知识库, 对query查询问题做召回, 将q, v结合后构建prompt喂给LLM做回答
建立向量数据库的方法跟第三章一模一样, 这里跳过
这里可以使用向量数据库的as_retriever方法把向量数据库构造成检索器
check一下检索到的内容:
向量数据库没问题以后, 就可以进行检索链的创建, 在课程示例中用LangChain Expression Language来构建这个workflow
下面用上面定义的retriever来定义一个简单的检索链:
这里面的RunnableLambda是LCEL中要求的类型, 这里的chain用到了管道符号链接retriever和定义的combiner, 即输入会先输给retriever检索器, 再由combine_doc对检索器的输出做整理
构建好以后, 再定义prompt模板, 就可以构造一个由langchain支持的LCEL数据到prompt然后喂给大模型最后再输出的标准的检索问答链, 这里原作者用的openai的模型, 我用的是智谱
这里可以试一下检索问答链的效果
然后看一下大模型直接输出的结果
可以看到大模型的输出有比较高的幻觉成分, 但是经过本地知识库以后, 回答质量明显变高了
然而, 以上有个问题, 这种思维链无法记住之前输入的内容, 这个特点不利于聊天机器人的搭建, 对话就不连续了
这样, 我们可以用Langchain中的ChatPromptTemplate,把先前的对话输如到语言模型中, 就像增加了一个cache
但是这也有问题, 如果对话的语义不全, 这样在查询向量数据库的时候就比较难检索到信息, 比如代词这种指代不明的情况, 为解决这个问题, 就可以用信息压缩的方式, 如下
然后我们可以看一下带和不带聊天记录的区别
最后面是使用streamlit做一个llm的网页端app, 还是很有意思的