news 2026/8/28 11:11:12

基于RAG与向量数据库的智能问答系统构建实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
基于RAG与向量数据库的智能问答系统构建实战

简介:检索增强生成(RAG)技术通过将外部知识库与大语言模型结合,有效解决了模型幻觉与知识更新难题。其核心原理在于将文档向量化存储,通过语义检索匹配用户问题与相关知识片段,再交由大模型生成精准答案。这一架构在专业领域问答、智能客服与教育辅助等场景中极具技术价值,尤其适用于需要高准确性与可溯源性的场景。本文以构建一个计算机考研408智能问答系统为例,详细解析了从文档处理、向量化存储到语义检索与提示工程的全流程实践,并针对常见问题如“api error: 400”及检索优化提供了具体解决方案。

1. 项目概述:一个为408考研人量身定制的“AI助教”

如果你正在准备计算机专业考研的408统考科目,面对数据结构、计算机组成原理、操作系统、计算机网络这四座大山,以及海量的教材、真题、笔记和辅导资料,是不是经常感到无从下手?知识点零散、问题找不到精准答案、复习效率低下是很多考生的痛点。我最近用业余时间,结合当下最热的RAG(检索增强生成)技术和大模型API,动手搭建了一个专为408考研设计的智能问答与学习辅助系统。这个系统的核心目标很简单:让你像有一个24小时在线的学霸助教,能瞬间从所有复习资料里找到最相关的知识,并用清晰、准确、易懂的方式回答你的任何疑问。

这个项目不是简单的关键词匹配搜索,而是通过建立所有408资料的“向量数据库”,让机器真正“理解”你问题的语义。比如,你问“虚拟内存和覆盖技术的区别是什么?”,系统不会只是返回包含“虚拟内存”和“覆盖”字样的段落,而是能理解这两个概念都属于内存管理范畴,并进行对比性解答。背后支撑的,是智谱清言(ChatGLM)大模型强大的理解与生成能力,以及RAG技术带来的“知识外挂”,确保回答既专业又不会“胡编乱造”。

整个系统从资料处理、向量化存储到问答交互,形成了一套完整的流水线。对于开发者而言,这是一个绝佳的RAG实战项目,涵盖了文档解析、文本分块、向量嵌入、语义检索、提示工程等核心环节;对于考研学子来说,它是一个能显著提升复习效率的利器。接下来,我将从设计思路到实操细节,完整拆解这个系统的构建过程,并分享其中踩过的坑和总结的经验。

2. 系统核心架构与设计思路拆解

2.1 为什么选择RAG而不是微调或直接问答?

构建一个专业领域的问答系统,通常有几种技术路径:直接使用大模型(Zero-Shot)、对大模型进行微调(Fine-Tuning)、或者采用检索增强生成(RAG)。我选择RAG,是基于408考研这个场景的特定需求做的权衡。

直接使用大模型(如直接问ChatGLM):优点是方便快捷。但缺点非常明显:第一,大模型的训练数据可能未包含最新、最全的408特定教材和真题,其知识存在滞后性和不完整性;第二,对于非常细节、精确的概念定义和公式推导,大模型容易产生“幻觉”,给出看似合理实则错误的答案,这在严肃的学习中是致命的;第三,无法引用具体的资料来源,学习者无法追溯和验证。

对大模型进行微调:这相当于让大模型“学习”所有408资料,使其成为该领域的专家。效果理论上最好,但成本极高。需要高质量的标注数据、大量的计算资源(GPU)和时间,并且每更新一次资料库(如新增一年真题),就需要重新微调或进行增量学习,维护成本巨大,对于个人或小团队项目不现实。

检索增强生成(RAG):这正是本项目的选择。它的核心思想是“知识库外置”。我们不对大模型本身做改动,而是建立一个专属的、结构化的外部知识库(向量数据库)。当用户提问时,系统先从知识库中检索出与问题最相关的文档片段,然后将这些片段作为“参考依据”和“上下文”,连同问题一起提交给大模型,让大模型基于这些可靠的资料生成答案。这样做的好处是:

  1. 答案精准可靠:答案来源于你提供的权威资料,极大减少了幻觉。
  2. 知识可更新:只需向向量数据库添加新的文档,即可更新系统知识,成本低。
  3. 可追溯源:系统可以返回答案所依据的原文片段,方便用户查证。
  4. 性价比高:主要消耗在检索和API调用上,远低于微调。

