项目背景
作为一个SRE工程师,平常会经常遇到下面这些几种痛点问题:
- 故障信息定位难:当线上系统出现紧急故障时,对应的解决方案往往散落在海量的PDF、Word文档或Wiki页面中。在巨大的时间压力下,通过传统关键词搜索来定位准确信息,效率低下且过程痛苦。
- 问题排查强依赖个人经验:许多资深工程师的排障经验和技巧,并未被完整地文档化。这些宝贵的“隐性知识”很容易随着人员的变动而流失,导致团队整体技术水平难以有效沉淀和提升。
- 知识更新不及时:业务和系统架构在快速迭代,但配套的运维文档却常常疏于更新。依赖过时的信息进行操作,不仅无助于解决问题,有时甚至会引发新的风险。
现有的知识库系统,大多扮演着“数字文件柜”的角色,检索能力有限,无法真正融入到快节奏的运维工作流中。
为何不直接使用通用大模型?
一个直接的想法是:能否将问题抛给强大的通用大模型来解决?经过一些实践,至少目前是此路不通。在业务私有知识场景下,通用大模型存在三个大问题:: - 私有知识的缺失与“AI幻觉”:通用模型的知识库源于公开的互联网数据,并且有明确的知识截止日期。它对企业内部的、非公开的实时信息(如:特定服务器的配置、近期的故障复盘报告)一无所知。直接向其提问,结果很可能是拒绝回答,或是更糟的——模型会依据其通用知识“推测”出一个看似合理但事实错误地答案,即“AI幻觉”。在要求精准的运维领域,这是不可接受的。
- 数据安全与隐私的红线:运维知识库包含了大量企业核心资产和敏感信息。将这些数据传输给任何外部的云服务商,都意味着严重的数据泄露风险,这与绝大多数企业的数据安全规范背道而驰。
- 答案的可靠性与可追溯性缺失:通用大模型像一个“黑盒”,它给出的答案,我们无法验证其信息来源。当一个操作建议导致意外结果时,我们无从追溯这个建议是基于哪篇官方文档或最佳实践,这在要求操作有据可依的运维场景下是致命的。
做出尝试:RAG与本地化部署的结合
为了解决上述问题,我们采用了检索增强生成(RAG)架构,并坚持完全本地化部署的技术路线。
这个方案的核心思路是“先检索,后生成”: - 检索(Retrieval):当用户提出问题时,系统并不直接去问大模型。而是先利用向量搜索技术,在企业内部的私有知识库中,找到与问题语义最相关的几个知识片段。
- 生成(Generation):然后,系统将这些检索到的、包含事实依据的知识片段作为“参考资料”,连同用户最初的问题,一起提交给一个部署在内网的大语言模型(我在测试用的是本地LM Studio部署的Qwen3 VL 4B模型),并要求它基于这些资料来组织和生成答案。
这种模式的价值在于: - 它限定了LLM的信息来源,确保答案建立在企业内部的可信数据之上,有效避免了“AI幻觉”。
- 所有数据处理和模型计算都在企业内网完成,根除了数据泄露的风险。
- 由于“参考资料”是我们自己提供的,因此我们能清晰地向用户展示答案的出处,实现了完全的可追溯性。
系统设计与实现
- 整体架构图
系统采用分层设计,确保各模块职责清晰,易于维护和扩展。
- 核心流程图
下面这张图,清晰地展示了“文档入库”和“智能问答”这两条核心链路是如何运转的。
- 部分实现细节
3.1 文本切分 (Text Splitting)
将长文档切分为合适的知识片段(Chunks),是保证检索质量的前提。我们针对不同类型的文档,采用了不同的切分策略: - 对于PDF、Word等非结构化文档:我们使用RecursiveCharacterTextSplitter。它会智能地按照段落、句子、标点等语义边界进行递归切分,最大限度地保留了文本的自然结构。
对于Excel、CSV等结构化文档:我们定制了RowBasedTextSplitter。该切分器按行处理数据,并将表头信息附加到每个数据块中,确保了表格数据行的语义完整性,避免了将一条记录错误地分割到不同片段中。
3.2 向量化 (Vectorization)
向量化是将文本转换为机器能够理解的数学表示形式。当前项目使用的BAAI/bge-small-zh-v1.5模型作为向量化引擎,主要因为它在中文语义理解任务上表现出色,同时模型体量适中,适合在CPU环境下部署。
在技术实现上,我们将文本片段输入该模型,生成512维的向量。这个过程可以理解为,在数学空间中为每个知识片段赋予一个独特的“语义坐标”。语义相近的片段,其空间坐标也更接近。
3.3 RAG调度器与Prompt工程
系统的核心是RAGOrchestrator,它负责调度整个问答流程。其中,最关键的设计在于如何构建Prompt来引导大语言模型。
设计的时候没有让LLM进行无约束的输出,而是为它设计了一个类似“开卷考试”的场景。关键的Prompt模板如下RAG Prompt 模板
RAG_PROMPT_TEMPLATE = """你是一个专业的知识库助手,基于以下上下文信息回答用户问题。
上下文信息(已按来源编号):
{context_with_citations}
用户问题:{question}
请基于上下文信息提供准确、详细的回答。如果上下文中没有相关信息,请明确说明。
重要要求:
- 在回答中,当你引用某个上下文片段时,必须在相应位置标注来源编号,格式如 [1], [2] 等
- 每个引用编号必须对应上下文中的实际编号
- 不要编造不存在的引用编号
- 如果某个信息来自多个来源,可以标注多个编号,如 [1,2]
回答:
"""
通过这种方式,我们将一个开放式的问题,转化成了一个有明确范围和约束的“阅读理解”任务。LLM的角色从一个“全知的创造者”转变为一个“高效的信息整合与总结者”,这极大地提升了答案的准确性和可靠性。
实现的效果
- 文档导入 & 创建索引


