Langchain介绍

随着chatGPT炽热,全球关于AIGC的论题也越来越多,也呈现了许多AI类型的产品,比方notionmidjourneycopilot等等。

而这些AI运用都离不开大言语模型,只有更好的了解人类言语才能将使命做的愈加精准。现在在自然言语了解能力上,OpenAI的GPT4模型可谓是名列前茅。

相信咱们都有用过chatGPT,只需给它一个提示词或许是一些样例,那么它就能够输出一些答案。这儿输出的成果可能有好有坏,这就取决于你给的提示词是否好

所以能够幻想一下:LLM能够协助咱们完成NLP使命,那么提示词便是LLM的编程言语,只需你的提示词能够让LLM完全了解,那么运用LLM来开发NLP使命将大大削减之前机器学习的许多步骤。

假如咱们想运用OpenAI的GPT3.5或许GPT4模型来开发运用,比方:文本翻译、编码、文本总结…

  • 首先得先注册获取OPENAI_KEY
  • 学习OpenAI的api接口文档
  • 自己编写prompt

这是基本的三个步骤,里边的第二步和第三步是核心,也是学习本钱比较高的。那么有没有便利的运用开发结构削减咱们的开发本钱?比方开发一款web运用,Java有Springboot,Python有FastAPI。

关于现在LLM运用开发,Langchain就充当了这么一个运用开发结构的人物,它最大的一个特色便是抽象了模型、抽象了提示词。

官方给它的介绍是: LangChain 是一个运用言语模型开发运用程序的结构。 它使运用程序能够:

  1. 数据感知:将言语模型与其他数据源连接起来
  2. 代理:答应言语模型与其环境交互

开发者文档:python.langchain.com/docs/integr…

代码完成:github.com/langchain-a…

langchain运用开发

接下来我将介绍怎么运用langchain来开发一款文本翻译工具。

需求: 完成PDF格局文件上传,能够传入需求翻译的言语,然后会将翻译好的内容以文件的形式供给下载。

由于国内的访问限制这儿我将运用azure的供给openAI服务,新注册的用户能够免费体会12个月

首先展现一下本运用的一个效果图:

Langchain应用开发之文本翻译

PDF格局解析

这儿不是咱们的重点,简单介绍一下。

PDF解析咱们采用pdfplumber这个python的开源结构

pdfplumber 项目(根据pdfminer.six开发),支撑解析PDF文件,获取每个文本字符、矩形和线条的详细信息。此外还支撑表格提取和可视化调试。

运用AzureChatOpenAI来结构LLChain

创立一个TranslationChain类,主要来完成咱们的翻译功能

from langchain.chat_models import ChatOpenAI, AzureChatOpenAI
from langchain.chains import LLMChain
from langchain.prompts.chat import (  
ChatPromptTemplate,  
SystemMessagePromptTemplate,  
HumanMessagePromptTemplate,  
)
class TranslationChain:
    def __init__(self, model_name: str = "gpt-3.5-turbo", verbose: bool = True):
    ...

这儿有一个结构办法:

  1. model_name:默许运用的是openAI的 gpt3.5模型;
  2. verbose:表示是否大于langchain日志。

结构提示词模板

在结构函数下面,先结构提示词模板 由于咱们运用的是ChatModel,所以关于的提示词模板需求运用ChatPromptTemplate


# 翻译使命指令始终由 System 人物承当  
template = (  
    """You are a translation expert, proficient in various languages. \n  
    Translates {source_language} to {target_language}."""  
)  
system_message_prompt = SystemMessagePromptTemplate.from_template(template)  
# 待翻译文本由 Human 人物输入  
human_template = "{text}"  
human_message_prompt = HumanMessagePromptTemplate.from_template(human_template)  
# 运用 System 和 Human 人物的提示模板结构 ChatPromptTemplate  
chat_prompt_template = ChatPromptTemplate.from_messages(  
    [system_message_prompt, human_message_prompt]  
)

创立chatModel实例

接下来在结构函数里边要初始化大言语模型实例

# 为了翻译成果的稳定性,将 temperature 设置为 0  
if model_name == "gpt-3.5-turbo":  
    chat = ChatOpenAI(model_name=model_name, temperature=0, verbose=verbose)  
else:  
    chat = AzureChatOpenAI(  
    deployment_name="xxx",  
    openai_api_version="2023-07-01-preview",  
    openai_api_type="azure",  
    openai_api_key="xxx",  
    openai_api_base="https://xxxx.openai.azure.com/",  
    temperature=0,  
    verbose=verbose  
    )  

