首页
看点啥
插画图片
首页 热点时事 大模型应用:智能对话意图识别:基于关键词、语义向量与大模型的三重融合验证.120

大模型应用:智能对话意图识别:基于关键词、语义向量与大模型的三重融合验证.120

2026-05-21 0

 一、前言

       很早我们就在做智能体相关的研发,在搭建对话系统、智能客服、虚拟助手这些 AI 应用时,最头疼、也最容易出问题的环节,就是意图识别。一开始总以为,只要听懂用户说了什么就行,可真正落地才发现:用户真正 想做什么,远比字面意思复杂得多。同样一个需求,表达方式千奇百怪,同义词、口语化、模糊表达、多意图混杂,都会让识别频频跑偏。我们试过关键词、规则匹配、传统模型,也踩过无数坑,识别不准、响应僵硬、体验断层的问题一直存在。

大模型应用:智能对话意图识别:基于关键词、语义向量与大模型的三重融合验证.120

       经过不断迭代、组合、验证,慢慢沉淀出了一套稳定、实用、可落地的意图识别方案。这也是一段踩坑、优化、最终成熟的全过程,通过复盘做一次完整梳理和总结。让大家可以从根上理解:在大模型时代,意图识别到底该怎么做,才能真正让 AI 听懂用户、理解意图、精准响应。我们从初次接触的视角,由浅入深拆解意图识别技术体系:从最基础的关键词匹配,到基于语义向量的相似度计算,再到结合大模型的精准验证,最终落地一套工业级的多方法集成方案,供大家一起学习参考。

二、核心基础

1. 什么是意图识别

       意图识别是自然语言处理的核心任务之一,指通过算法分析用户的自然语言输入,判断其背后的核心诉求和目的。

举个简单例子:

       与“语义理解”不同,意图识别更聚焦于“用户想完成什么动作”,而非“句子的字面意思”。它是智能对话系统的大脑中枢,只有准确识别意图,后续的对话管理、响应生成才有意义。

2. 典型的应用场景

意图识别几乎是所有智能交互系统的必备模块:

3. 意图识别的难题

相信我们大家一样,都很容易误以为“意图识别就是关键词匹配”,但实际场景中存在诸多难点:

4. 意图识别的迭代过程

       早期我们也是接触医疗行业,做内容匹配都是基于关键词规则和正则表达式,但基于同义词表达和模糊表述对一个约束做了很多规则表达式,不仅冗余,准确性也没有大幅度提供,在后来经历过机器学习,到BERT模型,直至现在的大模型识别,也是经历了逐步优化迭代的过程,和早期的困难相比,现在随着各种向量模型和大模型的出现,是容易的多了;

阶段核心技术优点缺点
第一阶段关键词匹配 / 正则表达式简单易实现、速度快无法处理同义词、语义模糊场景
第二阶段传统机器学习(SVM / 朴素贝叶斯)可处理简单语义变化依赖人工特征工程、泛化能力弱
第三阶段预训练模型(BERT/TextCNN)语义理解能力强需标注数据、部署成本高
第四阶段大模型 + 向量记忆精准度高、适配复杂场景推理速度稍慢、需资源优化

三、基础原理

       我们通过“规则关键词 + 语义向量 + 小参数大模型”轻量化的集成方案,逐步由浅入深的探讨每个过程的原理,每个过程我们都基于现实应用的优缺点做出详细说明,兼顾精准度与实用性,保障可落地应用;

1. 基础方案:关键词规则匹配

1.1 核心原理

       关键词匹配是意图识别的最简单的基础方案,核心逻辑是:为每个意图定义专属关键词列表,通过统计用户输入中关键词的出现次数,判断最匹配的意图。

例如以下示例:

1.2 示例实现

def keyword_based_intent_recognition(text: str, intent_keywords: dict) -> tuple:
    """
    基于关键词的意图识别
    :param text: 用户输入文本
    :param intent_keywords: 意图-关键词映射字典
    :return: 识别出的意图、置信度
    """
    # 统一转为小写,避免大小写干扰
    text_lower = text.lower()
    max_score = 0
    best_intent = "未知"
    
    # 遍历所有意图的关键词
    for intent, keywords in intent_keywords.items():
