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

简介: 别再说“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

结果:

👉 一上线就崩

反而是那些:

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

的系统,活得最长。


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

如果你现在的系统:

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

那你真的该重构一遍了。

因为:

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

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

👉 意图识别 + 槽位提取

目录
相关文章
|
2天前
|
人工智能 JSON 机器人
让龙虾成为你的“公众号分身” | 阿里云服务器玩Openclaw
本文带你零成本玩转OpenClaw:学生认证白嫖6个月阿里云服务器,手把手配置飞书机器人、接入免费/高性价比AI模型(NVIDIA/通义),并打造微信公众号“全自动分身”——实时抓热榜、AI选题拆解、一键发布草稿,5分钟完成热点→文章全流程!
10251 35
让龙虾成为你的“公众号分身” | 阿里云服务器玩Openclaw
|
14天前
|
人工智能 安全 Linux
【OpenClaw保姆级图文教程】阿里云/本地部署集成模型Ollama/Qwen3.5/百炼 API 步骤流程及避坑指南
2026年,AI代理工具的部署逻辑已从“单一云端依赖”转向“云端+本地双轨模式”。OpenClaw(曾用名Clawdbot)作为开源AI代理框架,既支持对接阿里云百炼等云端免费API,也能通过Ollama部署本地大模型,完美解决两类核心需求:一是担心云端API泄露核心数据的隐私安全诉求;二是频繁调用导致token消耗过高的成本控制需求。
5938 14
|
22天前
|
人工智能 JavaScript Ubuntu
5分钟上手龙虾AI!OpenClaw部署(阿里云+本地)+ 免费多模型配置保姆级教程(MiniMax、Claude、阿里云百炼)
OpenClaw(昵称“龙虾AI”)作为2026年热门的开源个人AI助手,由PSPDFKit创始人Peter Steinberger开发,核心优势在于“真正执行任务”——不仅能聊天互动,还能自动处理邮件、管理日程、订机票、写代码等,且所有数据本地处理,隐私完全可控。它支持接入MiniMax、Claude、GPT等多类大模型,兼容微信、Telegram、飞书等主流聊天工具,搭配100+可扩展技能,成为兼顾实用性与隐私性的AI工具首选。
23212 120
|
8天前
|
人工智能 JavaScript API
解放双手!OpenClaw Agent Browser全攻略(阿里云+本地部署+免费API+网页自动化场景落地)
“让AI聊聊天、写代码不难,难的是让它自己打开网页、填表单、查数据”——2026年,无数OpenClaw用户被这个痛点困扰。参考文章直击核心:当AI只能“纸上谈兵”,无法实际操控浏览器,就永远成不了真正的“数字员工”。而Agent Browser技能的出现,彻底打破了这一壁垒——它给OpenClaw装上“上网的手和眼睛”,让AI能像真人一样打开网页、点击按钮、填写表单、提取数据,24小时不间断完成网页自动化任务。
1956 4