
我一直坚信一件事:企业的知识不是问题,找到知识才是问题。
尤其是信息孤岛林立、知识文档散落在各业务系统的企业中,员工在寻找答案的时间,可能比解决问题本身还久。这不禁让我思考:有没有一种方式,能让大家像用ChatGPT一样,在公司内部随时提问,立刻获得准确、专业的回答?
于是,我决定动手搞一套企业级知识库问答系统,目标是让它支持自然语言提问,基于我们企业已有的文档、数据库、业务流程知识自动回答问题。
整套系统基于RAG(Retrieval-Augmented Generation)检索增强生成架构构建,从零开始搭建,实现从数据采集、向量化、知识存储、再到调用大模型生成回答的完整闭环。
这篇文章就来给你讲讲我这一路踩过的坑,遇到的挑战,以及最终如何完成上线这套系统的!
我们整个系统大致分为以下几个模块:
用户提问 --> 问题预处理 --> 检索相似文档(向量检索) --> 构建Prompt --> 调用LLM生成回答 --> 返回用户核心组件:
我一开始就遇到第一个现实问题:企业知识数据不统一,格式五花八门。
于是,我写了一个多格式文档解析模块,用 unstructured + PyMuPDF 来处理 PDF,Word 用 python-docx,网页信息用 BeautifulSoup。
from unstructured.partition.auto import partition
from pathlib import Path
def extract_text(file_path):
elements = partition(filename=file_path)
return "\n".join([el.text for el in elements if el.text.strip() != ""])
text = extract_text("example_docs/财务制度.pdf")针对网页类的知识,我还加了一段代码自动去重广告、侧边栏等“噪音”内容。
from bs4 import BeautifulSoup
import requests
def scrape_clean_text(url):
resp = requests.get(url)
soup = BeautifulSoup(resp.text, 'html.parser')
[s.extract() for s in soup(['script', 'style', 'footer', 'nav'])]
return soup.get_text(strip=True)
html_text = scrape_clean_text("https://intranet.company.com/rules")✍️ 小心得:千万别小看“数据清洗”,否则垃圾进垃圾出(Garbage In, Garbage Out)!
数据准备好后,下一步就是把它转成“模型能理解的向量”。
我选择了 OpenAI 的 text-embedding-3-small 模型来生成 Embedding(也可替换为 HuggingFace 模型如 bge-small-zh-v1.5)。
from openai import OpenAI
import numpy as np
client = OpenAI(api_key="你的API_KEY")
def get_embedding(text):
res = client.embeddings.create(
input=text,
model="text-embedding-3-small"
)
return np.array(res.data[0].embedding)生成向量之后,我们使用 FAISS 构建索引:
import faiss
dimension = 1536 # 向量维度,取决于embedding模型
index = faiss.IndexFlatL2(dimension)
# 假设我们有多个文本段的向量
vectors = np.array([get_embedding(chunk) for chunk in documents])
index.add(vectors)并将 text -> vector 的映射关系存入持久化存储中(我用 SQLite + json 文件组合)。
当用户输入问题后,我们首先对问题生成Embedding,然后在 FAISS 里检索最相关的文档段落。
def retrieve_docs(query, k=5):
query_vec = get_embedding(query).astype('float32')
D, I = index.search(query_vec.reshape(1, -1), k)
return [documents[i] for i in I[0]]接着,把检索结果和用户问题拼接为 Prompt,喂给大模型:
def build_prompt(question, docs):
context = "\n".join([f"文档片段{i+1}:{doc}" for i, doc in enumerate(docs)])
return f"""你是一个企业内部的知识助手,请根据以下内容回答问题:
{context}
问题:{question}
请用简洁、准确的语言回答:"""
prompt = build_prompt("公司财务报销流程是怎样的?", retrieve_docs("财务报销流程"))最终调用 LLM:
res = client.chat.completions.create(
model="gpt-4",
messages=[{"role": "user", "content": prompt}]
)
print(res.choices[0].message.content)为了更快实现原型,我用 LangChain 封装了整个问答链条,还用 Streamlit 搭了一个小前端,供业务同事试用。
import streamlit as st
st.title("企业知识库问答系统")
query = st.text_input("请输入你的问题:")
if query:
docs = retrieve_docs(query)
prompt = build_prompt(query, docs)
answer = client.chat.completions.create(
model="gpt-4",
messages=[{"role": "user", "content": prompt}]
).choices[0].message.content
st.write("### 回答:")
st.write(answer)运行后,我们的同事们可以在浏览器中直接提问,如“请问最新的报销标准是怎样的?”系统会从公司制度文档中提取答案,几乎秒回。
这套系统上线后,最让我惊喜的是:它不仅帮新人学习制度,也成了老员工查规范的工具。
以前动辄“去群里问”“等主管回话”的情况大大减少,大家渐渐养成了“自己提问自己找”的习惯。而且,基于文档的回答有出处、可追溯,避免了“道听途说”。
当然,也不是一帆风顺。比如:
但总的来说,RAG 架构非常适合企业内部知识问答场景。相比直接喂大模型“公司百科”,RAG既能动态更新知识,又能节省token成本。
我一直相信一句话:数据无用不是因为它不值钱,而是因为它没人用。
企业知识很多时候“躺在硬盘上吃灰”,而一个RAG架构的问答系统,恰好能让这些沉睡的知识重新活过来,帮我们提升效率、减少沟通成本。
这只是一个起点,未来我还想加上权限控制、知识更新自动化、支持流程图解析等功能。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。