083-LangChain结构化输出链完整案例

本案例详细介绍了如何使用LangChain和OpenAI的语言模型实现结构化输出生成。我们将构建一个测验生成系统,能够创建具有一致格式和结构的多项选择题。

1. 案例目标

本案例的主要目标是:

  1. 掌握结构化输出链的创建和使用:学习如何使用LangChain创建能够生成结构化数据的链
  2. 理解Pydantic模型在结构化输出中的作用:了解如何使用Pydantic定义输出结构
  3. 学习如何使用ChatPromptTemplate指导模型输出:掌握如何设计提示模板以获得期望的结构化输出
  4. 掌握with_structured_output方法的使用:学习如何将语言模型转换为结构化输出模型
  5. 实现测验生成系统:构建一个能够根据主题生成多项选择题的完整系统

2. 技术栈与核心依赖

  • Python 3.8+
  • LangChain:用于构建语言模型应用的核心框架
  • LangChain OpenAI:用于集成OpenAI模型
  • LangChain Core:提供LangChain的核心功能
  • Pydantic:用于数据验证和设置管理
  • OpenAI API:用于访问GPT-4o等语言模型

核心依赖安装:

# 安装LangChain及相关依赖
!pip install langchain langchain-openai langchain-core

# 安装Pydantic用于数据模型定义
!pip install pydantic

3. 环境配置

在开始之前,需要配置以下环境:

  1. 安装必要的Python包:通过pip安装LangChain及相关依赖
  2. 设置OpenAI API密钥:确保有有效的OpenAI API密钥
  3. 配置LangSmith(可选):用于跟踪和调试LangChain应用
# 设置环境变量
import os
os.environ["OPENAI_API_KEY"] = "sk-..."  # 替换为您的API密钥
os.environ["LANGCHAIN_API_KEY"] = "ls-..."  # LangSmith API密钥(可选)
os.environ["LANGCHAIN_TRACING_V2"] = "true"
os.environ["LANGCHAIN_PROJECT"] = "Structured-Output-Chain"

4. 案例实现

4.1 定义Pydantic模型

首先,我们使用Pydantic定义测验的结构,包括问题、难度级别和四个答案选项:

from pydantic import BaseModel, Field
from typing import List

# 定义Quiz类 - 表示4选项多项选择题的结构
class Quiz(BaseModel):
    """提取4选项多项选择题的信息"""
    
    question: str = Field(..., description="测验问题")  # 测验问题
    level: str = Field(
        ..., description="测验的难度级别(easy, medium, hard)"
    )
    options: List[str] = Field(..., description="测验的4个答案选项")  # 答案选项

4.2 设置语言模型

使用ChatOpenAI设置GPT-4o模型,并配置适当的参数:

from langchain_openai import ChatOpenAI

# 设置带有适当参数的GPT-4o模型
llm = ChatOpenAI(model="gpt-4o", temperature=0.1)

4.3 创建提示模板

设计一个ChatPromptTemplate来指导模型生成测验:

from langchain_core.prompts import ChatPromptTemplate

# 定义一个提示模板来指导模型生成测验
prompt = ChatPromptTemplate.from_messages(
    [
        (
            "system",
            "你是一位世界闻名的测验专家,能够以结构化格式生成测验。",
        ),
        (
            "human",
            "请根据下面提供的主题创建一个4选项的多项选择题。"
            "如果可能,请基于现有的知识设计问题,但不要在问题中直接包含主题的细节。"
            "\n主题:\n{topic}",
        ),
        ("human", "提示:确保以正确的格式回答"),
    ]
)

4.4 创建结构化输出模型

使用with_structured_output方法将语言模型转换为结构化输出模型:

# 创建一个结构化输出模型以匹配Quiz类结构
llm_with_structured_output = llm.with_structured_output(Quiz)

4.5 组合成完整的链

将提示模板和结构化输出模型组合成一个完整的链:

# 将提示模板和结构化输出模型组合成一个链
chain = prompt | llm_with_structured_output

4.6 调用链生成测验

使用创建的链根据给定主题生成测验:

# 请求基于给定主题生成测验
generated_quiz = chain.invoke({"topic": "韩国美食"})

# 打印生成的测验
print(f"{generated_quiz.question} (难度: {generated_quiz.level})\n")
for i, opt in enumerate(generated_quiz.options):
    print(f"{i+1}) {opt}")

示例输出:

以下哪一种是通过发酵蔬菜(主要是大白菜和韩国萝卜)和各种调味料制成的传统韩国菜肴?(难度: 中等)

1) 泡菜
2) 寿司
3) 塔可
4) 西班牙海鲜饭

5. 案例效果

通过本案例,我们可以实现:

  • 结构化数据生成:语言模型能够生成符合预定义结构的输出,而不仅仅是文本
  • 一致的数据格式:所有生成的测验都遵循相同的结构,便于后续处理和使用
  • 类型安全:使用Pydantic模型确保输出的数据类型正确
  • 灵活的主题输入:可以根据任何主题生成相应的测验

