一文读懂如何使用LangChain进行Json格式化输出

在这里插入图片描述

如果你不使用LangChain调用大模型,也有很多办法对大模型的输出进行Json格式化,不过就是相对没有LangChain方便。本文会将如何使用Langchain进行Json格式化进行系统性梳理,希望能帮助到你。方法有三种

  1. 基础方法:提示词进行Json格式化
  2. 使用JsonOutputParser
  3. 使用PydanticOutputParser

下面是完整的示例代码,代码里面包含了详细的中文解释,这里就不再文字赘述了。另外,示例代码是可以执行的,建议想学习的同学copy一份下来自己调试一下哦

内容参考自LangChain官网

#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
@author: Junius 
@Email: see619055@gmail.com
@time: 2025/5/26 16:13 
@file: 05.3 Json格式化输出
@project: OpenAppAI
@describe: LangChain JSON格式化输出示例
"""
from typing import List, Dict, Any, Optional
import json
from pydantic import BaseModel, Field

# 导入LangChain相关模块
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import JsonOutputParser, PydanticOutputParser
from langchain_core.pydantic_v1 import BaseModel, Field, validator
from langchain.output_parsers import OutputFixingParser
from langchain_core.exceptions import OutputParserException

# 定义一个模型类用于结构化JSON输出
class Person(BaseModel):
    """人物信息模型"""
    name: str = Field(description="人物姓名")
    age: int = Field(description="人物年龄")
    occupation: str = Field(description="职业")
    hobbies: List[str] = Field(description="爱好列表")
    
    @validator("age")
    def validate_age(cls, value):
        if value < 0 or value > 150:
            raise ValueError("年龄必须在0到150之间")
        return value

# 初始化LLM模型
llm = ChatOpenAI(
    openai_api_base="https://open.bigmodel.cn/api/paas/v4/",
    # openai_api_key="你的API密钥",  # 使用智谱免费的模型进行学习
    model="glm-4-flash-250414"
)

# 示例1: 基础JSON输出
def basic_json_output():
    """基础的JSON输出示例"""
    print("\n=== 示例1: 基础JSON输出 ===")
    
    # 创建JSON解析器
    json_parser = JsonOutputParser()
    
    # 创建提示模板,明确指示模型输出JSON格式
    prompt = ChatPromptTemplate.from_messages([
        ("system", "你是一个提供JSON格式化数据的助手。请以有效的JSON格式回复,不要添加额外的文本说明。"),
        ("user", "请提供关于'{topic}'的基本信息,包括名称、描述和至少3个关键特点。")
    ])
    
    # 构建链
    chain = prompt | llm | json_parser
    
    # 调用链并打印结果
    result = chain.invoke({"topic": "人工智能"})
    print(json.dumps(result, ensure_ascii=False, indent=2))

# 示例2: 使用Pydantic模型进行结构化输出
def pydantic_structured_output():
    """使用Pydantic模型进行结构化JSON输出示例"""
    print("\n=== 示例2: 使用Pydantic模型进行结构化输出 ===")
    
    # 创建Pydantic解析器
    parser = PydanticOutputParser(pydantic_object=Person)
    
    # 获取解析器的格式指令
    format_instructions = parser.get_format_instructions()
    
    # 创建提示模板
    prompt = ChatPromptTemplate.from_messages([
        ("system", "你是一个提供JSON格式化数据的助手。请按照指定的格式输出。\n{format_instructions}"),
        ("user", "请生成一个关于'{character}'的人物信息。")
    ])
    
    # 构建链
    chain = prompt | llm | parser
    
    # 调用链并打印结果
    result = chain.invoke({
        "format_instructions": format_instructions,
        "character": "爱因斯坦"
    })
    
    # 由于result已经是Person对象,我们可以直接访问其属性
    print(f"姓名: {result.name}")
    print(f"年龄: {result.age}")
    print(f"职业: {result.occupation}")
    print(f"爱好: {', '.join(result.hobbies)}")
    print("\n完整JSON:")
    print(json.dumps(result.dict(), ensure_ascii=False, indent=2))

# 示例3: 流式输出JSON
def streaming_json_output():
    """流式输出JSON示例"""
    print("\n=== 示例3: 流式输出JSON ===")
    
    json_parser = JsonOutputParser()
    
    prompt = ChatPromptTemplate.from_messages([
        ("system", "你是一个提供JSON格式化数据的助手。请以有效的JSON格式回复,不要添加额外的文本说明。"),
        ("user", "请列出'{country}'的5个主要城市,包括名称、人口和一句话描述。")
    ])
    
    # 构建链
    chain = prompt | llm | json_parser
    
    print("流式输出开始:")
    # 流式输出
    result = {}
    for chunk in chain.stream({"country": "中国"}):
        print(f"收到chunk: {chunk}")
        # 更新结果字典
        if isinstance(chunk, dict):
            result.update(chunk)
    
    print("\n最终完整结果:")
    print(json.dumps(result, ensure_ascii=False, indent=2))

# 示例4: 错误处理和修复
def error_handling_and_fixing():
    """JSON解析错误处理和修复示例"""
    print("\n=== 示例4: 错误处理和修复 ===")
    
    # 创建解析器
    parser = PydanticOutputParser(pydantic_object=Person)
    
    # 创建错误修复包装器
    fixing_parser = OutputFixingParser.from_llm(
        parser=parser,
        llm=llm
    )
    
    # 创建提示模板 - 故意使用较弱的提示以演示错误修复
    prompt = ChatPromptTemplate.from_messages([
        ("system", "请提供一个人物的信息。"),
        ("user", "描述'{character}'的信息。")
    ])
    
    # 构建链
    chain_with_fixing = prompt | llm | fixing_parser
    
    try:
        # 调用链并打印结果
        result = chain_with_fixing.invoke({
            "character": "马云"
        })
        print("修复后的结果:")
        print(json.dumps(result.dict(), ensure_ascii=False, indent=2))
    except OutputParserException as e:
        print(f"解析错误: {e}")

# 示例5: 复杂嵌套JSON结构
def complex_nested_json():
    """复杂嵌套JSON结构示例"""
    print("\n=== 示例5: 复杂嵌套JSON结构 ===")
    
    # 定义更复杂的模型
    class Address(BaseModel):
        street: str = Field(description="街道名称")
        city: str = Field(description="城市")
        country: str = Field(description="国家")
    
    class Contact(BaseModel):
        email: str = Field(description="电子邮件")
        phone: Optional[str] = Field(description="电话号码", default=None)
    
    class Employee(BaseModel):
        name: str = Field(description="员工姓名")
        position: str = Field(description="职位")
        address: Address = Field(description="地址信息")
        contact: Contact = Field(description="联系方式")
        skills: List[str] = Field(description="技能列表")
        projects: Dict[str, str] = Field(description="项目名称和描述")
    
    # 创建Pydantic解析器
    complex_parser = PydanticOutputParser(pydantic_object=Employee)
    format_instructions = complex_parser.get_format_instructions()
    
    # 创建提示模板
    prompt = ChatPromptTemplate.from_messages([
        ("system", "请生成符合以下格式的JSON数据:\n{format_instructions}"),
        ("user", "创建一个名为'{name}'的技术领导者的详细信息。")
    ])
    
    # 构建链
    chain = prompt | llm | complex_parser
    
    # 调用链并打印结果
    result = chain.invoke({
        "format_instructions": format_instructions,
        "name": "张三"
    })
    
    print(json.dumps(result.dict(), ensure_ascii=False, indent=2))

if __name__ == "__main__":
    print("LangChain JSON格式化输出示例")
    print("="*50)
    
    # 运行各示例
    basic_json_output()
    pydantic_structured_output()
    streaming_json_output()
    error_handling_and_fixing()
    complex_nested_json()
    
    print("\n所有示例执行完毕")

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值