Key Words

LangChain供给了便利的组件库能够将LLM模型与各种外部数据源(图片、PDF、视频、邮件…)进行衔接。并供给了一个东西链,能够指导LLM履行一系列的任务(简单的关于文件查询、杂乱的关于职业常识图谱的收集)。从而为LLM扩展了更多的能力。

触及常识点

  • 如何完成对不同LLM支撑对接。经过Api、自定义LLM Wrapper的方法和闭源、开源模型交互;
  • 外部非结构化数据源导入;
  • 数据Embedding。尤其是对中文场景下向量相似度区别;
  • 使用向量数据库进行数据检索;
  • Prompt管理,自定义模板规划。假如经过零样本、小样本、示例等方法规划Prompt;

LangChain是什么?起到什么效果?

LLM模型自身现已把握了必定的常识。可是假如想让模型对一些“它”不了解的内容进行回复时。咱们需要先要奉告模型一些“额定”的内容(当然也能够经过预训练和finetunin的方法对LLM进行微调、这个能够再另一篇文章做阐明)。这些“额定”的内容可能是一份PDF文档、或者是某个视频。这些就是“外部常识库”。咱们期望LLM能够帮咱们对这些“外部常识库”进行的问答、总结。这个时候就能够用到LangChain。

简单说LangChain的效果如下:

  1. 能够将 LLM 模型与外部数据源进行衔接
  2. 供给一些组件能够更高效的和 LLM 模型进行交互。比如对向量数据库的支撑。

LangChain 包括的组件

组件阐明

大模型实战入门(一)-通过LangChain+GLM实现基于本地知识库的问答应用案例

本文并不会对LangChain所包括的组件进行详细的阐明。本次首要触及ModelsIndexesPrompts 3个组件(其他组件另开章节再说,也能够参阅能够参阅 LangChain Doc 文档 – Pyhton)。Models首要担任和本地以及在线LLM的交互。Indexe首要担任和外部数据源以及向量数据库打交道。Prompts是给LLM更精准的输入信息以及输出格式。

简单举例介绍-爬取网页并输出JSON数据

LLMRequestsChain 是 LangChain供给的一个API。能够直接获得访问URL的Html内容并进行解解析。参阅链接:LangChain-LLMRequestsChain

from langchain.prompts import PromptTemplate
from langchain.llms import OpenAI
from langchain.chains import LLMRequestsChain, LLMChain
# 和OpenAI的GPT 模型进行交互。
llm = OpenAI(model_name="gpt-3.5-turbo", temperature=0)
# 结构Prompt 模版
template = """在 >>> 和 <<< 之间是网页的回来的HTML内容。
网页是新浪财经A股上市公司的公司简介。
请抽取参数恳求的信息。
>>> {requests_result} <<<
请使用如下的JSON格式回来数据
{{
  "company_name":"a",
  "company_english_name":"b",
  "issue_price":"c",
  "date_of_establishment":"d",
  "registered_capital":"e",
  "office_address":"f",
  "Company_profile":"g"
}}
Extracted:"""
prompt = PromptTemplate(
    input_variables=["requests_result"],
    template=template
)
# 使用LLMRequestsChain 访问Url
chain = LLMRequestsChain(llm_chain=LLMChain(llm=llm, prompt=prompt))
inputs = {
  "url": "https://vip.stock.finance.sina.com.cn/corp/go.php/vCI_CorpInfo/stockid/600519.phtml"
}
response = chain(inputs)
print(response['output'])
# 回来成果
{
  "company_name":"贵州茅台酒股份有限公司",
  "company_english_name":"Kweichow Moutai Co.,Ltd.",
  "issue_price":"31.39",
  "date_of_establishment":"1999-11-20",
  "registered_capital":"125620万元(CNY)",
  "office_address":"贵州省仁怀市茅台镇",
  "Company_profile":"公司是根据贵州省人民政府黔府函〔1999〕291号文,由中国贵州茅台酒厂有限责任公司作为主发起人,联合贵州茅台酒厂技能开发公司、贵州省轻纺集体工业联社、深圳清华大学研究院、中国食物发酵工业研究院、北京市糖业烟酒公司、江苏省糖烟酒总公司、上海捷强烟草糖酒(集团)有限公司于1999年11月20日一起发起设立的股份有限公司。经中国证监会证监发行字[2001]41号文核准并依照财政部企[2001]56号文件的批复,公司于2001年7月31日在上海证券交易所公开发行7,150万(其中,国有股存量发行650万股)A股股票。主营业务:贵州茅台酒系列产品的生产与出售,饮料、食物、包装材料的生产与出售,防伪技能开发;信息产业相关产品的研制和开发等。"
}

