欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

在langchain中對(duì)大模型的輸出進(jìn)行格式化實(shí)現(xiàn)

 更新時(shí)間:2023年11月27日 11:28:57   作者:flydean  
這篇文章主要為大家介紹了在langchain中對(duì)大模型的輸出進(jìn)行格式化實(shí)現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

簡(jiǎn)介

我們知道在大語言模型中, 不管模型的能力有多強(qiáng)大,他的輸入和輸出基本上都是文本格式的,文本格式的輸入輸出雖然對(duì)人來說非常的友好,但是如果我們想要進(jìn)行一些結(jié)構(gòu)化處理的話還是會(huì)有一點(diǎn)點(diǎn)的不方便。

不用擔(dān)心,langchain已經(jīng)為我們想到了這個(gè)問題,并且提出了完滿的解決方案。

langchain中的output parsers

langchain中所有的output parsers都是繼承自BaseOutputParser。這個(gè)基礎(chǔ)類提供了對(duì)LLM大模型輸出的格式化方法,是一個(gè)優(yōu)秀的工具類。

我們先來看下他的實(shí)現(xiàn):

class BaseOutputParser(BaseModel, ABC, Generic[T]):
    @abstractmethod
    def parse(self, text: str) -> T:
        """Parse the output of an LLM call.
        A method which takes in a string (assumed output of a language model )
        and parses it into some structure.
        Args:
            text: output of language model
        Returns:
            structured output
        """
    def parse_with_prompt(self, completion: str, prompt: PromptValue) -> Any:
        """Optional method to parse the output of an LLM call with a prompt.
        The prompt is largely provided in the event the OutputParser wants
        to retry or fix the output in some way, and needs information from
        the prompt to do so.
        Args:
            completion: output of language model
            prompt: prompt value
        Returns:
            structured output
        """
        return self.parse(completion)
    def get_format_instructions(self) -> str:
        """Instructions on how the LLM output should be formatted."""
        raise NotImplementedError
    @property
    def _type(self) -> str:
        """Return the type key."""
        raise NotImplementedError(
            f"_type property is not implemented in class {self.__class__.__name__}."
            " This is required for serialization."
        )
    def dict(self, **kwargs: Any) -> Dict:
        """Return dictionary representation of output parser."""
        output_parser_dict = super().dict()
        output_parser_dict["_type"] = self._type
        return output_parser_dict

BaseOutputParser 是一個(gè)基礎(chǔ)的類,可能被其他特定的輸出解析器繼承,以實(shí)現(xiàn)特定語言模型的輸出解析。

這個(gè)類使用了Python的ABC模塊,表明它是一個(gè)抽象基類(Abstract Base Class),不能被直接實(shí)例化,而是需要子類繼承并實(shí)現(xiàn)抽象方法。

Generic[T] 表示這個(gè)類是一個(gè)泛型類,其中T 是一個(gè)類型變量,它表示解析后的輸出數(shù)據(jù)的類型。

@abstractmethod 裝飾器標(biāo)記了 parse 方法,說明它是一個(gè)抽象方法,必須在子類中實(shí)現(xiàn)。parse 方法接受一個(gè)字符串參數(shù) text,通常是語言模型的輸出文本,然后將其解析成特定的數(shù)據(jù)結(jié)構(gòu),并返回。

parse_with_prompt 方法也是一個(gè)抽象方法,接受兩個(gè)參數(shù),completion 是語言模型的輸出,prompt 是與輸出相關(guān)的提示信息。這個(gè)方法是可選的,可以用于在需要時(shí)解析輸出,可能根據(jù)提示信息來調(diào)整輸出。

get_format_instructions 方法返回關(guān)于如何格式化語言模型輸出的說明。這個(gè)方法可以用于提供解析后數(shù)據(jù)的格式化信息。

_type 是一個(gè)屬性,可能用于標(biāo)識(shí)這個(gè)解析器的類型,用于后續(xù)的序列化或其他操作。

dict 方法返回一個(gè)包含輸出解析器信息的字典,這個(gè)字典可以用于序列化或其他操作。

其中子類必須要實(shí)現(xiàn)的方法就是parse。其他的都做為輔助作用。

langchain中有哪些Output Parser

那么langchain中有哪些Output Parser的具體實(shí)現(xiàn)呢?具體對(duì)應(yīng)我們應(yīng)用中的什么場(chǎng)景呢?

接下來我們將會(huì)一一道來。

List parser

ListOutputParser的作用就是把LLM的輸出轉(zhuǎn)成一個(gè)list。

ListOutputParser也是一個(gè)基類,我們具體使用的是他的子類:CommaSeparatedListOutputParser。

看一下他的parse方法:

def parse(self, text: str) -> List[str]:
        """Parse the output of an LLM call."""
        return text.strip().split(", ")

