大模型知识-使用本地Embedding模型+Chromadb构建知识库(RAG)

1.知识库构建流程:

  • 文档入库过程
    • 文档读取
    • 文档切块(chunk)
    • 进行向量化
    • 入库向量库
  • 根据输入信息查询
  • 检索向量数据库返回结果

image

注:文档入库使用的embedding模型与问题向量化使用的embedding模型要保持一致

2.使用本地Embedding模型+Chromadb实践过程

使用在线/本地Embedding模型+Chromadb向量库+Agently框架 -> 知识库

1.文档读取

# 1.读取文件
from PyPDF2 import PdfReader
from agently import Agently
from agently.integrations.chromadb import ChromaData, ChromaEmbeddingFunction
from chromadb import Client

with open("./prd/xx需求文档.pdf","rb") as f:
    reader = PdfReader(f)
    context = "\n\n".join( [page.extract_text() for page in reader.pages])

2.文档内容切片

说明:

  • 因受到向量化模型向量化能力限制,需要控制向量化的内容块长度
  •  作用:信息聚焦便于应用、关键信息清晰便于检索
  • 切分正文:是为了保证高质量内容能够为后续智能工作流程服务
  • 切分常用的工具:
    • LangChain TextSplitters
    • 根据需要自行撰写处理脚本(与业务逻辑有关)
  • 所谓的切分方式可以是:
    • 按长度切分
    • 按段落切分
    • 按内容切分
    • 不仅仅是切分,还可以是信息二次组织(如汇总、重拼装等)
# 2.文件切片,使用langchain_text_split
from langchain_text_splitters import RecursiveCharacterTextSplitter

# 创建切片对象
splitter = RecursiveCharacterTextSplitter(
    separators=["\n\n","\n"],#使用切分的符号
    chunk_size=1000,#期望切块的长度
    chunk_overlap=100, #允许超过的最大长度
    keep_separator=True #是否保留分隔符
)

chunk_data =splitter.split_text(context)

print(chunk_data)

  3.向量化并入库

  说明:向量化主要由向量化模型完成,选择模型的要点:

  • 考虑对应的语言、场景,选择更合适的模型(如英文场景、中文场景、代码场景)
  • 考虑上下文窗口长度(512窗口就只能处理400字左右内容,8k窗口能做的事情就多很多)
  • 考虑运算能力允许
  • Chromadb的数据结构:
    • documents
    • metadatas
    • ids
    • embeddings1
# 3.向量化并入库
#设置embedding模型
embedding = Agently.create_agent()
embedding.set_settings(
    "OpenAICompatible",{
        "model":"qwen3-embedding",
        "base_url":"http://127.0.0.1:11434/v1",
        "auth":"nothing",
        "model_type":"embeddings"
    }
)
#创建embedding函数
embedding_function = ChromaEmbeddingFunction(embedding_agent=embedding)

#连接chroma
client = Client()
collection = client.create_collection(
        name="swagger",
        get_or_create=True,
        metadata={
            "hnsw:space": "cosine"
        },
        embedding_function=embedding_function
    )
#制作入库数据
doc_data = ChromaData([
    {
    "document":chunk
    } for chunk in chunk_data
])
collection.add(**doc_data.get_kwargs())

  4.根据问题检索,返回查询结果

1) 问题向量化
  • 不涉及到复杂数据结构,只需要对问题进行向量化
  • 目的:计算“问题向量 - 索引向量”的距离(向量距离越近,概念越接近)
2) 设置查询方案,获取结果
  • Top N:召回数
  • Distance:准确性
  # 4.信息查询
results = collection.query(query_texts=["动态召回流程"],
                               n_results=3)

for index, document in enumerate(results['documents'][0]):
        print(f"\n\n编号:{index} \n")
        print(document)
        print("\n=====================\n")
        print(f"匹配的距离:{results['distances'][0][index]}")

  注:向量余弦相似度是一种衡量两个向量方向相似程度的度量方法。它通过计算两个向量夹角的余弦值来确定,余弦值越接近1,表示两个向量的方向越相似,即它们越接近。

 

 3.文档与索引的关系:

知识库是一个存储和管理结构化、半结构化或非结构化信息的系统,

而索引是为了快速检索这些信息而建立的结构化数据映射。

在实际应用中,索引就像图书馆的目录系统,帮助用户在海量数据中迅速定位目标内容。没有索引的知识库,检索效率会大幅下降,尤其在百万级甚至更大规模的数据场景中。

核心区别

  • 知识库:存储全部知识条目(文档、图片、视频、结构化数据等),包含内容本身及其元数据

  • 索引:对知识库内容的关键词、向量特征、分类标签等进行组织,以支持高效搜索。

索引在知识库中的作用

  1. 加速检索:通过倒排索引、向量索引(如FAISS、HNSW)等技术,将查询延迟控制在毫秒级。

  2. 提升可发现性:支持同义词、近义词匹配,增加召回率。

  3. 多维度搜索:结合全文索引、元数据索引、语义向量索引,实现混合检索。

  4. 动态更新:实时反映新增或修改的内容,保持知识库的时效性。

image

 

posted @ 2026-04-18 17:00  sunshine_coast  阅读(75)  评论(0)    收藏  举报