LangChain组件Chat models详解(4)——结构化输出
本章目录如下:
- 《Gradio全解13——LangChain组件Chat models详解(1)——功能介绍》
- 《Gradio全解13——LangChain组件Chat models详解(2)——接口》
- 《Gradio全解13——LangChain组件Chat models详解(3)——消息(Messages)》
- 《Gradio全解13——LangChain组件Chat models详解(4)——结构化输出》
- 《Gradio全解13——LangChain组件Chat models详解(5)——多模态》
- 《Gradio全解13——LangChain组件Chat models详解(6)——高级主题》
本篇摘要
本章介绍LangChain组件Chat Models。
13. LangChain组件Chat models详解
LangChain本身集成了大量供应商和组件,资料庞杂,理解起来颇有难度。Chat models作为LangChain的主要组件,涵盖了最常用的功能,也是各提供商集成的主要载体,所以本章将详细介绍Chat models。更详细资料请参阅官方LangChain Componets文档。
本章主要内容包括Chat models介绍、接口、消息、结构化输出、多模态和高级主题,为后续使用Agent创建Gradio做铺垫。
13.4 结构化输出
对于聊天机器人等应用,模型需要直接以自然语言响应用户。然而在某些场景中,需要模型以结构化格式输出,比如希望将模型输出存储在数据库中,并确保输出符合数据库模式。这种需求促成了结构化输出的概念,即可以指示模型以特定的输出结构进行响应。
结构化输出包含以下关键概念:
(1) 模式定义:输出结构以模式schema的形式表示,可以通过多种方式定义,本文列举两种:一个是python dict方式,另一种是通过Pydantic;
(2) 返回结构化输出:模型通过工具绑定或结构化函数被赋予某种模式,模型将被指示返回符合该模式的输出;另外还可以通过模型参数配置结构化输出格式。

下面看一下模式定义以及其它配置模式方法。
13.4.1 模式Schema定义
模式定义的核心概念是模型响应的输出结构需要以某种方式表示。虽然对象类型取决于正在使用的模型,但有一些常见的对象类型被推荐用于Python中的结构化输出。有两种方式定义结构化输出Schema:一种是python dict方式,另一种是通过Pydantic。
1. 使用python字典
第一种Schema定义方法:结构化输出最简单且最常见的格式是类似JSON的结构,在Python中可以用字典(dict)或列表(list)表示,或直接使用JSON对象。而JSON对象(或Python中的dict)通常在工具需要原始、灵活且低开销的结构化数据时直接使用。定义代码如下:
# 使用大括号定义
dict_schema|json_schema = {
"answer": "The answer to the user's question",
"followup_question": "A followup question the user could ask"
}
# 使用dict()函数定义一个字典
dict_schema2 = dict(answer="The answer to the user's question", followup_question="A followup question the user could ask")
# 使用
注意:python dict的定义使用单引号或双引号都可以,但JSON格式必须使用双引号。
2. 使用Pydantic
第二种方法是使用Pydantic: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")
13.4.2 返回结构化输出
定义了模式后,我们需要一种方法来指示模型使用它。虽然可以将此模式包含在提示中并礼貌地请求模型使用它,但并不推荐,有几种更强大的方法可以通过模型提供商API中的原生功能来使用schema:工具调用、JSON模式和结构化输出方法。
1. 使用工具调用
许多模型提供商支持工具调用,这一概念在工具调用指南中已有更详细的讨论。简而言之,工具调用涉及将工具绑定到模型,并在适当的时候,模型可以决定调用此工具并确保其响应符合工具的模式。有了这个理论,核心概念就很简单:只需将我们的模式作为工具绑定到模型上即可!以下是使用上面定义的ResponseFormatter模式的一个示例:
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?")
工具调用的参数tool_calls已经被提取为一个字典,这个字典可以选择性地被解析为一个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"])
关于工具请参考后面章节。
2. JSON模式
除了工具调用外,一些模型提供商还支持一种称为JSON模式的功能。它支持将JSON模式定义作为输入,并强制模型生成符合要求的JSON输出。你可以在Chat models中找到支持JSON模式的模型提供商的表格:Featured Providers,或见下面截图。以下是如何使用OpenAI的JSON模式的示例:
from langchain_openai import ChatOpenAI
model = ChatOpenAI(model="gpt-4o", model_kwargs={ "response_format": { "type": "json_object" } })
ai_msg = model.invoke("Return a JSON object with key 'random_ints' and a value of 10 random ints in [0-99]")
ai_msg.content
'\n{\n "random_ints": [23, 47, 89, 15, 34, 76, 58, 3, 62, 91]\n}'
需要注意的一个重要事项:模型仍然返回一个字符串,需要将其解析为JSON对象,这可以使用json库或JSON输出解析器来完成。如果需要更高级的功能,请参阅how-to guide on the JSON output parser。这里使用json库将模型输出解析为JSON对象,代码如下:
import json
json_object = json.loads(ai_msg.content)
{'random_ints': [23, 47, 89, 15, 34, 76, 58, 3, 62, 91]}
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?')
这既将模式作为工具绑定到模型,又将输出解析为指定的输出模式。
推荐用法:LangChain提供的with_structured_output(),它自动化了将模式绑定到模型并解析输出的过程,此辅助函数适用于所有支持结构化输出的模型提供商,在信息提取任务中非常有用,更多信息请阅读Structured outputs。
65

被折叠的 条评论
为什么被折叠?



