Chroma 开源的 AI 应用搜索与检索数据库(即向量数据库)
支持通过 Python(pip install chromadb
)和 JavaScript(npm install chromadb
)快速构建带记忆功能的 LLM 应用,核心 API 仅 4 个函数,操作简洁;它具备简单易用、多工具集成(如 LangChain、LlamaIndex)、支持开发/测试/生产多场景、功能丰富(查询、过滤、正则等) 等特性,提供本地部署(客户端-服务器模式:chroma run --path /chroma_db_path
)和托管服务 Chroma Cloud(含 30 秒内创建数据库、$5 免费额度的优势);
默认用 Sentence Transformers 生成嵌入向量,也支持 OpenAI、Cohere 嵌入或自定义嵌入,适用于“基于数据对话”等场景
2. 思维导图(mindmap)
## **Chroma 基础信息**
- 定位:开源 AI 应用搜索与检索数据库(向量数据库)
- 核心价值:快速构建带记忆的 Python/JavaScript LLM 应用
- 许可证:Apache 2.0
- 发布节奏:每周一发布 pypi/npm 新标签版本,热修复随时发布
## **安装与部署**
- 客户端安装- Python:`pip install chromadb`- JavaScript:`npm install chromadb`
- 部署模式- 本地部署:客户端-服务器模式(命令:`chroma run --path /chroma_db_path`)- 托管服务:Chroma Cloud(30 秒创建数据库,$5 免费额度)
## **核心功能与 API**
- 核心特性- 简单:全类型、全测试、全文档- 集成性:支持 LangChain(Python/JS)、LlamaIndex 等- 多场景:开发/测试/生产统一 API- 功能丰富:查询、过滤、正则等
- 核心 API(4 个关键函数)- 初始化客户端:`chromadb.Client()`- 集合操作:创建/获取/删除集合(如 `create_collection("all-my-documents")`)- 文档操作:添加/更新/删除文档(如 `collection.add(documents=[...], metadatas=[...], ids=[...])`)- 查询操作:搜索相似结果(如 `collection.query(query_texts=[...], n_results=2)`)
## **嵌入向量相关**
- 嵌入向量定义- 字面:将图像/文本/音频转为数字列表(如 `[1.2, 2.1, ....]`)- 类比:代表文档本质,使同类文档“相近”易查找- 技术:文档在深度神经网络某层的 latent-space 位置(嵌入模型为最后一层)
- 支持的嵌入方式- 默认:Sentence Transformers- 第三方:OpenAI 嵌入、Cohere(多语言)嵌入- 自定义:用户可传入自有嵌入向量
## **典型用例**
- “基于数据对话”(Chat your data)1. 向数据库添加文档(可自定义嵌入、嵌入函数或依赖 Chroma 自动处理)2. 用自然语言查询相关文档3. 将文档整合到 GPT4 等 LLM 的上下文窗口,进行总结或分析
## **开发者参与**
- 参与渠道- 社区交流:Discord 的 `#contributing` 频道- 路线规划:查看 Roadmap 并提出想法- 代码贡献:认领标注“Good first issue”的问题并提交 PR
- 参考资料:阅读 contributing guide、DEVELOP.md 等文档
3. 详细总结
一、Chroma 核心定位与基础属性
- 产品定位:开源的 AI 应用搜索与检索数据库,本质是向量数据库,核心作用是为 LLM 应用提供“记忆”能力,支持快速存储、检索嵌入向量数据。
- 许可证:采用 Apache 2.0 许可证,免费且开源,允许商业使用与二次开发。
- 发布节奏:
- 常规版本:每周一发布
pypi
(Python 包)和npm
(JavaScript 包)的新标签版本; - 紧急修复:热修复(Hotfixes)无固定时间,出现问题时随时发布。
- 常规版本:每周一发布
二、安装与部署方式
1. 客户端安装
支持 Python 和 JavaScript 两种主流开发语言,安装命令简洁:
开发语言 | 安装命令 |
---|---|
Python | pip install chromadb |
JavaScript | npm install chromadb |
2. 部署模式
提供本地部署和托管服务两种选择,满足不同场景需求:
- 本地部署(客户端-服务器模式):通过命令
chroma run --path /chroma_db_path
启动服务,可指定数据存储路径,适合需要自主控制数据的场景; - 托管服务(Chroma Cloud):官方提供的 serverless 向量与全文搜索服务,优势包括:
- 速度快、成本低、可扩展;
- 上手门槛低:30 秒内可创建数据库;
- 优惠政策:提供 $5 免费额度,便于快速试用。
三、核心 API 与操作流程
Chroma 核心 API 仅包含 4 个关键函数,操作逻辑清晰,以下为完整示例流程:
- 初始化客户端:创建内存模式客户端(便于原型开发,可轻松添加持久化):
import chromadb client = chromadb.Client()
- 集合(Collection)操作:集合是存储文档的容器,支持创建、获取、删除等操作:
# 创建集合 collection = client.create_collection("all-my-documents") # 其他操作:get_collection()、get_or_create_collection()、delete_collection()
- 文档(Document)操作:向集合添加文档,支持自动处理tokenization、嵌入和索引,也可手动传入嵌入向量:
collection.add(documents=["This is document1", "This is document2"], # 文档内容metadatas=[{"source": "notion"}, {"source": "google-docs"}], # 元数据(用于过滤)ids=["doc1", "doc2"] # 每个文档的唯一ID ) # 其他操作:支持文档更新(update)和删除(delete)
- 查询(Query)操作:搜索相似文档,可指定返回结果数量、元数据过滤、文档内容过滤:
results = collection.query(query_texts=["This is a query document"], # 查询文本n_results=2, # 返回Top 2相似结果where={"metadata_field": "is_equal_to_this"}, # 可选:元数据过滤where_document={"$contains":"search_string"} # 可选:文档内容包含过滤 )
四、核心特性
特性类别 | 具体说明 |
---|---|
简单易用 | 全类型标注、全测试覆盖、全文档说明,降低开发上手难度 |
多工具集成 | 支持与 LangChain(Python 和 JavaScript 版本)、LlamaIndex 等主流 LLM 工具链集成 |
多场景适配 | 开发、测试、生产环境使用统一 API,无需修改代码即可切换环境 |
功能丰富 | 支持基础查询、元数据过滤、文档内容过滤、正则匹配等多种检索能力 |
五、嵌入向量相关说明
1. 嵌入向量的定义
- 字面含义:将非结构化数据(图像、文本、音频等)转换为结构化的数字列表(如
[1.2, 2.1, ....]
),使机器可“理解”数据; - 类比理解:嵌入向量代表文档的“本质”,本质相似的文档(如“旧金山著名桥梁”和“金门大桥照片”)对应的嵌入向量在空间中距离更近,便于快速检索;
- 技术定义:文档在深度神经网络某一层的 latent-space( latent 空间)位置,对于专门的嵌入模型,该位置对应网络的最后一层。
2. 支持的嵌入方式
Chroma 提供灵活的嵌入方案,满足不同需求:
- 默认嵌入:使用 Sentence Transformers 模型自动处理嵌入,无需用户手动配置;
- 第三方嵌入:支持集成 OpenAI 嵌入、Cohere 嵌入(支持多语言);
- 自定义嵌入:允许用户跳过内置嵌入流程,直接传入自己生成的嵌入向量。
六、典型用例:“基于数据对话”(Chat your data)
该用例是 Chroma 最核心的应用场景,流程分为 3 步:
- 数据导入:向 Chroma 数据库添加目标文档,可选择:
- 依赖 Chroma 自动完成 tokenization、嵌入和索引;
- 手动指定嵌入函数;
- 直接传入已生成的嵌入向量;
- 自然语言查询:用日常语言(如“旧金山著名桥梁的相关信息”)作为查询条件,检索数据库中相似的文档;
- LLM 整合:将检索到的相关文档作为上下文,传入 GPT4 等 LLM 中,让 LLM 基于特定数据进行总结、分析或回答,实现“基于私有数据对话”。
4. 关键问题
问题 1:Chroma 作为向量数据库,支持哪些嵌入方式?不同嵌入方式分别适用于什么场景?
答案:Chroma 支持 3 种嵌入方式,适用场景各有不同:
- 默认嵌入(Sentence Transformers):适用于无特殊嵌入需求、追求快速上手的场景,如原型开发、简单的文本检索任务,无需用户额外配置嵌入模型,Chroma 会自动完成 tokenization、嵌入和索引;
- 第三方嵌入(OpenAI 嵌入、Cohere 嵌入):适用于需要更高嵌入质量或特定功能的场景,例如用 OpenAI 嵌入匹配 GPT 系列 LLM 的上下文(减少模型间语义偏差)、用 Cohere 嵌入处理多语言文本检索任务;
- 自定义嵌入:适用于已有成熟嵌入流程(如自研嵌入模型、特定领域优化的嵌入算法)的场景,例如金融、医疗等垂直领域,用户可跳过 Chroma 内置嵌入步骤,直接传入自有嵌入向量,确保嵌入结果符合领域需求。
问题 2:Chroma 的本地部署与托管服务(Chroma Cloud)有什么核心差异?企业该如何选择这两种部署模式?
答案:两者核心差异及企业选择建议如下:
对比维度 | 本地部署(客户端-服务器模式) | 托管服务(Chroma Cloud) |
---|---|---|
数据控制权 | 高(数据存储在自有服务器,自主管理) | 中(数据由 Chroma 托管,需信任第三方) |
运维成本 | 高(需自行维护服务器、处理扩容、故障修复) | 低(serverless 架构,无需关注底层运维) |
上手门槛 | 中(需执行部署命令、配置存储路径) | 低(30 秒内创建数据库,提供 $5 免费额度) |
扩展性 | 依赖自有 IT 资源,扩容需手动规划 | 自动弹性扩容,适配流量波动 |
企业选择建议:
- 若企业对数据安全性、隐私性要求极高(如涉及用户敏感数据、行业合规数据),且有成熟的运维团队,优先选择本地部署;
- 若企业追求开发效率、无充足运维资源,或场景为非核心业务的轻量级检索任务(如内部文档查询工具),优先选择Chroma Cloud,可快速上线并降低运维成本。
问题 3:Chroma 的“基于数据对话(Chat your data)”用例具体如何落地?结合核心 API 说明关键步骤和价值?
答案:该用例落地需 3 个关键步骤,核心 API 贯穿全程,价值在于让 LLM 具备“私有数据理解能力”:
1. 落地步骤(结合核心 API)
- 步骤 1:初始化客户端与创建集合:用
chromadb.Client()
初始化客户端,再通过client.create_collection("doc-collection")
创建存储文档的集合,为数据导入做准备; - 步骤 2:导入目标文档:调用
collection.add(documents=[...], metadatas=[...], ids=[...])
向集合添加私有数据(如企业知识库、用户历史对话),Chroma 可自动处理嵌入,也支持传入自定义嵌入; - 步骤 3:检索+LLM 整合:用
collection.query(query_texts=["用户问题"], n_results=3)
检索与用户问题最相关的 3 条文档,将这些文档作为上下文传入 GPT4 等 LLM,让 LLM 基于私有数据生成回答(而非依赖通用训练数据)。
2. 核心价值
- 突破 LLM 通用数据限制:解决 LLM 无法理解企业私有数据、实时数据的问题(如让 LLM 回答“本公司 2024 年产品规划”);
- 降低开发门槛:核心 API 仅 4 个,无需复杂向量检索逻辑开发,企业可快速搭建“私有数据+LLM”的对话系统;
- 提升回答准确性:基于检索到的精准文档生成回答,减少 LLM 幻觉(虚构信息),尤其适用于需要事实依据的场景(如客服、知识库问答)。
Chroma 并非“不需要嵌入模型”,而是默认内置了嵌入模型,并支持灵活扩展第三方或自定义嵌入模型,无需用户手动从零搭建嵌入能力,大幅降低了使用门槛。具体逻辑可从以下两方面理解:
一、Chroma 「默认自带嵌入模型」,开箱即用
为了让用户快速上手(尤其是原型开发、简单检索场景),Chroma 已经预先集成了 Sentence Transformers 嵌入模型,作为默认的嵌入方案。
- 当你调用
collection.add(documents=[...])
传入原始文本时,Chroma 会自动完成:- 文本 tokenization(分词);
- 调用内置的 Sentence Transformers 模型生成嵌入向量;
- 将嵌入向量与文档、元数据关联后存入数据库。
- 这种“零配置”模式,让没有嵌入模型开发经验的用户,也能直接使用向量检索功能,无需额外部署或调用外部嵌入服务。
二、Chroma 支持「灵活替换嵌入模型」,满足个性化需求
默认模型并非唯一选择——如果你的场景需要更高质量、多语言或领域定制的嵌入能力,Chroma 允许手动指定嵌入方式,核心支持三类:
-
第三方主流嵌入模型
直接对接 OpenAI、Cohere 等主流服务商的嵌入 API,例如:- 使用 OpenAI 的
text-embedding-3-small
模型(适合与 GPT 系列 LLM 搭配,减少语义偏差); - 使用 Cohere 的
multilingual-22-12
模型(支持 100+ 语言,适配多语言检索场景)。
只需在初始化集合时指定嵌入函数,即可自动调用第三方 API 生成嵌入向量。
- 使用 OpenAI 的
-
自定义嵌入模型
若你有自研的嵌入模型(如针对金融、医疗等垂直领域优化的模型),或已通过其他工具生成了嵌入向量,Chroma 支持“跳过内置嵌入步骤”:- 调用
collection.add(embeddings=[...])
直接传入预生成的嵌入向量(需确保向量维度与集合配置一致); - 也可自定义嵌入函数类(继承 Chroma 的
EmbeddingFunction
接口),将自研模型接入 Chroma 流程。
- 调用
-
本地部署的开源嵌入模型
若对数据隐私要求极高(不愿将文本发送到第三方 API),可部署开源嵌入模型(如 BERT、MiniLM)到本地,再通过自定义嵌入函数对接 Chroma,实现“全链路本地化”。
总结:Chroma 不是“不需要嵌入模型”,而是“简化了嵌入模型的使用流程”
- 对新手/快速验证场景:默认内置模型足够用,无需额外操作;
- 对专业/定制化场景:支持替换为第三方/自定义模型,兼顾灵活性与专业性;
- 核心目标是让用户聚焦“向量检索逻辑”,而非“嵌入模型的搭建与维护”——嵌入能力是 Chroma 的核心组成部分,只是以更友好的方式提供给用户。
Python3 实战:用 Chroma 搭建「本地文档检索系统」
以下是基于 Chroma 的完整实战案例,我们将搭建一个本地技术文档检索工具——支持导入 Markdown 技术文档、用自然语言查询相关内容,最终结合 LLM 生成精准回答(以 OpenAI GPT-3.5 为例)。
一、环境准备
1. 安装依赖库
需安装 Chroma 客户端、OpenAI SDK(用于 LLM 问答)、Python-Markdown(用于解析 Markdown 文档),执行以下命令:
pip install chromadb openai python-markdown python-dotenv
2. 配置环境变量
创建 .env
文件,填入 OpenAI API Key(用于 LLM 生成回答,若仅需检索可跳过此步):
OPENAI_API_KEY=your-openai-api-key # 从 OpenAI 控制台获取:https://platform.openai.com/
二、实战步骤:完整代码与解析
步骤 1:初始化 Chroma 客户端与集合
首先创建 Chroma 客户端(本地持久化存储,避免数据丢失),并创建「技术文档集合」(类似数据库中的“表”)。
import os
import chromadb
from chromadb.utils import embedding_functions
from dotenv import load_dotenv
from markdown import markdown
import openai# 加载环境变量(OpenAI API Key)
load_dotenv()
openai.api_key = os.getenv("OPENAI_API_KEY")# 1. 初始化 Chroma 客户端(本地持久化存储,数据存放在 ./chroma_tech_db 目录)
client = chromadb.PersistentClient(path="./chroma_tech_db")# 2. 配置嵌入模型(此处用 OpenAI 嵌入模型,与 GPT 语义匹配更优;也可默认用 Sentence Transformers)
openai_ef = embedding_functions.OpenAIEmbeddingFunction(api_key=openai.api_key,model_name="text-embedding-3-small" # 轻量型嵌入模型,成本低、速度快
)# 3. 创建/获取集合(若集合已存在则直接获取,避免重复创建)
collection = client.get_or_create_collection(name="tech_documents", # 集合名称:技术文档embedding_function=openai_ef, # 指定嵌入模型metadata={"description": "存储本地技术文档的向量集合,用于检索相关内容"}
)print("Chroma 客户端与集合初始化完成!")
步骤 2:导入本地 Markdown 技术文档
假设我们有 2 个技术文档(python_basics.md
、chroma_guide.md
),需解析 Markdown 内容并导入 Chroma 集合。
示例文档内容(参考)
-
python_basics.md
:记录 Python 列表推导式、装饰器基础# Python 基础语法笔记 ## 1. 列表推导式 列表推导式是快速创建列表的语法,格式:[表达式 for 变量 in 可迭代对象 if 条件] 示例:生成 1-10 的偶数列表 → [x for x in range(1,11) if x%2 ==0]## 2. 装饰器 装饰器(@decorator)用于增强函数功能,不修改原函数代码。 示例:统计函数执行时间的装饰器 import time def timer(func):def wrapper(*args, **kwargs):start = time.time()res = func(*args, **kwargs)print(f"执行时间:{time.time()-start:.2f}s")return resreturn wrapper
-
chroma_guide.md
:记录 Chroma 核心操作(添加文档、查询)# Chroma 核心操作指南 ## 1. 添加文档(add) 向集合添加文档时,需指定 documents(内容)、ids(唯一标识)、metadatas(元数据,可选)。 示例: collection.add(documents=["文档1内容", "文档2内容"],ids=["doc1", "doc2"],metadatas=[{"source": "本地文件"}, {"source": "本地文件"}] )## 2. 查询文档(query) 通过 query_texts 传入查询文本,n_results 指定返回相似结果数量,支持元数据过滤。 示例:查询“Chroma 添加文档”相关内容 results = collection.query(query_texts=["如何用 Chroma 添加文档?"],n_results=1 )
文档导入代码
def load_markdown_doc(file_path: str) -> str:"""解析 Markdown 文件,返回纯文本内容(去除 Markdown 格式)"""with open(file_path, "r", encoding="utf-8") as f:md_content = f.read()# 将 Markdown 转为纯文本(去除标题、列表等格式)html_content = markdown(md_content)# 简单清洗:去除 HTML 标签(实际场景可用 BeautifulSoup 优化)import repure_text = re.sub(r"<.*?>", "", html_content)return pure_text# 定义要导入的文档列表(文件路径 + 文档唯一ID + 元数据)
docs_to_import = [{"file_path": "python_basics.md","doc_id": "python_20241015","metadata": {"category": "Python", "source": "本地Markdown", "author": "dev"}},{"file_path": "chroma_guide.md","doc_id": "chroma_20241015","metadata": {"category": "Chroma", "source": "本地Markdown", "author": "dev"}}
]# 批量导入文档到 Chroma 集合
for doc in docs_to_import:# 1. 加载并解析 Markdown 内容doc_content = load_markdown_doc(doc["file_path"])# 2. 检查文档是否已存在(避免重复导入)if doc["doc_id"] not in collection.get(ids=[doc["doc_id"]])["ids"]:collection.add(documents=[doc_content], # 文档内容(列表格式,支持批量传入多个)ids=[doc["doc_id"]], # 唯一ID(必须与 documents 一一对应)metadatas=[doc["metadata"]] # 元数据(用于过滤,可选))print(f"成功导入文档:{doc['file_path']}(ID:{doc['doc_id']})")else:print(f"文档已存在,跳过导入:{doc['file_path']}(ID:{doc['doc_id']})")
步骤 3:实现「检索+LLM 问答」功能
先通过 Chroma 检索与用户问题最相关的文档片段,再将片段作为上下文传给 GPT-3.5,生成精准回答(避免 LLM 幻觉)。
def retrieve_relevant_docs(query_text: str, n_results: int = 1) -> tuple[list, list]:"""从 Chroma 检索相关文档返回:(相关文档内容列表, 相关文档元数据列表)"""results = collection.query(query_texts=[query_text],n_results=n_results,# 可选:添加元数据过滤(例如只检索 Python 类文档)# where={"category": "Python"})# 提取检索结果(注意:results 结构为嵌套列表,需扁平化)relevant_docs = results["documents"][0] # 文档内容relevant_metadatas = results["metadatas"][0] # 文档元数据return relevant_docs, relevant_metadatasdef llm_answer_with_context(query_text: str, relevant_docs: list) -> str:"""结合检索到的文档上下文,调用 GPT-3.5 生成回答"""# 构建提示词(包含上下文+用户问题)prompt = f"""请基于以下参考文档,回答用户的问题。若参考文档未提及相关内容,直接说明“文档中未找到相关信息”。参考文档:{chr(10).join(relevant_docs)} # 用换行符连接多个文档用户问题:{query_text}回答要求:简洁明了,基于文档内容,不添加额外信息。"""# 调用 OpenAI API 生成回答response = openai.ChatCompletion.create(model="gpt-3.5-turbo",messages=[{"role": "user", "content": prompt}],temperature=0.2 # 降低随机性,确保回答基于文档)return response.choices[0].message["content"].strip()# 测试:用户查询示例
if __name__ == "__main__":# 示例1:查询 Python 装饰器user_query1 = "Python 装饰器的作用是什么?如何写一个统计函数执行时间的装饰器?"print(f"\n=== 用户问题1:{user_query1} ===")docs1, metas1 = retrieve_relevant_docs(user_query1)print(f"检索到相关文档(来源:{metas1[0]['category']}):\n{docs1[0][:200]}...") # 显示前200字符answer1 = llm_answer_with_context(user_query1, docs1)print(f"LLM 回答:\n{answer1}")# 示例2:查询 Chroma 添加文档的方法user_query2 = "如何向 Chroma 集合添加本地文档?需要指定哪些参数?"print(f"\n=== 用户问题2:{user_query2} ===")docs2, metas2 = retrieve_relevant_docs(user_query2)print(f"检索到相关文档(来源:{metas2[0]['category']}):\n{docs2[0][:200]}...")answer2 = llm_answer_with_context(user_query2, docs2)print(f"LLM 回答:\n{answer2}")
三、运行结果与说明
1. 预期输出
Chroma 客户端与集合初始化完成!
成功导入文档:python_basics.md(ID:python_20241015)
成功导入文档:chroma_guide.md(ID:chroma_20241015)=== 用户问题1:Python 装饰器的作用是什么?如何写一个统计函数执行时间的装饰器? ===
检索到相关文档(来源:Python):
Python 基础语法笔记 1. 列表推导式 列表推导式是快速创建列表的语法,格式:[表达式 for 变量 in 可迭代对象 if 条件] 示例:生成 1-10 的偶数列表 → [x for x in range(1,11) if x%2 ==0] 2. 装饰器 装饰器(@decorator)用于增强函数功能,不修改原函数代码。 示例:统计函数执行时间的装饰器 import time def timer(func): def wrapper(*args, **kwargs): start = time.time() res = func(*args, **kwargs) print(f"执行时间:{time.time()-start:.2f}s") return res return wrapper...
LLM 回答:
Python 装饰器(@decorator)的作用是增强函数功能,且不修改原函数代码。统计函数执行时间的装饰器示例如下:
import time
def timer(func):def wrapper(*args, **kwargs):start = time.time()res = func(*args, **kwargs)print(f"执行时间:{time.time()-start:.2f}s")return resreturn wrapper=== 用户问题2:如何向 Chroma 集合添加本地文档?需要指定哪些参数? ===
检索到相关文档(来源:Chroma):
Chroma 核心操作指南 1. 添加文档(add) 向集合添加文档时,需指定 documents(内容)、ids(唯一标识)、metadatas(元数据,可选)。 示例: collection.add( documents=["文档1内容", "文档2内容"], ids=["doc1", "doc2"], metadatas=[{"source": "本地文件"}, {"source": "本地文件"}] ) 2. 查询文档(query) 通过 query_texts 传入查询文本,n_results 指定返回相似结果数量,支持元数据过滤。 示例:查询“Chroma 添加文档”相关内容 results = collection.query( query_texts=["如何用 Chroma 添加文档?"], n_results=1 )...
LLM 回答:
向 Chroma 集合添加本地文档的步骤如下:
1. 先加载并解析本地文档内容(如解析 Markdown 为纯文本);
2. 调用集合的 add 方法传入相关参数。需指定的参数包括:
- documents:文档内容(列表格式,支持批量传入多个文档);
- ids:文档唯一标识(列表格式,必须与 documents 一一对应);
- metadatas:文档元数据(列表格式,用于过滤,可选,如指定文档来源、类别等)。示例代码参考:
collection.add(documents=["文档1内容", "文档2内容"],ids=["doc1", "doc2"],metadatas=[{"source": "本地文件"}, {"source": "本地文件"}]
)
2. 关键说明
- 数据持久化:用
PersistentClient
而非默认的内存客户端,数据会存在./chroma_tech_db
目录,重启程序后不丢失; - 嵌入模型选择:若不想用 OpenAI 嵌入(需 API 费用),可删除
embedding_function=openai_ef
参数,默认使用 Sentence Transformers(本地免费,但速度略慢); - 文档解析优化:实战中可替换
load_markdown_doc
函数,用BeautifulSoup
更精准地清洗 HTML 标签,或用langchain.document_loaders.MarkdownLoader
简化解析; - 过滤功能:检索时可通过
where
参数筛选文档(如where={"category": "Python"}
),只返回指定类别的内容,提高检索精度。
四、扩展场景
- 多格式文档支持:添加 PDF、Word 文档导入,需安装
PyPDF2
(PDF 解析)、python-docx
(Word 解析); - 批量检索优化:当文档较多时,可将文档按段落拆分(避免单文档过长),用
metadatas
记录段落归属,检索时返回更精准的片段; - 本地 LLM 替代:若不想用 OpenAI,可替换
llm_answer_with_context
函数,对接本地部署的 LLM(如 Llama 3、Qwen),实现“全链路本地化”。