跳到主要内容

如何使用输出解析器将 LLM 响应解析为结构化格式

先决条件

本指南假设您熟悉以下概念

语言模型输出文本。但有时您希望获得比文本更结构化的信息。虽然一些模型提供商支持内置方式返回结构化输出,但并非所有都支持。对于这些提供商,您必须使用提示来鼓励模型以所需的格式返回结构化数据。

LangChain 有输出解析器,可以帮助将模型输出解析为可用的对象。我们将在下面介绍一些示例。

入门

用于处理模型响应中结构化数据的主要输出解析器类型是StructuredOutputParser。在下面的示例中,我们使用zod 定义了我们期望从模型获得的输出类型的模式。

首先,让我们看看我们将插入提示中的默认格式化说明

选择您的聊天模型

安装依赖项

yarn add @langchain/openai 

添加环境变量

OPENAI_API_KEY=your-api-key

实例化模型

import { ChatOpenAI } from "@langchain/openai";

const model = new ChatOpenAI({
model: "gpt-4o-mini",
temperature: 0
});
import { z } from "zod";
import { RunnableSequence } from "@langchain/core/runnables";
import { StructuredOutputParser } from "@langchain/core/output_parsers";
import { ChatPromptTemplate } from "@langchain/core/prompts";

const zodSchema = z.object({
answer: z.string().describe("answer to the user's question"),
source: z
.string()
.describe(
"source used to answer the user's question, should be a website."
),
});

const parser = StructuredOutputParser.fromZodSchema(zodSchema);

const chain = RunnableSequence.from([
ChatPromptTemplate.fromTemplate(
"Answer the users question as best as possible.\n{format_instructions}\n{question}"
),
model,
parser,
]);

console.log(parser.getFormatInstructions());
You must format your output as a JSON value that adheres to a given "JSON Schema" instance.

"JSON Schema" is a declarative language that allows you to annotate and validate JSON documents.

For example, the example "JSON Schema" instance {{"properties": {{"foo": {{"description": "a list of test words", "type": "array", "items": {{"type": "string"}}}}}}, "required": ["foo"]}}}}
would match an object with one required property, "foo". The "type" property specifies "foo" must be an "array", and the "description" property semantically describes it as "a list of test words". The items within "foo" must be strings.
Thus, the object {{"foo": ["bar", "baz"]}} is a well-formatted instance of this example "JSON Schema". The object {{"properties": {{"foo": ["bar", "baz"]}}}} is not well-formatted.

Your output will be parsed and type-checked according to the provided schema instance, so make sure all fields in your output match the schema exactly and there are no trailing commas!

Here is the JSON Schema instance your output must adhere to. Include the enclosing markdown codeblock:
```json
{"type":"object","properties":{"answer":{"type":"string","description":"answer to the user's question"},"source":{"type":"string","description":"source used to answer the user's question, should be a website."}},"required":["answer","source"],"additionalProperties":false,"$schema":"http://json-schema.org/draft-07/schema#"}
```

接下来,让我们调用链

const response = await chain.invoke({
question: "What is the capital of France?",
format_instructions: parser.getFormatInstructions(),
});

console.log(response);
{
answer: "The capital of France is Paris.",
source: "https://en.wikipedia.org/wiki/Paris"
}

输出解析器实现Runnable 接口,这是LangChain 表达式语言 (LCEL) 的基本构建块。这意味着它们支持 invokestreambatchstreamLog 调用。

验证

StructuredOutputParser 的一项功能是它支持更严格的 Zod 验证。例如,如果您传递一个不符合模式的模拟模型输出,我们将收到一个详细的类型错误

import { AIMessage } from "@langchain/core/messages";

await parser.invoke(new AIMessage(`{"badfield": "foo"}`));
Error: Failed to parse. Text: "{"badfield": "foo"}". Error: [
{
"code": "invalid_type",
"expected": "string",
"received": "undefined",
"path": [
"answer"
],
"message": "Required"
},
{
"code": "invalid_type",
"expected": "string",
"received": "undefined",
"path": [
"source"
],
"message": "Required"
}
]