对于408考研,资料(教材、王道/天勤讲义、历年真题及解析)是相对稳定和结构化的,非常适合构建高质量的向量知识库。RAG方案在准确性、可维护性和成本之间取得了最佳平衡。

2.2 技术栈选型:从向量数据库到大模型API

确定了RAG的路线,接下来就是具体技术组件的选型。每一个选择都经过了对比和实测。

1. 向量数据库:ChromaDB向量数据库负责存储文本转换成的向量(Embedding),并提供高效的相似性检索。市面上有Milvus、Pinecone(云服务)、Qdrant、Weaviate以及Chroma等。

  • 不选Milvus:虽然功能强大、性能卓越,但部署相对复杂(需要Docker,有多个组件),对于本项目这种单机、轻量级的应用来说有点“杀鸡用牛刀”。在Windows上部署Standalone版本也可能遇到一些环境依赖问题。
  • 选择ChromaDB:它是一个轻量级、嵌入式的向量数据库,可以直接用Python包安装(pip install chromadb),无需单独部署服务。它提供了简单的API,足以应对中小规模资料库的存储和检索需求。对于408全部文本资料(预计在几十到上百MB的纯文本),Chroma完全够用,且开发调试极其方便。

2. 嵌入模型:text-embedding-3-small嵌入模型负责将文本转换为向量。这里我没有使用智谱的嵌入模型,而是选择了OpenAI的text-embedding-3-small。原因如下:

  • 性能与成本:该模型在MTEB等基准测试上表现优异,且价格非常便宜($0.02 / 1M tokens)。虽然需要调用OpenAI API,但嵌入是一次性的(构建知识库时),后续检索不产生费用。对于个人项目,构建一次知识库的成本几乎可以忽略不计。
  • 兼容性:ChromaDB与OpenAI的Embedding API集成非常简单。当然,你也可以选择开源的模型(如BGE、M3E),在本地运行,实现完全离线,这需要一定的GPU资源。本项目以快速实现和验证效果优先,故选用API方案。

3. 大语言模型API:智谱清言(ChatGLM)这是系统的“大脑”,负责最终的答案生成。选择智谱清言(GLM-4)主要基于几点考虑:

  • 对中文的深度优化:GLM系列模型对中文的理解和生成能力非常出色,符合408资料以中文为主的特点。
  • API稳定易用:智谱提供了清晰、稳定的API文档,计费模式透明。虽然网络热词中提到了“api error: 400 the thinking_budget parameter must be a positive integer”等错误,但这通常是由于参数传递不正确导致的,API本身服务是可靠的。
  • 上下文长度:GLM-4支持128K的长上下文,这对于RAG场景非常有利。我们可以一次性传入多个检索到的文档片段(可能长达数千token)作为上下文,模型也能很好地处理。

4. 应用框架:LangChain vs 纯手工打造LangChain是一个流行的LLM应用开发框架,它封装了包括文档加载、分块、检索链等很多模块。对于快速原型开发非常友好。但在本项目后期,我选择了基于LangChain核心思想但自己编写主要流程。原因是为了更精细的控制和更深入的理解。例如,文档分块策略、检索后处理、提示词工程等,自己实现可以针对408资料的特点做深度定制,避免框架的“黑盒”感。不过,对于初学者,我仍然建议从LangChain开始,它能帮你快速搭建起流水线。

注意:技术选型不是一成不变的。例如,如果资料量暴涨到数百万级,可能需要考虑升级到Milvus或Qdrant;如果追求完全离线,则需要部署本地嵌入模型和开源大模型(如Qwen、ChatGLM3-6B)。本项目选型是基于“个人开发者、有限资料、快速实现、高准确性”的假设。