案例-根据本地常识库的问答使用

本案例参阅根据本地常识库的 ChatGLM 等大言语模型使用完成。使用 langchain 完成的根据本地常识库的问答使用。经过ChatGLM对一份本地的文档进行解析。并根据解析内容对用户输入的问题进行答复。

项目工程结构

大模型实战入门(一)-通过LangChain+GLM实现基于本地知识库的问答应用案例

加载ChatGlm模型

因为 LangChain 没有对 ChatGLM 的支撑,需要用自定义LLM Wrapper的方法封装ChatGLM模型。官方的完成参阅:How to write a custom LLM wrapper。 同时学习在huggingface上的完成。加载本地ChatGLM模型。

相关代码

model_name_or_path: str = "/root/autodl-tmp/model/chatglm-6b"
...
self.tokenizer = AutoTokenizer.from_pretrained(model_name_or_path,trust_remote_code=True)
model_config = AutoConfig.from_pretrained(model_name_or_path, trust_remote_code=True)

这儿能够引申一个常识点,如何将ChatGLM进行本地化部署并经过本地Api对外供给服务。

加载外部数据并进行检索

  1. 经过Unstructured File Loader将从指定源进行数据的加载并生成Document目标并进行文本切割。详细能够参阅LangChain官方文档Unstructured File Document Loader 。

    1.1 Document目标阐明。Document目标首要包括了page_content,以及meta_content两部分内容。

      ```
        [Document    (page_content='LayoutParser : A Unified Toolkit for Deep Learning Based Document Image Analysis',      lookup_str='',      metadata={'source': '../../layout-parser-paper.pdf'},      lookup_index=0)]
        ```
    

    1.2 文本切割阐明。需要文本切割的原因是每次不管是做把文本当作 prompt 发给LLM,仍是仍是使用 embedding 功能都是有字符限制的。

  2. 将外部数据向量化存储,并使用向量数据库进行检索。

    2.1 数据向量化并存储

    数据向量化能够简单理解为用一组浮点数据来表明一个实体目标。这个实体目标能够是视频、图片、文本。同时向量之间的间隔衡量实体目标的相关性。小间隔表明高相关性,大间隔表明低相关性。在本例中是把一段文本内容转化成向量。选取的Embeding Model是text2vec-large-chinese。可是LangChain自身并不支撑这个Model。能够通HuggingFace供给的API下载和加载Model,并经过模型核算输入文本的Embedding。

    LangChain现已集成了许多向量数据库 Chroma / ElasticSearch / FAISS / Milvus / Pinecone 。咱们能够直接使用这些向量数据库进行数据的存储和查询。在本案例中咱们使用的是FAISS向量数据库。更多了解可参阅LangChain – Vectorstores

    相关代码

    ```
        # 经过HuggingFace来生成中文Sentence Embedding
        embedding = HuggingFaceEmbeddings(model_name='shibing624/text2vec-base-chinese')
        ...
        # 加载切割好的文本内容
        vector_store = FAISS.load_local(vs_path, self.embeddings)
    ```
    

    2.2 经过向量数据库进行相似性查找并结构Prompt

    咱们知道经过向LLM输入更多的上下文信息。LLM能够输出愈加精准的内容。所以经过FAISS供给的similarity_search_with_score接口函数。咱们能够得到跟query 相关的内容。从而构建更有用的Prompt。

    相关代码

    大模型实战入门(一)-通过LangChain+GLM实现基于本地知识库的问答应用案例

  3. 和LLM交互得到输出成果

    相关代码

    self.llm._call(prompt=prompt, history=chat_history):
    

延展内容

  • 不同向量数据库的相似度检索方案对比
  • 不同向量数据库的常用接口

参阅文章

Sentence Embeddings For Chinese & English

LangChain Python Doc

根据本地常识库的 ChatGLM 等大言语模型使用完成