還有一個(gè)get_format_instructions:

def get_format_instructions(self) -> str:
        return (
            "Your response should be a list of comma separated values, "
            "eg: `foo, bar, baz`"
        )

get_format_instructions是告訴LLM以什么樣的格式進(jìn)行數(shù)據(jù)的返回。

就是把LLM的輸出用逗號(hào)進(jìn)行分割。

下面是一個(gè)基本的使用例子:

output_parser = CommaSeparatedListOutputParser()
format_instructions = output_parser.get_format_instructions()
prompt = PromptTemplate(
    template="列出幾種{subject}.\n{format_instructions}",
    input_variables=["subject"],
    partial_variables={"format_instructions": format_instructions}
)
_input = prompt.format(subject="水果")
output = model(_input)
print(output)
print(output_parser.parse(output))

我們可以得到下面的輸出:

Apple, Orange, Banana, Grape, Watermelon, Strawberry, Pineapple, Peach, Mango, Cherry
['Apple', 'Orange', 'Banana', 'Grape', 'Watermelon', 'Strawberry', 'Pineapple', 'Peach', 'Mango', 'Cherry']

看到這里,大家可能有疑問了, 為什么我們問的是中文,返回的卻是因?yàn)槟兀?/p>

這是因?yàn)閛utput_parser.get_format_instructions就是用英文描述的,所以LLM會(huì)自然的用英文來回答。

別急,我們可以稍微修改下運(yùn)行代碼,如下:

output_parser = CommaSeparatedListOutputParser()
format_instructions = output_parser.get_format_instructions()
prompt = PromptTemplate(
    template="列出幾種{subject}.\n{format_instructions}",
    input_variables=["subject"],
    partial_variables={"format_instructions": format_instructions + "用中文回答"}
)
_input = prompt.format(subject="水果")
output = model(_input)
print(output)
print(output_parser.parse(output))

我們?cè)趂ormat_instructions之后,提示LLM需要用中文來回答問題。這樣我們就可以得到下面的結(jié)果:

蘋果,橘子,香蕉,梨,葡萄,芒果,檸檬,桃
['蘋果,橘子,香蕉,梨,葡萄,芒果,檸檬,桃']

是不是很棒?

Datetime parser

DatetimeOutputParser用來將LLM的輸出進(jìn)行時(shí)間的格式化。

class DatetimeOutputParser(BaseOutputParser[datetime]):
    format: str = "%Y-%m-%dT%H:%M:%S.%fZ"
    def get_format_instructions(self) -> str:
        examples = comma_list(_generate_random_datetime_strings(self.format))
        return f"""Write a datetime string that matches the 
            following pattern: "{self.format}". Examples: {examples}"""
    def parse(self, response: str) -> datetime:
        try:
            return datetime.strptime(response.strip(), self.format)
        except ValueError as e:
            raise OutputParserException(
                f"Could not parse datetime string: {response}"
            ) from e
    @property
    def _type(self) -> str:
        return "datetime"

在get_format_instructions中,他告訴LLM返回的結(jié)果是一個(gè)日期的字符串。

然后在parse方法中對(duì)這個(gè)LLM的輸出進(jìn)行格式化,最后返回datetime。

我們看下具體的應(yīng)用:

output_parser = DatetimeOutputParser()
template = """回答下面問題:
{question}
{format_instructions}"""
prompt = PromptTemplate.from_template(
    template,
    partial_variables={"format_instructions": output_parser.get_format_instructions()},
)
chain = LLMChain(prompt=prompt, llm=model)
output = chain.run("中華人民共和國(guó)是什么時(shí)候成立的?")
print(output)
print(output_parser.parse(output))

 1949-10-01T00:00:00.000000Z
1949-10-01 00:00:00

回答的還不錯(cuò),給他點(diǎn)個(gè)贊。

Enum parser

如果你有枚舉的類型,那么可以嘗試使用EnumOutputParser.

EnumOutputParser的構(gòu)造函數(shù)需要傳入一個(gè)Enum,我們主要看下他的兩個(gè)方法:

@property
    def _valid_values(self) -> List[str]:
        return [e.value for e in self.enum]
    def parse(self, response: str) -> Any:
        try:
            return self.enum(response.strip())
        except ValueError:
            raise OutputParserException(
                f"Response '{response}' is not one of the "
                f"expected values: {self._valid_values}"
            )
    def get_format_instructions(self) -> str:
        return f"Select one of the following options: {', '.join(self._valid_values)}"

parse方法接收一個(gè)字符串 response,嘗試將其解析為枚舉類型的一個(gè)成員。如果解析成功,它會(huì)返回該枚舉成員;如果解析失敗,它會(huì)拋出一個(gè) OutputParserException 異常,異常信息中包含了所有有效值的列表。