6. 案例实现思路

本案例的实现思路如下:

  1. 定义数据结构:使用Pydantic定义期望的输出结构
  2. 设置语言模型:选择适合的语言模型并配置参数
  3. 设计提示模板:创建指导模型生成结构化输出的提示
  4. 创建结构化输出模型:将语言模型转换为结构化输出模型
  5. 组合处理链:使用LCEL将各组件组合成完整的处理链
  6. 调用链生成输出:使用链根据输入生成结构化输出

7. 扩展建议

  • 批量生成:扩展系统以支持批量生成多个测验
  • 答案验证:添加功能来验证生成的问题和答案的正确性
  • 难度自适应:根据用户反馈自动调整生成测验的难度
  • 多语言支持:扩展系统以支持生成不同语言的测验
  • 集成到应用:将测验生成功能集成到教育或培训应用中

8. 总结

本案例详细介绍了如何使用LangChain实现结构化输出生成,重点展示了如何结合Pydantic模型和语言模型创建能够生成结构化数据的链。我们构建了一个测验生成系统,能够根据主题生成具有一致格式的多项选择题。

结构化输出是LangChain的强大功能之一,它使得语言模型的输出更加可控和可用,特别适用于需要特定数据格式的应用场景。通过本案例的学习,您可以轻松地将这种方法应用到其他需要结构化输出的场景中,如表单填写、数据提取、API调用等。

### LangChain结构化输出功能 LangChain 提供了强大的工具来帮助开发者构建具有结构化输出能力的应用程序。以下是关于 LangChain 结构化输出的一些核心概念及其使用方法。 #### 1. 设置系统消息和用户消息模板 通过 `@SystemMessage` 和 `@UserMessage` 注解,可以定义系统的上下文以及用户的输入格式。这使得模型能够更好地理解和解析复杂任务的要求[^1]。 ```java public interface TextUtils { @SystemMessage("You are an AI assistant that translates and summarizes text.") @UserMessage("Translate the following sentence into {language}: {text}") String translate(String text, String language); @UserMessage("Summarize the following text into {n} bullet points: {text}") List<String> summarize(String text, int n); } ``` 在此示例中,`translate` 方法被配置为接受一段文本和目标语言作为参数,并返回翻译后的字符串;而 `summarize` 方法则会将给定的文本总结成指定数量的关键点列表。 --- #### 2. 实现情感分析服务 除了简单的翻译与摘要外,还可以利用 LangChain 构建更复杂的业务逻辑,比如情感分析。通过自定义的消息模板和服务接口设计,可以让大模型专注于特定领域的问题解决[^2]。 ```java public interface SentimentAnalyzer { @SystemMessage("You will analyze the sentiment of user input and classify it as 'positive', 'negative' or 'neutral'.") @UserMessage("Analyze the sentiment of this review: {reviewText}. Return only one word indicating its polarity ('positive', 'negative', or 'neutral').") String analyzeSentiment(String reviewText); } ``` 此代码片段展示了一个典型的情感分类器实现方式——它接收评论内容作为输入,并输出对应的情绪标签(正面、负面或中立)。 --- #### 3. 数字提取服务 对于某些场景下需要从非结构化的数据源中抽取数值信息的任务来说,也可以借助类似的机制完成自动化处理过程[^3]。 ```java public interface NumberExtractor { @SystemMessage("Extract all numbers mentioned in the given passage below:") @UserMessage("{inputText}") List<Double> extractNumbers(String inputText); } ``` 这里我们创建了一个名为 `extractNumbers` 的新 API 来查找并收集任何存在于传入字符串中的浮点数形式的数据项。 --- #### 4. 基于 POJO 的对象映射 当涉及到更加复杂的实体关系时,则可能需要用到 Java 中所谓的 Plain Old Java Object (POJO),即普通的旧式 Java 对象来进行表示。下面的例子说明了如何结合注释技术自动填充这些实例属性值的过程[^4]: 假设有一个描述图书基本信息的类 BookInfo 如下所示: ```java @Data // Lombok annotation for generating getters/setters etc. @AllArgsConstructor @NoArgsConstructor public class BookInfo { private String title; private Author author; public static class Author { private String name; private LocalDate birthDate; } } // Corresponding service definition using annotations: public interface POJOExtractor { @SystemMessage(""" Extract book information including Title & Author details \ from provided description then map them onto corresponding fields within returned object instance. """) @UserMessage("{description}") BookInfo parseBookDescriptionToPojo(String description); } ``` 在这个例子当中,我们的目的是教会人工智能怎样去识别一本书的相关元数据并将它们适配到预先设定好的内存布局之中。 --- ### 总结 以上就是有关 LangChain 结构化输出的主要应用案例介绍。无论是基础的语言转换还是深入的知识图谱构建,这套框架都能够很好地满足实际项目需求的同时保持较高的灵活性和技术前瞻性。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值