意图识别落地方案

一、组合模式

用户消息

┌─────────────────────────────┐

│ 第1层:规则(<1ms, 零成本) │ ← 拦截明确意图

│ 关键词 / 正则 / 前缀匹配 │

└──────┬──────────┬───────────┘

│命中 │未命中

↓ ↓

直接路由 ┌─────────────────────────────┐

│ 第2层:Embedding(~50ms) │ ← 拦截常见意图

│ 向量相似度匹配 │

└──────┬──────────┬───────────┘

│高置信度 │低置信度

↓ ↓

直接路由 ┌─────────────────────────────┐

│ 第3层:LLM FC(1-3s) │ ← 处理模糊/复杂意图

│ Function Calling │

└─────────────────────────────┘

每一层拦截一部分,漏下来的才到下一层。80% 的请求在前两层就结束了

二、具体实现

class IntentRouter:

"""三层意图路由"""

def init(self, embedding_model, tools, model_service):

self.rules = {} # 规则库

self.intent_examples = {} # Embedding 意图示例库

self.tools = tools # FC 工具定义

self.model_service = model_service

async def route(self, user_message: str) -> dict:

第1层:规则匹配(零延迟)

result = self._match_rules(user_message)

if result:

return {"source": "rule", **result}

第2层:Embedding 匹配(低延迟)

result = self._match_embedding(user_message)

if result and result"score" > 0.85:

return {"source": "embedding", **result}

第3层:LLM Function Calling(兜底)