2.3 系统工作流程全景图

整个系统可以清晰地分为两个阶段:知识库构建(离线)问答服务(在线)

离线阶段:知识库构建

  1. 文档加载:收集所有408考研资料,包括PDF版的教材、讲义,以及Markdown/Word格式的笔记。使用像PyPDF2pdfplumberpython-docxmarkdown等库来提取纯文本。
  2. 文本预处理与清洗:去除无关的页眉页脚、版权信息、过多的换行和空格。将全角字符统一,可能还需要进行简单的纠错。
  3. 文本分块:这是影响检索效果的关键一步。不能简单按固定字数切割,那样会割裂完整的概念。我采用的策略是“递归式分块”:先按段落或章节等自然分隔符切分,如果块太大(如超过500字),再按句子或固定重叠窗口进行二次切分。同时,设置重叠窗口(例如100字),确保上下文连贯性,避免一个概念被硬生生切到两个块里导致检索不全。
  4. 向量化与存储:使用text-embedding-3-small模型将每一个文本块转换为一个高维向量(1536维)。然后将(文本块, 对应向量, 元数据)存入ChromaDB。元数据包括该块出自哪本书、哪个章节、页码等,便于溯源。

在线阶段:问答服务

  1. 用户提问:用户输入一个自然语言问题,例如“简述TCP三次握手的过程”。
  2. 问题向量化:使用同样的嵌入模型,将用户问题转换为一个向量。
  3. 语义检索:在ChromaDB中,计算问题向量与所有文本块向量的相似度(通常用余弦相似度),返回相似度最高的K个文本块(例如top-5)。这就是系统找到的“参考资料”。
  4. 提示工程与上下文构建:将检索到的top-K个文本块,按照相关性排序,拼接成一个长的“上下文”字符串。然后,精心设计一个提示词(Prompt),其核心结构是:“你是一个计算机考研408科目的专家助手。请严格根据以下提供的资料来回答问题。如果资料中没有相关信息,请直接说‘根据现有资料无法回答’。资料:[此处插入检索到的上下文]。问题:[用户问题]。请给出准确、清晰的答案。”
  5. 调用大模型生成:将构建好的提示词发送给智谱GLM-4 API,模型会基于我们提供的“资料”生成最终答案。
  6. 返回答案与溯源:将生成的答案返回给用户。同时,可以将答案所依据的文本块(或它们的元数据,如出处章节)一并返回,增强可信度。

3. 核心模块实现与实操要点

3.1 资料处理与向量库构建的“脏活累活”

构建高质量向量库是整个系统的基石,这里面的细节决定了最终问答的精度。

文档加载的坑:PDF解析是最头疼的。PyPDF2对简单文本PDF还行,但遇到扫描版或复杂排版的PDF,提取的文本会夹杂大量乱码和错误换行。我后来主要使用pdfplumber,它在表格和保持文字顺序上表现更好,但速度稍慢。一个实用的技巧是:多种解析库结合使用,并辅以正则表达式清洗。例如,先用pdfplumber提取,然后用正则匹配连续的非中文字符、过多的换行符进行清理。

文本分块的艺术:这是本项目的核心技巧之一。固定长度分块(如256个token)简单但愚蠢,很容易把一句话或一个定义从中间切断。

  • 我的策略:首先,利用文档自身的结构。对于Markdown笔记,按##标题进行切分是最自然的。对于PDF教材,可以尝试识别“章”、“节”等标题样式(通常字体较大)作为分块边界。如果识别不到,则退回到按段落(\n\n)分块。
  • 重叠窗口的必要性:假设块大小设为500字,重叠窗口设为100字。那么第一个块是1-500字,第二个块是401-900字……这样,处于400-500字这个边界的重要信息,会在两个块中都出现,确保检索时不会被遗漏。这个重叠比例需要根据文本特点调整,我一般设置在10%-20%。
  • 元数据记录:为每个块记录丰富的元数据至关重要。我设计的元数据字段包括:source(文件名,如“计算机网络-谢希仁第7版.pdf”)、chapter(章节名,如“第3章 数据链路层”)、page(起始页码)、chunk_id(块序号)。这些信息会在最终答案时被引用。

