LangChain 实现文本分类任务

LangChain 实现文本分类任务

任务背景

  • 利用 LangChain 的结构化输出能力,将 LLM(此处为 DashScope 兼容的 Qwen 系列模型)封装为可控的"信息抽取器"。
  • 针对输入文本自动输出结构化情感标签、攻击性评分与语言类别,便于后续分析或自动化处理。

任务目标

  1. 连接 Qwen 模型,确保能以结构化格式返回结果。
  2. 基于 Pydantic 定义分类 Schema,限制返回字段的类型和取值。
  3. 构建 Prompt → LLM → 结构化输出的 LangChain Chain。
  4. 演示两个不同 Schema(自由输出与枚举约束)的分类流程。

关键依赖库

  • langchain_core:提供 ChatPromptTemplate,用于构建提示模板。
  • langchain_openai:封装 DashScope 兼容接口,负责与 Qwen 模型通信。
  • pydantic.v1:通过 BaseModelField 描述结构化 Schema,驱动模型输出校验。

解决问题的核心逻辑

1. 初始化 LLM

通过 ChatOpenAI 连接 DashScope 提供的 Qwen 模型,配置 modelapi_keybase_url

python 复制代码
model = ChatOpenAI(
    model='qwen-turbo',
    api_key=qwen_api_key,
    base_url='https://dashscope.aliyuncs.com/compatible-mode/v1'
)

2. 定义结构化输出 Schema

使用 Pydantic BaseModel 声明分类任务需要的字段,并通过 Field 提供描述或枚举约束。LangChain 会返回符合 Schema 的对象。

python 复制代码
class Classification(BaseModel):
	"""
         定义一个Pydantic的数据模型,未来需要根据该类型,完成文本的分类
    """
	# 文本的情感倾向,预期为字符串类型
	sentiment: str = Field(description="文本的情感")
	# 文本的攻击性,预期为1到10的整数
	aggressiveness: int = Field(
		description="描述文本的攻击性,数字越大表示越攻击性"
	)
	# 文本使用的语言,预期为字符串类型
	language: str = Field(description="文本使用的语言")
python 复制代码
class Classification1(BaseModel):
    """
        定义一个Pydantic的数据模型,未来需要根据该类型,完成文本的分类
    """
    # 文本的情感倾向,预期为字符串类型
    # ...没有默认值
    # 枚举限制:这个字段的值只能是列表里的字符
	# description告诉模型这个属性是干什么的
    sentiment: str = Field(..., enum=["happy", "neutral", "sad"], description="文本的情感")

    # 文本的攻击性,预期为1到5的整数
    aggressiveness: int = Field(..., enum=[1, 2, 3, 4, 5], description="描述文本的攻击性,数字越大表示越攻击性")

    # 文本使用的语言,预期为字符串类型
    language: str = Field(..., enum=["spanish", "english", "french", "中文", "italian"], description="文本使用的语言")
 

3. 构建 Prompt 与 Chain

ChatPromptTemplate 负责把输入文本嵌入提示词;model.with_structured_output 让 LLM 根据 Schema 自动解析输出;最后通过 | 组合成 Chain。

python 复制代码
tagging_prompt = ChatPromptTemplate.from_template(
    """
    从以下段落中提取所需信息。
    只提取'Classification'类中提到的属性。
    段落:
    {input}
    """
)

chain = tagging_prompt | model.with_structured_output(Classification)
chain1 = tagging_prompt1 | model.with_structured_output(Classification1)

4. 调用 Chain 并解释结果

准备输入文本,执行 chain.invoke({'input': input_text}),即可获得 Pydantic 对象,并直接访问字段或打印。

python 复制代码
input_text = "中国人民大学的王教授:我靠,真的是师德败坏..."
result: Classification = chain.invoke({'input': input_text})
result1: Classification = chain.invoke({'input': input_text})
print(result)
# sentiment='愤怒' aggressiveness=8 language='中文'
print(result1)
# sentiment='sad' aggressiveness=5 language='中文'

文本流程图

输入文本


ChatPromptTemplate 注入上下文


ChatOpenAI (Qwen) 生成结构化响应


with_structured_output 校验并转换为 Pydantic 模型

打印或消费分类结果

总结

  • 通过 LangChain 的结构化输出能力,可以让大模型直接返回经过 Schema 校验的数据对象。
  • Pydantic Schema 提供了类型与取值的硬约束,使模型输出更可控。
  • 该示例展示了自由 Schema 与严格枚举 Schema 的对比,为情感分析、内容审核等场景提供了模版。

