目前主流的大语言模型(LLM)输出内容格式都是Markdown,这是因为LLM的训练数据通常包含大量Markdown格式的文本,模型会倾向于生成类似格式的内容。但有时我们需要LLM生成一些其它格式的内容,例如CSV、JSON等,我们可以使用提示词让大语言模型返回对应格式的文本,LangChain则提供了对应的解析器。
chain = prompt_template | llm | StrOutputParser()
前面我们编写的例子中大量使用了StrOutputParser()
,它也是一种数据抽取方式,只不过它基本什么都没做,只是把LLM返回的文本原样输出。一般来说,它抽取的结果都是纯文本或Markdown文本。
让LLM输出JSON信息需要给出适当的提示,下面是一个例子。
from langchain.globals import set_debug, set_verbose
from langchain_core.prompts import PromptTemplate
from langchain_core.output_parsers import JsonOutputParser
from langchain_ollama import OllamaLLM
set_debug(True)
set_verbose(True)
llm = OllamaLLM(model='llama3.1:8b', temperature=1)
prompt_template = PromptTemplate.from_template("Print a json object with random name and age. Print JSON only, DO NOT include any other text.")
chain = prompt_template | llm | JsonOutputParser()
result = chain.invoke({})
print(result)
上面例子我们使用了JsonOutputParser()
,它能够将LLM返回的JSON文本自动解析为嵌套的字典格式。
注意:JSON输出相比普通文本更困难,Llama3.1:8b
是一个可以在个人电脑上运行的效果较好的LLM,但如果你使用的是其它能力更弱的LLM或者提示词不是特别明确,LLM可能并不总是按预期工作,它可能输出嵌套在Markdown里的JSON内容,或者是完全错误的内容,此时JsonOutputParser()
将解析失败并抛出错误。实际开发中,我们最好编写完善的异常处理机制,处理LLM未正确返回JSON的情况。
前面我们让LLM输出的JSON数据没有明确指出类型约束,LLM可能输出任意JSON,这有时不符合我们的需求。LangChain还支持根据Pydantic模型创建类型约束的提示词,引导LLM输出正确的字段信息,下面是一个例子。
from langchain.globals import set_debug, set_verbose
from langchain_core.prompts import PromptTemplate
from langchain_core.output_parsers import JsonOutputParser
from langchain_ollama import OllamaLLM
from pydantic import BaseModel, Field
set_debug(True)
set_verbose(True)
llm = OllamaLLM(model='llama3.1:8b', temperature=1)
class Student(BaseModel):
name: str = Field(description='Student name')
age: int = Field(description='Student age')
parser = JsonOutputParser(pydantic_object=Student)
prompt_template = PromptTemplate.from_template(
template="""
Print a json object with random name and age. Print JSON only, DO NOT include any other text.
format instructions:
{format_instructions}
""",
partial_variables={"format_instructions": parser.get_format_instructions()}
)
chain = prompt_template | llm | parser
result = chain.invoke({})
print(result)
代码中我们创建了一个Pydantic模型Student
,在JsonOutputParser
对象上,我们调用了get_format_instructions()
方法,它能自动生成和类型相关的提示词,引导LLM输出正确的内容,调用“Chain”后也能自动根据类型约束解析数据。当然,它的本质还是输出JSON文本,这非常依赖LLM的能力。
前面解析JSON时我们使用过Pydantic模型进行类型约束,但输出的还是字典类型数据,LangChain也支持直接输出Pydantic模型对象,我们使用PydanticOutputParser
即可,其余用法和之前的JsonOutputParser
完全一致。
parser = PydanticOutputParser(pydantic_object=Student)