return await self._llm_route(user_message

三、各层职责

┌───────────┬─────────────────────────

│ 层级 │ 拦截什么 │

├───────────┼─────────────────────────

│ 规则 │ 模式固定的高频意图 │

├───────────┼────────────────────────

│ Embedding │ 表达多样但语义明确的意图 │

├───────────┼────────────────────────

│ FC │ 模糊、复杂、多步骤意图 │

四、Embedding 意图路由实现

核心思路:每个意图准备几条示例句 → 算 embedding → 存起来 → 用户消息来了算相似度匹配。

  1. 数据准备

每个意图 5-10 条示例句,覆盖不同表达方式

INTENT_EXAMPLES = {

"ssh_command": [

"查看 nginx 日志",

"看看服务器磁盘使用情况",

"重启 docker 容器",

"检查进程是否在运行",

"瞅瞅服务器咋了",

"帮我看看内存占用",

],

"task_plan": [

"下载安装 nginx",

"帮我部署一个 Node.js 项目",

"按照这个文档配置环境",

"批量安装这几个依赖",

"把项目从源码编译安装",

],

"knowledge_query": [

"什么是微服务架构",

"解释一下 Docker 和虚拟机的区别",

"如何设计高并发系统",

"JWT 认证的原理是什么",

],

"normal_chat": [

"今天天气怎么样",

"帮我写一首诗",

"你好",

"谢谢",

],

}

  1. Embedding 服务

import httpx

import numpy as np

from typing import List, Dict

class EmbeddingService:

"""Embedding 服务 - 调用 embedding 模型 API"""

def init(self, base_url: str, api_key: str, model: str = "text-embedding-3-small"):

self.base_url = base_url.rstrip("/")

self.api_key = api_key

self.model = model

async def embed(self, texts: Liststr) -> ListList\[float]:

"""批量获取文本的 embedding 向量"""

async with httpx.AsyncClient() as client:

resp = await client.post(

f"{self.base_url}/embeddings",

headers={"Authorization": f"Bearer {self.api_key}"},

json={"model": self.model, "input": texts}

)

data = resp.json()

按 index 排序,确保顺序和输入一致

sorted_data = sorted(data"data", key=lambda x: x"index")

return item\["embedding" for item in sorted_data]

async def embed_single(self, text: str) -> Listfloat:

"""获取单条文本的 embedding"""

result = await self.embed(text)

return result0

  1. 意图路由器

class EmbeddingIntentRouter:

"""基于 Embedding 的意图路由器"""

def init(self, embedding_service: EmbeddingService):

self.embedding_service = embedding_service

self.intent_vectors: Dictstr, List\[List\[float]] = {} # intent -> 向量列表

self.intent_labels: Liststr = \[\] # 展平的意图标签

self.all_vectors: np.ndarray = None # 展平的向量矩阵

async def build_index(self, intent_examples: Dictstr, List\[str]):

"""

构建意图索引

Args:

intent_examples: {"intent_name": "示例句1", "示例句2", ...}

"""

all_texts = \[\]

self.intent_labels = \[\]

for intent, examples in intent_examples.items():

for text in examples:

all_texts.append(text)

self.intent_labels.append(intent)

批量获取 embedding

vectors = await self.embedding_service.embed(all_texts)

self.all_vectors = np.array(vectors)

按意图分组存储

for intent, examples in intent_examples.items():

self.intent_vectorsintent = \[\]

print(f"EmbeddingRouter 索引构建完成: {len(all_texts)} 条示例, {len(intent_examples)} 个意图")

async def match(self, query: str, top_k: int = 3) -> Listdict:

"""

匹配用户查询最相似的意图

Args:

query: 用户消息

top_k: 返回前 k 个结果

Returns:

{"intent": "ssh_command", "score": 0.92, "matched_example": "查看 nginx 日志"}, ...

"""

if self.all_vectors is None:

raise ValueError("索引未构建,请先调用 build_index()")

获取查询的 embedding

query_vec = np.array(await self.embedding_service.embed_single(query))

计算余弦相似度

similarities = self._cosine_similarity(query_vec, self.all_vectors)

取 top_k

top_indices = np.argsort(similarities)::-1:top_k

results = \[\]

seen_intents = set()

for idx in top_indices:

intent = self.intent_labelsidx

每个意图只取最高分

if intent not in seen_intents:

seen_intents.add(intent)

results.append({

"intent": intent,

"score": float(similaritiesidx),

"matched_example": list(intent_examples.values())0 # 简化

})

return results

@staticmethod

def _cosine_similarity(a: np.ndarray, b: np.ndarray) -> np.ndarray:

"""计算余弦相似度"""

a_norm = a / np.linalg.norm(a)

b_norm = b / np.linalg.norm(b, axis=1, keepdims=True)

return np.dot(b_norm, a_norm)

  1. 接入三层路由

class IntentRouter:

def init(self, embedding_router: EmbeddingIntentRouter, tools, model_service):

self.embedding_router = embedding_router

self.tools = tools

self.model_service = model_service

规则层:高频固定模式

self.rules = [

(r"^(help|帮助|\\?)$", "help"),

(r"^(clear|清空|清除)$", "clear"),

(r"^/", "command"), # 斜杠命令

]

async def route(self, user_message: str, model_id: int) -> dict:

===== 第1层:规则(<1ms)=====

for pattern, intent in self.rules:

if re.match(pattern, user_message.strip()):

return {"intent": intent, "source": "rule", "confidence": 1.0}

===== 第2层:Embedding(~50ms)=====

matches = await self.embedding_router.match(user_message, top_k=1)

if matches and matches0"score" > 0.85:

return {

"intent": matches0"intent",

"source": "embedding",

"confidence": matches0"score"

}

===== 第3层:LLM FC(兜底)=====

return await self._llm_route(user_message, model_id)

  1. 启动时初始化

应用启动时

embedding_service = EmbeddingService(

base_url="http://localhost:11434", # 或 OpenAI API

api_key="your-key",

model="text-embedding-3-small"

)

embedding_router = EmbeddingIntentRouter(embedding_service)

await embedding_router.build_index(INTENT_EXAMPLES)

关键点

相似度阈值需要根据实际数据调:

> 0.90 非常确定,直接路由

0.80-0.90 比较确定,可以路由但记录日志

< 0.80 不确定,交给 LLM FC

意图示例的质量决定准确率:

  • 每个意图 5-10 条,覆盖不同说法

  • 包含口语化表达("瞅瞅"、"咋了")

  • 定期根据 LLM FC 的日志补充新示例

模型选择:

  • OpenAI text-embedding-3-small - 效果好,成本低

  • 本地 bge-large-zh - 中文效果好,零成本

  • Milvus 内置向量搜索 - 你项目已有 Milvus,可以直接

相关推荐
mengge.cloud2 小时前
0909华为云计算类综合服务小白实验教程
linux·运维·服务器·网络·华为云·云计算
QYR-分析3 小时前
蓝海赛道高速扩容!全球小型观察ROV市场格局、细分场景与发展趋势分析
大数据·运维·云计算
陈皮糖..4 小时前
从零搭建一个简易 AI 运维问答机器人(RAG + LangChain + Streamlit)
运维·人工智能·ai·langchain·机器人
制造业的搬运工4 小时前
AI服务器背板与传统背板差异:三大设计升级解析
运维·服务器·人工智能·科技·制造·pcb工艺
顶点多余4 小时前
仿muduo库实现高并发服务器项目
运维·服务器
脚踏实地,坚持不懈!5 小时前
Linux 6.18.7 内存分配与回收 —— 代码梳理
linux·运维·网络
2601_962300475 小时前
python在运维上可以干什么,请举几个具体的例子
运维·python·系统管理·网络监控·自动化脚本
Android系统攻城狮6 小时前
Linux Gstreamer深度解析之gst_audio_format_build_integer调用流程与实战(十二)
linux·运维·服务器·音视频·车载音视频·gstreamer进阶
天远API6 小时前
零信任架构实战:基于天远行驶OCR证识别构建自动化智能停车网关
运维·人工智能·架构·自动化