完整代码

python 复制代码
import os

from langchain_core.prompts import ChatPromptTemplate
from langchain_experimental.tabular_synthetic_data.prompts import SYNTHETIC_FEW_SHOT_PREFIX, SYNTHETIC_FEW_SHOT_SUFFIX
from langchain_openai import ChatOpenAI
from pydantic.v1 import BaseModel, Field

# Qwen(通义千问)API Key
qwen_api_key = 'sk-TripleH'  # 请替换为您的 DashScope API Key

# 创建 Qwen LLM 模型
# 可选模型:qwen-turbo, qwen-plus, qwen-max, qwen-max-longcontext
model = ChatOpenAI(
    model='qwen-turbo',  # 可以根据需要改为 qwen-plus 或 qwen-max
    api_key=qwen_api_key,
    base_url='https://dashscope.aliyuncs.com/compatible-mode/v1'
)

class Classification(BaseModel):
	"""
         定义一个Pydantic的数据模型,未来需要根据该类型,完成文本的分类
    """
	# 文本的情感倾向,预期为字符串类型
	sentiment: str = Field(description="文本的情感")
	# 文本的攻击性,预期为1到10的整数
	aggressiveness: int = Field(
		description="描述文本的攻击性,数字越大表示越攻击性"
	)
	# 文本使用的语言,预期为字符串类型
	language: str = Field(description="文本使用的语言")

# 创建一个用于提取信息的提示模板
tagging_prompt = ChatPromptTemplate.from_template(
    """
    从以下段落中提取所需信息。
    只提取'Classification'类中提到的属性。
    段落:
    {input}
    """
)


chain = tagging_prompt | model.with_structured_output(Classification)

input_text = "中国人民大学的王教授:我靠,真的是师德败坏,做出的事情实在让我生气!"
# input_text = "Estoy increiblemente contento de haberte conocido! Creo que seremos muy buenos amigos!"

result: Classification = chain.invoke({'input' : input_text})

print(result)
# sentiment='愤怒' aggressiveness=8 language='中文'



class Classification1(BaseModel):
    """
        定义一个Pydantic的数据模型,未来需要根据该类型,完成文本的分类
    """
    # 文本的情感倾向,预期为字符串类型
    # ...没有默认值
    # 枚举限制:这个字段的值只能是列表里的字符
	# description告诉模型这个属性是干什么的
    sentiment: str = Field(..., enum=["happy", "neutral", "sad"], description="文本的情感")

    # 文本的攻击性,预期为1到5的整数
    aggressiveness: int = Field(..., enum=[1, 2, 3, 4, 5], description="描述文本的攻击性,数字越大表示越攻击性")

    # 文本使用的语言,预期为字符串类型
    language: str = Field(..., enum=["spanish", "english", "french", "中文", "italian"], description="文本使用的语言")
    
# 创建一个用于提取信息的提示模板
tagging_prompt1 = ChatPromptTemplate.from_template(
    """
    从以下段落中提取所需信息。
    只提取'Classification'类中提到的属性。
    段落:
    {input}
    """
)

chain = tagging_prompt1 | model.with_structured_output(Classification1)

input_text1 = "中国人民大学的王教授:我靠,真的是师德败坏,做出的事情实在让我生气!"
# input_text1 = "Estoy increiblemente contento de haberte conocido! Creo que seremos muy buenos amigos!"

result1: Classification1 = chain.invoke({'input' : input_text1})

print(result1)
# sentiment='sad' aggressiveness=5 language='中文'
相关推荐
FreeCode17 小时前
使用LangSmith评估智能体
python·langchain·agent
FreeCode18 小时前
使用LangSmith追踪智能体运行
python·langchain·agent
汗流浃背了吧,老弟!19 小时前
LangChain提取和输出结构化数据
langchain
王国强20091 天前
LangGraph 如何通过 Checkpoint 实现持久化
langchain
权泽谦1 天前
脑肿瘤分割与分类的人工智能研究报告
人工智能·分类·数据挖掘
余俊晖1 天前
文档图像旋转对VLM OCR的影响及基于Phi-3.5-Vision+分类头的文档方向分类器、及数据构建思路
人工智能·分类·ocr
王国强20091 天前
剖析 LangGraph 的 Super-step 概念
langchain
xuehaikj1 天前
【甲状腺病理AI】基于YOLO11-SOEP的甲状腺乳头状癌病理特征识别与分类系统研究
人工智能·分类·数据挖掘
前端小东1 天前
Langchain Template 全面指南
langchain·openai