AzureChatOpenAI里边有几个参数是azure供给的openai需求的

  1. deployment_name:部署的实例名称
  2. openai_api_key:密钥
  3. openai_api_base:azure供给的openai访问地址
  4. openai_api_version:模板版本,有:2023-05-15 和 2023-07-01-preview,2023-07-01-preview能够支撑function-calling

初始化LLMChain

提示词模板和模型结构完成之后,就能够结构LLMChain了

self.chain = LLMChain(llm=chat, prompt=chat_prompt_template, verbose=verbose)

创立一个用于翻译工作的办法

经过调用LLMChain的 run 办法,就能够调用模型的api,并且咱们有了提示词模板,翻译的目标言语能够动态的传入,其底层便是根据python的f-string的字符串处理

def run(self, text: str, source_language: str, target_language: str) -> (str, bool):
    result = ""  
    try:  
        result = self.chain.run({  
        "text": text,  
        "source_language": source_language,  
        "target_language": target_language,  
        })  
    except Exception as e:  
        LOG.error(f"An error occurred during translation: {e}")  
        return result, False  
    return result, True

成果处理生成文件

关于文本类的生成成果处理比较简单,但是关于表格类型的就需求将文本内容转换为表格。

以下是langchain的日志:

System: You are a translation expert, proficient in various languages.
        Translates English to Chinese.
Human: [Fruit, Color, Price (USD)] [Apple, Red, 1.20] [Banana, Yellow, 0.50] [Orange, Orange, 0.80] [Strawberry, Red, 2.50] [Blueberry, Blue, 3.00] [Kiwi, Green, 1.00] [Mango, Orange, 1.50] [Grape, Purple, 2.00]
>Finished chain.
2023-08-28 21:37:23.774 | DEBUG    | book.content:set_translation:54 - [translation]
[生果, 色彩, 价格(美元)] [苹果, 赤色, 1.20] [香蕉, 黄色, 0.50] [橙子, 橙色, 0.80] [草莓, 赤色, 2.50] [蓝莓, 蓝色, 3.00] [猕猴桃, 绿色, 1.00] [芒果, 橙色, 1.50] [葡萄, 紫色, 2.00]

能够发现,传入给模型的格局和模型回来的格局并无法发生变化,那么直接格局进行字符串割接和拼接操作,组成一个pandas对象

import pandas as pd
def set_translation(self, translation, status):  
    try:  
        if not isinstance(translation, str):  
            raise ValueError(f"Invalid translation type. Expected str, but got {type(translation)}")  
        LOG.debug(f"[translation]\n{translation}")  
        # Extract column names from the first set of brackets  
        header = translation.split(']')[0][1:].split(', ')  
        # Extract data rows from the remaining brackets  
        data_rows = translation.split('] ')[1:]  
        # Replace Chinese punctuation and split each row into a list of values  
        data_rows = [row[1:-1].split(', ') for row in data_rows]  
        # Create a DataFrame using the extracted header and data  
        translated_df = pd.DataFrame(data_rows, columns=header)  
        LOG.debug(f"[translated_df]\n{translated_df}")  
        self.translation = translated_df  
        self.status = status  
    except Exception as e:  
        LOG.error(f"An error occurred during table translation: {e}")  
        self.translation = None  
        self.status = False

运用gradio,生成UI页面

官方文档:Gradio

import sys
import os  
import gradio as gr  
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
def translation(input_file, source_language, target_language):  
    LOG.debug(f"[翻译使命]\n源文件: {input_file.name}\n源言语: {source_language}\n目标言语: {target_language}")  
    output_file_path = Translator.translate_pdf(  
    input_file.name, source_language=source_language, target_language=target_language)  
    return output_file_path  
def launch_gradio():  
    iface = gr.Interface(  
        fn=translation,  
        title="OpenAI-Translator v2.0(PDF 电子书翻译工具)",  
        inputs=[  
        gr.File(label="上传PDF文件"),  
        gr.Textbox(label="源言语(默许:英文)", placeholder="English", value="English"),  
        gr.Textbox(label="目标言语(默许:中文)", placeholder="Chinese", value="Chinese")  
        ],  
        outputs=[  
        gr.File(label="下载翻译文件")  
        ],  
        allow_flagging="never"  
    )  
    iface.launch(share=True, server_name="0.0.0.0")
if __name__ == "__main__":  
    # 初始化 translator  
    #initialize_translator()
    # 启动 Gradio 服务  
    launch_gradio()

需求留意的是,gradio经过 Interface办法来结构页面

  1. fn:恳求履行的办法
  2. inputs:恳求参数,依照次序和fn的办法参数匹配。比方这个例子中,fn的办法参数有三个,第一个是文件,第二个是源言语,第三个是目标言语,那么inputs的参数列表需求和它关于上,次序不能搞乱
  3. outputs:呼应参数
  4. allow_flagging:服务器是否存储文件