大家好!在处理文本数据时,给文本打上标准化标签是关键一步。今天咱们就来聊聊如何用 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"]
)
关键作用:
- 字段约束:
enum
参数限定了模型输出的取值范围(比如情感只能是 “happy”“neutral”“sad”),避免生成无效值 - 语义明确:
description
让模型清楚每个字段的含义,比如 “aggressiveness” 是 “攻击性评分” 而非其他指标 - 结构化保证:模型必须返回这三个字段,缺一不可,确保输出格式统一
二、构建提示模板:告诉模型 “怎么提取标签”
有了标签模板,还需要告诉模型 “去哪里提取”。通过ChatPromptTemplate
定义提示,明确告诉模型:
- 要提取哪些标签(对应 Pydantic 模型的字段)
- 输入文本是什么(通过
{input}
变量传入) - 输出格式要求(必须返回 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)
核心优势:
- 自动校验:模型生成结果后,LangChain 会自动校验是否符合 Pydantic 模型定义(比如
aggressiveness
是否为整数,是否在枚举范围内) - 类型转换:即使模型返回非标准格式(比如语言写成 “中文”),也会尝试转换为定义的枚举值(需确保枚举包含对应值)
- 错误处理:若模型输出不符合结构,会抛出明确错误,方便调试(比如缺少
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” 在枚举中),需要:
- 检查 Pydantic 模型的
enum
是否包含该值(如添加"chinese"
到语言枚举) - 调整提示表述(如将 “如中文、英文” 改为 “如 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 模型定义 + 提示模板引导 + 结构化输出绑定”,我们实现了:
- 输出可控:模型必须返回指定字段和取值范围,避免无效输出
- 流程标准化:无论是情感分析、语言识别还是风格分类,都可以通过修改 Pydantic 模型和提示模板快速适配
- 工程友好:结构化的 JSON 输出可以直接接入数据库、数据分析工具或下游 AI 系统,无需额外解析
这正是 LangChain 结构化输出的核心价值 —— 让非结构化的文本处理变得可预测、可控制,特别适合需要标准化输出的场景(如数据标注、内容审核、智能客服等)。
写在最后
文本分类的核心难点在于 “让模型理解我们想要什么”,而结构化输出就是解决这个问题的关键。通过定义清晰的标签体系和严格的格式要求,我们既能发挥大模型的语义理解能力,又能避免其 “自由发挥”。如果你在实操中遇到枚举值不匹配、模型拒答等问题,欢迎在评论区留言,我们可以一起调整提示模板和模型参数。
觉得这篇文章对你有帮助的话,记得点击左上角关注我的 CSDN 账号~后续会继续分享 LangChain 实战系列,包括多模型对比、长文本分类优化等进阶内容。收藏这篇文章,下次实操时就能快速找到啦!技术路上没有捷径,但清晰的思路和规范的流程能让我们少走弯路,一起加油吧~