钉钉 AI 客服:RAG 架构设计

5 阅读1分钟

钉钉 AI 客服:RAG 架构设计

RAG 是 AI 客服的核心架构。


一、RAG 概念

Retrieval-Augmented Generation:检索增强生成

用户问题 → 检索相关文档 → 组合提示词 → AI 生成回答

二、架构设计

┌─────────────────────────────────────────────┐
│                  用户问题                    │
└─────────────────────────────────────────────┘
                    ↓
┌─────────────────────────────────────────────┐
│               问题理解                       │
│  - 意图识别                                  │
│  - 实体提取                                  │
└─────────────────────────────────────────────┘
                    ↓
┌─────────────────────────────────────────────┐
│               文档检索                       │
│  - 向量检索                                  │
│  - 关键词检索                                │
│  - 混合检索                                  │
└─────────────────────────────────────────────┘
                    ↓
┌─────────────────────────────────────────────┐
│               重排序                        │
│  - 相关性评分                                │
│  - 多样性过滤                                │
└─────────────────────────────────────────────┘
                    ↓
┌─────────────────────────────────────────────┐
│               LLM 生成                      │
│  - 提示词组合                                │
│  - 答案生成                                  │
└─────────────────────────────────────────────┘

三、文档处理

3.1 文档分割

function splitDocument(text, chunkSize = 500) {
  const chunks = [];
  
  for (let i = 0; i < text.length; i += chunkSize) {
    chunks.push(text.slice(i, i + chunkSize));
  }
  
  return chunks;
}

3.2 向量化存储

async function indexDocument(doc) {
  const chunks = splitDocument(doc.content);
  
  for (const chunk of chunks) {
    const vector = await embed(chunk);
    await storeVector(vector, {
      docId: doc.id,
      content: chunk
    });
  }
}

四、检索优化

4.1 多路召回

async function retrieve(question) {
  // 向量检索
  const vectorResults = await vectorSearch(question, 10);
  
  // 关键词检索
  const keywordResults = await keywordSearch(question, 10);
  
  // 融合
  return mergeAndRerank(vectorResults, keywordResults);
}

4.2 重排序

async function rerank(question, documents) {
  const scores = await Promise.all(
    documents.map(doc => computeRelevance(question, doc))
  );
  
  return documents
    .map((doc, i) => ({ doc, score: scores[i] }))
    .sort((a, b) => b.score - a.score)
    .slice(0, 5);
}

五、提示词组合

function buildPrompt(question, contexts) {
  return `
基于以下知识回答用户问题:

${contexts.map(c => c.content).join('\n\n')}

用户问题:${question}

要求:简洁准确,不超过 100 字。
`;
}

六、效果优化

优化点方法
召回率多路召回
准确率重排序
响应速度缓存
成本模型选择

项目地址:GitHub - dingtalk-connector-pro 有问题欢迎 Issue 或评论区交流