这是什么?
MultiVector (多向量索引)是 LangChain 的一种高级检索技术。它的核心思想是:为每个文档生成多个假设性问题,将这些问题向量化用于检索,但最终返回的是原始文档。
核心原理:
markdown
原始文档 → LLM生成假设性问题 → 问题向量化存储
↓
用户查询 → 向量检索 → 匹配假设性问题 → 返回原始文档
有什么用?
主要用途: • 电商产品搜索 - 用户可能用各种方式描述产品需求 • 文档问答系统 - 用户提问方式与文档表述不一致 • 知识库检索 - 提高检索准确率和召回率 • 客服系统 - 匹配用户多样化的提问方式
解决问题:传统向量检索中,文档表述与用户查询可能语义不匹配。MultiVector 通过生成多个假设性问题增加匹配概率。
示例代码
python
from typing import List
from pydantic import BaseModel, Field
from langchain_core.prompts import ChatPromptTemplate
from langchain_openai import ChatOpenAI
from langchain_core.documents import Document
# 1. 定义假设性问题的数据结构
class HypotheticalQuestions(BaseModel):
"""生成假设性问题"""
questions: List[str] = Field(
description="假设性问题列表,类型为字符串列表",
)
# 2. 构建生成假设性问题的 prompt
prompt = ChatPromptTemplate.from_template(
"生成一个包含3个假设性问题的列表,这些问题可以用于回答下面的文档:\n\n{doc}"
)
# 3. 创建 LLM 并绑定结构化输出
llm = ChatOpenAI(model="moonshot-v1-8k", temperature=0)
structured_llm = llm.with_structured_output(HypotheticalQuestions)
# 4. 创建链应用
chain = (
{"doc": lambda x: x.page_content}
| prompt
| structured_llm
)
# 5. 调用链生成假设性问题
hypothetical_questions = chain.invoke(
Document(page_content="我叫慕小课,我喜欢打篮球,游泳")
)
print(hypothetical_questions.questions)
# 输出示例:
# [
# "慕小课喜欢什么运动?",
# "谁喜欢打篮球和游泳?",
# "慕小课的兴趣爱好是什么?"
# ]
流程图
markdown
┌─────────────────────────────────────────────────────────────┐
│ MultiVector 检索流程 │
└─────────────────────────────────────────────────────────────┘
【索引构建阶段】
原始文档集合
│
▼
┌─────────────────┐
│ 遍历每个文档 │
└────────┬────────┘
│
▼
┌─────────────────────────────────┐
│ LLM 生成假设性问题(3-5个) │
│ - "这个文档可能回答什么问题?" │
└────────┬────────────────────────┘
│
▼
┌─────────────────────────────────┐
│ 将假设性问题进行 Embedding │
│ (问题 → 向量) │
└────────┬────────────────────────┘
│
▼
┌─────────────────────────────────┐
│ 存储到向量数据库 │
│ - key: 问题向量 │
│ - value: 原始文档 │
└─────────────────────────────────┘
【检索阶段】
用户查询
│
▼
┌─────────────────────────────────┐
│ 将查询转向量 (Query Embedding) │
└────────┬────────────────────────┘
│
▼
┌─────────────────────────────────┐
│ 向量相似度搜索 │
│ (找出最相似的假设性问题) │
└────────┬────────────────────────┘
│
▼
┌─────────────────────────────────┐
│ 返回假设性问题对应的原始文档 │
└────────┬────────────────────────┘
│
▼
┌─────────────────────────────────┐
│ 使用检索到的文档回答用户查询 │
└─────────────────────────────────┘