钉钉 AI 客服:对话上下文管理策略

3 阅读1分钟

钉钉 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 或评论区交流