钉钉 AI 客服:向量检索实战

4 阅读1分钟

钉钉 AI 客服:向量检索实战

向量检索是知识库搜索的核心技术。


一、为什么需要向量检索?

方式问题
关键词匹配无法理解语义
正则匹配规则复杂
向量检索语义理解

二、向量嵌入

2.1 文本向量化

async function embed(text) {
  const response = await openai.embeddings.create({
    model: 'text-embedding-3-small',
    input: text
  });
  return response.data[0].embedding;
}

// 示例
const vector = await embed('怎么退货');
// [0.123, -0.456, 0.789, ...]

2.2 批量向量化

async function batchEmbed(texts) {
  const response = await openai.embeddings.create({
    model: 'text-embedding-3-small',
    input: texts
  });
  return response.data.map(d => d.embedding);
}

三、向量存储

3.1 Pinecone

const pinecone = new Pinecone();

async function upsert(id, vector, metadata) {
  await pinecone.index('knowledge').upsert([{
    id,
    values: vector,
    metadata
  }]);
}

async function query(vector, topK = 5) {
  const result = await pinecone.index('knowledge').query({
    vector,
    topK,
    includeMetadata: true
  });
  return result.matches;
}

3.2 Milvus

const milvus = new MilvusClient('localhost:19530');

await milvus.insert({
  collection_name: 'faqs',
  fields_data: [{ id: 1, vector: [...], question: '...' }]
});

const results = await milvus.search({
  collection_name: 'faqs',
  vectors: [queryVector],
  top_k: 5
});

四、相似度计算

4.1 余弦相似度

function cosineSimilarity(a, b) {
  const dot = a.reduce((sum, ai, i) => sum + ai * b[i], 0);
  const normA = Math.sqrt(a.reduce((sum, ai) => sum + ai * ai, 0));
  const normB = Math.sqrt(b.reduce((sum, bi) => sum + bi * bi, 0));
  return dot / (normA * normB);
}

五、混合检索

async function hybridSearch(question) {
  // 向量检索
  const vectorResults = await vectorSearch(question);
  
  // 关键词检索
  const keywordResults = await keywordSearch(question);
  
  // 融合排序
  const merged = mergeResults(vectorResults, keywordResults);
  
  return merged.slice(0, 5);
}

六、性能优化

6.1 索引优化

  • 使用 IVF 索引
  • 设置合适的 nlist
  • 定期重建索引

6.2 缓存

const cache = new Map();

async function cachedSearch(question) {
  const key = hash(question);
  if (cache.has(key)) return cache.get(key);
  
  const result = await vectorSearch(question);
  cache.set(key, result);
  
  return result;
}

七、效果评估

指标关键词向量检索
召回率60%90%
准确率70%85%
响应时间10ms50ms

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