开启左侧

LangChain:输出封装OutputParser

[复制链接]
CaryMcKee 发表于 昨天 23:03 | 显示全部楼层 |阅读模式 打印 上一主题 下一主题
作者:CSDN博客
随着理解的加深,后续会回来优化。
1 输出封装

  LLM模型的输出通常都是字符串形式,Langchain中的输出封装OutputParser可以将其转化解析成结构化对象。简单举例如下:
  1. from langchain_openai import ChatOpenAI
  2. from langchain_core.output_parsers import CommaSeparatedListOutputParser
  3. prompt1='说出几种常见的水果'
  4. prompt2="输出20以内的素数"
  5. llm=ChatOpenAI()
  6. comma_parser=CommaSeparatedListOutputParser()
  7. response=llm.invoke(prompt1)print("===模型原始输出===")print(response.content)print('===CommaSeparatedListOutputParser解析输出===')print(comma_parser.parse(response.content))
  8. response=llm.invoke(prompt2)print("===模型原始输出===")print(response.content)print('===CommaSeparatedListOutputParser解析输出===')print(comma_parser.parse(response.content))
复制代码
其输出结果如下:
  1. ===模型原始输出===
  2. 苹果、香蕉、橙子、草莓、葡萄、梨、樱桃、桃子、西瓜、哈密瓜、柚子、柠檬、火龙果、李子、菠萝、榴莲等。
  3. ===CommaSeparatedListOutputParser解析输出===['苹果、香蕉、橙子、草莓、葡萄、梨、樱桃、桃子、西瓜、哈密瓜、柚子、柠檬、火龙果、李子、菠萝、榴莲等。']===模型原始输出===2, 3, 5, 7, 11, 13, 17, 19===CommaSeparatedListOutputParser解析输出===['2', '3', '5', '7', '11', '13', '17', '19']
复制代码
Tips:针对prompt1模型输出的结果中的没有,所以CommaSeparatedListOutputParser解析器没有正确解析出来。
本篇主要介绍langchain和langchain_core中的解析器。
1.1 langchain_core中的解析器

  目前langchain_core.output_parsers中的OutputParser类主要包括以下几种(虚拟类不列出):
    json类:JsonOutputParser,将结果解析成json串。list类:        CommaSeparatedListOutputParser、MarkdownListOutputParser和NumberedListOutputParser,将结果解析成类似List的对象。CommaSeparatedListOutputParser其结果是对LLM模型返回的字符串使用(,)进行分割得到的List。后面两种分别采用正则表达式从LLM模型返回的字符串中提取出符合规则的部分。string类。StrOutputParser,直接输出LLM模型返回的结果。xml类。XMLOutputParser,将LLM模型返回的结果解析成xml。pydantic类。PydanticOutputParser, 第2部分介绍。openai_function和openai_tools类:这两类可以帮助提取出LLM产生的函数调用的参数。openai_function系列针对的是使用function_call字段表示函数调用的参数的情况,后者针对的使用tool_calls字段表示function call的参数的情况(GPT系列模型采用的是这种方式)。这里只介绍openai_tools类。主要包括JsonOutputKeyToolsParser、JsonOutputToolsParser和PydanticToolsParser。其用法举例如下:
  1. from langchain_openai import ChatOpenAI
  2. from langchain_core.outputs import ChatGeneration
  3. #注意引用方法from langchain_core.output_parsers.openai_tools import JsonOutputToolsParser
  4. tools=[{"type":"function","function":{"name":"sum","description":"加法器,计算一组数的和","parameters":{"type":"object","properties":{"numbers":{"type":"array","items":{"type":"number"}}}}}}]
  5. llm=ChatOpenAI(model_kwargs={"tools":tools})
  6. parser=JsonOutputToolsParser()
  7. response=llm.invoke("计算一组数据的和:13,49837,3489,23423")print(response)
  8. 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功能同上
retryRetryOutputParser、RetryWithErrorOutputParser可以自动修复异常并重新解析
structuredStructuredOutputParser将LLM模型输出进行结构化解析
yamlYamlOutputParser提取LLM模型输出中的YAML部分
  虽然OutputParser可以对LLM的输出结果进行解析,但这种使用方式用户体验并不好,正如第一个案例中针对prompt1的输出结果,因为无法确定LLM模型输出的结果中是否使用,,所以解析结果无法掌控。可以使用OutputParser类的get_format_instructions()方法来调整LLM模型输出。举例如下:
  1. from langchain.output_parsers import DatetimeOutputParser
  2. from langchain_openai import ChatOpenAI
  3. from langchain_core.prompts import PromptTemplate
  4. parser=DatetimeOutputParser()
  5. format_instruction=parser.get_format_instructions()
  6. llm=ChatOpenAI()
  7. prompt=PromptTemplate.from_template(template="计算机时间的起始时间是什么时候?{format_instruction}")
  8. prompt=prompt.format(format_instruction=format_instruction)
  9. 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版本):
  1. from pydantic import BaseModel,Field,validator
  2. import re
  3. classFunc_Json(BaseModel):
  4.     name:str=Field(description="函数名称,只能由字母组成并且长度不超过10")
  5.     description:str=Field(description="函数描述")@validator("name")defvalid_name(cls,field):if re.match(r'^[a-zA-Z]+$',field)andlen(field)<10:return field
  6.         else:raise ValueError("函数名称不符合要求")print(Func_Json(name="sum",description="求一组数据的和"))print(Func_Json(name='sum2',description="求一组数据的和"))
复制代码
其代码运行结果如下:

LangChain:输出封装OutputParser-1.png


2.2 PydanticOutputParser基本用法
  1. from pydantic import BaseModel,Field,validator
  2. from langchain_core.output_parsers import PydanticOutputParser
  3. from langchain_openai import ChatOpenAI
  4. from typing import List
  5. from langchain_core.prompts import PromptTemplate
  6. classNew_List(BaseModel):
  7.     item:List[str]
  8. llm=ChatOpenAI()
  9. parser=PydanticOutputParser(pydantic_object=New_List)
  10. prompt=PromptTemplate.from_template("请列出10种常见的水果。{format_instruction}")
  11. prompt=prompt.format(format_instruction=parser.get_format_instructions())
  12. response=llm.invoke(prompt)print(response.content)
  13. prompt="请列出10种常见的汽车品牌"
  14. new_parser=OutputFixingParser.from_llm(parser=parser,llm=ChatOpenAI())
  15. response=llm.invoke(prompt)print(response.content)print(new_parser.parse(response.content))
复制代码
其结果如下:
{
“item”: [“apple”, “banana”, “orange”, “strawberry”, “grape”, “watermelon”, “kiwi”, “pineapple”, “mango”, “pear”]
}
    ToyotaFordChevroletHondaVolkswagenBMWMercedes-BenzAudiNissan
  • Hyundai
    item=[‘Toyota’, ‘Ford’, ‘Chevrolet’, ‘Honda’, ‘Volkswagen’, ‘BMW’, ‘Mercedes-Benz’, ‘Audi’, ‘Nissan’, ‘Hyundai’]
参考文献

    https://blog.csdn.net/codename_cys/article/details/107675748

原文地址:https://blog.csdn.net/yeshang_lady/article/details/137936178
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

发布主题
阅读排行更多+

Powered by Discuz! X3.4© 2001-2013 Discuz Team.( 京ICP备17022993号-3 )