
图片来自 nikitabuida 在 Freepik
大型语言模型(LLM)彻底改变了人们的工作方式。通过帮助用户根据文本提示生成答案,LLM 可以做很多事情,例如回答问题、总结、规划事件等等。
然而,有时 LLM 的输出可能不符合我们的标准。例如,生成的文本可能完全错误,需要进一步的指导。这时 LLM 输出解析器就能派上用场。
通过使用 LangChain 输出解析器标准化输出结果,我们可以对输出进行一定的控制。那么,它是如何工作的呢?让我们开始吧。
准备
在本文中,我们将依赖 LangChain 包,因此我们需要在环境中安装它们。要做到这一点,您可以使用以下代码。
1 |
pip install langchain langchain_core langchain_community langchain_openai python-dotenv |
此外,我们将使用 OpenAI GPT 模型进行文本生成,因此请确保您拥有它们的 API 访问权限。您可以从 OpenAI 平台获取 API 密钥。
我将在 Visual Studio Code IDE 中工作,但您也可以在任何喜欢的 IDE 中工作。在项目文件夹中创建一个名为 .env
的文件,并将 OpenAI API 密钥放在其中。它应该看起来像这样。
1 |
OPENAI_API_KEY = sk-XXXXXXXXXX |
一切准备就绪后,我们将进入文章的核心部分。
输出解析器
我们可以使用 LangChain 中的多种输出解析器来标准化我们的 LLM 输出。我们将尝试其中的几种来更好地理解输出解析器。
首先,我们将尝试 Pydantic 解析器。它是一个输出解析器,我们可以用它来控制和验证生成文本的输出。让我们通过一个例子更好地使用它们。在您的 IDE 中创建一个 Python 脚本,然后将下面的代码复制到您的脚本中。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
from typing import List from dotenv import load_dotenv from langchain.output_parsers import PydanticOutputParser from langchain_core.prompts import PromptTemplate from langchain_core.pydantic_v1 import BaseModel, Field, validator from langchain_openai import ChatOpenAI load_dotenv() class MovieReview(BaseModel): title: str = Field(description="The movie title") year: int = Field(description="The year of the movie was released") genre: List[str] = Field(description="The main genres of the movie") rating: float = Field(description="Rating out of 10") summary: str = Field(description="Brief summary of the movie plot") review: str = Field(description="Critical review of the movie") @validator("year") def valid_year(cls, val): if val 2025: raise ValueError("Must a valid movie year") return val @validator("rating") def valid_rating(cls, val): if val 10: raise ValueError("Rating must be between 0 and 10") return val parser = PydanticOutputParser(pydantic_object=MovieReview) prompt = PromptTemplate( template="Generate a movie review for the following movie:\n{movie_title}\n\n{format_instructions}", input_variables=["movie_title"], partial_variables={"format_instructions": parser.get_format_instructions()} ) model = ChatOpenAI(temperature=0) chain = prompt | model | parser movie_title = "The Matrix" review = chain.invoke({"movie_title": movie_title}) print(review) |
我们首先在上面的代码中导入了所需的包,并使用 load_dotenv
加载了 OpenAI 密钥。之后,我们创建了一个名为 MovieReview
的类,其中包含我们想要的所有信息输出。输出将提供标题、年份、类型、评分、摘要和评论。在每个输出中,我们都定义了我们想要的输出描述。
从输出中,我们为年份和评分创建了一个验证器,以确保结果是我们想要的。如果需要,您还可以添加更多验证机制。
然后我们创建了提示模板,它将接受我们的查询输入和所需的格式。
最后一步是创建模型链并将查询传递以获取结果。请注意,上面变量 chain
使用“|”接受结构,这是 LangChain 中的一种独特方法。
总体而言,结果与下图类似。
输出
1 |
title='The Matrix' year=1999 genre=['Action', 'Sci-Fi'] rating=9.0 summary='A computer hacker learns about the true nature of reality and his role in the war against its controllers.' review="The Matrix is a groundbreaking film that revolutionized the action genre with its innovative special effects and thought-provoking storyline. Keanu Reeves delivers a memorable performance as Neo, the chosen one who must navigate the simulated reality of the Matrix to save humanity. The film's blend of martial arts, philosophy, and dystopian themes make it a must-watch for any movie enthusiast." |
如您所见,输出遵循了我们想要的格式,并且结果通过了我们的验证方法。
Pydantic 解析器是我们标准使用的输出解析器。如果我们已经有了特定的格式,可以使用其他的输出解析器。例如,如果我们希望结果仅以逗号分隔的项目形式出现,可以使用 CSV 解析器。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
from dotenv import load_dotenv from langchain.output_parsers import CommaSeparatedListOutputParser from langchain_core.prompts import PromptTemplate from langchain_openai import ChatOpenAI load_dotenv() output_parser = CommaSeparatedListOutputParser() format_instructions = output_parser.get_format_instructions() prompt = PromptTemplate( template="List six {subject}.\n{format_instructions}", input_variables=["subject"], partial_variables={"format_instructions": format_instructions}, ) model = ChatOpenAI(temperature=0) chain = prompt | model | output_parser print(chain.invoke({"subject": "Programming Language"})) |
输出
1 |
['Java', 'Python', 'C++', 'JavaScript', 'Ruby', 'Swift'] |
结果是一个由逗号分隔值的列表。如果结果是逗号分隔的,您可以根据需要扩展模板。
还可以获取 datetime 格式的输出。通过更改代码和提示,我们可以获得想要的结果。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
from dotenv import load_dotenv from langchain.output_parsers import DatetimeOutputParser from langchain_core.prompts import PromptTemplate from langchain_openai import ChatOpenAI load_dotenv() output_parser = DatetimeOutputParser() format_instructions = output_parser.get_format_instructions() prompt = PromptTemplate( template="""Answer the users question: {question} {format_instructions}""", input_variables=["question"], partial_variables={"format_instructions": format_instructions}, ) model = ChatOpenAI(temperature=0) chain = prompt | model | output_parser print(chain.invoke({"question": "When is the Python Programming Language invented?"})) |
输出
1 |
1991-02-20 00:00:00 |
您可以看到结果是 datetime 格式。
以上就是关于 LangChain LLM 输出解析器的全部内容。您可以访问他们的文档查找所需的输出解析器,或者使用 Pydantic 自己进行结构化。
结论
在本文中,我们学习了 LangChain 输出解析器,它能标准化 LLM 生成的文本。我们可以使用 Pydantic 解析器来结构化 LLM 输出,并提供您想要的结果。LangChain 还有许多其他输出解析器可能适合您的情况,例如 CSV 解析器和 Datetime 解析器。
暂无评论。