钉钉 AI 客服:对话状态管理
状态管理是多轮对话的基础。
一、状态类型
| 状态 | 说明 |
|---|---|
| IDLE | 空闲 |
| COLLECTING | 收集信息 |
| CONFIRMING | 确认中 |
| PROCESSING | 处理中 |
| COMPLETED | 完成 |
二、状态机设计
const STATES = {
IDLE: {
onMessage: (msg) => {
if (isOrderQuery(msg)) return 'COLLECTING_ORDER';
if (isRefund(msg)) return 'COLLECTING_REFUND';
return 'IDLE';
}
},
COLLECTING_ORDER: {
onMessage: (msg, context) => {
if (hasOrderId(msg)) {
context.orderId = extractOrderId(msg);
return 'CONFIRMING';
}
return 'COLLECTING_ORDER';
}
},
CONFIRMING: {
onMessage: (msg, context) => {
if (isConfirm(msg)) return 'PROCESSING';
if (isCancel(msg)) return 'IDLE';
return 'CONFIRMING';
}
},
PROCESSING: {
onMessage: async (msg, context) => {
await processOrder(context);
return 'COMPLETED';
}
}
};
三、状态存储
// Redis 存储
async function saveState(sessionId, state, context) {
await redis.hset('session', sessionId, JSON.stringify({ state, context }));
}
async function getState(sessionId) {
const data = await redis.hget('session', sessionId);
return data ? JSON.parse(data) : { state: 'IDLE', context: {} };
}
四、状态转换
async function handleMessage(sessionId, message) {
// 获取当前状态
const { state, context } = await getState(sessionId);
// 执行状态转换
const newState = await STATES[state].onMessage(message, context);
// 保存新状态
await saveState(sessionId, newState, context);
// 返回响应
return generateResponse(newState, context);
}
五、超时处理
// 设置超时
async function setTimeout(sessionId, seconds = 300) {
await redis.expire(`session:${sessionId}`, seconds);
}
// 超时回调
redis.on('expired', async (key) => {
const sessionId = key.split(':')[1];
await handleTimeout(sessionId);
});
六、场景示例
订单查询流程
IDLE → 用户问订单 → COLLECTING_ORDER
COLLECTING_ORDER → 用户提供订单号 → CONFIRMING
CONFIRMING → 用户确认 → PROCESSING
PROCESSING → 查询完成 → COMPLETED
COMPLETED → → IDLE
七、最佳实践
- 状态清晰定义
- 转换逻辑简单
- 超时自动重置
- 日志记录转换
项目地址:GitHub - dingtalk-connector-pro 有问题欢迎 Issue 或评论区交流