哈尔滨做网站seo的网站地图分析工具
哈尔滨做网站seo的,网站地图分析工具,搭建企业网站,工信部域名备案查询PROJECT MOGFACE本地知识库构建#xff1a;从零开始搭建基于向量数据库的智能问答系统
你是不是也遇到过这样的烦恼#xff1f;公司里海量的技术文档、产品手册、会议纪要#xff0c;想找个答案得翻半天#xff0c;效率低不说#xff0c;还容易漏掉关键信息。或者#x…PROJECT MOGFACE本地知识库构建从零开始搭建基于向量数据库的智能问答系统你是不是也遇到过这样的烦恼公司里海量的技术文档、产品手册、会议纪要想找个答案得翻半天效率低不说还容易漏掉关键信息。或者你手头有一堆学习资料想快速定位某个知识点却感觉无从下手。今天我就带你亲手搭建一个属于自己的智能问答系统。它就像给你的文档装上一个“最强大脑”你问它问题它能立刻从你的资料库里找到最相关的信息并组织成清晰的答案告诉你。整个过程我们会用到PROJECT MOGFACE和一个开源的向量数据库完全私有化部署数据安全自己掌握。这个教程我会用最直白的话一步步拆解哪怕你之前没怎么接触过向量数据库也能跟着做出来。我们的目标很明确让你能跑通一个从文档处理到智能问答的完整流程。1. 动手之前先搞清楚我们要做什么在开始敲代码之前咱们先花几分钟把整个系统的“骨架”和“原理”摸清楚。这样后面每一步操作你都知道是在干什么为什么要这么干。想象一下你要建一个超级高效的图书馆。传统的图书馆靠书名、作者、分类号来找书而我们建的“智能图书馆”靠的是书里的“意思”来找书。核心流程其实就四步准备书籍数据预处理把各种格式PDF、Word、TXT的文档拆分成一段段有意义的文字方便后续处理。给每段文字做“指纹”文本向量化利用PROJECT MOGFACE这样的模型把一段文字转换成一大串数字向量。这个“数字指纹”神奇的地方在于意思相近的文字它们的“指纹”在数字空间里的位置也接近。建立“指纹”索引库向量索引构建把所有文档片段的“指纹”存进一个专门的数据库比如Milvus这个数据库特别擅长快速查找哪些“指纹”和给定的“指纹”最相似。问答与生成检索与回答当你提出一个问题系统先把问题也转换成“指纹”然后去索引库里快速找到最相似的几个文档片段这就是检索。最后把问题和这些找到的片段一起交给一个大语言模型比如PROJECT MOGFACE的对话能力让它组织成一个通顺、准确的答案。所以你看到的智能问答背后是“检索”和“生成”的强强联手。下面这张图清晰地展示了这个流程graph TD A[原始文档brPDF/Word/TXT] -- B[数据预处理br文本清洗与分割] B -- C[文本向量化br使用MOGFACE生成向量] C -- D[向量数据库br存储与构建索引] D -- E{用户提问} E -- F[将问题向量化] F -- G[向量相似度检索] G -- H[获取Top-K相关文本片段] H -- I[提示词工程br组合问题与上下文] I -- J[大语言模型生成br使用MOGFACE生成最终答案] J -- K[返回精准答案]整个系统的核心就是利用“向量”这把尺子去衡量文本之间的语义相似度。接下来我们就从零开始把这个系统搭建起来。2. 环境准备安装必要的工具和库工欲善其事必先利其器。我们先来把需要的软件和Python库准备好。我假设你已经在电脑上装好了Python建议3.8以上版本和pip。首先我们需要一个向量数据库。这里我选用Milvus因为它开源、性能好而且社区活跃。为了最简单快速地启动我们使用它的单机Docker版本。安装Docker如果你还没安装Docker请先去Docker官网根据你的操作系统下载并安装。拉取并运行Milvus打开终端或命令提示符运行下面这条命令。它会下载最新的Milvus单机版镜像并运行起来。docker run -d --name milvus-standalone \ -p 19530:19530 \ -p 9091:9091 \ -v ~/milvus/db:/var/lib/milvus/db \ -v ~/milvus/conf:/var/lib/milvus/conf \ -v ~/milvus/logs:/var/lib/milvus/logs \ -v ~/milvus/wal:/var/lib/milvus/wal \ milvusdb/milvus:latest运行成功后你可以用docker ps命令查看容器是否在运行。看到milvus-standalone就说明启动成功了。安装Python依赖库接下来我们创建一个项目文件夹并在里面安装必要的Python包。# 创建一个项目文件夹 mkdir mogface_knowledge_base cd mogface_knowledge_base # 创建并激活虚拟环境可选但推荐 python -m venv venv source venv/bin/activate # Linux/Mac # venv\Scripts\activate # Windows # 安装核心库 pip install pymilvus # Milvus的Python客户端 pip install sentence-transformers # 用来将文本转换成向量这里我们用它来模拟MOGFACE的嵌入能力 pip install langchain # 一个强大的LLM应用开发框架能帮我们简化很多流程 pip install langchain-community # LangChain的社区组件 pip install pypdf # 用于读取PDF文件 pip install python-docx # 用于读取Word文件 pip install tiktoken # 用于文本分词计算长度这里解释一下sentence-transformers库提供了很多优秀的文本向量化模型我们先用它来演示核心流程。在实际使用PROJECT MOGFACE时你需要替换成调用MOGFACE模型API或本地部署的相应代码。3. 第一步数据预处理——把原始文档“切”好你的知识库原料可能是PDF产品手册、Word技术文档或者纯文本文件。第一步就是把这些不同格式的文件统一转换成纯文本并切割成合适大小的“片段”。为什么不能把整本书直接扔进去因为大语言模型有输入长度限制而且太长的文本包含的信息可能太杂不利于精准检索。切割的原则是保持语义的完整性比如按段落、按章节或者按固定长度但不断句来切。我们来写一个预处理工具# file_processor.py import os from pathlib import Path from typing import List from pypdf import PdfReader from docx import Document class FileProcessor: def __init__(self, chunk_size: int 500, chunk_overlap: int 50): 初始化处理器 :param chunk_size: 每个文本块的最大字符数 :param chunk_overlap: 块之间的重叠字符数防止上下文断裂 self.chunk_size chunk_size self.chunk_overlap chunk_overlap def read_file(self, file_path: str) - str: 读取不同格式的文件返回纯文本 ext Path(file_path).suffix.lower() text try: if ext .pdf: reader PdfReader(file_path) for page in reader.pages: text page.extract_text() \n elif ext .docx: doc Document(file_path) for para in doc.paragraphs: text para.text \n elif ext in [.txt, .md]: with open(file_path, r, encodingutf-8) as f: text f.read() else: print(f暂不支持的文件格式: {ext}) return except Exception as e: print(f读取文件 {file_path} 时出错: {e}) return return text.strip() def split_text(self, text: str) - List[str]: 将长文本按大小和语义分割成块 if not text: return [] # 一个简单的按句子和长度分割的方法 sentences text.replace(\n, ).split(。) chunks [] current_chunk for sentence in sentences: sentence sentence.strip() 。 if len(current_chunk) len(sentence) self.chunk_size: current_chunk sentence else: if current_chunk: chunks.append(current_chunk) # 处理超长单句 if len(sentence) self.chunk_size: # 如果单句就超长按字符切分 for i in range(0, len(sentence), self.chunk_size - self.chunk_overlap): chunks.append(sentence[i:i self.chunk_size]) current_chunk else: current_chunk sentence if current_chunk: chunks.append(current_chunk) # 确保重叠简化版实际可用更复杂的滑动窗口 final_chunks [] for i in range(len(chunks)): start max(0, i - 1) context .join(chunks[start:i1])[-self.chunk_size:] # 简单模拟重叠上下文 final_chunks.append(context) return final_chunks def process_directory(self, dir_path: str) - List[dict]: 处理整个目录下的文档返回文本块列表 all_chunks [] for root, _, files in os.walk(dir_path): for file in files: if file.lower().endswith((.pdf, .docx, .txt, .md)): file_path os.path.join(root, file) print(f正在处理: {file_path}) raw_text self.read_file(file_path) chunks self.split_text(raw_text) for idx, chunk in enumerate(chunks): all_chunks.append({ id: f{Path(file_path).stem}_{idx}, # 简单生成ID text: chunk, source: file_path, chunk_index: idx }) print(f共处理完成 {len(all_chunks)} 个文本块。) return all_chunks # 使用示例 if __name__ __main__: processor FileProcessor(chunk_size300, chunk_overlap30) # 假设你的文档放在 ./docs 文件夹下 chunks processor.process_directory(./docs) for chunk in chunks[:2]: # 打印前两个看看效果 print(f来源: {chunk[source]}) print(f内容预览: {chunk[text][:100]}...\n)这个工具会遍历你指定文件夹下的文档把它们读出来切成一段段并且记录下每段文字来自哪个文件的哪一部分。这是构建知识库的原材料。4. 第二步文本向量化——给每段文字制作“数字指纹”有了文本块接下来就要用模型把它们变成向量。这里我们用sentence-transformers库里的一个轻量级模型all-MiniLM-L6-v2来演示。它速度快效果也不错适合本地运行。在实际项目中你可以替换为PROJECT MOGFACE提供的嵌入模型以获得更强大的语义理解能力。# embedding_model.py from sentence_transformers import SentenceTransformer import numpy as np class EmbeddingModel: def __init__(self, model_name: str all-MiniLM-L6-v2): 初始化向量化模型 :param model_name: 模型名称这里用一个小型模型做演示 print(f正在加载模型: {model_name}...) self.model SentenceTransformer(model_name) print(模型加载完毕。) def encode(self, texts: List[str]) - np.ndarray: 将文本列表编码为向量 :param texts: 文本字符串列表 :return: 向量数组形状为 [文本数量, 向量维度] if not texts: return np.array([]) # 转换为向量 embeddings self.model.encode(texts, convert_to_numpyTrue, show_progress_barTrue, normalize_embeddingsTrue) # 归一化方便后续计算余弦相似度 return embeddings # 使用示例 if __name__ __main__: from file_processor import FileProcessor # 1. 处理文档 processor FileProcessor(chunk_size300) chunks processor.process_directory(./docs) texts [chunk[text] for chunk in chunks] # 2. 生成向量 embedder EmbeddingModel() vectors embedder.encode(texts) print(f生成了 {len(vectors)} 个向量每个向量维度为 {vectors.shape[1]}。) print(f第一个向量的前10个值: {vectors[0][:10]})运行这段代码你会看到模型加载进度条然后输出向量的数量和维度。每个文本块现在都有一个对应的、代表其语义的“数字指纹”了。5. 第三步构建向量索引——把“指纹”存进智能库现在我们要把这些向量和它们对应的原始文本存到Milvus数据库里并建立索引以便快速检索。首先我们需要在Milvus里创建一个“集合”Collection这类似于数据库中的表用来定义数据的结构。# vector_store.py from pymilvus import connections, FieldSchema, CollectionSchema, DataType, Collection, utility import numpy as np class MilvusStore: def __init__(self, hostlocalhost, port19530, collection_nameknowledge_base): 初始化Milvus连接和集合 :param host: Milvus服务地址 :param port: Milvus服务端口 :param collection_name: 集合名称 self.host host self.port port self.collection_name collection_name self.collection None # 连接Milvus connections.connect(aliasdefault, hosthost, portport) print(f已连接到Milvus: {host}:{port}) self._create_collection_if_not_exists() def _create_collection_if_not_exists(self): 如果集合不存在则创建它 if utility.has_collection(self.collection_name): print(f集合 {self.collection_name} 已存在准备使用。) self.collection Collection(self.collection_name) else: print(f正在创建集合: {self.collection_name}) # 1. 定义字段 fields [ FieldSchema(nameid, dtypeDataType.VARCHAR, is_primaryTrue, max_length100), FieldSchema(nametext, dtypeDataType.VARCHAR, max_length65535), # 存储原始文本 FieldSchema(namesource, dtypeDataType.VARCHAR, max_length500), FieldSchema(nameembedding, dtypeDataType.FLOAT_VECTOR, dim384) # 维度需与你的模型匹配 ] # 2. 定义集合模式 schema CollectionSchema(fieldsfields, description本地知识库) # 3. 创建集合 self.collection Collection(nameself.collection_name, schemaschema) # 4. 为向量字段创建索引这是快速检索的关键 index_params { metric_type: COSINE, # 使用余弦相似度 index_type: IVF_FLAT, # 一种高效的索引类型 params: {nlist: 128} # 聚类中心数值越大精度越高但速度越慢 } self.collection.create_index(field_nameembedding, index_paramsindex_params) print(集合与索引创建成功。) def insert_data(self, chunks: List[dict], embeddings: np.ndarray): 将文本块和向量插入到Milvus中 :param chunks: 文本块字典列表包含id, text, source等 :param embeddings: 对应的向量数组 if not chunks or len(embeddings) 0: print(没有数据可插入。) return # 准备数据按字段分组 ids [chunk[id] for chunk in chunks] texts [chunk[text] for chunk in chunks] sources [chunk[source] for chunk in chunks] embedding_list embeddings.tolist() # 确保数据长度一致 min_len min(len(ids), len(texts), len(sources), len(embedding_list)) ids ids[:min_len] texts texts[:min_len] sources sources[:min_len] embedding_list embedding_list[:min_len] data [ids, texts, sources, embedding_list] # 插入数据 print(f正在插入 {min_len} 条数据...) insert_result self.collection.insert(data) print(f数据插入完成。) # 将数据从内存刷新到磁盘确保可搜索 self.collection.flush() print(f集合中现有实体数量: {self.collection.num_entities}) return insert_result def search(self, query_embedding: np.ndarray, top_k: int 5): 在集合中搜索最相似的向量 :param query_embedding: 查询问题的向量 :param top_k: 返回最相似的结果数量 :return: 搜索结果 # 在搜索前加载集合到内存 self.collection.load() search_params { metric_type: COSINE, params: {nprobe: 10} # 搜索时探查的聚类中心数 } # 执行搜索 results self.collection.search( data[query_embedding.tolist()], anns_fieldembedding, paramsearch_params, limittop_k, output_fields[id, text, source] # 指定要返回的字段 ) return results # 使用示例将前几步处理的数据存入Milvus if __name__ __main__: from file_processor import FileProcessor from embedding_model import EmbeddingModel # 1. 处理文档并生成向量 processor FileProcessor(chunk_size300) chunks processor.process_directory(./docs) texts [chunk[text] for chunk in chunks] embedder EmbeddingModel() vectors embedder.encode(texts) # 2. 存入Milvus store MilvusStore() store.insert_data(chunks, vectors) print(知识库数据构建完成)运行这段代码你的文档片段和它们的向量“指纹”就被安全地存储到本地的Milvus数据库里了并且建立了高效的索引随时准备回答你的问题。6. 第四步智能问答——让系统“开口说话”万事俱备只欠东风。现在我们来组装最后一步接收用户问题检索相关文档并生成答案。这里我们需要一个大语言模型来生成最终答案。为了演示我们使用一个本地运行的轻量级模型通过langchain的Ollama集成或者你也可以使用PROJECT MOGFACE的对话API。首先确保你有一个能用的LLM。这里以使用Ollama运行qwen2.5:7b模型为例你需要先安装Ollama并拉取该模型。# qa_system.py from typing import List import numpy as np from embedding_model import EmbeddingModel from vector_store import MilvusStore from langchain_community.llms import Ollama from langchain.prompts import PromptTemplate from langchain.chains import LLMChain class QASystem: def __init__(self, embedding_model: EmbeddingModel, vector_store: MilvusStore, llm_model_nameqwen2.5:7b): 初始化问答系统 :param embedding_model: 向量化模型 :param vector_store: 向量数据库存储 :param llm_model_name: 使用的LLM模型名称 self.embedding_model embedding_model self.vector_store vector_store # 初始化语言模型 self.llm Ollama(modelllm_model_name, temperature0.1) # temperature低一点答案更确定 print(f语言模型 {llm_model_name} 已加载。) # 定义一个提示词模板告诉LLM如何利用检索到的上下文回答问题 self.prompt_template PromptTemplate( input_variables[context, question], template请根据以下上下文信息回答用户的问题。如果上下文信息不足以回答问题请直接说“根据提供的信息我无法回答这个问题”不要编造信息。 上下文信息 {context} 用户问题{question} 请给出准确、简洁的答案 ) self.chain LLMChain(llmself.llm, promptself.prompt_template) def ask(self, question: str, top_k: int 3) - str: 核心问答函数 :param question: 用户问题 :param top_k: 检索最相关的文档片段数量 :return: 生成的答案 print(f用户提问: {question}) # 1. 将问题转换为向量 print(正在将问题转换为向量...) query_vector self.embedding_model.encode([question])[0] # 2. 在向量数据库中检索相似内容 print(f正在数据库中检索最相关的 {top_k} 个片段...) search_results self.vector_store.search(query_vector, top_ktop_k) if not search_results or not search_results[0]: return 抱歉知识库中没有找到相关信息。 # 3. 组装检索到的上下文 contexts [] for hits in search_results: for hit in hits: context_text hit.entity.get(text) source hit.entity.get(source) score hit.score # 相似度分数 contexts.append({ text: context_text, source: source, score: score }) print(f[相似度: {score:.3f}] 来源: {source}) print(f 片段: {context_text[:150]}...\n) # 将所有上下文文本合并作为LLM的输入 context_for_llm \n\n.join([c[text] for c in contexts]) # 4. 调用LLM结合上下文生成答案 print(正在生成答案...) answer self.chain.run(contextcontext_for_llm, questionquestion) return answer.strip() # 主程序串联所有步骤 if __name__ __main__: # 初始化各个组件 print( 初始化智能问答系统 ) embedder EmbeddingModel() store MilvusStore() qa_system QASystem(embedder, store) print(\n 系统准备就绪可以开始提问 ) print(输入 exit 或 quit 退出程序。) while True: user_question input(\n请输入你的问题: ).strip() if user_question.lower() in [exit, quit]: print(再见) break if not user_question: continue # 获取答案 answer qa_system.ask(user_question) print(f\n【系统回答】\n{answer}\n)运行这个程序它会加载所有组件然后进入一个循环等待你提问。你可以试试问一些你文档里肯定有的内容比如“产品的核心功能是什么”或者“如何安装XXX”。系统会先找到最相关的文档片段然后让大模型“阅读”这些片段并组织成答案。7. 总结与下一步跟着上面这些步骤走下来一个本地的、基于向量数据库的智能问答系统就初具雏形了。整个过程从文档处理、向量化、存储到检索生成我们亲手搭建了一条完整的流水线。用下来的感觉是对于企业内部文档、个人知识库这类场景这种方案确实能大幅提升信息检索的效率。你不用再记住文件在哪、关键词是什么直接用自然语言去问就行。Milvus的检索速度很快即使文档量大了体验也依然流畅。当然这只是一个起点。如果你想让它更强大、更实用还可以从这些方面继续探索尝试更强的模型把演示用的文本向量模型和对话模型替换成PROJECT MOGFACE家族中更强大的版本效果会有显著提升。优化文本分割试试更智能的分割方法比如按语义分割langchain的RecursiveCharacterTextSplitter就很好用能更好地保持上下文。加入元数据过滤检索时不仅可以按内容相似度找还可以加上“文档类型”、“部门”、“日期”等条件进行过滤。设计更复杂的问答链比如让模型先判断问题是否需要检索或者对检索结果进行重排序Rerank以提高精度。构建Web界面用Gradio或Streamlit快速做一个聊天界面让非技术同事也能方便使用。最重要的是你现在有了一个完全在自己掌控之中的知识库系统。数据安全流程透明可以根据自己的需求随意定制。希望这个教程能帮你打开一扇门后面更精彩的世界就等你去探索了。获取更多AI镜像想探索更多AI镜像和应用场景访问 CSDN星图镜像广场提供丰富的预置镜像覆盖大模型推理、图像生成、视频生成、模型微调等多个领域支持一键部署。