用 LangChain 实现文本结构化分类:从自定义标签到模型输出的全流程实践

大家好!在处理文本数据时,给文本打上标准化标签是关键一步。今天咱们就来聊聊如何用 LangChain 结合 DeepSeek 模型,实现文本的结构化分类 —— 也就是让模型按照我们定义的标签体系返回指定格式的结果。这个过程就像给模型一个 “填表模板”,让它乖乖按规则输出,特别适合处理情感分析、语言识别等场景。

一、定义标签体系:用 Pydantic 模型规范输出结构

首先,我们需要明确 “要提取什么标签”。借助 Pydantic 模型,我们可以定义每个标签的数据类型描述甚至允许的取值范围,就像给模型制定一套 “填表规则”:

python

from pydantic import BaseModel, Field

class Classification(BaseModel):
    sentiment: str = Field(
        description="文本的情感倾向",
        enum=["happy", "neutral", "sad"]  # 限定情感只能是这三种
    )
    aggressiveness: int = Field(
        description="1-10范围内的攻击性评分,数字越高攻击性越强",
        enum=[1, 2, 3, 4, 5]  # 这里示例限定为1-5,实际可根据需求扩展
    )
    language: str = Field(
        description="文本使用的语言",
        enum=["spanish", "english", "french", "german", "italian"]
    )

关键作用:

  1. 字段约束enum参数限定了模型输出的取值范围(比如情感只能是 “happy”“neutral”“sad”),避免生成无效值
  2. 语义明确description让模型清楚每个字段的含义,比如 “aggressiveness” 是 “攻击性评分” 而非其他指标
  3. 结构化保证:模型必须返回这三个字段,缺一不可,确保输出格式统一

二、构建提示模板:告诉模型 “怎么提取标签”

有了标签模板,还需要告诉模型 “去哪里提取”。通过ChatPromptTemplate定义提示,明确告诉模型:

  1. 要提取哪些标签(对应 Pydantic 模型的字段)
  2. 输入文本是什么(通过{input}变量传入)
  3. 输出格式要求(必须返回 JSON,且包含所有字段)

python

from langchain_core.prompts import ChatPromptTemplate

tagging_prompt = ChatPromptTemplate.from_template(
    """
    从以下段落中提取情感分析相关属性:
    - 情感倾向(sentiment):文本表达的情感是积极、消极还是中性?
    - 攻击性评分(aggressiveness):在1到10的范围内,1表示完全无攻击性,10表示极强攻击性。
    - 使用语言(language):文本使用的语言(如中文、英文)。
    
    段落:{input}
    请严格按照JSON格式返回,确保包含所有字段,即使某些字段需要根据语义推测。
    """
)

提示设计技巧:

  • 分点说明:每个标签单独列出来,模型更容易理解对应关系(比如 “情感倾向” 对应sentiment字段)
  • 格式强制:明确要求 “严格按照 JSON 格式返回”,避免模型输出自由文本
  • 容错引导:“即使需要推测” 告诉模型不要因为原文没有显式关键词就拒绝回答

三、加载模型与结构化输出:让模型按规则 “填表”

接下来接入 DeepSeek 模型,并通过with_structured_output方法将 Pydantic 模型与模型输出绑定 —— 相当于给模型戴上 “格式枷锁”,让它只能按我们定义的结构返回结果:

python

from langchain_deepseek import ChatDeepSeek

llm = ChatDeepSeek(
    model="deepseek-chat",
    temperature=0,  # 固定为0,确保输出确定性
    max_tokens=None,
    api_key="你的API密钥"
)

# 关键一步:将Pydantic模型与模型输出绑定
structured_llm = llm.with_structured_output(Classification)

核心优势:

  1. 自动校验:模型生成结果后,LangChain 会自动校验是否符合 Pydantic 模型定义(比如aggressiveness是否为整数,是否在枚举范围内)
  2. 类型转换:即使模型返回非标准格式(比如语言写成 “中文”),也会尝试转换为定义的枚举值(需确保枚举包含对应值)
  3. 错误处理:若模型输出不符合结构,会抛出明确错误,方便调试(比如缺少language字段时会报错)

四、实战演示:用示例文本触发模型输出

以一段积极的中文文本为例,看看模型如何按规则返回结构化结果:

python

inp = "我非常高兴认识你!我觉得我们会成为非常好的朋友!"
prompt = tagging_prompt.invoke({"input": inp})  # 生成带输入的提示
response = structured_llm.invoke(prompt)  # 调用结构化输出模型

# 打印原始响应(包含元数据和结构化内容)
print(response.model_dump())

输出结果解析(简化版):

json

{
  "sentiment": "happy",       # 情感倾向匹配“高兴”的语义
  "aggressiveness": 1,        # 无攻击性,取最低评分
  "language": "chinese"       # 自动识别为中文(需确保枚举包含对应值,此处示例枚举需扩展)
}

注意:

如果发现模型返回值不在枚举范围内(比如language返回 “chinese” 而非 “chinese” 在枚举中),需要:

  1. 检查 Pydantic 模型的enum是否包含该值(如添加"chinese"到语言枚举)
  2. 调整提示表述(如将 “如中文、英文” 改为 “如 chinese、english”,与枚举值一致)

五、进阶:细化标签规则与错误处理

1. 限定更严格的取值范围

比如将aggressiveness的枚举改为 1-10,让评分更精细:

python

aggressiveness: int = Field(..., enum=list(range(1, 11)))  # 1-10的整数

2. 处理模型拒答

如果模型因信息不足拒绝回答(返回refusal字段),可以添加默认值或重试逻辑:

python

try:
    response = structured_llm.invoke(prompt)
except Exception as e:
    # 处理错误,比如返回默认标签
    default_output = Classification(sentiment="neutral", aggressiveness=5, language="unknown")

3. 结合元数据优化

利用模型返回的token_usage(token 消耗)监控成本,或通过finish_reason判断是否输出截断(stop表示正常结束,length表示因长度限制截断)

六、总结:为什么要这么做?

通过 “Pydantic 模型定义 + 提示模板引导 + 结构化输出绑定”,我们实现了:

  1. 输出可控:模型必须返回指定字段和取值范围,避免无效输出
  2. 流程标准化:无论是情感分析、语言识别还是风格分类,都可以通过修改 Pydantic 模型和提示模板快速适配
  3. 工程友好:结构化的 JSON 输出可以直接接入数据库、数据分析工具或下游 AI 系统,无需额外解析

这正是 LangChain 结构化输出的核心价值 —— 让非结构化的文本处理变得可预测、可控制,特别适合需要标准化输出的场景(如数据标注、内容审核、智能客服等)。

写在最后

文本分类的核心难点在于 “让模型理解我们想要什么”,而结构化输出就是解决这个问题的关键。通过定义清晰的标签体系和严格的格式要求,我们既能发挥大模型的语义理解能力,又能避免其 “自由发挥”。如果你在实操中遇到枚举值不匹配、模型拒答等问题,欢迎在评论区留言,我们可以一起调整提示模板和模型参数。

觉得这篇文章对你有帮助的话,记得点击左上角关注我的 CSDN 账号~后续会继续分享 LangChain 实战系列,包括多模型对比、长文本分类优化等进阶内容。收藏这篇文章,下次实操时就能快速找到啦!技术路上没有捷径,但清晰的思路和规范的流程能让我们少走弯路,一起加油吧~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

佑瞻

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值