钉钉 AI 客服:对话上下文管理策略
上下文管理是 AI 客服的核心技术。
一、为什么需要上下文?
没有上下文:
用户:我想退货
AI:好的,请提供订单号
用户:123456
AI:请问您需要什么帮助?
有上下文:
用户:我想退货
AI:好的,请提供订单号
用户:123456
AI:订单 123456 已找到,确认退货吗?
二、上下文结构
const context = {
sessionId: 'user_123',
userId: 'user_123',
messages: [
{ role: 'user', content: '我想退货' },
{ role: 'assistant', content: '好的,请提供订单号' },
{ role: 'user', content: '123456' }
],
metadata: {
orderId: '123456',
intent: 'refund'
}
};
三、存储方案
3.1 Redis 存储
async function saveContext(sessionId, context) {
await redis.set(
`context:${sessionId}`,
JSON.stringify(context),
'EX',
3600 // 1 小时过期
);
}
async function getContext(sessionId) {
const data = await redis.get(`context:${sessionId}`);
return data ? JSON.parse(data) : null;
}
3.2 数据库存储
CREATE TABLE contexts (
session_id VARCHAR(64) PRIMARY KEY,
user_id VARCHAR(64),
messages JSON,
metadata JSON,
updated_at TIMESTAMP
);
四、上下文窗口
4.1 限制长度
const MAX_CONTEXT = 10; // 最多保留 10 轮对话
function trimContext(messages) {
if (messages.length > MAX_CONTEXT) {
return messages.slice(-MAX_CONTEXT);
}
return messages;
}
4.2 Token 限制
const MAX_TOKENS = 4000;
function trimByTokens(messages) {
let total = 0;
const result = [];
for (let i = messages.length - 1; i >= 0; i--) {
const tokens = countTokens(messages[i].content);
if (total + tokens > MAX_TOKENS) break;
total += tokens;
result.unshift(messages[i]);
}
return result;
}
五、上下文压缩
5.1 摘要压缩
async function compressContext(messages) {
if (messages.length < 10) return messages;
// 用 AI 生成摘要
const summary = await ai.summarize(
messages.slice(0, -5).map(m => m.content).join('\n')
);
return [
{ role: 'system', content: `上下文摘要:${summary}` },
...messages.slice(-5)
];
}
六、多轮对话
6.1 意图跟踪
function trackIntent(context, newMessage) {
const intent = detectIntent(newMessage);
if (intent !== context.currentIntent) {
context.intentHistory.push(context.currentIntent);
context.currentIntent = intent;
}
return context;
}
6.2 实体提取
function extractEntities(context, message) {
const entities = {
orderId: extractOrderId(message),
productId: extractProductId(message),
date: extractDate(message)
};
context.entities = { ...context.entities, ...entities };
return context;
}
七、上下文清理
7.1 超时清理
// 会话超时 30 分钟
const SESSION_TIMEOUT = 30 * 60 * 1000;
setInterval(() => {
const now = Date.now();
for (const [sessionId, context] of contexts) {
if (now - context.lastActive > SESSION_TIMEOUT) {
contexts.delete(sessionId);
}
}
}, 60000);
7.2 主动清理
function endSession(sessionId) {
// 保存对话记录
saveConversation(sessionId);
// 清理上下文
contexts.delete(sessionId);
}
项目地址:GitHub - dingtalk-connector-pro 有问题欢迎 Issue 或评论区交流