get_format_instructions告訴LLM需要從Enum的有效value中選擇一個(gè)輸出。這樣parse才能接受到正確的輸入值。

具體使用的例子可以參考前面兩個(gè)parser的用法。篇幅起見,這里就不列了。

Pydantic (JSON) parser

JSON可能是我們?cè)谌粘4a中最常用的數(shù)據(jù)結(jié)構(gòu)了,這個(gè)數(shù)據(jù)結(jié)構(gòu)很重要。

在langchain中,提供的JSON parser叫做:PydanticOutputParser。

既然要進(jìn)行JSON轉(zhuǎn)換,必須得先定義一個(gè)JSON的類型對(duì)象,然后告訴LLM將文本輸出轉(zhuǎn)換成JSON格式,最后調(diào)用parse方法把json字符串轉(zhuǎn)換成JSON對(duì)象。

我們來看一個(gè)例子:

class Student(BaseModel):
    name: str = Field(description="學(xué)生的姓名")
    age: str = Field(description="學(xué)生的年齡")
student_query = "告訴我一個(gè)學(xué)生的信息"
parser = PydanticOutputParser(pydantic_object=Student)
prompt = PromptTemplate(
    template="回答下面問題.\n{format_instructions}\n{query}\n",
    input_variables=["query"],
    partial_variables={"format_instructions": parser.get_format_instructions()+"用中文回答"},
)
_input = prompt.format_prompt(query=student_query)
output = model(_input.to_string())
print(output)
print(parser.parse(output))

這里我們定義了一個(gè)Student的結(jié)構(gòu)體,然后讓LLM給我一個(gè)學(xué)生的信息,并用json的格式進(jìn)行返回。

之后我們使用parser.parse來解析這個(gè)json,生成最后的Student信息。

我們可以得到下面的輸出:

示例輸出:{"name": "張三", "age": "18"}
name='張三' age='18'

Structured output parser

雖然PydanticOutputParser非常強(qiáng)大, 但是有時(shí)候我們只是需要一些簡(jiǎn)單的結(jié)構(gòu)輸出,那么可以考慮StructuredOutputParser.

我們看一個(gè)具體的例子:

response_schemas = [
    ResponseSchema(name="name", description="學(xué)生的姓名"),
    ResponseSchema(name="age", description="學(xué)生的年齡")
]
output_parser = StructuredOutputParser.from_response_schemas(response_schemas)
format_instructions = output_parser.get_format_instructions()
prompt = PromptTemplate(
    template="回答下面問題.\n{format_instructions}\n{question}",
    input_variables=["question"],
    partial_variables={"format_instructions": format_instructions}
)
_input = prompt.format_prompt(question="給我一個(gè)女孩的名字?")
output = model(_input.to_string())
print(output)
print(output_parser.parse(output))

這個(gè)例子是上面的PydanticOutputParser的改寫,但是更加簡(jiǎn)單。

我們可以得到下面的結(jié)果:

` ` `json
{
    "name": "Jane",
    "age": "18"
}
 ` ` `
{'name': 'Jane', 'age': '18'}

output返回的是一個(gè)markdown格式的json字符串,然后通過output_parser.parse得到最后的json。

其他的一些parser

除了json,xml格式也是比較常用的格式,langchain中提供的XML parser叫做XMLOutputParser。

另外,如果我們?cè)谑褂胮arser的過程中出現(xiàn)了格式問題,langchain還貼心的提供了一個(gè)OutputFixingParser。也就是說當(dāng)?shù)谝粋€(gè)parser報(bào)錯(cuò)的時(shí)候,或者說不能解析LLM輸出的時(shí)候,就會(huì)換成OutputFixingParser來嘗試修正格式問題:

from langchain.output_parsers import OutputFixingParser
new_parser = OutputFixingParser.from_llm(parser=parser, llm=ChatOpenAI())
new_parser.parse(misformatted)

如果錯(cuò)誤不是因?yàn)楦袷揭鸬?,那么langchain還提供了一個(gè)RetryOutputParser,來嘗試重試:

from langchain.output_parsers import RetryWithErrorOutputParser
retry_parser = RetryWithErrorOutputParser.from_llm(
    parser=parser, llm=OpenAI(temperature=0)
)
retry_parser.parse_with_prompt(bad_response, prompt_value)

這幾個(gè)parser都非常有用,大家可以自行嘗試。

總結(jié)

雖然langchain中的有些parser我們可以自行借助python語言的各種工具來實(shí)現(xiàn)。但是有一些parser實(shí)際上是要結(jié)合LLM一起來使用的,比如OutputFixingParser和RetryOutputParser。

所以大家還是盡可能的使用langchain提供的parser為好。畢竟輪子都給你造好了,還要啥自行車。