向量化存储实操

import chromadb from chromadb.config import Settings import openai import os # 初始化Chroma客户端,持久化到本地目录 chroma_client = chromadb.PersistentClient(path="./chroma_408_db") # 创建或获取一个集合(Collection),类似数据库的表 collection = chroma_client.get_or_create_collection(name="408_knowledge_base") # 假设我们已经有了清洗和分块好的文本列表 `text_chunks` 和对应的元数据列表 `metadatas` # 使用OpenAI Embedding API进行向量化 openai.api_key = os.getenv("OPENAI_API_KEY") def get_embedding(text): response = openai.embeddings.create( model="text-embedding-3-small", input=text ) return response.data[0].embedding # 分批处理,避免一次请求太大 batch_size = 100 for i in range(0, len(text_chunks), batch_size): batch_texts = text_chunks[i:i+batch_size] batch_metadatas = metadatas[i:i+batch_size] batch_embeddings = [get_embedding(text) for text in batch_texts] batch_ids = [f"chunk_{i+j}" for j in range(len(batch_texts))] # 添加到集合 collection.add( embeddings=batch_embeddings, documents=batch_texts, metadatas=batch_metadatas, ids=batch_ids ) print(f"已插入 {i+len(batch_texts)} / {len(text_chunks)} 个块")

实操心得:在调用OpenAI Embedding API时,务必做好异常处理和重试机制。网络波动可能导致单次失败。可以封装一个带有指数退避重试的函数。另外,将所有资料向量化可能需要一些时间和API费用,建议先用小部分数据测试流程。

3.2 检索策略与提示词工程的精雕细琢

检索和提示词是连接向量库和大模型的桥梁,直接决定答案质量。

语义检索的优化

  • 相似度度量:ChromaDB默认使用余弦相似度,这通常是最佳选择。也可以尝试L2距离,但对于文本向量,余弦相似度更关注方向而非大小,效果更好。
  • 检索数量K的选择top_k取多少?太少可能信息不全,太多则会给大模型带来无关噪音,增加成本并可能干扰判断。我通过实验发现,对于408这种定义清晰、答案相对聚焦的问题,top_k=34通常就能覆盖核心资料。对于需要综合多个知识点的问题(如“比较进程和线程”),可以适当增加到56
  • 重排序:简单的相似度排序可能不是最优的。可以引入一个“重排序”模型,对初步检索到的top_n(n>k)个结果进行更精细的相关性打分,再取前k个。这属于进阶优化,初期可以不做。

提示词工程:让大模型“守规矩”提示词是命令大模型如何工作的指令。一个糟糕的提示词会导致模型无视你的资料,自己胡编乱造。

def build_prompt(query, retrieved_docs): # retrieved_docs 是一个列表,每个元素包含 `document`文本和 `metadata` context = "" for i, doc in enumerate(retrieved_docs): # 可以加入出处信息,让模型和用户都知道来源 source_info = f"[来自:{doc['metadata'].get('source', '未知')}, 章节:{doc['metadata'].get('chapter', '未知')}]" context += f"参考资料片段 {i+1}: {source_info}\n{doc['document']}\n\n" prompt = f"""你是一位专业的计算机考研408科目(数据结构、计算机组成原理、操作系统、计算机网络)辅导老师。 你的任务是严格根据用户提供的参考资料来回答问题。请遵守以下规则: 1. 答案必须基于提供的参考资料。如果资料中没有足够信息来回答问题,请明确告知“根据提供的资料无法回答该问题”。 2. 答案应准确、清晰、有条理,优先使用参考资料中的表述。 3. 如果参考资料中有矛盾或多种说法,请指出并说明。 4. 答案中可适当引用参考资料的出处(如资料片段编号)。 以下是相关的参考资料片段: {context} 用户问题:{query} 请根据以上资料,给出专业、准确的回答:""" return prompt

