点击上方↗️「活水智能」,关注 + 星标🌟

作者:Anoop Maurya
编译:活水智能
引言
各位技术宅们,大家好!有没有过这样的感觉:你的大脑就像一个混乱的图书馆,里面堆满了各种随机的 PDF、Word 文档,甚至还有那些你几乎记不清的旧项目的 PowerPoint 演示文稿?然后你心里想着:“我只需要找到 那个文件……但它到底在哪儿呢?!” 🧐
如果我告诉你,你可以不用手动翻遍那些布满灰尘的文件夹,而是在你的电脑上拥有一个 AI 驱动的引擎,不仅能找到文件,还能回答关于这些文件的问题,你会不会很兴奋?没错,我们说的是一个 本地文件的生成式搜索引擎——由 FAISS、句子 Transformer 和开源模型的魔力驱动。
我已经为你构建好了这个工具,这样你就不需要记住每个文件的位置,还能在几秒钟内找到所需的信息,感觉自己像个天才一样。那么,让我们来看看它是如何工作的吧!

为什么我们要构建这个工具?🤔
说实话,因为我们是技术宅,我们希望我们的文件能像托尼·斯塔克的系统一样井井有条!
以下是主要原因:
1. 隐私优先:
你不希望你的敏感文件漂浮在某些基于云的黑盒子里,对吧?你希望这个工具是 本地的 和 私密的。只有你的电脑能看到你的文件。2. 文件格式很复杂:
PDF、DOCX、PPTX——这些格式存储信息的方式各不相同。但是有了这个引擎,我们可以像专业人士一样轻松从所有这些格式中提取数据。3. AI 的意义搜索能力:
你有没有试过搜索某些东西,却记不起具体的关键词,但你知道你 想表达的意思?我们使用 AI 来寻找查询的 意义,而不仅仅是关键词。🧠
它是如何工作的:技术宅模式 9000 🚀
接下来,让我们分步骤解析这个工具的代码。我们使用了一些很酷的库,比如 FAISS 用于索引,句子 Transformer 用于理解文档,还有 Ollama 的大语言模型(LLM),用来根据你的文件生成答案。
我会带你逐步了解这个设置的关键部分,因为说实话,细节决定成败。🧐
1. 基础设置🛠️
import os
import faiss
import numpy as np
from sentence_transformers import SentenceTransformer
import PyPDF2
import docx
from pptx import Presentation
import json
import streamlit as st
import ollama
我们导入了以下酷炫的库:
• FAISS:我们的索引冠军,处理快速相似性搜索。
• 句子 Transformer:将你的文件内容转换为向量嵌入。
• PyPDF2、docx、pptx:因为我们需要像专业人士一样处理所有文件类型。
• Streamlit:为工具提供一个即便是非技术宅也能使用的漂亮用户界面。
• Ollama:生成基于 AI 的精彩回答。
2. 初始化搜索引擎的大脑 🧠
model = SentenceTransformer('sentence-transformers/msmarco-bert-base-dot-v5')
dimension = 768
index = faiss.IndexFlatIP(dimension)
metadata = []
魔法开始的地方!我们加载了一个预训练的 BERT 模型,将你的文档转换为有意义的向量。然后我们设置 FAISS 来执行一些很酷的内积(IP)操作,以比较这些向量并找到相似的文本块。
• 768 维度:这是向量的维度数量。可以理解为每段文本有 768 个特征可以用来比较。
• FAISS 索引:存储和搜索这些向量的核心工具。
3. 读取你的所有文件📁
现在,我们需要从本地 PDF、DOCX、PPT 和纯文本文件中提取内容。📄🗂️
def read_pdf(file_path):
with open(file_path, 'rb') as file:
reader = PyPDF2.PdfReader(file)
return ' '.join([page.extract_text() for page in reader.pages])
def read_docx(file_path):
doc = docx.Document(file_path)
return ' '.join([para.text for para in doc.paragraphs])
def read_pptx(file_path):
prs = Presentation(file_path)
return ' '.join([shape.text for slide in prs.slides for shape in slide.shapes if hasattr(shape, 'text')])
每种文件类型都有其专属的读取函数 📚。我们循环读取内容,提取文本,并为索引做好准备 📜。
4. 专业文本分块✂️
为了获得更有效的搜索结果,我们需要将文档分割成较小的文本块。以下是实现方式:
def chunk_text(text, chunk_size=500, overlap=50):
words = text.split()
chunks = []
for i in range(0, len(words), chunk_size - overlap):
chunks.append(' '.join(words[i:i + chunk_size]))
return chunks
这个函数将文本分割为 500 个单词的块(稍有重叠),确保搜索结果既详细又易于管理。
5. 索引所有数据📊
这是魔法真正发生的地方!我们为每个文本块建立索引,以便稍后可以搜索。
def index_documents(directory):
global metadata
documents = []
for root, _, files in os.walk(directory):
for file in files:
content = ""
if file.endswith('.pdf'):
content = read_pdf(file_path)
elif file.endswith('.docx'):
content = read_docx(file_path)
elif file.endswith('.pptx'):
content = read_pptx(file_path)
if content:
chunks = chunk_text(content)
for i, chunk in enumerate(chunks):
documents.append(chunk)
metadata.append({"path": file_path, "chunk_id": i})
embeddings = model.encode(documents)
index.add(np.array(embeddings))
你可以输入一个查询,比如“我的项目截止日期是什么时候?”,引擎会返回与你的文件中相关的文本块——即使文件中没有明确提到“截止日期”这个词。这就是 AI 的魔力!
• 索引文档:读取文件,将其分块,并使用 BERT 模型生成嵌入。
• FAISS 索引:将所有嵌入存储在 FAISS 中,以高效处理搜索查询。
6. 搜索魔法🔍
当你输入搜索查询时,引擎会这样搜索你的文件:
def semantic_search(query, k=10):
query_vector = model.encode([query])[0]
distances, indices = index.search(np.array([query_vector]), k)
results = []
for idx in indices[0]:
meta = metadata[idx]
content = read_document_chunk(meta["path"], meta["chunk_id"])
results.append({"path": meta["path"], "content": content})
return results
• 语义搜索:将你的查询转换为嵌入,与所有文档嵌入进行比较,并返回最接近的匹配项。
• Top-K:返回基于相似度的前 10 个结果!
7. 使用 AI 生成答案🤖💬
你可以提出问题,而我们的 AI 小助手(使用 Ollama)会生成一个答案,并引用它参考的具体文档块。以下是实现方式:
def generate_answer(query, context):
prompt = f"""Answer the user's question using the documents given in the context..."""
response = ollama.generate(model='tinyllama', prompt=prompt)
return response['response']
它会读取你索引的文件,提取相关内容,生成一个智能答案。搞定——你现在有了一个聪明的 AI 助手!
8. Streamlit 用户界面魔法🎨✨
最后,我们用 Streamlit 构建了一个用户界面,使整个工具看起来既酷炫又易用。
def main():
st.markdown('<p class="big-font">本地生成式 AI 搜索 🔍</p>')
documents_path = st.text_input("📁 请输入你的文档文件夹路径:")
if st.button("🚀 索引文档"):
index_documents(documents_path)
question = st.text_input("🤔 你想知道什么?")
if st.button("🔍 搜索并回答"):
search_results = semantic_search(question)
answer = generate_answer(question, search_results)
st.markdown(f"### 🤖 AI 答案:\n{answer}")
• 输入框:用于输入文档文件夹路径和问题。
• 搜索按钮:触发引擎搜索索引文件。
• 答案显示:显示 AI 的回答以及相关文档。
总结
现在你有了一个完整的 本地文件生成式搜索引擎,它在你的电脑上运行,保护你的隐私,并利用开源模型的强大功能,从各种文件中搜索和回答问题。这就像拥有一个超级聪明的助手,能读取并理解你保存的所有内容——而无需依赖任何云服务。
现在,去让你的文件感受 AI 的力量吧!为什么要手动搜索,当你可以让机器为你做这件事呢?😎🖖
活水智能成立于北京,致力于通过AI教育、AI软件和社群提高知识工作者生产力。中国AIGC产业联盟理事。
活水现有AI线下工作坊等10+门课程,15+AI软件上线,多款产品在研。知识星球中拥有2600+成员,涵盖大厂程序员、公司高管、律师等各类知识工作者。在北、上、广、深、杭、重庆等地均有线下组织。
欢迎加入我们的福利群,每周都有一手信息、优惠券发放、优秀同学心得分享,还有赠书活动~
👇🏻👇🏻👇🏻





