构建企业级知识库问答:基于InternLM2-Chat-1.8B与向量数据库
构建企业级知识库问答:基于InternLM2-Chat-1.8B与向量数据库
你有没有遇到过这种情况?公司新来的同事,面对堆积如山的项目文档、产品手册和会议纪要,想找个具体问题的答案,却像大海捞针一样,半天也找不到。或者,客服同学每天要回答大量重复的问题,虽然答案就在知识库里,但就是没法快速、准确地调出来。
这其实就是企业内部信息管理的一个普遍痛点:知识明明就在那里,却用不起来。今天,我们就来聊聊怎么用现在很火的AI大模型和向量数据库,亲手搭建一个能“听懂人话”、能“精准回答”的企业级智能知识库问答系统。你不用是AI专家,跟着思路走,就能理解这套方案是怎么运转的,以及它能给你的团队带来什么实实在在的好处。
1. 为什么需要智能知识库?从痛点说起
想象一下,你们公司有一份上百页的产品技术白皮书,或者一个不断更新的客服问题清单。传统的搜索方式,比如用关键词在文档里“Ctrl+F”,局限性很大。如果用户问“这个产品支持哪些安全协议?”,而文档里写的是“支持TLS 1.2和1.3”,关键词对不上,可能就搜不到。更别提那些需要综合多段信息才能回答的复杂问题了。
这就是传统检索的“词汇鸿沟”问题——用户的问题表述和文档里的专业表述,往往对不上。而我们要做的智能知识库,核心目标就是跨越这个鸿沟。它不再只是机械地匹配关键词,而是去理解问题的语义,也就是真正的意图。
这套方案的基本思路很直观,就像一个有超强记忆力和理解力的助手:
- 知识入库:我们把所有文档(Word、PDF、TXT等)打碎成一段段有意义的文本,然后把每一段文本转换成计算机能理解的“数学向量”(这个过程叫嵌入),存进一个特殊的数据库(向量数据库)。
- 智能问答:当用户提问时,我们把问题也转换成向量,然后去数据库里快速找出“意思最接近”的那些文本片段。
- 组织答案:最后,让AI大模型(比如InternLM2-Chat-1.8B)充当一个聪明的“信息整理官”,它阅读这些检索到的相关片段,组织成通顺、准确、完整的答案,回复给用户。
这样一来,无论用户怎么问,只要知识库里有过类似意思的内容,系统就能找到并生成答案。下面,我们就拆开看看每个环节具体怎么做。
2. 核心组件选择:轻量模型与高效数据库
搭建这个系统,我们需要两个核心“引擎”:一个负责理解并生成答案的AI模型,一个负责快速查找相似内容的数据库。
对于AI模型,我们选择了InternLM2-Chat-1.8B。你可能会问,现在动辄百亿、千亿参数的大模型那么多,为什么选一个1.8B的“小模型”?原因很简单:务实。
- 够用就好:在企业内部知识问答这个场景下,模型的核心任务不是天马行空地创作,而是基于给定的文本片段,进行准确的信息提取、总结和重组。一个经过精心微调的1.8B模型,完全能胜任这项工作,而且效果相当不错。
- 成本友好:小模型对计算资源(GPU内存、算力)的要求低得多。这意味着你可以在性价比更高的服务器上部署,甚至用消费级显卡来跑,大大降低了硬件门槛和长期运营的电力成本。
- 响应迅速:参数少,推理速度自然就快。这对于需要实时交互的问答系统来说,体验上的提升是巨大的,用户不用等待太久。
- 易于掌控:模型越小,微调、部署和优化的可控性就越强。企业内部的数据往往涉及商业机密,使用开源的小模型,在数据隐私和安全上也更让人放心。
InternLM2-Chat-1.8B就是一个在中文对话上表现突出的开源小模型,它经过了大量的指令微调,非常擅长遵循指令、理解上下文并生成符合要求的回复,正好契合我们“基于文档片段生成答案”的需求。
对于向量数据库,我们以Chroma为例。向量数据库是专门为存储和检索向量数据而设计的。它的核心能力是“相似性搜索”,能以极快的速度,从海量向量中找到与目标向量最相似的那一批。Chroma是一个轻量级、易用且功能强大的开源向量数据库,特别适合快速原型验证和中小规模的应用。
它用起来很简单,提供了友好的Python API,几行代码就能完成客户端的连接、集合(相当于表)的创建、向量的插入和查询。对于刚开始尝试的企业来说,Chroma是一个绝佳的起点。当然,如果你的数据量非常庞大,对性能要求极高,也可以考虑像Milvus这样的分布式向量数据库,其架构设计能应对更严苛的数据库课程设计场景,但初期使用复杂度也会稍高一些。
3. 实战四步走:搭建你的智能知识库
理论说完了,我们来看看具体怎么动手。整个过程可以清晰地分为四个步骤。
3.1 第一步:准备知识原料——文档加载与切片
你的原始文档可能是各种格式。我们需要先把它们统一转换成纯文本。可以使用像langchain这样的社区工具库,它集成了多种文档加载器。
from langchain.document_loaders import DirectoryLoader, TextLoader, PyPDFLoader # 假设你的文档放在 ./knowledge_docs 目录下 loader = DirectoryLoader('./knowledge_docs', glob="**/*.pdf", # 加载所有PDF,也可用 "**/*.txt" 等 loader_cls=PyPDFLoader) # 指定PDF加载器 documents = loader.load() print(f"共加载了 {len(documents)} 份文档")拿到长文档后,不能直接整个扔进去,那样检索会不精准,模型处理起来也困难。我们需要进行“切片”,把文档切成一段段语义相对完整的小块。
from langchain.text_splitter import RecursiveCharacterTextSplitter # 创建文本分割器 text_splitter = RecursiveCharacterTextSplitter( chunk_size=500, # 每个片段大约500字符 chunk_overlap=50, # 片段间重叠50字符,避免上下文断裂 separators=["\n\n", "\n", "。", "!", "?", ";", ",", " ", ""] # 按此优先级分割 ) # 对加载的文档进行切片 all_splits = text_splitter.split_documents(documents) print(f"文档被切分为 {len(all_splits)} 个文本片段。")这里的关键是chunk_size(片段大小)和chunk_overlap(重叠长度)的设置,需要根据你文档的特点(如技术文档句子长,客服QA句子短)进行微调,目标是让每个切片都能独立表达一个相对完整的意思。
3.2 第二步:将文本转化为“向量指纹”——嵌入与存储
接下来,我们要把这些文本片段变成向量。需要一个“嵌入模型”来完成这个任务。你可以使用在线的API(如OpenAI的text-embedding-ada-002),也可以部署一个开源的本地模型(如bge-small-zh)。这里为了演示完整性,我们假设使用一个本地嵌入模型。
同时,我们初始化Chroma向量数据库,并将向量存储进去。
from langchain.embeddings import HuggingFaceEmbeddings from langchain.vectorstores import Chroma # 1. 初始化嵌入模型(这里以开源模型为例,需要提前下载) embed_model = HuggingFaceEmbeddings( model_name="BAAI/bge-small-zh-v1.5", # 一个优秀的中文嵌入模型 model_kwargs={'device': 'cpu'}, # 使用CPU,若有大内存GPU可改为'cuda' encode_kwargs={'normalize_embeddings': True} # 归一化向量,有利于相似度计算 ) # 2. 指定向量数据库的持久化目录 persist_directory = './chroma_db' # 3. 将文本切片转换为向量,并存入Chroma vectordb = Chroma.from_documents( documents=all_splits, embedding=embed_model, persist_directory=persist_directory ) # 4. 持久化保存 vectordb.persist() print("向量数据已成功存入Chroma数据库。")执行完这一步,你的知识库的“记忆体”就构建好了。所有文档内容都以向量的形式,整整齐齐地躺在数据库里,等待被检索。
3.3 第三步:从海量记忆中精准定位——相似性检索
当用户提出一个问题时,系统首先进行检索。这个过程就是把用户问题也转换成向量,然后在向量数据库里进行“相似度计算”,找出最相关的几个文本片段。
# 用户提问 query = "我们产品的数据加密采用了什么标准?" # 在已创建的向量库中进行相似性搜索 retriever = vectordb.as_retriever(search_kwargs={"k": 3}) # 检索最相关的3个片段 relevant_docs = retriever.get_relevant_documents(query) print(f"针对问题 '{query}',检索到 {len(relevant_docs)} 个相关片段:") for i, doc in enumerate(relevant_docs): print(f"\n--- 片段 {i+1} (相关性得分: {doc.metadata.get('score', 'N/A')}) ---") print(doc.page_content[:200] + "...") # 打印前200字符预览检索到的relevant_docs就是我们给大模型准备的“参考资料”。检索的质量直接决定了最终答案的上限,因此嵌入模型的好坏和切片是否合理至关重要。
3.4 第四步:组织信息,生成最终答案——大模型合成
最后一步,我们把用户的问题和检索到的参考资料,一起交给InternLM2-Chat-1.8B模型,让它生成最终答案。这里我们需要构建一个“提示词”(Prompt),来引导模型如何利用这些资料。
from langchain.llms import HuggingFacePipeline from transformers import AutoTokenizer, AutoModelForCausalLM, pipeline import torch # 1. 加载InternLM2-Chat-1.8B模型与分词器(假设模型已下载至本地路径) model_path = "./models/InternLM2-Chat-1.8B" tokenizer = AutoTokenizer.from_pretrained(model_path, trust_remote_code=True) model = AutoModelForCausalLM.from_pretrained(model_path, torch_dtype=torch.float16, device_map="auto", trust_remote_code=True) # 2. 创建文本生成管道 pipe = pipeline("text-generation", model=model, tokenizer=tokenizer, max_new_tokens=512, # 生成答案的最大长度 temperature=0.1, # 较低的温度使输出更确定、更基于事实 do_sample=True) llm = HuggingFacePipeline(pipeline=pipe) # 3. 构建提示词模板 from langchain.prompts import PromptTemplate prompt_template = """基于以下提供的上下文信息,请专业、准确地回答用户的问题。如果上下文信息不足以回答问题,请直接说“根据现有资料无法回答该问题”,不要编造信息。 上下文信息: {context} 用户问题:{question} 请根据上下文信息回答:""" PROMPT = PromptTemplate( template=prompt_template, input_variables=["context", "question"] ) # 4. 组装检索到的上下文 context = "\n\n".join([doc.page_content for doc in relevant_docs]) # 5. 格式化提示词并请求模型生成答案 formatted_prompt = PROMPT.format(context=context, question=query) answer = llm(formatted_prompt) print("\n=== 生成的答案 ===\n") print(answer)这个提示词模板清晰地告诉模型:你的回答必须严格基于我提供的“上下文信息”。这有效限制了模型的“幻觉”(即编造不存在的信息),让它的回答牢牢扎根于你的企业知识库。
4. 让系统更智能:进阶优化思路
走通上述四步,一个最基础的智能问答系统就搭建完成了。但要让它在企业环境中真正好用,我们还可以从以下几个方面进行优化:
- 检索优化:单纯的向量相似度检索有时会漏掉关键信息。可以结合“关键词检索”(如BM25)进行混合检索,取长补短。还可以对检索结果进行重排序,把质量最高的片段排在前面。
- 提示词工程:精心设计提示词能让模型发挥得更好。比如,在提示词中明确要求答案包含引用来源的片段编号,增加答案的可追溯性;或者要求答案以要点列表的形式呈现,提高可读性。
- 对话记忆:实现多轮对话,让系统能记住之前的聊天历史,理解像“上面提到的那个协议,具体版本号是多少?”这样的指代性问题。这通常通过维护一个对话历史缓冲区来实现。
- 知识库更新与评估:建立知识库的定期更新机制。同时,设计评估体系,通过人工抽查或自动化测试(如验证答案是否包含某个关键词),来监控问答系统的准确率,持续迭代优化。
5. 总结
回过头看,我们基于InternLM2-Chat-1.8B和Chroma向量数据库构建的企业知识库问答系统,本质上是在做一件事:让静态的知识“活”起来,以最自然的方式(问答)服务于人。
这套方案的优势很明显。它成本可控,利用开源的小模型和工具链,技术门槛和硬件投入都不高。效果直接,能够理解语义,回答的准确度和相关性远胜传统关键词搜索。而且,它把知识的管理和使用流程自动化了,从文档入库到智能问答,形成了一个闭环。
当然,在真正部署到生产环境时,还会遇到更多工程上的挑战,比如如何设计一个友好的前端界面,如何管理用户权限,如何应对高并发请求等等。但这些都属于数据库课程设计和系统架构的范畴了,有了今天这个坚实的AI核心,那些外围的搭建就有了明确的方向。
如果你正被企业内部的知识检索问题困扰,不妨就从一个小型的、特定的文档集开始尝试。比如,先为某个技术团队的产品手册搭建一个原型。当你看到模型能快速、准确地回答出那些曾经需要翻半天文档才能找到的问题时,你就会真切地感受到,技术是如何实实在在地提升效率、解放人的。
获取更多AI镜像
想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。