这个提示词明确了角色、任务、规则,并将资料与问题清晰分隔。强调“严格根据资料”是抑制幻觉的关键。

调用智谱GLM-4 API

from zhipuai import ZhipuAI import os client = ZhipuAI(api_key=os.getenv("ZHIPUAI_API_KEY")) def ask_glm4(prompt): try: response = client.chat.completions.create( model="glm-4", # 或 "glm-4-plus" 根据需求选择 messages=[ {"role": "user", "content": prompt} ], temperature=0.1, # 温度设低,让输出更确定、更少创造性 top_p=0.7, max_tokens=2000 # 根据答案长度调整 ) return response.choices[0].message.content except Exception as e: # 处理网络错误、API限额错误等 print(f"调用API出错: {e}") # 这里可以加入重试逻辑 return None

注意事项temperature参数控制随机性,对于知识问答,建议设置在0.1-0.3之间,让输出更稳定可靠。max_tokens要根据你预期的答案长度设置,留足余量,避免答案被截断。务必妥善管理API Key,并关注调用费用。

3.3 前端交互与系统集成

为了让非开发者的同学也能方便使用,一个简单的前端界面是必要的。这里我选择了用Gradio快速搭建一个Web界面。

import gradio as gr # ... 省略之前的向量库和模型调用代码 ... def answer_question(question, history): # 1. 将用户问题向量化 query_embedding = get_embedding(question) # 2. 检索 results = collection.query( query_embeddings=[query_embedding], n_results=4 ) # results 包含 `documents`, `metadatas`, `distances`等 retrieved_docs = [] for i in range(len(results['documents'][0])): retrieved_docs.append({ 'document': results['documents'][0][i], 'metadata': results['metadatas'][0][i], 'distance': results['distances'][0][i] }) # 3. 构建提示词 prompt = build_prompt(question, retrieved_docs) # 4. 调用大模型 answer = ask_glm4(prompt) if answer is None: answer = "抱歉,服务暂时不可用,请稍后再试。" # 5. 可以附带来源信息 source_info = "\n\n---\n**参考来源**:\n" for doc in retrieved_docs: source_info += f"- {doc['metadata'].get('source')} - {doc['metadata'].get('chapter')}\n" final_response = answer + source_info return final_response # 创建Gradio界面 demo = gr.ChatInterface( fn=answer_question, title="408考研智能问答助手", description="请输入关于数据结构、计组、操作系统、计算机网络的问题。系统将基于权威资料为您解答。", examples=["什么是虚拟内存?", "TCP和UDP的主要区别是什么?", "简述快速排序算法的思想"], cache_examples=False ) if __name__ == "__main__": demo.launch(server_name="0.0.0.0", server_port=7860, share=False) # share=True可生成临时公网链接

这样,一个拥有聊天界面、示例问题的本地Web应用就搭建好了。运行脚本后,在浏览器打开http://localhost:7860即可使用。

4. 效果评估、优化与踩坑实录

4.1 如何评估问答系统的效果?

没有评估,优化就无从谈起。对于这类问答系统,不能只看答案“看起来”对不对,需要有更客观的方法。

1. 人工评估(黄金标准): 准备一个测试集,包含50-100个覆盖四门科目的典型问题,并准备好标准答案(可以来自教材或权威解析)。然后让系统回答,由你(或几位同学)从以下几个维度打分(1-5分):

  • 相关性:答案是否紧扣问题?
  • 准确性:答案中的事实、概念、数据是否正确?
  • 完整性:是否涵盖了问题所问的所有要点?
  • 依据性:答案是否明显来源于提供的资料,而非模型臆造? 计算平均分,作为系统的基线分数。任何优化措施前后,都应用同一测试集评估,看分数是否提升。

2. 自动评估指标(辅助)

  • 检索召回率:对于测试集中的问题,系统检索到的前K个文档中,是否包含了能回答该问题的关键文档?这评估了向量库和检索模块的质量。
  • 答案相似度:使用句子嵌入模型(如BGE),计算系统生成的答案与标准答案的余弦相似度,作为一个量化参考。但要注意,表达方式不同但意思正确的答案,相似度可能不高,所以这个指标要谨慎看待。

3. 案例分析

  • 成功案例:问“Dijkstra算法和Floyd算法的区别”。系统能准确检索到图论中关于最短路径的章节,并从适用场景(单源vs多源)、算法思想(贪心vs动态规划)、时间复杂度等方面进行清晰对比,答案结构好,依据充分。
  • 失败案例:问“某年408真题第XX题答案解析”。由于真题解析可能分散在不同的资料块中,或者解析本身是图片格式未被提取,系统可能检索不到最精准的块,导致回答不完整或要求模型“综合”,从而产生幻觉。

4.2 性能优化与效果提升技巧

在基础系统跑通后,我通过以下方法进一步提升了体验和效果:

1. 混合检索:单纯的语义检索(向量检索)有时会被“语义相似但主题无关”的文档干扰。可以加入关键词检索(如BM25)进行混合。例如,先用关键词快速筛选出包含“Dijkstra”、“Floyd”、“最短路径”等术语的文档,再在这些文档中进行语义相似度排序。这能提高检索的精确度。ChromaDB本身也支持基于元数据的过滤,可以先用“科目=数据结构”进行筛选。

2. 查询扩展:用户的问题可能比较简短或口语化。例如“学PV操作有啥用?”。系统可以先用一个小模型(或规则)对原问题进行扩展或改写,如改写成“PV操作(wait/signal操作)在操作系统进程同步中的作用和应用场景是什么?”,再用改写后的问题去检索,效果更好。

3. 分阶段检索与重排序

  • 第一阶段:用问题向量进行粗筛,取出top_n(比如20)个候选块。
  • 第二阶段:使用一个更精细的“交叉编码器”模型(如BGE-Reranker),计算问题与每个候选块的深度相关性分数。这个模型比简单的向量点积计算量更大,但更准确。
  • 第三阶段:根据重排序分数,选取top_k(比如4)个块送入大模型。 这种方法显著提升了检索质量,但增加了复杂度和延迟。

4. 上下文窗口的智能利用:GLM-4支持长上下文,但并非塞得越多越好。我采用了“动态上下文构建”策略:如果检索到的前几个块相似度非常高(距离很近),且总长度适中,就全部送入。如果检索结果分散(相似度分数断层),则只取最相关的前1-2个块,避免噪音。还可以尝试让模型自己判断需要哪些上下文,但这属于更复杂的Agent范畴了。

4.3 常见问题与排查实录(踩坑记录)

在开发过程中,遇到了不少典型问题,这里记录下来供大家参考:

问题1:答案出现明显的“幻觉”,即资料中没有的内容被编造出来。

  • 排查:首先检查检索结果。打印出top_k检索到的原文,看是否真的包含了回答问题所需的信息。很可能检索失败,返回了不相关的片段。
  • 解决
    • 优化分块:检查是不是分块太小割裂了上下文,或者太大包含了无关信息。调整分块大小和重叠窗口。
    • 优化提示词:在提示词中加强指令,如“必须严格根据资料回答”、“如果资料中没有,请直接说不知道”,并用显眼的标记(如###资料###)把上下文包起来。
    • 降低Temperature:将API调用的temperature参数降至0.1甚至0.01,让模型输出更保守。

问题2:检索速度慢,尤其是资料库变大后。

  • 排查:ChromaDB在默认情况下,每次查询会计算与库中所有向量的距离。当向量数量超过数万时,延迟会明显增加。
  • 解决
    • 建立索引:ChromaDB支持多种索引类型(如HNSW)。在创建集合时指定hnsw:space等参数可以加速检索,但会稍微影响精度。
    • 元数据过滤:如果用户问题可以明确分类(如问的是“计算机网络”),可以先通过元数据where={"subject": "computer_network"}过滤,大幅缩小检索范围。
    • 考虑专业向量数据库:如果数据量真的非常大(数十万以上),需要考虑迁移到Milvus或Qdrant,它们为大规模向量检索做了深度优化。

问题3:智谱API返回错误,如“api error: 400 the thinking_budget parameter must be a positive integer”。

  • 排查:这是传递了无效参数。检查调用API时,是否在messages之外错误地传递了thinking_budget等GLM-4特定参数。GLM-4的API参数可能与OpenAI格式略有不同。
  • 解决:仔细阅读智谱AI官方最新的API文档,确保参数名和格式完全正确。使用官方的SDK(zhipuai)能减少这类错误。

问题4:处理包含代码、公式或图片的资料时效果差。

  • 排查:PDF解析器可能无法正确提取代码块(格式混乱)或完全忽略图片中的文字。
  • 解决
    • 代码:对于已知的代码资料(如算法实现),可以尝试用pandoc等工具先转换为Markdown,或使用专门针对代码的解析器。
    • 公式:简单的行内公式(如E=mc^2)文本解析可能保留。复杂公式则需要OCR或使用LaTeX源文件。
    • 图片:这是当前方案的硬伤。如果需要处理扫描版资料中的图文,必须引入OCR技术(如PaddleOCR、Tesseract)来提取图片中的文字,再将文字融入文本流进行处理。这会大大增加复杂度。

问题5:系统回答“根据资料无法回答”,但明明资料里有。

  • 排查:最常见的原因是术语不匹配。资料里写的是“同步原语”,用户问的是“锁机制”。虽然人类知道它们高度相关,但向量模型可能认为它们的语义向量不够接近。
  • 解决
    • 同义词扩展:在检索前,对用户问题中的关键术语进行同义词扩展。可以维护一个408领域的同义词词典(如“PV操作”->“wait/signal”、“信号量”)。
    • 使用领域微调的嵌入模型text-embedding-3-small是通用模型。可以尝试使用在中文学术或计算机领域微调过的开源嵌入模型(如BGE-large-zh),它们在专业术语的向量表示上可能更准确。你可以在本地部署这些模型,虽然会牺牲一些构建速度,但能提升检索质量。

构建这样一个系统,更像是一个持续迭代和调优的过程。没有一劳永逸的配置,需要根据你的具体资料和问题类型,不断地评估、分析、调整分块策略、检索参数和提示词。当看到系统能准确、流畅地回答出一个个复杂的408问题时,那种成就感是对所有调试工作最好的回报。这个项目不仅是一个工具,更是一个深入理解RAG技术、大模型应用以及信息检索原理的绝佳实践。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/28 11:10:38

最小二乘法:从误差量化到多元回归,原理推导与Python实践

1. 从“猜”到“算”:为什么我们需要最小二乘法? 做数据分析、搞模型拟合,或者哪怕只是用Excel画条趋势线,你大概率都听过“最小二乘法”这个名字。它听起来像个高深的数学工具,但实际上,它的核心思想朴素得…

作者头像 李华
网站建设 2026/8/28 11:09:24

MarkItDown 使用指南:一条命令将 10 余种办公文档转为 Markdown

MarkItDown 使用指南:一条命令将 10 余种办公文档转为 Markdown 【免费下载链接】markitdown Python tool for converting files and office documents to Markdown. 项目地址: https://gitcode.com/GitHub_Trending/ma/markitdown 把一沓 PDF 论文、Word 报…

作者头像 李华
网站建设 2026/8/28 11:08:59

Claude Code 会话秒结束?从 Session 原理到实战排查

昨天还能正常跑的长任务,今天一启动就“秒结束”;恢复历史会话时,刚打印几行就被截断;甚至还没开始干活,进程就直接退出。HN 上也有人专门发帖问:Anyones Claude Code session finishing quickly from yest…

作者头像 李华
网站建设 2026/8/28 11:06:05

深度强化学习在移动边缘计算任务卸载与资源分配中的应用实践

简介:任务卸载与资源分配是分布式计算和网络优化中的核心基础问题,旨在解决有限计算资源在多用户、多任务场景下的高效调度挑战。其原理是通过智能决策算法,动态决定计算任务的执行位置(本地或远程)以及分配相应的CPU、…

作者头像 李华