相比

await parser.invoke(
new AIMessage(`{"answer": "Paris", "source": "I made it up"}`)
);
{ answer: "Paris", source: "I made it up" }

还支持更高级的 Zod 验证。要了解更多信息,请查看Zod 文档

流式传输

虽然所有解析器都是可运行的并支持流式接口,但只有某些解析器可以流式传输部分解析的对象,因为这高度依赖于输出类型。StructuredOutputParser不支持部分流式传输,因为它在每一步都会验证输出。如果你尝试使用带有此输出解析器的链进行流式传输,该链将只生成完全解析的输出。

const stream = await chain.stream({
question: "What is the capital of France?",
format_instructions: parser.getFormatInstructions(),
});

for await (const s of stream) {
console.log(s);
}
{
answer: "The capital of France is Paris.",
source: "https://en.wikipedia.org/wiki/Paris"
}

然而,更简单的JsonOutputParser支持通过部分输出进行流式传输。

import { JsonOutputParser } from "@langchain/core/output_parsers";

const template = `Return a JSON object with a single key named "answer" that answers the following question: {question}.
Do not wrap the JSON output in markdown blocks.`;

const jsonPrompt = ChatPromptTemplate.fromTemplate(template);
const jsonParser = new JsonOutputParser();
const jsonChain = jsonPrompt.pipe(model).pipe(jsonParser);

const stream = await jsonChain.stream({
question: "Who invented the microscope?",
});

