一、系统需求分析
1.1 核心业务场景
意图类型 |
业务描述 |
关键实体 |
对接系统 |
OA请假审批 |
员工休假申请处理 |
用户ID、起止日期、请假事由 |
OA系统 |
订单状态查询 |
客户订单跟踪服务 |
订单ID、用户ID |
订单管理系统 |
库存实时查询 |
商品存货信息展示 |
商品ID、仓库名称 |
WMS系统 |
销售价格查询 |
多渠道价格展示 |
商品ID、销售渠道、用户ID |
价格中心系统 |
1.2 技术指标要求
性能要求
响应时间<500ms
准确率>95%
并发量1000+/sec
扩展要求
支持动态意图扩展
支持多语言实体识别
分布式部署能力
二、系统架构设计
2.1 整体架构
监控体系
业务系统层
智能处理层
接入层
Grafana
Prometheus
预警系统
ELK日志
OA系统
订单系统
仓储系统
价格系统
NLU服务集群
NER服务集群
规则引擎
负载均衡
API Gateway
2.2 核心模块分解
class SystemComponents:
""" 组件功能说明 """
@staticmethod
def nlu_service():
""" 意图识别服务
- 基于BERT的微调模型
- 支持在线热更新
- 多模型版本管理
"""
@staticmethod
def ner_service():
""" 实体识别服务
- BiLSTM-CRF序列标注
- 领域自适应训练
- 实体归一化处理
"""
@staticmethod
def dialog_manager():
""" 对话管理引擎
- 多轮对话状态跟踪
- 槽位填充校验
- 异常恢复机制
"""
三、数据流转设计
3.1 数据处理流程
用户 网关 NLU NER 业务系统 原始请求文本 结构化请求 意图类型+文本 结构化参数 业务响应 用户 网关 NLU NER 业务系统
3.2 数据格式规范
{
"session_id": "CONV-20240315-001",
"text": "帮我查订单ID20240315001的状态",
"context": {
"user_id": "U1001",
"channel": "微信小程序"
}
}
{
"intent": "订单查询",
"entities": {
"order_id": "20240315001",
"user_id": "U1001"
},
"response": {
"status": "已发货",
"logistics": "SF123456789",
"timestamp": "2024-03-15 14:30:00"
},
"dialog_state": {
"next_action": "confirm",
"missing_slots": []
}
}
四、核心实现代码
4.1 服务端实现
from fastapi import FastAPI
from pydantic import BaseModel
import uvicorn
app = FastAPI()
class NLURequest(BaseModel):
text: str
context: dict = {}
class NLUResponse(BaseModel):
intent: str
entities: dict
response: dict
@app.post("/nlu", response_model=NLUResponse)
async def process_query(request: NLURequest):
""" 统一NLU处理接口 """
intent = IntentClassifier.predict(request.text)
entities = EntityRecognizer.extract(request.text, intent)
biz_response = BusinessAdapter.call(intent, entities)
dialog_state = DialogManager.update_state(
request.context.get("session_id"),
intent,
entities
)
return {
"intent": intent,
"entities": entities,
"response": biz_response,
"dialog_state": dialog_state
}
if __name__ == "__main__":
uvicorn.run(app, host="0.0.0.0", port=8000)
4.2 业务适配器实现
class BusinessAdapter:
""" 业务系统对接适配器 """
@classmethod
def call(cls, intent: str, params: dict):
handler_map = {
"OA-请假": cls.handle_leave,
"订单查询": cls.handle_order,
"库存查询": cls.handle_inventory,
"价格查询": cls.handle_price
}
return handler_map[intent](params)
@staticmethod
def handle_leave(params):
""" 请假业务处理 """
required = ["user_id", "start_date"]
cls._validate_params(params, required)
return OA_API.apply_leave(
user_id=params["user_id"],
start_date=params["start_date"],
end_date=params.get("end_date"),
reason=params.get("reason", "个人事务")
)
@staticmethod
def _validate_params(params, required):
missing = [field for field in required if field not in params]
if missing:
raise ValueError(f"Missing required fields: {missing}")
class OA_API:
@staticmethod
def apply_leave(**kwargs):
return {
"status": "SUCCESS",
"leave_id": f"LV{random.randint(100000,999999)}",
"approver": "李主管"
}
五、测试验证方案
5.1 单元测试用例
import pytest
def test_leave_approval():
""" 请假审批流程测试 """
request = {
"text": "申请3月18日到20日病假",
"context": {"user_id": "TEST001"}
}
response = client.post("/nlu", json=request)
assert response.status_code == 200
assert "leave_id" in response.json()["response"]
assert response.json()["intent"] == "OA-请假"
def test_order_query():
""" 订单查询异常测试 """
request = {
"text": "查询我的订单状态",
"context": {"user_id": "TEST002"}
}
response = client.post("/nlu", json=request)
assert response.json()["dialog_state"]["missing_slots"] == ["order_id"]
5.2 性能测试报告
测试项目 |
单节点QPS |
平均响应时延 |
错误率 |
意图识别 |
1250 |
68ms |
0.02% |
实体识别 |
980 |
112ms |
0.15% |
完整业务流程 |
650 |
210ms |
0.3% |
六、部署运维方案
6.1 容器化部署
# Dockerfile示例
FROM python:3.9-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
EXPOSE 8000
CMD ["uvicorn", "main:app", "--host", "0.0.0.0"]
6.2 监控配置
scrape_configs:
- job_name: 'nlu_service'
metrics_path: '/metrics'
static_configs:
- targets: ['nlu-service:8000']
- job_name: 'ner_service'
static_configs:
- targets: ['ner-service:8001']
七、扩展开发指南
7.1 新意图接入流程
- 在意图配置中心注册新意图
{
"intent_name": "报销申请",
"required_slots": ["user_id", "amount"],
"api_endpoint": "reimburse"
}
- 实现业务处理逻辑
@BusinessAdapter.register_handler("报销申请")
def handle_reimburse(params):
return FinanceSystem.submit_reimburse(params)
- 添加训练数据
{
"text": "申请差旅费报销500元",
"intent": "报销申请",
"entities": {
"amount": "500",
"type": "差旅费"
}
}