以上就是在langchain中對(duì)大模型的輸出進(jìn)行格式化的詳細(xì)內(nèi)容,更多關(guān)于langchain大模型輸出格式化的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Python?GDAL庫在Anaconda環(huán)境中的配置方法

    Python?GDAL庫在Anaconda環(huán)境中的配置方法

    這篇文章主要介紹了Python?GDAL庫在Anaconda環(huán)境中的配置,本文介紹在Anaconda環(huán)境下,安裝Python中柵格、矢量等地理數(shù)據(jù)處理庫GDAL的方法,需要的朋友可以參考下
    2023-04-04
  • python通過郵件服務(wù)器端口發(fā)送郵件的方法

    python通過郵件服務(wù)器端口發(fā)送郵件的方法

    這篇文章主要介紹了python通過郵件服務(wù)器端口發(fā)送郵件的方法,涉及Python發(fā)送郵件的相關(guān)技巧,非常具有實(shí)用價(jià)值,需要的朋友可以參考下
    2015-04-04
  • 使用Python提取PDF表格到Excel文件的操作步驟

    使用Python提取PDF表格到Excel文件的操作步驟

    在對(duì)PDF中的表格進(jìn)行再利用時(shí),除了直接將PDF文檔轉(zhuǎn)換為Excel文件,我們還可以提取PDF文檔中的表格數(shù)據(jù)并寫入Excel工作表,本文將介紹如何使用Python提取PDF文檔中的表格并寫入Excel文件中,需要的朋友可以參考下
    2024-09-09
  • 使用icecream實(shí)現(xiàn)優(yōu)雅調(diào)試Python代碼

    使用icecream實(shí)現(xiàn)優(yōu)雅調(diào)試Python代碼

    在大型項(xiàng)目中,使用print()調(diào)試代碼可能導(dǎo)致終端輸出過多,難以分辨輸出結(jié)果與代碼的對(duì)應(yīng)關(guān)系,為了更清晰地調(diào)試,可以采用Icecream庫,本文介紹了如何使用icecream實(shí)現(xiàn)優(yōu)雅調(diào)試Python代碼,需要的朋友可以參考下
    2024-08-08
  • 給Python的Django框架下搭建的BLOG添加RSS功能的教程

    給Python的Django框架下搭建的BLOG添加RSS功能的教程

    這篇文章主要介紹了給Python的Django框架下搭建的BLOG添加RSS功能的教程,示例代碼非常簡(jiǎn)單,需要的朋友可以參考下
    2015-04-04
  • 20個(gè)被低估的Python性能優(yōu)化技巧分享

    20個(gè)被低估的Python性能優(yōu)化技巧分享

    這篇文章主要為大家詳細(xì)介紹了20個(gè)被低估的Python性能優(yōu)化技巧并附上了實(shí)測(cè)數(shù)據(jù),文中的示例代碼簡(jiǎn)潔易懂,有需要的小伙伴可以參考一下
    2025-03-03
  • Python-re中search()函數(shù)的用法詳解(查找ip)

    Python-re中search()函數(shù)的用法詳解(查找ip)

    這篇文章主要介紹了Python-re中search()函數(shù)的用法-----查找ip,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-03-03
  • flask框架渲染Jinja模板與傳入模板變量操作詳解

    flask框架渲染Jinja模板與傳入模板變量操作詳解

    這篇文章主要介紹了flask框架渲染Jinja模板與傳入模板變量操作,結(jié)合實(shí)例形式詳細(xì)分析了flask框架模板相關(guān)原理、模板渲染、傳入?yún)?shù)等相關(guān)操作技巧與注意事項(xiàng),需要的朋友可以參考下
    2020-01-01
  • Python使用pathlib庫實(shí)現(xiàn)優(yōu)雅的處理路徑

    Python使用pathlib庫實(shí)現(xiàn)優(yōu)雅的處理路徑

    如果你需要在 Python 里進(jìn)行文件處理,那么標(biāo)準(zhǔn)庫中的os和os.path兄弟倆一定是你無法避開的兩個(gè)模塊,本文主要來和大家聊聊如何使用pathlib庫實(shí)現(xiàn)優(yōu)雅的處理路徑,感興趣的可以了解下
    2023-12-12
  • Python調(diào)用pyttsx3實(shí)現(xiàn)離線文字轉(zhuǎn)語音的方式

    Python調(diào)用pyttsx3實(shí)現(xiàn)離線文字轉(zhuǎn)語音的方式

    pyttsx3是 Python 中的文本到語音的離線轉(zhuǎn)換庫,本文給大家介紹Python調(diào)用pyttsx3實(shí)現(xiàn)離線文字轉(zhuǎn)語音的方式,感興趣的朋友一起看看吧
    2024-03-03

最新評(píng)論