文章目录
- 输出解析器的使用
- Pydantic JSON输出解析器
- 结构化输出解析器
输出解析器的使用
输出解析器的使用主要依靠提示词模板对象的partial方法注入输出指令的字符
串,主要的实现方式是利用PromptTemplate对象的partial方法或在实例化PromptTemplate对象时传递partial variables参数。这样做可以提高代码的灵活性,使得提示词的占位符变量可以根据需要动态增加或减少。使用这种方式可为提示词模板添加输出指令,指导模型输出。
具体操作是,首先使用output parser…get_format_instructions()获取预设的输出指令,然后在实例化PromptTemplate类时将format instructions作为partial variables的一部分传入,如此便在原有的提示词模板中追加了format instructions变量,这个变量是输出指令字符串。以下是相关的示例代码:
format instructions= output_parser.get_format instructions (
prompt PromptTemplate(
template="List five (subject).\n(format instructions)",
input variables=["subject"],
partial variables={"format instructions":format instructions))
在这段代码中,PromptTemplate的模板字符串template中包含两个占位符变量{subject}和{format_instructions}。在实例化PromptTemplate对象时,除了要传人input variables-=[“subject’”]参数,还要通过partial_variables-={“format_instructions’”:format instructions}参数预先填充{format instructions}变量,这样就成功地为提示词模板添加了输出解析器所提供的输出指令。
现在通过下面的示例完成输出解析器的两大功能:添加输出指令和解析输出格式,同时展示如何将输出解析器运用到链组件上。首先,采用CommaSeparatedListOutputParser输出解析器:
from langchain.output_parsers import CommaSeparatedListoutputParser
from langchain.prompts import PromptTemplate
from langchain.11ms import OpenAI
output_parser =CommaSeparatedListOutputParser()
然后,使用output parser…get_format_instructions()方法获取预设的格式化输出指令。这个字符串输出指令会指导模型如何将输出格式化为以逗号分隔的消息列表。接下来,创建一个PromptTemplate提示词模板对象:
format_instructions= output_parser.get_format_instructions()
prompt PromptTemplate(
template="List five (subject).\n(format_instructions)",
input_variables=["subject"],
partial_variables=("format instructions":format instructions)
)
这个提示词模板中定义了一个字符串模板,其中包含两个占位符变量{subject}和{formatinstructions}。{subject}是希望模型产生的列表主题,例如“ice cream flavors’”,而{format instructions}是从输出解析器中获取的预设的输出指令。这里引入OpenAI的LLM模型包装器。打印format instructions的结果,内容是
“Your response should be a list of comma"
separated values,eg:'foo,bar,baz'"
from langchain.chains import LLMChain
chain =LLMChain(
llm=OpenAI(
openai_api_key="填人OpenAI的密钥"
prompt=prompt))
将subject的值设为ice cream flavors,然后调用prompt…format(subject=-“ice cream flavors”)方法,返回一个完整的提示词字符串,包含指导模型产生5种冰淇淋口味的指令。导入LLMChain链组件,为OpenAI模型类设置密钥,将PromptTemplate类实例化后的对象传人LLMChain链:output chain (“ice cream flavors”)。
运行这个链得到的是一个JSON对象,output['text]是模型回答的字符串,然后调用输出解析器的pase0方法将这个字符串解析为一个列表。由于输出解析器是CommaSeparatedListOutputParser,所以它会将模型输出的以逗号分隔的文本解析为列表。output_parser.parse (output[‘text’])。最后得到的结果是一个包含5种冰淇淋口味的列表,代表口味的值用逗号隔开:
['Vanilla',
'Chocolate',
'Strawberry',
'Mint Chocolate Chip',
'Cookies and Cream']
Pydantic JSON输出解析器
PydanticOutputParser输出解析器可以指定JSON数据格式,并指导LLM输出符合开发者需求的JSON格式数据。可以使用Pydantic来声明数据模式。Pydantic的BaseModel就像一个Python数据类,但它具有实际的类型检查和强制转换功能。下面是最简单的Pydantic JSON输出解析器示例代码,导入OpenAI模型包装器和提示词模板包装器:
from langchain.prompts import (PromptTemplate)
from langchain.11ms import OpenAI
导人PydanticOutputParser类:
from langchain.output parsers import PydanticOutputParser
from pydantic import BaseModel,Field,validator
from typing import List
这里使用LLM模型包装器,实现与机器人的对话:
model=OpenAI(openai_api_key="填人你的密钥")
定义数据结构Joke,实例化PydanticOutputParser输出解析器,将该输出解析器预设的输出指令注入提示词模板:
#定义所需的数据结构
class Joke (BaseModel):
setup:str Field(description="question to set up a joke")
punchline:str Field(description="answer to resolve the joke")
#使用Pydantic轻松添加自定义的验证逻辑
@validator("setup")
def question_ends_with question mark(cls,field):
if field[-1]!="?":
raise ValueError ("Badly formed question!")
return field
#创建一个用于提示LLM生成数据结构的查询
joke query "Tell me a joke."
#设置一个输出解析器,并将指令注人提示词模板
parser PydanticOutputParser(pydantic object=Joke)
prompt =PromptTemplate
template="Answer the user query.\n(format_instructions)\n(query}\n",
input_variables=["query"],
partial variables=("format instructions":
parser.get format instructions ())
)
_input =prompt.format_prompt (query=joke query)
output =model(input.to string())
parser.parse (output)
将用户输人“ice cream flavors’”绑定到提示词模板的query变量上,使用LLM模型包装器与模型平台进行交互。将该输出解析器预设的输出指令绑定到提示词模板的format instructions变量上:
input =prompt.format (subject="ice cream flavors")
output =model(input)
调用输出解析器的parse方法,将输出解析为Pydantic JSON格式:output_parser.parse(output)
最终的结果是符合Joke定义的数据格式:
Joke(setup='Why did the chicken cross the road?',punchline='To get to the other side!')
结构化输出解析器
OutputParsers是一组工具,其主要目标是处理和格式化模型的输出。它包含了多个部分,但对于实际的开发需求来说,其中最关键的部分是结构化输出解析器(StructuredOutputParser)。这个工具可以将模型原本返回的字符串形式的输出,转化为可以在代码中直接使用的数据结构。特别要指出的是,通过定义输出的数据结构,提示词模板中加人了包含这个定义的输出指令,让模型输出符合该定义的数据结构。本质上来说就是通过告诉模型数据结构定义,要求模型给出一个符合该定义的数据,不再仅仅是一句话的回答,而是抽象的数据结构。
使用结构化输出解析器时,首先需要定义所期望的输出格式。输出解析器将根据这个期望的输出格式来生成模型提示词,从而引导模型产生所需的输出,例如使用StructuredOutputParser来获取多个字段的返回值。尽管Pydantic/JSON解析器更强大,但在早期实验中,选择的数据结构只包含文本字段。首先从LangChain中导入所需的类和方法:
from langchain.output_parsers import StructuredOutputParser,ResponseSchema
from langchain.prompts import PromptTemplate,ChatPromptTemplate,HumanMessagePromptTemplate
from langchain.11ms import OpenAI
from langchain.chat models import ChatopenAI
然后定义想要接收的响应模式:
response_schemas =[
ResponseSchema(
name="answer",
description="answer to the user's question",)
ResponseSchema(
name="source",
description=(
"source used to answer the user's question,
"should be a website."))
]
output parser =StructuredoutputParser.from_response_schemas(response schemas)
接着获取一个format instructions,包含将响应格式化的输出指令,然后将其插人提示词模板:
format instructions output_parser.get format instructions (
prompt =PromptTemplate(
template=(
"answer the users question as best as possible.\n"
"(format instructions)\n(question}"
),
input_variables=["question"],
partial variables={
"format instructions":format instructions}
)
model=OpenAI(openai_api_key="填人你的密钥")
_input prompt.format prompt (question="what's the capital of france?")
output model(input.to_string ()
output_parser.parse (output)
返回结果如下:(‘answer’:‘Paris’,‘source’:·请参考本书代码仓库URL映射表,找到对应资//www.worldatlas.com/articles/what-is-the-capital-of-france.html’)接下来是一个在聊天模型包装器中使用这个方法的示例:
chat_model=ChatOpenAI(openai_api_key="填人你的密钥")
prompt =ChatPromptTemplate
messages=[
HumanMessagePromptTemplate.from template(
"answer the users question as best as possible.\n"
"(format instructions)\n(question)")
],
input_variables=["question"],
partial_variables={
"format instructions":format instructions"
}
)
input prompt.format prompt(question="what's the capital of france?")
output chat model(input.to messages ()
output_parser,parse(output.content)#多包一层content
返回结果如下:(‘answer’:‘Paris’,‘source’:·请参考本书代码仓库URL映射表,找到对应资源://en.wikipedia.org/wiki/Paris’这就是使用PromptTemplate和StructuredOutputParser来格式化和解析模型输人及输出的完整过程。