news 2026/10/20 3:27:44

RAG实战指南:从原理到优化,搭建私有知识库问答系统

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
RAG实战指南:从原理到优化,搭建私有知识库问答系统

1. 先从“为什么”说起:大模型再强,也答不了你的私有问题

做AI应用落地的人,基本都会撞上同一堵墙:模型聊宏观问题头头是道,一聊到你自己的业务就露馅。

你问大模型“我们公司的报销流程是什么”,它要么给你一段网上搜来的通用流程,要么干脆一本正经地编一个。你问它“下周服务器运维排期表有空隙吗”,它连你的排期表都没见过,只能瞎猜。这不是模型不够聪明,而是它本来就没看过你的数据——训练它的时候,你的内部文档、个人笔记、私有数据库还不存在。

那能不能让模型“记”下这些数据呢?传统思路有几个:微调、长上下文硬塞。前者贵且容易过拟合,后者受上下文窗口限制,塞个几十万字进来,成本爆炸,还容易让模型“看不过来”,答得丢三落四。

RAG,全称Retrieval-Augmented Generation,检索增强生成,就是来解这个局的。

它的思路一句话能说清:让大模型学会“开卷考试”。回答问题时,先从你的知识库里把相关资料“翻出来”,再把资料连同问题一起交给大模型,让它照着资料写答案。

这篇文章面向刚入门RAG的开发者。我会把RAG的底层原理、模块拆解、完整实操代码、优化手段和排坑经验一次讲完,全程用我自己跑通项目的视角来讲。不管你之前没碰过大模型应用开发,还是已经试过几次被乱七八糟的报错卡住,这文都能让你把整条链路彻底打通。

2. RAG 的完整链路:五个环节,一个都不能少

很多人第一次被RAG,是从别人画的一张架构图开始的:文档 → 分块 → 向量化 → 存库 → 检索 → 喂给大模型 → 出答案。图很简单,但真正落地时,每个环节都有讲究。

完整链路是:

  1. 文档加载:读取PDF、Word、Markdown、HTML等格式,把内容提取成纯文本。
  2. 文本分块:把长文档切成若干小块。这一块直接决定后续检索的上限。
  3. 向量化:用Embedding模型把每个文本块转换成一个向量,也就是一串数字。
  4. 建立索引:把向量和原文存进向量数据库,同时建立高效索引结构,方便后续快速查找。
  5. 检索与生成:用户提问时,把问题也转成向量,在库里找语义最相近的几个文本块,拼到Prompt里,交给大模型生成答案。

听起来不复杂,但每个环节都藏了一堆决策点。下面我把每个模块掰开了讲。

2.1 文档加载:格式越多,坑越多

文档加载这事看起来土,其实最容易翻车。PDF有扫描版和电子版,扫描版要先OCR;Word里有表格、图片、页眉页脚;HTML里全是标签噪音。

我常用的处理原则是这样的:

  • 电子版PDF:用专用解析库提取文字,注意多栏排版会被读乱。
  • 扫描版PDF:必须先OCR识别,否则后面检索全是乱码。
  • Markdown文件:直接读取,尽量保留标题层级,后面分块能用上。
  • Word文档:提取段落和表格时,表格内容要单独处理,别和上下文字混成一团。
  • 网页:先去掉HTML标签,只保留正文。

还有个容易忽略的细节:编码。有些老文档是GBK编码,直接读会出现乱码。加载时统一转成UTF-8处理,能省很多事。

文档加载阶段的产出,是一堆干净、连续的文本。判断标准很简单:你把提取出来的文本读一遍,如果自己读得通顺、分得出段落,后面基本不会出大问题。

2.2 分块:这个参数决定检索质量上限

分块是RAG里最容易被低估的环节。很多人随便设个500字就跑了,结果检索出来的内容是半截话,大模型看了云里雾里,答得自然很差。

分块有两个核心参数:块大小(chunk size)和重叠(overlap)。

