# 对接自定义向量数据库的配置与使用

# 问题背景

当企业已有内部向量检索服务,或者使用的数据库没有现成 LangChain 集成时,可以封装自定义 VectorStore 或 Retriever。目标不是为了形式上兼容,而是统一 add/search/delete 和返回 Document 的约定。

# 工程要点

这部分能力进入生产前,需要把输入、输出、版本和可观测信息设计清楚。输入包括原始文档、用户问题和业务过滤条件;输出包括 chunk、向量、检索结果、答案和引用来源;版本包括模型版本、切分规则、索引版本和文档更新时间。

不要只验证代码能跑通,还要验证结果是否符合业务问题。可以准备一组固定问题,每次调整参数后观察 Top K 是否命中正确资料、答案是否引用正确来源、延迟和成本是否可接受。

# 源码示例

from langchain_core.documents import Document
from langchain_core.vectorstores import VectorStore

class CompanyVectorStore(VectorStore):
    def __init__(self, client, embedding):
        self.client = client
        self.embedding = embedding

    def add_documents(self, documents, **kwargs):
        ids = []
        for doc in documents:
            vector = self.embedding.embed_query(doc.page_content)
            doc_id = self.client.upsert(
                text=doc.page_content,
                vector=vector,
                metadata=doc.metadata,
            )
            ids.append(doc_id)
        return ids

    def similarity_search(self, query, k=4, **kwargs):
        vector = self.embedding.embed_query(query)
        rows = self.client.search(vector=vector, top_k=k, filter=kwargs.get("filter"))
        return [Document(page_content=row["text"], metadata=row["metadata"]) for row in rows]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

# 拓展

这类组件通常不是孤立使用。Embedding 会影响向量库召回,切分会影响 Embedding 表达,metadata 会影响过滤和权限,Prompt 会影响模型是否忠于证据。任何一处改动,都可能改变最终回答质量。

建议把 RAG 当成数据工程、检索工程和生成工程的组合系统。先保证数据正确进入索引,再保证检索能稳定召回,最后再优化模型表达。

# 最新版 LangChain 用法提示

自定义适配时优先对齐 langchain_core 的抽象和 Runnable 使用方式。若只需要检索,不一定必须实现完整 VectorStore,也可以封装自定义 Retriever,返回 Document 列表即可。

# 常见问题

# 这类组件应该先在什么规模上验证?

先用一小批真实文档和真实问题验证,而不是直接全量入库。验证时至少观察三类结果:检索是否命中正确片段、返回片段是否包含足够上下文、最终回答是否严格基于证据。

# 只看相似度分数够不够?

不够。相似度分数只能说明向量距离,不代表答案一定正确。还要看 chunk 是否完整、metadata 是否正确、过滤条件是否过严或过松,以及 Prompt 是否要求模型只根据上下文回答。

# 参数应该怎么调?

先固定评测问题集,再一次只改一个变量,例如 chunk 大小、overlap、top_k、Embedding 模型或过滤条件。每次改动都记录召回命中率、答案准确率、延迟和成本。

# 面试题

# 1. RAG 链路里最容易被忽略的工程点是什么?

最容易被忽略的是数据处理和评估。很多问题不是 LLM 不会答,而是文档解析错误、chunk 切坏、metadata 丢失、向量版本混乱、检索过滤条件错误,导致模型拿不到正确证据。

# 2. 为什么不能只依赖 LLM 自身参数记忆?

参数记忆存在知识过期、领域知识缺失、事实边界不清和不可追踪的问题。RAG 通过检索外部证据,把回答范围约束在可追踪内容上,适合企业知识库、产品文档和实时资料问答。

# 3. 如何判断一个 RAG 系统的问题出在检索还是生成?

先直接查看检索返回的文档。如果返回内容已经不相关,问题在加载、切分、Embedding、向量库或 Retriever;如果返回内容正确但回答错误,问题多半在 Prompt、上下文压缩、引用组织或模型输出约束。

# 生产问题排查

问题 常见原因 处理方式
回答看起来合理但没有依据 Prompt 没要求基于上下文,或检索片段不相关 增加拒答策略、引用来源、检索结果抽样检查
召回结果经常跑偏 chunk 过短、Embedding 模型不适合、query 表达不完整 调整切分策略,评估 Embedding,必要时做查询改写
命中了旧内容 文档更新后没有重新入库,或缓存没有区分版本 使用文档 hash、版本号、更新时间和重建任务
多租户数据串库 metadata filter 缺失或字段设计不严谨 强制 tenant_id / dataset_id 过滤,并做权限测试
成本增长明显 重复 Embedding、top_k 过大、无缓存 增加缓存、批处理、限流和调用统计
延迟不稳定 向量库网络抖动、LLM 响应慢、检索链路串行 并行化可并行步骤,增加超时、重试和降级策略