Skip to main content
在 GitHub 上打开

结构化输出

概述

对于许多应用程序,例如聊天机器人,模型需要直接以自然语言响应用户。 但是,在某些情况下,我们需要模型以结构化格式输出。 例如,我们可能希望将模型输出存储在数据库中,并确保输出符合数据库架构。 这种需求激发了结构化输出的概念,其中可以指示模型使用特定的输出结构进行响应。

结构化输出

关键概念

(1) Schema 定义:输出结构表示为 Schema,可以通过多种方式定义。(2) 返回结构化输出:为模型提供此架构,并指示返回符合该架构的输出。

此伪代码说明了使用结构化输出时建议的工作流程。 LangChain 提供了一个方法with_structured_output(),这将自动执行将 Schema 绑定到模型并解析输出的过程。 此帮助程序函数可用于支持结构化输出的所有模型提供程序。

# Define schema
schema = {"foo": "bar"}
# Bind schema to model
model_with_structure = model.with_structured_output(schema)
# Invoke the model to produce structured output that matches the schema
structured_output = model_with_structure.invoke(user_input)

Schema 定义

中心概念是模型响应的输出结构需要以某种方式表示。 虽然您可以使用的对象类型取决于您正在使用的模型,但在 Python 中,通常允许或推荐用于结构化输出的常见对象类型。

结构化输出的最简单和最常见的格式是类似 JSON 的结构,在 Python 中可以表示为字典 (dict) 或列表 (list)。 当工具需要原始、灵活且开销最小的结构化数据时,通常会直接使用 JSON 对象(或 Python 中的字典)。

{
"answer": "The answer to the user's question",
"followup_question": "A followup question the user could ask"
}

作为第二个示例,Pydantic 对于定义结构化输出模式特别有用,因为它提供了类型提示和验证。 下面是一个 Pydantic 架构的示例:

from pydantic import BaseModel, Field
class ResponseFormatter(BaseModel):
"""Always use this tool to structure your response to the user."""
answer: str = Field(description="The answer to the user's question")
followup_question: str = Field(description="A followup question the user could ask")

返回结构化输出

定义 schema 后,我们需要一种方法来指示模型使用它。 虽然一种方法是在提示中包含此架构并友好地请求模型使用它,但不建议这样做。 有几种更强大的方法可用于利用模型提供程序的 API 中的本机功能。

使用工具调用

许多模型提供商都支持工具调用,我们的工具调用指南中更详细地讨论了这一概念。 简而言之,工具调用涉及将工具绑定到模型,在适当的时候,模型可以决定调用此工具并确保其响应符合工具的架构。 考虑到这一点,中心概念很简单:只需将我们的 schema 绑定到一个模型作为工具!下面是一个使用ResponseFormatterschema 的定义:

from langchain_openai import ChatOpenAI
model = ChatOpenAI(model="gpt-4o", temperature=0)
# Bind responseformatter schema as a tool to the model
model_with_tools = model.bind_tools([ResponseFormatter])
# Invoke the model
ai_msg = model_with_tools.invoke("What is the powerhouse of the cell?")
API 参考:ChatOpenAI

工具调用的参数已提取为字典。 这个字典可以选择性地解析成一个 Pydantic 对象,匹配我们原来的ResponseFormatter图式。

# Get the tool call arguments
ai_msg.tool_calls[0]["args"]
{'answer': "The powerhouse of the cell is the mitochondrion. Mitochondria are organelles that generate most of the cell's supply of adenosine triphosphate (ATP), which is used as a source of chemical energy.",
'followup_question': 'What is the function of ATP in the cell?'}
# Parse the dictionary into a pydantic object
pydantic_object = ResponseFormatter.model_validate(ai_msg.tool_calls[0]["args"])

JSON 模式

除了工具调用之外,一些模型提供程序还支持名为JSON mode. 这支持将 JSON 架构定义作为输入,并强制模型生成符合要求的 JSON 输出。 您可以在此处找到支持 JSON 模式的模型提供程序表。 以下是如何将 JSON 模式与 OpenAI 一起使用的示例:

from langchain_openai import ChatOpenAI
model = ChatOpenAI(model="gpt-4o").with_structured_output(method="json_mode")
ai_msg = model.invoke("Return a JSON object with key 'random_ints' and a value of 10 random ints in [0-99]")
ai_msg
{'random_ints': [45, 67, 12, 34, 89, 23, 78, 56, 90, 11]}
API 参考:ChatOpenAI

结构化输出方法

使用上述方法生成结构化输出时存在一些挑战:

(1) 使用工具调用时,需要将工具调用参数从字典解析回原始架构。

(2) 此外,需要指示模型在我们想要强制执行结构化输出时始终使用该工具,这是特定于提供程序的设置。

(3) 使用 JSON 模式时,需要将输出解析为 JSON 对象。

考虑到这些挑战,LangChain 提供了一个辅助函数 (with_structured_output()) 来简化流程。

结构化输出的图表

这既将架构绑定到作为工具的模型,又将输出解析为指定的输出架构。

# Bind the schema to the model
model_with_structure = model.with_structured_output(ResponseFormatter)
# Invoke the model
structured_output = model_with_structure.invoke("What is the powerhouse of the cell?")
# Get back the pydantic object
structured_output
ResponseFormatter(answer="The powerhouse of the cell is the mitochondrion. Mitochondria are organelles that generate most of the cell's supply of adenosine triphosphate (ATP), which is used as a source of chemical energy.", followup_question='What is the function of ATP in the cell?')
延伸阅读

有关使用的更多详细信息,请参阅我们的操作指南