score = 0
for keyword in keywords:
    if keyword.lower() in text_lower:
score += 1  # 每匹配一个关键词,得分+1

# 更新最优意图
if score > max_score and score > 0:
    max_score = score
    best_intent = intent
    
    # 计算置信度(归一化到0-1)
    confidence = min(max_score / 3.0, 1.0) if best_intent != "未知" else 0.0
    return best_intent, confidence
# 测试代码
if __name__ == "__main__":
    # 定义意图-关键词映射
    INTENT_KEYWORDS = {
"问候": ["你好", "嗨", "早上好", "下午好", "晚上好"],
"天气查询": ["天气", "气温", "温度", "下雨", "晴天"],
"计算": ["计算", "加", "减", "乘", "除", "等于"]
    }
    
    # 测试用例
    test_cases = [
"你好,今天天气怎么样?",
"帮我算一下5乘6等于多少",
"晚上好,外面冷不冷?"
    ]
    
    for case in test_cases:
intent, conf = keyword_based_intent_recognition(case, INTENT_KEYWORDS)
print(f"输入:{case} → 意图:{intent}(置信度:{conf:.2f})")

输出结果:

输入:你好,今天天气怎么样? → 意图:问候(置信度:0.33)

输入:帮我算一下5乘6等于多少 → 意图:计算(置信度:0.67)

输入:晚上好,外面冷不冷? → 意图:问候(置信度:0.33)

1.3 优缺点分析

2. 进阶方案:语义向量相似度匹配

2.1 核心原理

语义向量(Embedding)是将自然语言转化为数值向量的技术,核心逻辑是:

余弦相似度的计算公式:similarity(A,B)= (A⋅B)/(∣∣A∣∣×∣∣B∣∣),取值范围为 [-1,1],越接近 1 表示语义越相似。

2.2 示例实现

from sentence_transformers import SentenceTransformer
from modelscope import snapshot_download
import torch
import torch.nn.functional as F
cache_dir = "D:\modelscope\hub"
embedding_model_dir = snapshot_download(
    model_id="sentence-transformers/all-MiniLM-L6-v2",
    cache_dir=cache_dir,
    revision="master"
)
# 初始化语义模型(轻量级,仅80MB)
embedding_model = SentenceTransformer(embedding_model_dir)
def semantic_based_intent_recognition(text: str, intent_examples: dict, top_k: int = 3) -> tuple:
    """
    基于语义向量的意图识别
    :param text: 用户输入文本
    :param intent_examples: 意图-示例句子映射字典
    :param top_k: 返回Top-K相似度结果
    :return: 最佳意图、置信度、Top-K相似度字典
    """
    # 空输入直接返回未知
    if not text.strip():
return "未知", 0.0, {}
    
    # 1. 将用户输入转为向量
    text_embedding = embedding_model.encode([text], convert_to_tensor=True)
    
    # 2. 遍历所有意图,计算相似度
    intent_scores = {}
    for intent, examples in intent_examples.items():
# 将该意图的所有示例转为向量
example_embeddings = embedding_model.encode(examples, convert_to_tensor=True)
# 计算用户输入与每个示例的余弦相似度
similarities = F.cosine_similarity(text_embedding, example_embeddings, dim=1)
# 取最大相似度作为该意图的得分
intent_scores[intent] = similarities.max().item()
    
    # 3. 确定最佳意图
    best_intent = max(intent_scores.keys(), key=lambda x: intent_scores[x])
    best_score = intent_scores[best_intent]
    
    # 4. 整理Top-K结果
    sorted_scores = dict(sorted(intent_scores.items(), key=lambda x: x[1], reverse=True)[:top_k])
    
    return best_intent, best_score, sorted_scores
# 测试代码
if __name__ == "__main__":
    # 定义意图-示例句子映射
    INTENT_EXAMPLES = {
"问候": ["你好啊", "大家好", "嗨", "早上好", "今天天气不错"],
"天气查询": ["今天天气怎么样", "明天会下雨吗", "现在温度是多少", "外面要不要带伞"],
"计算": ["帮我算一下1加1", "3乘5等于多少", "100减50是多少"]
    }
    
    # 测试用例(包含同义不同词的场景)
    test_cases = [
"你好,今天外面冷不冷?",
"帮我算一下8除以2等于几",
"明天出门需要带伞吗?"
    ]
    
    for case in test_cases:
intent, conf, top_scores = semantic_based_intent_recognition(case, INTENT_EXAMPLES)
print(f"n输入:{case}")
print(f"最佳意图:{intent}(置信度:{conf:.3f})")
print(f"Top3相似度:{top_scores}")

细节说明:

输出结果:

输入:你好,今天外面冷不冷?

最佳意图:天气查询(置信度:0.885)

Top3相似度:{'天气查询': 0.8847869634628296, '问候': 0.8260104060173035, '计算': 0.43486738204956055}

输入:帮我算一下8除以2等于几

最佳意图:计算(置信度:0.794)

Top3相似度:{'计算': 0.7936053276062012, '问候': 0.5505934953689575, '天气查询': 0.5266945362091064}

输入:明天出门需要带伞吗?

最佳意图:天气查询(置信度:0.813)

Top3相似度:{'天气查询': 0.812972366809845, '问候': 0.699776291847229, '计算': 0.4986198842525482}

2.3 优缺点分析

3. 高级方案:大模型辅助意图验证

3.1 核心原理

       大模型具备强大的自然语言理解能力,可通过“提示词工程”让大模型直接分析用户输入的意图,我们此处基于Qwen1.5-1.8B-Chat模型来实践。其核心逻辑是:

3.2 示例实现

通过简化提示词结构,将用户输入直接置于意图列表前,输出逐步的调试内容,清楚大模型的执行过程。调试过程中发现模型输出存在多余内容,通过精确匹配意图词在生成序列中的起始位置,从正确位置提取token概率并使用几何平均计算,得到最终的置信度。

from transformers import AutoTokenizer, AutoModelForCausalLM
from modelscope import snapshot_download
import torch
cache_dir = "D:\modelscope\hub"
# 加载大模型(Qwen1.5-1.8B-Chat,本地部署)
model_name = "qwen/Qwen1.5-1.8B-Chat"
local_model_path = snapshot_download(model_name, cache_dir=cache_dir)
tokenizer = AutoTokenizer.from_pretrained(local_model_path, trust_remote_code=True)
model = AutoModelForCausalLM.from_pretrained(
    local_model_path,
    trust_remote_code=True,
    torch_dtype=torch.float16,
    device_map="auto"
)
model.eval()
def llm_based_intent_recognition(text: str, intent_list: list) -> tuple:
    """
    基于大模型的意图识别
    :param text: 用户输入文本
    :param intent_list: 可选意图列表
    :return: 识别出的意图、置信度
    """
    # 构造提示词(关键:明确指令,避免大模型输出多余内容)
    prompt = f"""用户输入:{text}
从以下意图中选择最匹配的一个:{', '.join(intent_list)}
答案:"""
    
    # 调用大模型
    inputs = tokenizer(prompt, return_tensors="pt", truncation=True, max_length=512).to(model.device)
    with torch.no_grad():
outputs = model.generate(
    **inputs,
    max_new_tokens=5,   # 减少输出长度,只需要意图名称
    temperature=0.0,    # 完全确定性生成
    do_sample=False,     # 关闭采样,保证结果可重复
    output_scores=True,   # 返回分数
    return_dict_in_generate=True,  # 返回字典格式
    pad_token_id=tokenizer.eos_token_id,
    repetition_penalty=1.1  # 减少重复
)
    
    # 解析结果
    response = tokenizer.decode(outputs.sequences[0][inputs["input_ids"].shape[1]:], skip_special_tokens=True).strip()
    
    # 调试:打印原始输出(包括所有token和概率)
    full_text = tokenizer.decode(outputs.sequences[0], skip_special_tokens=True)
    # print(f"  [调试] 完整文本(含输入): '{full_text}'")
    print(f"  [调试] 模型原始输出: '{response}'")
    # print(f"  [调试] 完整生成序列: {outputs.sequences[0].tolist()}")
    print(f"  [调试] 输入长度: {inputs['input_ids'].shape[1]}")
    print(f"  [调试] 生成token数: {len(outputs.sequences[0]) - inputs['input_ids'].shape[1]}")
    
    # 提取匹配的意图(处理换行符、前缀词等问题)
    matched_intent = None
    for intent in intent_list:
# 优先完全匹配或起始匹配
if response == intent or response.startswith(intent):
    matched_intent = intent
    break
# 其次包含匹配(去除多余前缀词)
elif intent in response or response in intent:
    matched_intent = intent
    break
    
    if matched_intent:
response = matched_intent
    
    # 验证结果是否在意图列表中
    if response in intent_list:
# 计算实际置信度:基于输出的log概率
with torch.no_grad():
    # 获取每个生成token的scores
    scores = outputs.scores  # tuple of tensors, each tensor is (batch_size, vocab_size)
    # 计算每个token的log概率
    log_probs = [torch.log_softmax(score, dim=-1) for score in scores]
    # 获取实际生成的token ids(不包括输入部分)
    generated_ids = outputs.sequences[0][inputs["input_ids"].shape[1]:]
    
    # 编码意图词为tokens
    intent_tokens = tokenizer.encode(response, add_special_tokens=False)
    
    # 找到意图词在生成序列中的起始位置
    intent_start_pos = -1
    for i in range(len(generated_ids) - len(intent_tokens) + 1):
# 检查从位置i开始的子序列是否匹配意图词
if generated_ids[i:i+len(intent_tokens)].tolist() == intent_tokens:
    intent_start_pos = i
    break
    
    print(f"  [调试] 生成的tokens长度 {len(outputs.sequences[0]) - inputs['input_ids'].shape[1]}: {generated_ids.tolist()}")
    print(f"  [调试] 意图词'{response}'的tokens: {intent_tokens}")
    print(f"  [调试] 意图词起始位置: {intent_start_pos}")
    
    # 提取意图词对应的token概率
    intent_token_probs = []
    
    if intent_start_pos >= 0:
for i, token_id in enumerate(intent_tokens):
    actual_pos = intent_start_pos + i
    if actual_pos < len(log_probs):
prob = torch.exp(log_probs[actual_pos][0, token_id])
intent_token_probs.append(prob)
print(f"  [调试] token {i} (位置{actual_pos}): id={token_id}, prob={prob:.4f}")
    else:
print(f"  [调试] token {i}: 超出log_probs范围")
    else:
print(f"  [调试] 未找到意图词在生成序列中的位置")
    
    # 使用几何平均计算置信度
    if intent_token_probs:
product = 1.0
for p in intent_token_probs:
    product *= p
avg_confidence = float(product ** (1.0 / len(intent_token_probs)))
    else:
avg_confidence = 0.0

return response, avg_confidence
    else:
return "未知", 0.0
# 测试代码
if __name__ == "__main__":
    INTENT_LIST = ["问候", "天气查询", "计算", "翻译", "告别"]
    
    test_cases = [
"你好,帮我查一下明天的天气",
"算一下10乘20等于多少",
"把“你好世界”翻译成英文"
    ]
    
    for case in test_cases:
intent, conf = llm_based_intent_recognition(case, INTENT_LIST)
print(f"输入:{case} → 意图:{intent}(置信度:{conf:.2f})")

提示词工程技巧:

输出结果:

 [调试] 模型原始输出: '天气查询'

 [调试] 输入长度: 44

 [调试] 生成token数: 5

 [调试] 生成的tokens长度 5: [104307, 51154, 271, 100345, 107494]

 [调试] 意图词'天气查询'的tokens: [104307, 51154]

 [调试] 意图词起始位置: 0

 [调试] token 0 (位置0): id=104307, prob=0.9740

 [调试] token 1 (位置1): id=51154, prob=0.9999

输入:你好,帮我查一下明天的天气 → 意图:天气查询(置信度:0.99)

 [调试] 模型原始输出: '计算'

 [调试] 输入长度: 45

 [调试] 生成token数: 5

 [调试] 生成的tokens长度 5: [100768, 271, 16, 15, 100252]

 [调试] 意图词'计算'的tokens: [100768]

 [调试] 意图词起始位置: 0

 [调试] token 0 (位置0): id=100768, prob=0.9961

