最新一段时间一直在学习LangChain相关的文档,发现LangChain供给了十分丰富的生态,而且也能够让业务十分便利的封装自己的东西,接入到LangcChain的生态中,比方切换不同向量存储(Vectorstores)、文件分片(Text Splitters)和文件加载器(Document Loaders)等。
本文将简略介绍下如何将自己建立的ChatGLM集成进LangChain东西链中,当然假如有其他的自己建立的LLM模型也能够选用相似的办法集成。

接入自己的LLM

参阅官方文档# How to write a custom LLM wrapper,只需要集成LLM办法,而且完成_call办法即可。一个简略的自定义LLM如下:

from langchain.llms.base import LLM
from typing import Optional, List, Mapping, Any
class CustomLLM(LLM):
  n:int
  @property
  def _llm_type(self) -> str:
    return "custom"
  def _call(self,prompt:str,stop:Optional[List[str]]=None) -> str:
    if stop is not None:
      raise ValueError("stop kwargs are not permitted")
    return prompt[:self.n]
  @property
  def _identifying_params(self) -> Mapping[str, Any]:
        """Get the identifying parameters."""
        return {"n": self.n}

上面虽然只是一个最简略的完成,可是进一步考虑,假如有自己的LLM,是不是也能够经过相似的办法接入到LangChain的生态中呢?

正好最近也在建立ChatGLM,于是在想是不是能够将ChatGLM加入到LangChain东西链中来,利用其供给的东西便利做更深入的研讨。于是查找了一番,果然有相似开源完成,比方thomas-yanxin/LangChain-ChatGLM-Webui,一种利用 ChatGLM-6B + langchain 完成的基于本地知识的 ChatGLM 运用。可是研讨了一下代码,发现其是将ChatGLM-6B和LangChain布置在一起的。可是由于资源有限,现在只要少量的显卡,不能每个人都能布置一套ChatGLM。

进一步考虑,是否ChatGLM也供给了相似于openai的api接口呢,只需要进行http调用就能够运用ChatGLM的能力?这样就能够将:ChatGLM和上层的运用解耦,每个人都能够在自己本地经过api调用来进行试验。

建立ChatGLM的api

查阅ChatGLM-6B文档,也发现了其的确能够经过API办法供给服务。
详细如下:

  • 首要需要装置额外的依靠 pip install fastapi uvicorn ,然后运行库房中的 api.py:
    python api.py
  • 默许布置在本地的 8000 端口,经过 POST 办法进行调用
curl -X POST "http://{your_host}:8000" \
     -H 'Content-Type: application/json' \
     -d '{"prompt": "你好", "history": []}'
  • 得到的返回值为
{
  "response":"你好!我是人工智能帮手 ChatGLM-6B,很快乐见到你,欢迎问我任何问题。",
  "history":[["你好","你好!我是人工智能帮手 ChatGLM-6B,很快乐见到你,欢迎问我任何问题。"]],
  "status":200,
  "time":"2023-03-23 21:38:40"
}

封装ChatGLM的LLM

有了API之后,就能够参照上面的自定义LLM的办法封装ChatGLM了,详细代码如下:

from langchain.llms.base import LLM
from langchain.llms.utils import enforce_stop_tokens
from typing import Dict, List, Optional, Tuple, Union
import requests
import json
class ChatGLM(LLM):
    max_token: int = 10000
    temperature: float = 0.1
    top_p = 0.9
    history = []
    def __init__(self):
        super().__init__()
    @property
    def _llm_type(self) -> str:
        return "ChatGLM"
    def _call(self, prompt: str, stop: Optional[List[str]] = None) -> str:
        # headers中添加上content-type这个参数,指定为json格局
        headers = {'Content-Type': 'application/json'}
        data=json.dumps({
          'prompt':prompt,
          'temperature':self.temperature,
          'history':self.history,
          'max_length':self.max_token
        })
        # print("ChatGLM prompt:",prompt)
        # 调用api
        response = requests.post("{your_host}/api",headers=headers,data=data)
		# print("ChatGLM resp:",response)
        if response.status_code!=200:
          return "查询结果错误"
        resp = response.json()
        if stop is not None:
            response = enforce_stop_tokens(response, stop)
        self.history = self.history+[[None, resp['response']]]
        return resp['response']

上面只是简略的调用ChatGLM API,让程序跑起来,当然也能够参照LangChain封装openai的办法来做愈加杂乱的封装,比方供给重试、限频让步重试等功能。

测验

llm = ChatGLM()
print(llm("你会做什么"))

输出如下:

ChatGLM prompt: 你会做什么
我是一个大型语言模型,被练习来答复人类提出的问题。我不能做任何实践的事情,只能经过文字答复问题。假如你有任何问题,我会尽力答复。

验证经过,能够经过封装的ChatGLM类来访问ChatGLM API。这样就能够将需要用到OpenAILLM类替换成自己封装的ChatGLM了。

总结

本文简略介绍下如何将自己建立的ChatGLM集成进LangChain东西链中,而且进行简略的试验的效果。当然假如有其他自己建立的LLM模型也能够选用相似的办法集成。后续将运用ChatGLM来完成一个本地知识库做问答体系。

参阅

thomas-yanxin/LangChain-ChatGLM-Webui

运用langchain配合chatglm建立本地的知识库,可是langchain和chatglm是布置在一起的,耦合性比较高

ChatGLM-6B

chatglm的api建立