LangChain中嵌套JSON输出Schema的优化定义方法咨询
更规范的LangChain嵌套JSON输出Schema定义方案
你当前在ResponseSchema的description中手写嵌套JSON结构的方式,存在依赖LLM对自然语言描述的理解、缺乏代码层面校验、维护成本高的问题,下面给出两种更优的规范实现方式:
方法一:基于Pydantic模型定义嵌套Schema(推荐)
这是LangChain官方推荐的结构化输出方案,通过强类型的Pydantic模型定义嵌套结构,既能明确约束输出格式,又能自动完成结果校验。
实现步骤
- 定义嵌套的Pydantic模型,明确各字段的类型和描述
- 使用
PydanticOutputParser绑定模型,自动生成格式指令 - 将格式指令注入prompt,集成到
plan_and_execute模块中
代码示例
from langchain.output_parsers import PydanticOutputParser from pydantic import BaseModel, Field from langchain.chains.plan_and_execute import PlanAndExecute, load_agent_executor, load_chat_planner from langchain.chat_models import ChatOpenAI from langchain.prompts import PromptTemplate # 定义子级嵌套Schema class ProductDetail(BaseModel): name: str = Field(description="产品名称") price: float = Field(description="产品价格,保留两位小数") stock: int = Field(description="当前库存数量") # 定义顶级Schema class OrderInfo(BaseModel): order_id: str = Field(description="唯一订单编号") user_name: str = Field(description="下单用户姓名") total_amount: float = Field(description="订单总金额") products: list[ProductDetail] = Field(description="订单包含的所有产品列表") # 初始化解析器 parser = PydanticOutputParser(pydantic_object=OrderInfo) # 构建带格式约束的prompt prompt = PromptTemplate( template="根据用户需求生成符合规范的订单信息:\n{format_instructions}\n用户需求:{query}", input_variables=["query"], partial_variables={"format_instructions": parser.get_format_instructions()} ) # 初始化plan_and_execute组件 llm = ChatOpenAI(temperature=0) planner = load_chat_planner(llm) executor = load_agent_executor(llm, verbose=True) plan_exec_chain = PlanAndExecute(planner=planner, executor=executor, verbose=True) # 执行并解析结果 raw_result = plan_exec_chain.run(prompt.format(query="生成一个用户名为李四、订单号OD20240601的订单,包含两台价格3999的手机(库存20)和一个价格199的耳机(库存50)")) parsed_result = parser.parse(raw_result) # 输出结构化结果 print(parsed_result.dict())
优势
- 强类型校验:LLM输出不符合Schema时会直接抛出错误,避免格式混乱
- 可维护性高:修改嵌套结构只需调整Pydantic模型,无需手动编写复杂描述
- 自动生成格式指令:无需手写嵌套JSON的规则,由解析器自动生成清晰的格式说明
方法二:使用嵌套ResponseSchema结合StructuredOutputParser
如果不想引入Pydantic依赖,可以通过嵌套的ResponseSchema定义结构,明确说明子字段的要求。
代码示例
from langchain.output_parsers import StructuredOutputParser, ResponseSchema from langchain.chains.plan_and_execute import PlanAndExecute, load_agent_executor, load_chat_planner from langchain.chat_models import ChatOpenAI from langchain.prompts import PromptTemplate # 定义子级ResponseSchema product_schemas = [ ResponseSchema(name="name", description="产品名称"), ResponseSchema(name="price", description="产品价格,数值类型"), ResponseSchema(name="stock", description="库存数量,整数类型") ] # 定义顶级ResponseSchema,明确products字段的嵌套结构 order_schemas = [ ResponseSchema(name="order_id", description="订单编号"), ResponseSchema(name="user_name", description="用户名"), ResponseSchema(name="products", description=f"产品列表,每个元素是包含以下字段的对象:{[s.dict() for s in product_schemas]}") ] # 初始化解析器 parser = StructuredOutputParser.from_response_schemas(order_schemas) # 构建prompt并集成到plan_and_execute prompt = PromptTemplate( template="生成符合要求的订单数据:\n{format_instructions}\n用户请求:{query}", input_variables=["query"], partial_variables={"format_instructions": parser.get_format_instructions()} ) llm = ChatOpenAI(temperature=0) planner = load_chat_planner(llm) executor = load_agent_executor(llm, verbose=True) plan_exec_chain = PlanAndExecute(planner=planner, executor=executor, verbose=True) # 执行并解析 raw_result = plan_exec_chain.run(prompt.format(query="生成订单号OD20240602,用户王五,包含一台价格5999的笔记本(库存15)")) parsed_result = parser.parse(raw_result) print(parsed_result)
优势
- 无需额外依赖Pydantic,适合轻量级嵌套场景
- 结构定义直观,通过列表嵌套清晰展示层级关系
总结
优先选择Pydantic模型的实现方式,它能提供最严谨的格式约束和代码层面的校验,是LangChain处理嵌套结构化输出的标准方案;若场景简单且不想引入Pydantic,可使用嵌套ResponseSchema的方式替代。
内容的提问来源于stack exchange,提问作者Zizi96
相关产品推荐
相关产品推荐

