文章目录
在传统的自然语言处理(NLP)中,文本分类通常需要训练专门的模型(如BERT)并进行繁琐的数据标注。而在大模型时代,利用 LangChain 结合 LLM(大语言模型),我们可以通过几行代码实现一个具备多维度分析能力的通用分类器。
本文将深入探讨如何使用 LangChain 的 with_structured_output 功能,构建一个能同时识别情感、攻击性和语言类型的智能标注系统。
一、核心概念与架构设计
在开始写代码之前,我们需要理解基于 LLM 的文本分类与传统方法的区别。LLM 分类本质上是一个 “理解 + 格式化” 的过程。
1.1 任务维度分析
我们的目标是输入一段文本,让 AI 输出三个维度的标签。这可以通过以下思维导图概括:
1.2 处理流程
LangChain 通过 Chain(链) 的概念将提示词(Prompt)与模型(Model)串联。为了保证输出的稳定性,我们引入 Pydantic 进行数据验证。
二、实战代码:构建分类器
下面是完整的实现代码。我们将使用 OpenAI 的 gpt-4o-mini 模型,因为它在保持低成本的同时,具备优秀的指令遵循能力。
2.1 环境准备
确保已安装核心依赖:
pip install langchain langchain-openai pydantic
2.2 代码实现
from langchain_core.prompts import ChatPromptTemplate
from langchain_openai import ChatOpenAI
from pydantic import BaseModel, Field
import os
# ----------------------------
# 1. 定义结构化数据模型 (Schema)
# ----------------------------
class Classification(BaseModel):
"""
定义输出的数据结构。
Pydantic 不仅用于验证,其文档字符串(docstring)也会作为提示词的一部分传给 LLM。
"""
sentiment: str = Field(
description="The sentiment of the text",
enum=["happy", "neutral", "sad"]
)
aggressiveness: int = Field(
description="describes how aggressive the statement is, the higher the number the more aggressive",
enum=[1, 2, 3, 4, 5]
)
language: str = Field(
description="The language the text is written in",
enum=["spanish", "english", "french", "german", "italian"]
)
# ----------------------------
# 2. 定义提示词模板 (Prompt)
# ----------------------------
# 我们使用 Few-shot 思想和明确的约束指令来构建 Prompt
tagging_prompt = ChatPromptTemplate.from_template(
"""
YOUR TASK: Analyze the passage and return ONLY a JSON object with these EXACT fields:
- sentiment: MUST be one of ["happy", "neutral", "sad"] (no other values)
- aggressiveness: MUST be an integer from 1-5
- language: MUST be one of ["spanish", "english", "french", "german", "italian"]
Passage:
{input}
JSON FORMAT REQUIREMENTS:
- NO extra fields or keys
- NO comments or explanations
- NO markdown or formatting
- ONLY valid JSON object
EXAMPLE OUTPUT:
{{"sentiment": "happy", "aggressiveness": 1, "language": "spanish"}}
"""
)
# ----------------------------
# 3. 初始化 LLM 并绑定结构化输出
# ----------------------------
llm = ChatOpenAI(
model_name="gpt-4o-mini",
temperature=0.7, # 稍微增加一点随机性以处理语义,但不要太高
max_tokens=2000,
api_key=os.environ["OPENAI_API_KEY_4O_MINI"],
base_url="https://oneapi.xty.app/v1/"
).with_structured_output(
Classification # 关键步骤:绑定 Pydantic 模型
)
# ----------------------------
# 4. 构建与执行链 (Chain)
# ----------------------------
tagging_chain = tagging_prompt | llm
# 测试输入(西班牙语:很高兴认识你!我觉得我们会成为好朋友!)
inp = "Estoy increiblemente contento de haberte conocido! Creo que seremos muy buenos amigos!"
# 调用
res = tagging_chain.invoke({"input": inp})
print(f"原始输入: {inp}")
print("-" * 30)
print(f"分类结果: {res}")
print(f"情感倾向: {res.sentiment}")
print(f"对象类型: {type(res)}")
2.3 执行结果
运行上述代码,控制台将输出:
原始输入: Estoy increiblemente contento de haberte conocido! Creo que seremos muy buenos amigos!
------------------------------
分类结果: sentiment='happy' aggressiveness=1 language='spanish'
情感倾向: happy
对象类型: <class '__main__.Classification'>
可以看到,LLM 不仅正确识别了西班牙语(Spanish)和开心的情绪(Happy),还给出了攻击性评级为 1(最低)。最重要的是,返回的 res 是一个标准的 Python 对象,可以直接通过属性访问。
三、底层原理深度解析
为什么 tagging_prompt | llm 这样简单的组合就能实现复杂的分类?这里涉及 LangChain 对 LLM 能力的封装。
3.1 提示词工程 (Prompt Engineering)
在代码中,tagging_prompt 充当了“指令官”的角色。它利用了以下技巧:
- Role Prompting(角色设定):明确任务是
YOUR TASK: Analyze...。 - Constraints(约束条件):使用
MUST be...和NO extra fields强制模型遵守规则。 - One-shot Learning(单样本学习):提供了一个
EXAMPLE OUTPUT,让模型模仿输出格式。
3.2 结构化输出机制 (Structured Output)
这是本教程的核心。llm.with_structured_output(Classification) 并非简单的后处理,其底层交互时序如下:
关键点解析:
- Schema 转换:LangChain 会自动读取
Classification类的 Pydantic 定义(包括description和enum),将其转换为 OpenAI API 支持的 Function Calling (Tools) 格式。 - 强制性:对于支持 Tool Calling 的模型(如 GPT-3.5/4),这种方式比单纯用 Prompt 让模型生成 JSON 更稳定,因为模型经过了专门的微调来输出这种结构。
- 自动验证:如果 LLM 返回的 JSON 缺少字段或类型错误(例如
aggressiveness返回了 6),Pydantic 会在 LangChain 内部抛出验证错误,甚至可以配置自动重试机制。
四、进阶应用场景
掌握了这种文本分类方法,你可以轻松扩展到更多业务场景:
| 场景 | 输入示例 | 输出 Schema 设计 |
|---|---|---|
| 客服工单路由 | “我的卡被吞了” | department: [“技术部”, “财务部”, “客服部”]urgency: [1-5] |
| 垃圾评论过滤 | “加微信号 xxxx 领奖” | is_spam: booleanreason: [“广告”, “色情”, “正常”] |
| 用户意图识别 | “帮我定明天去北京的票” | intent: [“booking”, “query”, “cancel”]entities: {“destination”: “北京”, “time”: “明天”} |
通过 LangChain 实现文本分类,我们将复杂的 NLP 任务简化为了两个步骤:定义数据结构 和 编写提示词。
- Pydantic 负责“立规矩”,确保输出是计算机可读的。
- Prompt 负责“教做事”,引导模型理解语义。
- LangChain 负责“跑腿”,处理 API 通信和数据转换。
这种模式极大地降低了 AI 应用落地的门槛,让开发者能专注于业务逻辑的设计。
:文本分类——利用结构化输出构建智能标注系统&spm=1001.2101.3001.5002&articleId=156944204&d=1&t=3&u=0c14439dbe4046e48648c5cf5c467448)
2万+

被折叠的 条评论
为什么被折叠?