for await (const s of stream) {
console.log(s);
}
{}
{ answer: "" }
{ answer: "The" }
{ answer: "The invention" }
{ answer: "The invention of" }
{ answer: "The invention of the" }
{ answer: "The invention of the microscope" }
{ answer: "The invention of the microscope is" }
{ answer: "The invention of the microscope is attributed" }
{ answer: "The invention of the microscope is attributed to" }
{ answer: "The invention of the microscope is attributed to Hans" }
{ answer: "The invention of the microscope is attributed to Hans L" }
{
answer: "The invention of the microscope is attributed to Hans Lippers"
}
{
answer: "The invention of the microscope is attributed to Hans Lippershey"
}
{
answer: "The invention of the microscope is attributed to Hans Lippershey,"
}
{
answer: "The invention of the microscope is attributed to Hans Lippershey, Zach"
}
{
answer: "The invention of the microscope is attributed to Hans Lippershey, Zacharias"
}
{
answer: "The invention of the microscope is attributed to Hans Lippershey, Zacharias Jans"
}
{
answer: "The invention of the microscope is attributed to Hans Lippershey, Zacharias Janssen"
}
{
answer: "The invention of the microscope is attributed to Hans Lippershey, Zacharias Janssen,"
}
{
answer: "The invention of the microscope is attributed to Hans Lippershey, Zacharias Janssen, and"
}
{
answer: "The invention of the microscope is attributed to Hans Lippershey, Zacharias Janssen, and Anton"
}
{
answer: "The invention of the microscope is attributed to Hans Lippershey, Zacharias Janssen, and Antonie"
}
{
answer: "The invention of the microscope is attributed to Hans Lippershey, Zacharias Janssen, and Antonie van"
}
{
answer: "The invention of the microscope is attributed to Hans Lippershey, Zacharias Janssen, and Antonie van"... 4 more characters
}
{
answer: "The invention of the microscope is attributed to Hans Lippershey, Zacharias Janssen, and Antonie van"... 8 more characters
}
{
answer: "The invention of the microscope is attributed to Hans Lippershey, Zacharias Janssen, and Antonie van"... 12 more characters
}
{
answer: "The invention of the microscope is attributed to Hans Lippershey, Zacharias Janssen, and Antonie van"... 13 more characters
}
{
answer: "The invention of the microscope is attributed to Hans Lippershey, Zacharias Janssen, and Antonie van"... 18 more characters
}
{
answer: "The invention of the microscope is attributed to Hans Lippershey, Zacharias Janssen, and Antonie van"... 20 more characters
}
{
answer: "The invention of the microscope is attributed to Hans Lippershey, Zacharias Janssen, and Antonie van"... 26 more characters
}
{
answer: "The invention of the microscope is attributed to Hans Lippershey, Zacharias Janssen, and Antonie van"... 29 more characters
}
{
answer: "The invention of the microscope is attributed to Hans Lippershey, Zacharias Janssen, and Antonie van"... 33 more characters
}
{
answer: "The invention of the microscope is attributed to Hans Lippershey, Zacharias Janssen, and Antonie van"... 38 more characters
}
{
answer: "The invention of the microscope is attributed to Hans Lippershey, Zacharias Janssen, and Antonie van"... 43 more characters
}
{
answer: "The invention of the microscope is attributed to Hans Lippershey, Zacharias Janssen, and Antonie van"... 48 more characters
}
{
answer: "The invention of the microscope is attributed to Hans Lippershey, Zacharias Janssen, and Antonie van"... 51 more characters
}
{
answer: "The invention of the microscope is attributed to Hans Lippershey, Zacharias Janssen, and Antonie van"... 52 more characters
}
{
answer: "The invention of the microscope is attributed to Hans Lippershey, Zacharias Janssen, and Antonie van"... 57 more characters
}
{
answer: "The invention of the microscope is attributed to Hans Lippershey, Zacharias Janssen, and Antonie van"... 63 more characters
}
{
answer: "The invention of the microscope is attributed to Hans Lippershey, Zacharias Janssen, and Antonie van"... 73 more characters
}
{
answer: "The invention of the microscope is attributed to Hans Lippershey, Zacharias Janssen, and Antonie van"... 80 more characters
}
{
answer: "The invention of the microscope is attributed to Hans Lippershey, Zacharias Janssen, and Antonie van"... 81 more characters
}
{
answer: "The invention of the microscope is attributed to Hans Lippershey, Zacharias Janssen, and Antonie van"... 85 more characters
}
{
answer: "The invention of the microscope is attributed to Hans Lippershey, Zacharias Janssen, and Antonie van"... 94 more characters
}
{
answer: "The invention of the microscope is attributed to Hans Lippershey, Zacharias Janssen, and Antonie van"... 99 more characters
}
{
answer: "The invention of the microscope is attributed to Hans Lippershey, Zacharias Janssen, and Antonie van"... 108 more characters
}
{
answer: "The invention of the microscope is attributed to Hans Lippershey, Zacharias Janssen, and Antonie van"... 112 more characters
}
{
answer: "The invention of the microscope is attributed to Hans Lippershey, Zacharias Janssen, and Antonie van"... 118 more characters
}
{
answer: "The invention of the microscope is attributed to Hans Lippershey, Zacharias Janssen, and Antonie van"... 127 more characters
}
{
answer: "The invention of the microscope is attributed to Hans Lippershey, Zacharias Janssen, and Antonie van"... 138 more characters
}
{
answer: "The invention of the microscope is attributed to Hans Lippershey, Zacharias Janssen, and Antonie van"... 145 more characters
}
{
answer: "The invention of the microscope is attributed to Hans Lippershey, Zacharias Janssen, and Antonie van"... 149 more characters
}
{
answer: "The invention of the microscope is attributed to Hans Lippershey, Zacharias Janssen, and Antonie van"... 150 more characters
}
{
answer: "The invention of the microscope is attributed to Hans Lippershey, Zacharias Janssen, and Antonie van"... 151 more characters
}
{
answer: "The invention of the microscope is attributed to Hans Lippershey, Zacharias Janssen, and Antonie van"... 157 more characters
}
{
answer: "The invention of the microscope is attributed to Hans Lippershey, Zacharias Janssen, and Antonie van"... 159 more characters
}
{
answer: "The invention of the microscope is attributed to Hans Lippershey, Zacharias Janssen, and Antonie van"... 163 more characters
}
{
answer: "The invention of the microscope is attributed to Hans Lippershey, Zacharias Janssen, and Antonie van"... 167 more characters
}
{
answer: "The invention of the microscope is attributed to Hans Lippershey, Zacharias Janssen, and Antonie van"... 171 more characters
}
{
answer: "The invention of the microscope is attributed to Hans Lippershey, Zacharias Janssen, and Antonie van"... 175 more characters
}
{
answer: "The invention of the microscope is attributed to Hans Lippershey, Zacharias Janssen, and Antonie van"... 176 more characters
}
{
answer: "The invention of the microscope is attributed to Hans Lippershey, Zacharias Janssen, and Antonie van"... 181 more characters
}
{
answer: "The invention of the microscope is attributed to Hans Lippershey, Zacharias Janssen, and Antonie van"... 186 more characters
}
{
answer: "The invention of the microscope is attributed to Hans Lippershey, Zacharias Janssen, and Antonie van"... 190 more characters
}
{
answer: "The invention of the microscope is attributed to Hans Lippershey, Zacharias Janssen, and Antonie van"... 202 more characters
}
{
answer: "The invention of the microscope is attributed to Hans Lippershey, Zacharias Janssen, and Antonie van"... 203 more characters
}
{
answer: "The invention of the microscope is attributed to Hans Lippershey, Zacharias Janssen, and Antonie van"... 209 more characters
}
{
answer: "The invention of the microscope is attributed to Hans Lippershey, Zacharias Janssen, and Antonie van"... 214 more characters
}
{
answer: "The invention of the microscope is attributed to Hans Lippershey, Zacharias Janssen, and Antonie van"... 226 more characters
}
{
answer: "The invention of the microscope is attributed to Hans Lippershey, Zacharias Janssen, and Antonie van"... 239 more characters
}
{
answer: "The invention of the microscope is attributed to Hans Lippershey, Zacharias Janssen, and Antonie van"... 242 more characters
}
{
answer: "The invention of the microscope is attributed to Hans Lippershey, Zacharias Janssen, and Antonie van"... 246 more characters
}
{
answer: "The invention of the microscope is attributed to Hans Lippershey, Zacharias Janssen, and Antonie van"... 253 more characters
}
{
answer: "The invention of the microscope is attributed to Hans Lippershey, Zacharias Janssen, and Antonie van"... 257 more characters
}
{
answer: "The invention of the microscope is attributed to Hans Lippershey, Zacharias Janssen, and Antonie van"... 262 more characters
}
{
answer: "The invention of the microscope is attributed to Hans Lippershey, Zacharias Janssen, and Antonie van"... 265 more characters
}
{
answer: "The invention of the microscope is attributed to Hans Lippershey, Zacharias Janssen, and Antonie van"... 268 more characters
}
{
answer: "The invention of the microscope is attributed to Hans Lippershey, Zacharias Janssen, and Antonie van"... 273 more characters
}
{
answer: "The invention of the microscope is attributed to Hans Lippershey, Zacharias Janssen, and Antonie van"... 288 more characters
}
{
answer: "The invention of the microscope is attributed to Hans Lippershey, Zacharias Janssen, and Antonie van"... 300 more characters
}
{
answer: "The invention of the microscope is attributed to Hans Lippershey, Zacharias Janssen, and Antonie van"... 303 more characters
}
{
answer: "The invention of the microscope is attributed to Hans Lippershey, Zacharias Janssen, and Antonie van"... 311 more characters
}
{
answer: "The invention of the microscope is attributed to Hans Lippershey, Zacharias Janssen, and Antonie van"... 316 more characters
}
{
answer: "The invention of the microscope is attributed to Hans Lippershey, Zacharias Janssen, and Antonie van"... 317 more characters
}

下一步

你已经了解了如何使用输出解析器来解析提示模型输出的结构化输出。

接下来,查看工具调用指南,这是一种更内置的方式来获取某些模型提供商支持的结构化输出,或者阅读有关其他类型结构化数据的输出解析器的更多信息,例如XML


此页面对您有帮助吗?


您也可以留下详细的反馈 在GitHub上.