块大小的选择是个权衡:

  • 块太小,比如100字,检索时容易命中局部信息,但缺少上下文背景,大模型难以理解全局。
  • 块太大,比如2000字,上下文信息完整,但向量里混了太多无关内容,语义精度下降,还会稀释关键词的权重。

我的实测经验:通用场景下,中文按 200到400个汉字分块,或者按向量模型的 token 数来算,通常512 token左右比较稳。如果是代码仓库问答,块可以更小一点;如果是长篇章、学术论文,可以适当放大。

重叠参数的意思是,相邻两个块之间保留一部分重复文本。这样能避免一句话恰好被拦腰截断。一般重叠量设为块大小的10%到20%。比如块大小512 token,重叠80到100 token。

更高级的分块方式是“结构感知分块”:先按Markdown标题、段落、列表把文档拆成语义完整的单位,再把过长的单位拆小。比如一篇文档有10个二级标题,每个标题下内容独立,那就按标题拆成10个块。用户问某个标题下的内容时,检索回来的就是一整段逻辑完整的文字,而不是从中间截断的碎片。

这里我要强调一个观点:分块策略没有银弹。不同文档、不同问答场景,最优参数不一样。靠谱的做法是搭好系统后,准备一批标注好的测试题,把分块参数当调参项,多跑几组对比效果。后面我会说怎么测。

2.3 Embedding:把“意思”变成数字

计算机理解文字,不靠“读懂”,靠数学。Embedding模型的作用,是把一句中文映射成一个几百维的向量,让意思相近的句子在向量空间里距离更近。

比如,“报销流程是什么”和“如何申请报销”这两句话,字面上不完全一样,但向量距离会很近。而“报销流程是什么”和“今天天气怎么样”的向量距离就很远。这个能力,正是RAG能实现“语义检索”的基础。

选Embedding模型有几个关键维度:

  1. 语言支持:处理中文场景,优先考虑中文效果好的模型,很多通用模型在中文上的表现明显弱于英文。
  2. 向量维度:维度越高通常表达能力越强,但存储和计算成本也上升。768维是比较常见的起步档位。
  3. 匹配方式:注意模型是“对称”还是“非对称”结构。有些模型对“问题”和“答案片段”分别做向量化效果更好,有些则用同一个编码器就行。这里看模型的说明文档即可。
  4. 最大输入长度:每个模型能接受的文本长度有限。分块大小要适配Embedding模型的最大输入长度,超过会被截断。

Embedding这块没有特别神秘的原理,关键是选对模型、看清楚输入限制。后续我实操部分会给出具体选型。

2.4 向量数据库:怎么在海量向量里“找相似”

向量化之后,知识库里有几千几万个向量。用户提问时,把问题变成一个查询向量,然后要在整个库里找到最相近的若干条。如果只是线性遍历,数据量大了就慢得没法看。

所以要用专门的向量索引结构。目前主流用的是HNSW(分层可导航小世界图)和IVF(倒排文件)两类。

HNSW的原理用人话讲:它把向量组织成多层的图,高层是稀疏的长连接,能快速跳到大致区域,低层是稠密的短连接,负责精细搜索。就像你到一个陌生城市找一家小店,先坐地铁到附近街区,再步行导航进去。HNSW在大多数场景下是默认选择,召回率高、速度快,缺点是构建索引要占内存。

向量数据库的选型也很重要。轻量本地场景可以选可以直接范式使用的文件型库,数据量在百万级以内完全够用;生产环境并发量大、数据量过千万,就要上专门的向量数据库服务。选型的标准无非是:数据量、并发量、是否需要持久化、是否有高可用需求。

实际开发中,我建议新手先从本地文件型向量库起步,把链路跑通,再考虑换生产级组件。一上来就搭分布式向量集群,只会被运维问题淹没,RAG本身还没搞明白。

2.5 检索与生成:Prompt 的组装很关键

检索环节返回了若干个文本块,接下来要把它们装进Prompt,交给大模型。

Prompt模板一般长这样:

你是一个知识库问答助手。请严格依据下面提供的参考资料回答用户问题。 如果参考资料中没有答案,请直接说明“资料中未找到相关信息”,不要编造。 参考资料: 1. [文档来源:产品手册,第3页] {chunk1} 2. [文档来源:FAQ文档] {chunk2} 用户问题:{question} 请给出准确、简洁的回答,并标注回答依据了哪条参考资料。

这个模板比“直接把资料和问题怼给模型”好在三点:

  1. 明确约束“只能依据资料回答”,有效降低幻觉。
  2. 标注来源,方便用户追溯原始文档。
  3. 要求“未找到就明说”,避免模型强行作答。

检索的TopK取值也值得说。取太少,可能漏掉关键信息;取太多,噪音进Prompt里反而干扰模型。我的经验是:通用问答取3到5条,需要综合多个段落回答时取5到8条。具体数值还是要评测着来。

3. 动手实操:从零搭一个私有知识库问答系统

理论讲完,直接上代码。我以一套最清晰、最少依赖的路线实现:本地文档解析 + 开源中文Embedding模型 + 文件型向量库 + 大模型API调用。

整个系统分成三步:数据准备、索引构建、检索问答。

3.1 环境准备与依赖安装

先建一个干净的Python环境,我用Python 3.10+。

需要安装的依赖如下:

pip install langchain pip install chromadb pip install sentence-transformers pip install pypdf pip install openai

说明一下:这里用了一个编排框架来省去胶水代码,用它对Embedding和向量库的封装来实现数据入库和检索。向量库用的是文件型方案,本地跑非常方便,不用单独起服务。Embedding模型用开源中文模型,完全本地运行,不需要额外付费。

大模型部分,我假设你有一个能调用的API服务,把API Key配置到环境变量里。代码里我留了接口位置,换成其他兼容接口都行。

3.2 文档加载与分块

先写文档加载与分块逻辑。

from langchain_community.document_loaders import PyPDFLoader, TextLoader from langchain_text_splitters import RecursiveCharacterTextSplitter # 加载PDF loader = PyPDFLoader("./docs/产品手册.pdf") docs = loader.load() # 加载纯文本文档 text_loader = TextLoader("./docs/员工手册.md", encoding="utf-8") text_docs = text_loader.load() # 合并所有文档 all_docs = docs + text_docs # 分块:块大小500字符,重叠50字符 splitter = RecursiveCharacterTextSplitter( chunk_size=500, chunk_overlap=50, separators=["\n\n", "\n", "。", "!", "?", ".", "!", "?", ",", ",", " ", ""], length_function=len, ) chunks = splitter.split_documents(all_docs) print(f"总共切分成 {len(chunks)} 个块")

这里要解释几个关键点:

  • chunk_size=500是字符数,不是token数。中文场景下500个字符大约对应300到400个token,是安全范围。
  • separators里的分隔符顺序很重要。它优先按段落切,其次按句子切,再次按逗号切,最后实在没办法才硬切。这个“从大到小”的优先级,能最大限度保证句子的完整性。
  • RecursiveCharacterTextSplitter是“递归分块”的典型实现。它的逻辑是:先按第一个分隔符把文本切成大块,如果某块还是超过chunk_size,再按第二个分隔符继续切。这样能保证切出来的块尽量语义完整。

如果你要保留Markdown结构,可以换用按标题层级分块的方式,或者自己写一个按标题切分再补切的逻辑。效果通常比纯按字符切好,因为每个块自带上下文边界。

3.3 向量化与向量库构建

加载Embedding模型,把文本块转成向量,存入本地向量库。

from langchain_community.embeddings import HuggingFaceEmbeddings from langchain_community.vectorstores import Chroma # 加载开源中文Embedding模型 embedding_model = HuggingFaceEmbeddings( model_name="BAAI/bge-large-zh-v1.5", model_kwargs={"device": "cpu"}, encode_kwargs={"normalize_embeddings": True}, ) # 构建向量库并持久化到本地目录 vectorstore = Chroma.from_documents( documents=chunks, embedding=embedding_model, persist_directory="./chroma_db", collection_name="private_knowledge", ) print("索引构建完成,向量库已持久化")

