别再说“AI听不懂人话”:从0到1手把手搭一个意图识别 + 槽位提取系统

举报
Echo_Wish 发表于 2026/03/23 20:49:12 2026/03/23
【摘要】 别再说“AI听不懂人话”:从0到1手把手搭一个意图识别 + 槽位提取系统

别再说“AI听不懂人话”:从0到1手把手搭一个意图识别 + 槽位提取系统

说句实话,我见过太多所谓“智能对话系统”,本质就是:

关键词匹配 + if-else 地狱

用户说一句:“帮我订明天去上海的机票”

系统回一句:“你是要查天气吗?”

——这不叫AI,这叫“人工智障”。

今天我们就来聊一个对话系统里最核心、也是最容易被低估的能力:

👉 意图识别(Intent Recognition) + 槽位提取(Slot Filling)

说白了就是:

  • 你想干嘛?(意图)
  • 你说了哪些关键信息?(槽位)

如果这两件事没做好,后面什么大模型、推荐系统,全是空中楼阁。


一、先把问题讲明白:什么是意图 + 槽位?

举个最简单的例子:

“帮我订一张明天从北京到上海的机票”

我们要解析成:

{
  "intent": "book_flight",
  "slots": {
    "date": "明天",
    "from_city": "北京",
    "to_city": "上海"
  }
}

你看,本质上就是一个“结构化理解”。


二、为什么这件事很难?

很多人一开始觉得:

👉 不就分类 + NER 吗?

但真正做起来你会发现:

1️⃣ 表达太多样

  • 明天去上海
  • 我要飞上海
  • 帮我订张去魔都的票

👉 全是一个意图


2️⃣ 槽位不完整

  • “帮我订票” → 缺日期
  • “明天去上海” → 缺出发地

👉 系统必须能“追问”


3️⃣ 噪声极多

  • “我想大概后天 maybe 去上海吧?”

👉 NLP 的现实就是 messy


三、先来一个最朴素版本(能跑最重要)

我们先不用大模型,直接用传统方法搞一版。


Step 1:意图识别(文本分类)

from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.linear_model import LogisticRegression

texts = [
    "帮我订机票",
    "我要买机票",
    "查一下天气",
    "今天上海天气怎么样"
]

labels = [
    "book_flight",
    "book_flight",
    "check_weather",
    "check_weather"
]

vectorizer = TfidfVectorizer()
X = vectorizer.fit_transform(texts)

model = LogisticRegression()
model.fit(X, labels)

def predict_intent(text):
    x = vectorizer.transform([text])
    return model.predict(x)[0]

print(predict_intent("帮我订一张票"))

👉 这一步解决:

  • 用户“想干嘛”

Step 2:槽位提取(规则版)

import re

def extract_slots(text):
    slots = {}

    # 简单城市识别
    if "北京" in text:
        slots["from_city"] = "北京"
    if "上海" in text:
        slots["to_city"] = "上海"

    # 日期识别
    if "明天" in text:
        slots["date"] = "明天"

    return slots

print(extract_slots("帮我订明天从北京到上海的机票"))

👉 很土,但有效


四、升级一下:用深度学习做联合建模

真正工业级的做法是:

Intent + Slot 一起建模(Joint Model)

为什么?

👉 因为它们是强相关的。


一个简单的 BiLSTM + CRF 示例

import torch
import torch.nn as nn

class JointModel(nn.Module):
    def __init__(self, vocab_size, hidden_dim, num_intents, num_slots):
        super().__init__()
        self.embedding = nn.Embedding(vocab_size, 128)
        self.lstm = nn.LSTM(128, hidden_dim, bidirectional=True, batch_first=True)
        
        self.intent_fc = nn.Linear(hidden_dim * 2, num_intents)
        self.slot_fc = nn.Linear(hidden_dim * 2, num_slots)

    def forward(self, x):
        emb = self.embedding(x)
        output, _ = self.lstm(emb)

        # intent 用最后一个 hidden
        intent_logits = self.intent_fc(output[:, -1, :])

        # slot 用每个 token
        slot_logits = self.slot_fc(output)

        return intent_logits, slot_logits

👉 核心思想:

  • 一次输入
  • 两个输出(intent + slot)

五、再往上走一步:用预训练模型(推荐)

现在还手写 LSTM 的人,说实话已经不多了。

直接上 BERT:

from transformers import BertTokenizer, BertModel
import torch.nn as nn

class BertNLU(nn.Module):
    def __init__(self, num_intents, num_slots):
        super().__init__()
        self.bert = BertModel.from_pretrained("bert-base-chinese")
        
        self.intent_fc = nn.Linear(768, num_intents)
        self.slot_fc = nn.Linear(768, num_slots)

    def forward(self, input_ids, attention_mask):
        outputs = self.bert(input_ids=input_ids, attention_mask=attention_mask)
        
        sequence_output = outputs.last_hidden_state
        pooled_output = outputs.pooler_output

        intent_logits = self.intent_fc(pooled_output)
        slot_logits = self.slot_fc(sequence_output)

        return intent_logits, slot_logits

👉 优点:

  • 少量数据也能起飞
  • 表达能力强
  • 更鲁棒

六、对话系统真正难的,其实不是模型

我讲点“踩坑经验”,这部分很多文章不会说。


1️⃣ 槽位标准化(巨坑)

用户说:

  • “魔都” → 上海
  • “帝都” → 北京

你要统一:

city_map = {
    "魔都": "上海",
    "帝都": "北京"
}

👉 否则系统逻辑全乱


2️⃣ 多轮对话状态管理(核心)

dialog_state = {
    "intent": "book_flight",
    "slots": {
        "from_city": "北京"
    }
}

用户下一句:

“明天的”

👉 你必须补齐:

dialog_state["slots"]["date"] = "明天"

3️⃣ 缺失槽位要追问

required_slots = ["from_city", "to_city", "date"]

def check_missing(slots):
    return [s for s in required_slots if s not in slots]

👉 这才像“会聊天”


七、一个完整流程(工程视角)

我帮你总结一个落地架构:

用户输入
   ↓
意图识别
   ↓
槽位提取
   ↓
状态管理(多轮)
   ↓
缺失补齐(追问)
   ↓
业务执行

八、说点真心话:大模型时代,这一套还重要吗?

很多人现在会问:

有大模型了,还需要意图识别吗?

我的答案是:

👉 更需要了。

原因很现实:

  • 大模型不稳定
  • 成本高
  • 可控性差

而:

意图 + 槽位 = 可控的“确定性系统”

最佳实践是:

👉 小模型做结构化理解 + 大模型做补充理解


九、我的一点感受

我做对话系统这么多年,有一个越来越深的体会:

对话系统不是“让机器更聪明”,而是“让系统更可控”。

很多团队一味追求 fancy:

  • 用最牛的模型
  • 做最复杂的 pipeline

结果:

👉 一上线就崩

反而是那些:

  • 意图清晰
  • 槽位干净
  • 流程简单

的系统,活得最长。


十、结尾:别做“听不懂人话”的系统

如果你现在的系统:

  • 靠关键词匹配
  • 经常理解错
  • 无法处理多轮对话

那你真的该重构一遍了。

因为:

对话系统的本质,不是“说话”,而是“理解”。

而“理解”的第一步,就是:

👉 意图识别 + 槽位提取

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。