输入:算一下10乘20等于多少 → 意图:计算(置信度:1.00)

 [调试] 模型原始输出: '翻译'

 [调试] 输入长度: 44

 [调试] 生成token数: 5

 [调试] 生成的tokens长度 5: [105395, 271, 31196, 36987, 99360]

 [调试] 意图词'翻译'的tokens: [105395]

 [调试] 意图词起始位置: 0

 [调试] token 0 (位置0): id=105395, prob=0.9904

输入:把“你好世界”翻译成英文 → 意图:翻译(置信度:0.99)

3.3 优缺点分析

四、集成方案

1. 核心逻辑

       单一方法的意图识别总有局限性,集成方案的核心是“多方法集成”,通过加权投票的方式,结合三种方法的优势:

加权投票公式:

最终得分 = 关键词得分 × 0.3 + 语义得分 × 0.5 + 大模型得分 × 0.2

2. 执行流程

       集成方案的执行流程融合了基于关键词的规则方法、语义向量的机器学习方法和大模型的深度学习方法,在准确率、灵活性和成本之间取得平衡。

流程说明:

4. 注意事项

5. 核心示例代码

5.1 后端(FastAPI)

将集成式意图识别封装为 API 接口,提供 HTTP 服务:

from fastapi import FastAPI, HTTPException
from fastapi.middleware.cors import CORSMiddleware
from pydantic import BaseModel
import uvicorn
app = FastAPI(title="意图识别系统")
# 跨域配置
app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)
# 数据模型
class IntentRequest(BaseModel):
    text: str
# API接口
@app.post("/api/classify-intent")
async def classify_intent(request: IntentRequest):
    try:
if not request.text.strip():
    raise HTTPException(status_code=400, detail="输入文本不能为空")

result = classify_intent_ensemble(request.text)
return {"success": True, "data": result}
    except Exception as e:
raise HTTPException(status_code=500, detail=f"识别失败:{str(e)}")
if __name__ == "__main__":
    uvicorn.run(app, host="0.0.0.0", port=8000)

服务启动日志记录:

系统接口列表清单:

5.2 前端(HTML+JS)

实现可视化的交互界面,支持:

核心交互代码:

// 调用意图识别API
async function classifyIntent(text) {
    try {
const response = await fetch('http://localhost:8000/api/classify-intent', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ text })
});
const result = await response.json();
return result.data;
    } catch (error) {
console.error('识别失败:', error);
return null;
    }
}

意图识别界面初始化:

单条文本意图识别测试:

批量测试结果对比:

五、总结

       围绕智能体意图识别的项目落地,我们从踩坑试错到打磨出成熟方案,核心就是跳出单一方法的局限,用关键词匹配 + 语义向量 + 大模型验证的集成思路,解决了识别偏差、泛化能力弱的核心问题。项目里没有追求复杂的大模型架构,而是选了 Qwen1.5-1.8B 轻量大模型 + all-MiniLM-L6-v2 语义模型,兼顾本地部署的轻量化和识别精准度,适配智能对话、客服助手这类实际应用场景。

       实操中先靠关键词匹配快速筛选意图,再用语义向量解决口语化、同义不同表达的问题,最后让大模型做精准兜底验证,还通过加权投票的方式整合三者结果,既避免了关键词的死板,又弥补了纯语义匹配的模糊性。整个优化过程也摸清了落地关键:意图识别不用贪大求全,贴合业务的意图定义 + 轻量高效的模型组合的部署优化,才是让智能体真正听懂用户需求的核心,也为后续智能体的多轮对话、场景化响应打下了扎实的基础。

喜欢(0)

上一篇

B站下载器app免费下载入口-哔哩哔哩as软件安卓最新版本下载

B站下载器app免费下载入口-哔哩哔哩as软件安卓最新版本下载

下一篇

电影《老师的宠物》剧情介绍

电影《老师的宠物》剧情介绍
猜你喜欢