几个实用经验:

  • normalize_embeddings=True表示对向量做归一化。这样后续计算相似度时,内积和余弦相似度等价,语义一致性更好。
  • 第一次运行会下载模型权重,需要联网。模型文件下载后缓存在本地,之后离线也能用。
  • persist_directory指定持久化目录。跑一次之后,向量库就存在本地文件夹里了,不用重复构建。

如果你想看实际检索效果,可以在构建完向量库后立刻做一次测试:

query = "员工报销需要哪些材料?" results = vectorstore.similarity_search_with_score(query, k=5) for doc, score in results: print(f"相似度得分: {score:.4f}") print(doc.page_content[:200]) print("---")

这里返回的score是“距离”或者相似度,数值越小说明向量越接近,具体语义取决于底层计算方式。第一次跑的时候,你可以用这个输出来判断分块是否合理、检索是否命中。

3.4 组装检索问答链路

检索系统就绪后,写问答链路:

from langchain.prompts import ChatPromptTemplate from langchain_openai import ChatOpenAI prompt_template = """ 你是一个知识库问答助手。请严格依据下面提供的参考资料回答用户问题。 如果参考资料中没有答案,请直接说“资料中未找到相关信息”,不要编造。 参考资料: {context} 用户问题:{question} 请给出准确、简洁的回答,并在回答末尾标注信息来源。 """ prompt = ChatPromptTemplate.from_template(prompt_template) llm = ChatOpenAI( base_url="http://your-llm-service-endpoint", api_key="your-api-key", model="your-model-name", temperature=0.1, ) def rag_answer(question, k=5): # 1. 检索:从向量库取最相关的文本块 retrieved_docs = vectorstore.similarity_search(question, k=k) # 2. 拼装上下文 context_parts = [] for i, doc in enumerate(retrieved_docs): source = doc.metadata.get("source", "未知来源") context_parts.append(f"[{i+1}] 来源文档:{source}\n{doc.page_content}") context = "\n\n".join(context_parts) # 3. 生成Prompt final_prompt = prompt.format(context=context, question=question) # 4. 调用大模型 response = llm.invoke(final_prompt) return response.content

关键点说明:

  • temperature=0.1是为了让模型输出更稳定、更忠于资料。做知识库问答,我建议temperature设低一点,0到0.3之间比较合适。完全用0有时候显得机械,但0.3以上就开始“放飞自我”了。
  • similarity_search返回的是文档对象,通过doc.metadata能拿到来源文件名,这是后期追溯答案来源的重要信息。
  • 我在上下文中给每条资料编了号,方便模型在回答时引用。这也是减少幻觉的有效手段之一。

3.5 跑一个真实例子

假设我的知识库存了一份“员工手册”,其中写道:

报销差旅费需要提供:行程单、住宿发票、在途交通票据。部门负责人审批后,财务在3个工作日内完成打款。

我提问:

print(rag_answer("出差报销要什么材料?多久能到账?"))

模型回答效果类似:

根据员工手册,报销差旅费需要提供行程单、住宿发票和在途交通票据。部门负责人审批后,财务会在3个工作日内完成打款。
该信息来源于《员工手册》。

这个回答有两个关键点:内容完全来自知识库,且没有添加手册里没写的信息;同时标明了来源。这就是RAG要达到的效果——准确、可追溯、不胡编。

4. 从“能用”到“好用”:六个我踩过坑后总结的优化方向

跑通基本链路只是开始。真实业务里,用户不会容忍一个经常答非所问的系统。下面是我在实际项目里用真金白银踩出来的六个优化方向,按性价比从高到低排列。

4.1 分块参数评测优化

分块参数不能拍脑袋,要用评测数据说话。

做法是准备20到50条测试问答对,覆盖知识库里的主要知识点。每条问题都标注“标准答案来自哪个文档段落”。然后分别用不同chunk_size、overlap组合跑一遍测试集,统计“检索命中率”和“最终回答准确率”。