- 已上传/索引的文档管理

- 问题检索
当前对于特定内容的查询,可完全以文档库内容为主,不存在的内容直接输出无实际引用资料,这样彻底避免大模型乱讲话、随便联想的问题。

当前方案的价值与意义
虽然这只是一个初步的探索性项目,但在当前阶段,该方案展现了其重要的现实意义: - 提供了可行的本地化解决方案:它解决了一个核心问题——如何在保障数据安全的前提下,利用大模型能力赋能企业内部知识管理。
- 确保了答案的可靠性与可追溯性:通过RAG架构,每个答案都能追溯到具体的内部文档来源,这为要求严谨、操作需负责的运维场景提供了必要的信任基础。
- 满足了基本的安全合规要求:所有组件和数据均在内网运行,没有任何信息与外部交互,满足了企业对数据隐私和安全的基本要求。
- 积累了宝贵的工程实践经验:通过该项目,我们完整地实践了数据处理、向量索引、异步任务调度等一系列AI工程化链路,为未来更复杂的应用场景奠定了基础。
问题与局限性
站在一个研发、运维视角,目前的系统还存在一些待解决的问题:
- 检索精度有待提升:当前单纯依赖语义相似度的检索方式,在处理包含特定错误码、专有缩写的查询时,可能会遗漏掉一些关键词精确匹配的重要结果。
- 上下文窗口大小固定:系统目前采用固定的top_k参数来召回知识片段。这种策略不够灵活,面对简单问题时可能引入过多无关信息,干扰模型判断;面对复杂问题时又可能因信息不足而无法给出全面答案。
- 对用户查询的鲁棒性不足:系统直接使用用户的原始输入进行检索,缺乏对口语化、模糊或包含错别字的查询进行优化和理解的能力。
- 缺少评估与反馈的闭环:系统目前缺乏一套有效的机制来客观评估答案的质量,也缺少用户反馈渠道(如“有用/没用”评级),这使得系统的优化方向不够明确。
可以优化的方向
下面也是针对上述问题的一些优化方向,未来可能会继续改进
- 引入重排序(Re-ranking)模块:在初步检索召回Top-K个候选片段后,使用一个更精细的排序模型(如Cross-Encoder)进行二次排序,将最相关的片段置顶,以提升最终答案的质量
- 实现查询缓存:利用Redis对已回答过的问题及其结果进行缓存,降低高频查询的响应延迟和计算成本。
- 增加查询改写(Query Rewriting):在检索前,利用LLM对用户的原始查询进行分析和改写,生成更清晰、更适合检索的查询语句。
- 探索混合检索(Hybrid Search):结合向量检索的语义理解能力和传统关键词检索(如BM25)的精确匹配能力,实现更全面的信息召回
项目总结与思考
这次尝试不仅是完成一个软件项目,更是一次在真实业务场景中对AI技术边界和落地路径的探索。
- RAG的定位:一个简单且务实的“过渡方案”。 RAG架构的本质,是在当前大模型自身能力(如私有知识注入、杜绝幻觉)尚不完美的情况下,一种简单有效的“辅助”或“外挂”系统。它通过为大模型提供一个开卷考试的环境,让LLM在可控的范围内发挥其强大的归纳和生成能力,站在一个专业的运维视角来看,当前的整体表现还不能够称之为满意,存在的问题比较多,但是整体对于我们了解大模型和应用大模型提供了另一种思路。
- 对未来的展望:终将有超强模型能完全解决上述痛点。 我对大模型技术本身的发展抱有充分的信心。可以预见,随着模型能力的提升、模型短期记忆的增强、上下文窗口的极大扩展以及私有化部署成本的降低,未来更先进的模型或许能直接“学习”并理解整个企业的知识体系。到那时,当前这种复杂的RAG工程链路可能会被大大简化,甚至被模型自身的能力所取代。
暂无评论
评论已关闭。