LangChain:输出封装OutputParser

随着理解的加深,后续会回来优化。

1 输出封装

  LLM模型的输出通常都是字符串形式,Langchain中的输出封装OutputParser可以将其转化解析成结构化对象。简单举例如下:

from langchain_openai import ChatOpenAI
from langchain_core.output_parsers import CommaSeparatedListOutputParser

prompt1='说出几种常见的水果'
prompt2="输出20以内的素数"
llm=ChatOpenAI()
comma_parser=CommaSeparatedListOutputParser()
response=llm.invoke(prompt1)
print("===模型原始输出===")
print(response.content)
print('===CommaSeparatedListOutputParser解析输出===')
print(comma_parser.parse(response.content))
response=llm.invoke(prompt2)
print("===模型原始输出===")
print(response.content)
print('===CommaSeparatedListOutputParser解析输出===')
print(comma_parser.parse(response.content))

其输出结果如下:

===模型原始输出===
苹果、香蕉、橙子、草莓、葡萄、梨、樱桃、桃子、西瓜、哈密瓜、柚子、柠檬、火龙果、李子、菠萝、榴莲等。
===CommaSeparatedListOutputParser解析输出===
['苹果、香蕉、橙子、草莓、葡萄、梨、樱桃、桃子、西瓜、哈密瓜、柚子、柠檬、火龙果、李子、菠萝、榴莲等。']
===模型原始输出===
2, 3, 5, 7, 11, 13, 17, 19
===CommaSeparatedListOutputParser解析输出===
['2', '3', '5', '7', '11', '13', '17', '19']

Tips:针对prompt1模型输出的结果中的没有,所以CommaSeparatedListOutputParser解析器没有正确解析出来。
本篇主要介绍langchainlangchain_core中的解析器。

1.1 langchain_core中的解析器

  目前langchain_core.output_parsers中的OutputParser类主要包括以下几种(虚拟类不列出):

  • json类:JsonOutputParser,将结果解析成json串。
  • list类: CommaSeparatedListOutputParserMarkdownListOutputParserNumberedListOutputParser,将结果解析成类似List的对象。CommaSeparatedListOutputParser其结果是对LLM模型返回的字符串使用(,)进行分割得到的List。后面两种分别采用正则表达式从LLM模型返回的字符串中提取出符合规则的部分。
  • string类。StrOutputParser,直接输出LLM模型返回的结果。
  • xml类。XMLOutputParser,将LLM模型返回的结果解析成xml。
  • pydantic类。PydanticOutputParser, 第2部分介绍。
  • openai_functionopenai_tools类:这两类可以帮助提取出LLM产生的函数调用的参数。openai_function系列针对的是使用function_call字段表示函数调用的参数的情况,后者针对的使用tool_calls字段表示function call的参数的情况(GPT系列模型采用的是这种方式)。这里只介绍openai_tools类。主要包括JsonOutputKeyToolsParserJsonOutputToolsParserPydanticToolsParser。其用法举例如下:
from langchain_openai import ChatOpenAI
from langchain_core.outputs import ChatGeneration
#注意引用方法
from langchain_core.output_parsers.openai_tools import JsonOutputToolsParser
tools=[{ 
            "type": "function",
            "function": {
                "name": "sum",
                "description": "加法器,计算一组数的和",
                "parameters": {
                    "type": "object",
                    "properties": {
                        "numbers": {"type": "array", "items": { "type": "number"}}
                    }
                }
            }
        }
    ]

llm=ChatOpenAI(model_kwargs={"tools":tools})
parser=JsonOutputToolsParser()
response=llm.invoke("计算一组数据的和:13,49837,3489,23423")
print(response)
response=ChatGeneration(message=response)
print("---解析后结果---")
print(parser.parse_result([response]))

其输出结果为:

content=‘’ additional_kwargs={‘tool_calls’: [{‘id’: ‘call_ek805JD7PATXCZ6yjNErBgpL’, ‘function’: {‘arguments’: ‘{“numbers”:[13,49837,3489,23423]}’, ‘name’: ‘sum’}, ‘type’: ‘function’}]} response_metadata={‘token_usage’: {‘completion_tokens’: 22, ‘prompt_tokens’: 68, ‘total_tokens’: 90}, ‘model_name’: ‘gpt-3.5-turbo’, ‘system_fingerprint’: ‘fp_c2295e73ad’, ‘finish_reason’: ‘tool_calls’, ‘logprobs’: None} id=‘run-ba534c13-9a3d-4e77-a056-37465fd58549-0’ tool_calls=[{‘name’: ‘sum’, ‘args’: {‘numbers’: [13, 49837, 3489, 23423]}, ‘id’: ‘call_ek805JD7PATXCZ6yjNErBgpL’}]
—解析后结果—
[{‘args’: {‘numbers’: [13, 49837, 3489, 23423]}, ‘type’: ‘sum’}]

