搭建本地基于Open Ai 的数据库
方案概述
- 1.数据预处理 :解析本地 Markdown 文件,提取文本内容并进行清洗。
- 2.向量化索引 :使用 AI 模型(如文本嵌入模型)将文本内容转化为向量,存储到向量数据库(如 Chroma、Faiss 或 Milvus)。
- 3.搜索接口 :通过用户输入的自然语言查询,生成查询向量并与索引库中的向量进行相似度匹配,返回最相关的文档或段落。
步骤实现
1. 安装必要的工具和库
-
Python 环境 :推荐使用 Python 来实现自动化流程。
-
文本解析库 :用于读取和解析 Markdown 文件。
bash
复制代码
pip install markdown # 解析 Markdown 语法 pip install python-markdown -
文本嵌入模型 :
-
云端模型
(如 OpenAI 的
text-embedding-ada-002):
bash
复制代码
pip install openai -
本地模型
(如
SentenceTransformers或
Llama):
bash
复制代码
pip install sentence-transformers # 或者安装本地大模型框架如 localAI、Qwen 的本地版本
-
-
向量数据库 :用于存储和快速检索向量。
bash
复制代码
pip install chromadb # 轻量级向量数据库 pip install faiss-cpu # Facebook 的高效向量相似度搜索库 -
前端框架 (可选,用于搭建搜索界面):
bash
复制代码
pip install streamlit # 轻量级 Web 框架
2. 收集和处理数据
目标 :遍历所有 Markdown 文件,提取文本内容并分块处理。
python
运行复制代码
import os
import markdown
from bs4 import BeautifulSoup # 清洗 HTML(解析后的 Markdown 可能转为 HTML)
def parse_markdown_files(directory):
docs = []
metadatas = []
for root, _, files in os.walk(directory):
for file in files:
if file.endswith(".md"):
file_path = os.path.join(root, file)
with open(file_path, "r", encoding="utf-8") as f:
content = f.read()
# 将 Markdown 转为纯文本
html = markdown.markdown(content)
text = BeautifulSoup(html, "html.parser").get_text()
# 分块处理(例如每 500 字符为一段)
chunks = [text[i:i+500] for i in range(0, len(text), 500)]
docs.extend(chunks)
# 添加元数据(如文件路径、标题)
metadatas.extend([{"source": file_path, "chunk": i} for i in range(len(chunks))])
return docs, metadatas3. 创建向量索引
目标 :将文本块转化为向量并存储到数据库。
使用 OpenAI 的文本嵌入模型
python
运行复制代码
import openai
# 设置 OpenAI API 密钥
openai.api_key = "YOUR_API_KEY"
def create_embeddings(docs):
embeddings = []
for doc in docs:
response = openai.Embedding.create(
input=doc,
model="text-embedding-ada-002"
)
embeddings.append(response["data"][0]["embedding"])
return embeddings
# 建立 Chroma 向量数据库
import chromadb
client = chromadb.Client()
collection = client.create_collection(name="markdown_search")
docs, metadatas = parse_markdown_files("your_markdown_directory")
embeddings = create_embeddings(docs)
collection.add(
documents=docs,
embeddings=embeddings,
metadatas=metadatas
)使用本地模型(如 SentenceTransformers)
python
运行复制代码
from sentence_transformers import SentenceTransformer
model = SentenceTransformer('all-MiniLM-L6-v2') # 轻量级模型
embeddings = model.encode(docs).tolist() # 转为列表方便存储
# 用 Faiss 保存向量
import faiss
import numpy as np
dimension = len(embeddings[0])
index = faiss.IndexFlatL2(dimension)
faiss_data = np.array(embeddings).astype("float32")
index.add(faiss_data)
faiss.write_index(index, "markdown_index.faiss")4. 搭建搜索接口
目标 :通过用户输入的查询,返回最相关的文档段。
使用 Streamlit 快速搭建 Web 界面
python
运行复制代码
import streamlit as st
import chromadb
import faiss
import numpy as np
# 初始化 Chroma 或加载 Faiss 索引
def search_query(query, top_k=5):
# 方法 1:使用 Chroma
client = chromadb.Client()
collection = client.get_collection("markdown_search")
results = collection.query(
query_texts=[query],
n_results=top_k
)
return results["documents"][0], results["metadatas"][0]
# 方法 2:使用 Faiss
# model = SentenceTransformer('all-MiniLM-L6-v2')
# query_embedding = model.encode([query]).astype("float32")
# index = faiss.read_index("markdown_index.faiss")
# distances, indices = index.search(query_embedding, top_k)
# return [docs[i] for i in indices[0]]
# Streamlit 界面
st.title("Markdown 文件智能搜索")
query = st.text_input("输入你的查询:")
if st.button("搜索"):
results, metadatas = search_query(query)
for i, (text, metadata) in enumerate(zip(results, metadatas)):
st.write(f"**结果 {i+1}**:")
st.write(text)
st.caption(f"来源:{metadata['source']}(第 {metadata['chunk']} 块)")5. 高级扩展(可选)
-
使用 LangChain :一个简化 AI 工作流的框架,支持端到端实现。
bash
复制代码
pip install langchain chromadbpython
运行复制代码
from langchain.text_splitter import MarkdownHeaderTextSplitter from langchain.embeddings import OpenAIEmbeddings from langchain.vectorstores import Chroma # 用 LangChain 分割 Markdown(按标题层次) splitter = MarkdownHeaderTextSplitter(["#", "##", "###"]) with open("your_file.md", "r") as f: md_file = f.read() data = splitter.split_text(md_file) # 创建索引 embeddings = OpenAIEmbeddings() db = Chroma.from_documents(data, embeddings) # 查询 query = "如何配置本地 Markdown 搜索?" docs = db.similarity_search(query) for doc in docs: st.write(doc.page_content) -
结合大模型生成答案 :用类似 Qwen 或 GPT 的模型总结结果。
python
运行复制代码
# 示例:用 OpenAI 的 GPT-3.5 生成答案 def get_answer(query, docs): prompt = f"根据以下内容回答问题:\n{query}\n\n内容:\n" + "\n".join(docs) response = openai.Completion.create( engine="text-davinci-003", prompt=prompt, max_tokens=150 ) return response.choices[0].text.strip() # 在搜索结果后调用 answer = get_answer(query, results) st.write(f"**答案**:{answer}")
推荐工具和框架
-
文本嵌入模型 :
- 云端 :OpenAI 的
text-embedding-ada-002(精度高,适合复杂场景)。 - 本地 :
all-MiniLM-L6-v2(轻量、快,适合小规模数据)、Qwen系列的本地模型(如Qwen-Max-WWM-Int8)、Llama系列。
- 云端 :OpenAI 的
-
向量数据库 :
- Chroma :轻量级,易于集成。
- Faiss :高效向量搜索,适合大规模数据。
- Milvus :分布式向量数据库,适合企业级应用。
-
前端框架 :
- Streamlit :快速搭建交互式界面。
- Flask/Django :自定义 Web 后端。
- VS Code 插件 :如果需要集成到编辑器(如通过 AI Search 插件)。
注意事项
-
1.数据隐私 :如果使用本地模型和数据库(如 Faiss + SentenceTransformers),数据完全在本地处理,适合敏感信息。
-
性能优化
:
- 分块大小:过大的文本块可能降低搜索精度,过小则增加索引数量。
- 使用 GPU:加速嵌入生成和向量搜索(如通过
sentence-transformers的 GPU 支持)。
-
3.定期更新索引 :当本地文件发生变化时,需要重新生成索引。
-
4.自然语言查询 :AI 的语义理解能力依赖于模型质量,可能需要多次调整查询策略。
完整示例代码
以下是一个基于 Chroma 和 OpenAI 的快速实现:
python
运行复制代码
import os
import markdown
from bs4 import BeautifulSoup
import chromadb
import openai
# 1. 解析 Markdown 文件
def load_markdown(directory):
docs = []
metadatas = []
for file in os.listdir(directory):
if file.endswith(".md"):
with open(os.path.join(directory, file), "r") as f:
text = f.read()
html = markdown.markdown(text)
cleaned_text = BeautifulSoup(html, "html.parser").get_text()
chunks = [cleaned_text[i:i+500] for i in range(0, len(cleaned_text), 500)]
docs.extend(chunks)
metadatas.extend([{"source": file, "chunk": i} for i in range(len(chunks))])
return docs, metadatas
# 2. 创建索引
def create_index(docs, metadatas):
# 使用 OpenAI 嵌入模型
embeddings = openai.Embedding.create(
input=docs,
model="text-embedding-ada-002"
)["data"]
# 存储到 Chroma
client = chromadb.Client()
collection = client.create_collection("markdown_search")
collection.add(
documents=docs,
embeddings=[e["embedding"] for e in embeddings],
metadatas=metadatas
)
# 3. 搜索函数
def search_query(query):
client = chromadb.Client()
collection = client.get_collection("markdown_search")
results = collection.query(
query_texts=[query],
n_results=5
)
return results["documents"][0], results["metadatas"][0]
# 4. 主流程
if __name__ == "__main__":
directory = "你的 Markdown 文件目录"
docs, metadatas = load_markdown(directory)
create_index(docs, metadatas)
# 测试搜索
query = "如何实现向量化索引?"
results, metadatas = search_query(query)
for text, metadata in zip(results, metadatas):
print(f"来源:{metadata['source']},段落:{text}")替代方案
-
Obsidian + 插件
:
- 使用 Obsidian 的 AI Search 插件,直接在 ](https://github.com/JeroenvO/ai-search),直接在)Obsidian 内实现 Markdown 文件的语义搜索。
-
Notion + API
:
- 将 Markdown 内容导入 Notion,利用 Notion API 和 AI 模型实现搜索(需 Notion 账户)。
通过以上步骤,你可以快速搭建一个本地 Markdown 文件的智能搜索系统。根据需求选择云端或本地模型,并结合简单的界面工具(如 Streamlit)提升用户体验。