LangChain 结构化输出指南
概述
对于许多应用程序(如聊天机器人),模型需要直接用自然语言回应用户。然而,在某些场景下,我们需要模型以结构化格式输出。例如,我们可能希望将模型输出存储在数据库中,并确保输出符合数据库模式。这种需求促成了结构化输出的概念,即可以指示模型以特定的输出结构进行响应。
核心概念
(1) 模式定义: 输出结构表示为模式,可以通过多种方式定义。
(2) 返回结构化输出: 模型被给予此模式,并被指示返回符合该模式的输出。
推荐用法
以下伪代码说明了使用结构化输出时的推荐工作流程。LangChain 提供了一个方法 with_structured_output()
,它自动化了将模式绑定到模型和解析输出的过程。此辅助函数适用于所有支持结构化输出的模型提供商。
# 定义模式
schema = {"foo": "bar"}
# 将模式绑定到模型
model_with_structure = model.with_structured_output(schema)
# 调用模型以产生符合模式的结构化输出
structured_output = model_with_structure.invoke(user_input)
模式定义
核心概念是模型响应的输出结构需要以某种方式表示。虽然您可以使用的对象类型取决于您使用的模型,但在Python中通常允许或推荐用于结构化输出的常见对象类型。
1. JSON格式(字典/列表)
结构化输出最简单和最常见的格式是类似JSON的结构,在Python中可以表示为字典(dict)或列表(list)。当工具需要原始、灵活和最小开销的结构化数据时,通常直接使用JSON对象(或Python中的字典)。
{"answer": "用户问题的答案","followup_question": "用户可以询问的后续问题"
}
2. Pydantic模式
Pydantic特别适用于定义结构化输出模式,因为它提供类型提示和验证。以下是Pydantic模式的示例:
from pydantic import BaseModel, Fieldclass ResponseFormatter(BaseModel):"""始终使用此工具来构建对用户的响应。"""answer: str = Field(description="用户问题的答案")followup_question: str = Field(description="用户可以询问的后续问题")
返回结构化输出
定义了模式后,我们需要一种方法来指示模型使用它。虽然一种方法是在提示中包含此模式并友好地要求模型使用它,但这不是推荐的做法。有几种更强大的方法可以利用模型提供商API中的原生功能。
使用工具调用
许多模型提供商支持工具调用,这个概念在我们的工具调用指南中有更详细的讨论。简而言之,工具调用涉及将工具绑定到模型,在适当的时候,模型可以决定调用此工具并确保其响应符合工具的模式。考虑到这一点,核心概念很简单:只需将我们的模式作为工具绑定到模型!
以下是使用上面定义的 ResponseFormatter
模式的示例:
from langchain_openai import ChatOpenAImodel = ChatOpenAI(model="gpt-4o", temperature=0)
# 将ResponseFormatter模式作为工具绑定到模型
model_with_tools = model.bind_tools([ResponseFormatter])
# 调用模型
ai_msg = model_with_tools.invoke("细胞的动力工厂是什么?")
工具调用的参数已经被提取为字典。此字典可以选择性地解析为Pydantic对象,匹配我们原始的 ResponseFormatter
模式。
# 获取工具调用参数
ai_msg.tool_calls[0]["args"]
{'answer': "细胞的动力工厂是线粒体。线粒体是产生细胞大部分三磷酸腺苷(ATP)供应的细胞器,ATP用作化学能源。",'followup_question': 'ATP在细胞中的功能是什么?'
}# 将字典解析为pydantic对象
pydantic_object = ResponseFormatter.model_validate(ai_msg.tool_calls[0]["args"])
JSON模式
除了工具调用,一些模型提供商还支持称为 JSON模式
的功能。这支持JSON模式定义作为输入,并强制模型产生符合要求的JSON输出。您可以在这里找到支持JSON模式的模型提供商表格。
以下是如何在OpenAI中使用JSON模式的示例:
from langchain_openai import ChatOpenAImodel = ChatOpenAI(model="gpt-4o").with_structured_output(method="json_mode")
ai_msg = model.invoke("返回一个JSON对象,键为'random_ints',值为[0-99]范围内的10个随机整数")
ai_msg
# 输出: {'random_ints': [45, 67, 12, 34, 89, 23, 78, 56, 90, 11]}
结构化输出方法
使用上述方法产生结构化输出时存在一些挑战:
-
解析挑战: 当使用工具调用时,工具调用参数需要从字典解析回原始模式。
-
强制使用工具: 此外,当我们想要强制结构化输出时,需要指示模型始终使用工具,这是一个特定于提供商的设置。
-
JSON解析: 当使用JSON模式时,输出需要解析为JSON对象。
考虑到这些挑战,LangChain提供了一个辅助函数(with_structured_output()
)来简化流程。
这既将模式绑定到模型作为工具,又将输出解析为指定的输出模式。
# 将模式绑定到模型
model_with_structure = model.with_structured_output(ResponseFormatter)
# 调用模型
structured_output = model_with_structure.invoke("细胞的动力工厂是什么?")
# 获取pydantic对象
structured_output
# 输出: ResponseFormatter(
# answer="细胞的动力工厂是线粒体。线粒体是产生细胞大部分三磷酸腺苷(ATP)供应的细胞器,ATP用作化学能源。",
# followup_question='ATP在细胞中的功能是什么?'
# )
实际应用场景
结构化输出在以下场景中特别有用:
- 数据库存储: 确保模型输出符合数据库模式
- API集成: 生成符合特定API要求的响应格式
- 数据提取: 从非结构化文本中提取结构化信息
- 表单填充: 自动填充具有特定字段的表单
- 报告生成: 创建具有一致格式的报告
最佳实践
- 明确的模式定义: 使用清晰的字段描述和类型提示
- 验证机制: 利用Pydantic的验证功能确保数据质量
- 错误处理: 实现适当的错误处理机制
- 性能考虑: 选择适合您用例的最高效方法
总结
LangChain的结构化输出功能为开发者提供了一种强大而灵活的方式来确保模型输出符合特定格式。通过使用 with_structured_output()
方法,您可以轻松地将模式绑定到模型并获得结构化的响应,这对于构建生产级应用程序至关重要。
参考资料:
- LangChain官方文档 - 结构化输出
方法,您可以轻松地将模式绑定到模型并获得结构化的响应,这对于构建生产级应用程序至关重要。
参考资料:
- LangChain官方文档 - 结构化输出
- 更多详细用法请参见官方使用指南