1.2 langchain中的输出封装

  目前langchain中的OutputParser类主要包括以下几种:

输出类型类名称备注
booleanBooleanOutputParser返回True或False
combiningCombiningOutputParser同时将多个输出解析成同一个格式
datetimeDatetimeOutputParser将日期转化成特定格式
enumEnumOutputParser将LLM模型输出解析成enum
fixOutputFixingParser可以自动修复异常并重新解析
pandas_dataframePandasDataFrameOutputParser使用pandas.dataframe的format对LLM进行解析
regexRegexParser使用正则表达式对LLM模型返回进行解析
regex_dictRegexDictParser功能同上
retryRetryOutputParserRetryWithErrorOutputParser可以自动修复异常并重新解析
structuredStructuredOutputParser将LLM模型输出进行结构化解析
yamlYamlOutputParser提取LLM模型输出中的YAML部分

  虽然OutputParser可以对LLM的输出结果进行解析,但这种使用方式用户体验并不好,正如第一个案例中针对prompt1的输出结果,因为无法确定LLM模型输出的结果中是否使用,,所以解析结果无法掌控。可以使用OutputParser类的get_format_instructions()方法来调整LLM模型输出。举例如下:

from langchain.output_parsers import DatetimeOutputParser
from langchain_openai import ChatOpenAI
from langchain_core.prompts import PromptTemplate

parser=DatetimeOutputParser()
format_instruction=parser.get_format_instructions()
llm=ChatOpenAI()
prompt=PromptTemplate.from_template(template="计算机时间的起始时间是什么时候?{format_instruction}")
prompt=prompt.format(format_instruction=format_instruction)
response=llm.invoke(prompt)
print(response.content)

其输出结果如下:

0001-01-01T00:00:00.000000Z

2 PydanticOutputParser

PydanticOutputParser类可以利用Pydantic库自定义解析模型。

2.1 Pydantic基本用法

Pydantic 是Python 中一个流行的数据验证和设置库,允许自定义数据模型,并在运行时验证输入数据是否符合模型规范,确保应用程序在处理数据时的健壮性和可靠性。其用法举例如下(目前Langchain中可能只支持pydantic的v1版本,为保持一致,这里也仅使用v1版本):

from pydantic import BaseModel,Field,validator
import re

class Func_Json(BaseModel):
    name:str=Field(description="函数名称,只能由字母组成并且长度不超过10")
    description:str=Field(description="函数描述")

    @validator("name")
    def valid_name(cls,field):
        if re.match(r'^[a-zA-Z]+$',field) and len(field)<10:
            return field
        else:
            raise ValueError("函数名称不符合要求")

print(Func_Json(name="sum",description="求一组数据的和"))
print(Func_Json(name='sum2',description="求一组数据的和"))

其代码运行结果如下:
在这里插入图片描述

2.2 PydanticOutputParser基本用法

from pydantic import BaseModel,Field,validator
from langchain_core.output_parsers import PydanticOutputParser
from langchain_openai import ChatOpenAI
from typing import List
from langchain_core.prompts import PromptTemplate

class New_List(BaseModel):
    item:List[str]

llm=ChatOpenAI()
parser=PydanticOutputParser(pydantic_object=New_List)

prompt=PromptTemplate.from_template("请列出10种常见的水果。{format_instruction}")
prompt=prompt.format(format_instruction=parser.get_format_instructions())

response=llm.invoke(prompt)
print(response.content)

prompt="请列出10种常见的汽车品牌"
new_parser=OutputFixingParser.from_llm(parser=parser,llm=ChatOpenAI())
response=llm.invoke(prompt)
print(response.content)
print(new_parser.parse(response.content))

其结果如下:

{
“item”: [“apple”, “banana”, “orange”, “strawberry”, “grape”, “watermelon”, “kiwi”, “pineapple”, “mango”, “pear”]
}

  1. Toyota
  2. Ford
  3. Chevrolet
  4. Honda
  5. Volkswagen
  6. BMW
  7. Mercedes-Benz
  8. Audi
  9. Nissan
  10. Hyundai
    item=[‘Toyota’, ‘Ford’, ‘Chevrolet’, ‘Honda’, ‘Volkswagen’, ‘BMW’, ‘Mercedes-Benz’, ‘Audi’, ‘Nissan’, ‘Hyundai’]

参考文献

  1. https://blog.csdn.net/codename_cys/article/details/107675748
  • 12
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值