我遇到过的一个真实案例:某内部文档里大量使用“如下”“以下”“流程”这类承接词,用500字符分块时,很多块只有引言没有正文,检索命中了引言却答不出实质内容。后来把chunk_size调到800,配合结构感知分块,回答准确率从60%提到了80%以上。

这种评测不一定要做得多精细,哪怕人工目测30个问题,也比凭感觉调参数强得多。

4.2 混合检索:向量检索和关键词检索互补

向量检索擅长语义相似,但在处理专有名词、精确编号、产品型号时经常失灵。比如你搜“BUG-2024-01387”,向量检索可能把它当成正常句子编码了,而关键词检索能精确命中这个编号。

混合检索的思路是:同时做向量检索和关键词检索(比如BM25),把两边的结果合并去重、重新排序后取TopK。这样既能抓住语义相关的模糊表达,又能精确命中唯一标识。

一个很实用的场景是:用户说“我要查一下预算调整的那个流程”,向量检索能匹配到“预算变更审批流程”这一段;用户说“查PRD-1023文档”,关键词检索能直接命中编号。两个能力缺一不可。

4.3 重排序:别把最好的候选埋没在第五名

向量检索返回的TopK里,有时正确答案排在第三第四位,前两名却是“看起来像但实际无用”的内容。直接把TopK塞进Prompt,噪音可能把正确答案的注意力稀释掉。

解决方法是加一个Rerank(重排序)环节。具体做法是:向量库先召回20到50条候选,再用一个专门的重排序模型对候选逐条计算与问题的相关度,最后取分数最高的3到5条进Prompt。

重排序模型比Embedding模型更“精细”,它不看全局语义近似,而是逐字比对问题与候选文本的相关程度。代价是多一次模型推理,耗时增加几十到几百毫秒。但在回答质量敏感的场景里,这个成本完全值得。

4.4 元数据过滤:让检索范围收窄

如果知识库里有不同类型文档(制度、产品手册、技术文档、历史公告),用户提问时,最好能限定范围。比如用户明确问“产品价格”,你就不该去制度文档里翻。

实现方式是在文档块上打元数据标签:

metadata = { "category": "产品", "version": "2024-Q3", "author": "产品部", "source": "产品价格表.pdf", "updated_at": "2024-09-01", }

检索时按需过滤:

results = vectorstore.similarity_search( question, k=10, filter={"category": "产品"}, )

这个技巧对多业务线的知识库特别有用。不仅能提高检索准确率,还能顺带解决权限问题:某些文档只对指定角色可见,元数据过滤就是最简单的权限边界。

4.5 Prompt 模板迭代:别只改一次就完事

很多人搭好一个Prompt模板就不动了。实际上,Prompt是RAG系统中“调试成本最低、收益最直接”的部分。

我在项目里迭代过几十轮Prompt,有几个常见优化方向:

  • 当资料互相矛盾时,要求模型“优先采纳时间戳最新的资料”。
  • 当问题涉及操作步骤时,要求“按步骤分条回答”。
  • 当资料不足时,规定回复模板:“根据现有资料,我无法完整回答该问题。已找到的相关信息如下:...”。
  • 要求模型“如果参考资料里出现了与问题无关的内容,忽略即可”。

这些看起来是细节,但模型对指令的敏感度很高。同样一组检索结果,改一个Prompt可能从“答偏了”变成“答得很准”。

4.6 多轮对话:别让上一句话丢失

真实用户不会每轮都问一遍完整背景。用户可能会先问“报销流程是什么”,再问“那发票要几份”。第二问如果只检索“发票要几份”,很可能检索不到完整上下文。

处理方式是把历史对话压缩后与当前问题合并,再做检索和生成。常用套路有两种:

  1. 把最近2到3轮对话原文拼进检索Query,让Embedding能感知上下文。
  2. 让模型先把“用户当前问题+历史对话”改写成一个独立的完整问题,再拿改写后的问题去检索。

第二种更稳,推荐优先尝试。改写Prompt参考:

你是对话系统的问题改写助手。请参考历史对话,把用户当前问题改写成一个可以独立检索的完整问题。 只输出改写后的问题,不要任何解释。 历史对话: 用户:{history_user} 助手:{history_assistant} 当前问题:{current_question}

改写后再检索,检索命中率会有明显改善。

5. 常见问题与排查实录

RAG系统出问题时,表象各有不同,但根因大多集中在这几处。我按实际排查经验整理了一份速查表。

5.1 检索不到相关内容

这是最让人崩溃的问题——明明库里就有答案,用户问出来却答不上。

排查路径:

  1. 先用向量检索原样跑一遍这个问题,看返回结果是什么。如果返回内容明显不相关,说明是检索问题。
  2. 检查分块是否合理。常见的坑是分块太大,关键句子被淹没在长段落里,向量表征被稀释。试着调小chunk_size看看。
  3. 检查Embedding模型对领域术语的效果。专业术语多的场景,通用Embedding模型可能编码效果差。换个领域预训练的模型试试。
  4. 尝试关键词检索。如果关键词能命中而向量不能,说明是语义编码问题,考虑混合检索。

5.2 检索到了,但回答还是错的

这种情况最常见的原因是:正确的文本块在TopK里排位太低,被其他无关片段挤出去了。或者,正确答案被切分成了两半,模型看到了上一半,没看到下一半。

排查路径:

  1. 把TopK调大,看看正确内容是否出现。如果增大K后才出现,说明排序不够准,加Rerank是正解。
  2. 检查分块时语境是否完整。若一个知识点刚好被切开,调高overlap或改为结构感知分块。
  3. 检查Prompt里是否有“忽略证据”的隐患。有些模板写“结合你的常识回答”,这等于给模型开了编造的口子,赶紧改掉。

5.3 幻觉依然存在

RAG的目标是减少幻觉,但没法完全杜绝。原因可能在于:仓库里本来就有错误信息、检索回来的资料之间存在矛盾、或者模型过度依赖自身记忆。

处理手段:

  1. 在Prompt里明确禁止“根据常识补充资料外的内容”。
  2. 要求模型输出引用标号,并在回答后附来源。这能强制模型“忠于资料”。
  3. 资料矛盾时,在Prompt里规定冲突处理优先级,比如按时间新旧的规则。
  4. 对资料本身做一轮内容审核,垃圾进、垃圾出是铁律。

5.4 回答质量对问题表述太敏感

同一问题换个问法,效果天差地别。比如“报销要什么材料”答得好,“我需要准备哪些单据去报销”答得就飘。这类问题通常出在检索Query本身。

好的做法是引入“查询改写”:把用户口语化问题改写成适合检索的书面表达,再做检索。或者做“多查询扩展”,把同一个问题改写几个不同的表述,分别检索后合并结果。

5.5 系统性能慢

RAG的延迟主要来自三块:Embedding(尤其本地CPU推理)、向量检索、大模型生成。如果用户反馈“转圈半天”,按此顺序排查。

实用手段:

  • 对Embedding做批量预计算,问题向量单独算。文档向量入库后就不变了,不需要每次问答重新算。
  • 向量检索换更高效的索引类型,HNSW的参数可以调。比如提高efSearch能提升召回率但增加延迟,需要trade-off。
  • 大模型的输出长度限制调低,或者换更快的小模型做摘要。
  • 热点知识加缓存:把高频问题及其回答缓存下来,命中缓存直接返回,省掉整条链路。

6. RAG 和微调:想清楚再选,别盲目跟风

很多新手一听到“让AI拥有私有知识库”,第一反应是“那就微调模型呗”。微调确实能做这件事,但它和RAG解决的问题有本质区别。

微调的本质,是改变模型内部的权重,让模型“记住”某种行为模式或知识分布。适合的场景是:模型的表达风格需要改变、输出格式有硬性要求、需要模仿特定语气或领域习惯。

RAG的本质,是给模型外挂一个动态更新的资料库。适合的场景是:知识内容频繁变化、需要引用具体来源、数据量巨大且更新频繁。

这张表能帮你快速决策:

对比维度RAG微调
知识更新速度改库即可,秒级生效重新训练,小时到天级
成本主要是检索和向量存储需要GPU训练资源
可解释性能追溯引用来源黑盒,难以说明
数据量要求少量示例也能用通常需要较多高质量数据
适合任务问答、知识查询、内容总结风格模仿、特定输出格式
幻觉问题缓解但无法根除可能加剧(模型自信地胡说)

我的建议是:绝大多数“私有知识库问答”类需求,先上RAG。只有当RAG无法解决风格、语气、专业术语表达这类问题时,再考虑微调。

更进阶的做法是两者结合:用RAG负责知识获取,用微调负责模型输出风格。比如,先用微调让模型学会“用公司规范格式写日报”,再用RAG让它在写日报时引用最新项目数据。两条腿走路,各管一段,效果通常比单做好。

最后说几句掏心窝的体会

RAG这个技术,入门门槛真的不高,但做深了确实有讲究。我经历过项目上线后被用户反馈“这AI还不如直接搜索框好用”的时刻,也经历过把分块和重排序调顺之后,问答体验脱胎换骨的瞬间。

如果你正在做自己的RAG项目,我建议你不要贪多,先把基础链路跑通——文档加载、分块、向量化、检索、生成,然后每天拿真实问题去拷问它。哪个问题答得不好,就顺着链路一层层排查,是检索错了,还是Prompt没约束住,还是资料本来就没写全。这套排查方法,比任何现成框架都管用。

另外一个小技巧,也是我后来才养成的习惯:从项目第一天起,就维护一份“测试题库”。每次调整分块、换模型、优化Prompt,都用同一批题目来回归。没有这套基准,你根本不知道改动到底好是坏,所有的“感觉变好了”都可能是错觉。

RAG之后还有不少可以聊的延展内容,比如多路召回、图增强的RAG、以及把RAG嵌入Agent工作流里让它具备调用工具的能力。等你在基础链路上跑顺手了,自然就有方向了。

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

.NET 5 WebAPI 中手写 WebSocket 服务端实战

1. 项目概述:为什么在 .NET 5 WebAPI 里硬要搭 WebSocket 服务端?WebSocket 不是“又一个 HTTP 接口”,它是让服务器能主动推消息给浏览器的底层通道——就像你家装了门铃,快递员不用反复敲门问“在不在”,直接按铃你就…

作者头像 李华
网站建设 2026/10/20 3:26:11

Docker Compose 部署 Nacos 并持久化配置到 MySQL 的完整指南

1. 为什么本地跑 Nacos 总在重启后丢配置很多人第一次在本地用 Docker 起 Nacos,流程都差不多:拉个镜像、跑个容器、打开控制台、建几个配置,用着挺顺。结果第二天电脑重启,或者手滑把容器删了重建,之前配的东西全没了…

作者头像 李华
网站建设 2026/10/20 3:25:17

VS Code接入Claude第三方API:扩展面板直连与环境变量注入

写代码这事儿,绕不开VS Code;而写AI辅助代码,现在也绕不开Claude。可问题在于,官方服务有配额、有地域限制、团队协作时还可能想把模型统一到一个出口管理。我最近又把VS Code里接Claude的几种路子重新捋了一遍,发现大多数人的需求最后都收敛到同一种解法:通过扩展把请求打到第…

作者头像 李华
网站建设 2026/10/20 3:24:58

AI率99.8%到14.9%:论文降重实战指南

最近我的小群里又被同一个问题刷屏了:论文写了初稿,研究、数据、分析都是自己做的,只是用AI顺手润色了一遍,结果检测报告出来,疑似AI生成内容比例99.8%。发消息的是一位叫A同学的研究生,他第一反应是“完了…

作者头像 李华
网站建设 2026/10/20 3:24:52

不重训不动权重:让AI Agent通过技能自演进实现终身学习

做了这么久的Agent落地,我越来越觉得"让Agent持续变强"这件事的真正难点不在模型能力,而在系统架构。最近半年我几乎把精力全压在一个方向上:在不重训、不动权重的前提下,让AI Agent拥有可塑性,通过技能自演…

作者头像 李华