资讯动态

企业知识库问答系统落地:RAG+LangChain+DeepSeek完整实践

发布时间:2026/10/20 14:09:36 来源:尧图企业网站定制
最近在帮一家制造企业搭内部知识库问答系统技术选型最终定为 RAG框架用 LangChain生成模型接 DeepSeek。整套系统从需求确认到生产环境跑起来踩了不少坑也摸索出一套相对稳定的搭建路径。这篇文章不打算讲概念直接把从选型、架构设计、代码实现到调优排错的全过程写出来给正在做企业私有知识库问答、或者刚接触 RAG 的团队一个可参考的落地参考。这套方案解决的核心问题是企业内部大量制度文件、产品手册、技术文档散落在各个地方员工想找一条制度规定根本不知道去哪搜即便搜到了也是关键词匹配经常答非所问。用 RAG 搭一个统一入口让员工用自然语言提问系统自己去文档库里检索相关内容再生成答案并且能标注答案来自哪份文档这才是企业问答该有的形态。适合有 Python 基础、想快速在企业内部落地知识库问答的开发者或技术负责人阅读。1. 为什么企业私有知识库问答要选 RAG而不是微调或纯搜索1.1 三种主流方案对比RAG 赢在可控性动手之前我先把能想到的方案列了一圈传统搜索引擎、模型微调、RAG。不列不知道一列就清楚为什么最终选了 RAG。传统搜索在内部知识库场景下最直接的痛点是不理解语义。员工搜离职要办哪些手续如果文档里写的是员工离场工作交接关键词搜索基本召回不到因为字面完全不重合。就算做了分词和同义词扩展也解决不了问法不同但语义相同的问题。更麻烦的是企业文档里的很多内容是表格、多级标题、交叉引用传统搜索很难把这种结构转换成可用的答案。模型微调是很多人第一反应想到的方案把企业知识灌进大模型参数里。但实际一评估就发现几个硬伤。第一是更新成本文档一变就要重新训练或增量训练企业制度经常改不可能每周花几万去微调。第二是可控性差模型学进去的知识没法追溯回答的时候到底引用了哪一条制度说不清楚合规审计直接卡死。第三是训练数据不好准备企业内部文档格式混乱、质量参差不齐要清洗到可以训练的程度工作量比搭 RAG 大得多。RAG 的思路完全不同它把知识存储和答案生成拆开了。知识放在向量数据库里更新文档时只需要增量重建索引几秒钟的事回答问题时系统先从知识库里检索出最相关的几段内容再把这几段内容作为上下文扔给大模型去组织语言。大模型不是凭记忆回答而是基于检索到的证据回答相当于开卷考试。这意味着每一条回答都能溯源到原始文档幻觉能大幅减少这是企业场景最看重的一点。1.2 RAG 的核心逻辑开卷考试先查资料再答题RAG 对很多人来说是个黑盒但拆开看就三层索引、检索、生成。索引阶段把企业文档切块、向量化、存入向量数据库检索阶段把用户问题也做向量化在向量库里找最相似的内容块生成阶段把检索到的内容块和用户问题一起拼进 Prompt交给语言模型生成最终答案。这里最核心的转化是文本到向量。文档切出来的每一段文字都会被一个 Embedding 模型映射成一组高维数字语义相近的文本在这个向量空间里的距离也近。用户提问后同样把问题转成向量然后去向量空间里做最近邻搜索。这个过程和关键词无关只和语义相关所以能解决问法不同但意思相同的问题。生成阶段的 Prompt 至关重要它直接决定模型是老老实实照着资料回答还是自己发挥。我在生产环境里用的 Prompt 几乎是一句一句抠出来的后面会详细写。你可以把它理解成给模型立规矩你是企业知识库助手只能依据提供的资料回答资料里没有的就说不知道并且要标注答案来自哪段资料。这条规矩反复强调之后模型的自由发挥空间会被压到很小。1.3 为什么组合偏偏是 LangChain DeepSeek选 LangChain 的理由其实很简单生态成熟组件齐全不必从零开始写。文档加载有几十种 Loader文本切分有各种 Splitter向量库封装了 Chroma、FAISS、Milvus模型接口兼容 OpenAI 格式的都能直接接。企业知识库的文档格式五花八门光解析 PDF、Word、Markdown、Excel 就需要很多适配代码用 LangChain 可以省掉大半工作量。选 DeepSeek 的理由一是中文理解能力在同类模型里属于第一梯队二是 API 的性价比确实高三是它的接口协议兼容 OpenAI 格式LangChain 可以直接复用现有的 ChatOpenAI 封装只需要改 base_url 和 model 参数。对于企业内部几十人使用的问答系统调用成本完全可以接受。更关键的是DeepSeek API 响应速度稳定作为生成层不会成为体验瓶颈。有人会问为什么不用完全本地化的开源模型。如果企业数据不允许出内网那确实需要本地部署生成模型但这意味着要准备 GPU 资源、维护模型服务成本会高一个量级。我们这次的需求是数据可以走内部知识库但推理走公共 API 也能接受所以选择了这个组合。架构上做了解耦后续如果安全要求升级只需把 DeepSeek 换成企业内网部署的模型接口LangChain 这边的调用代码改动量很小。2. 架构设计与关键组件选型每一环都要知道为什么2.1 一条完整的 RAG 链路包含哪些节点我们最后敲定的链路不算复杂但每个节点都反复验证过。整体分两条线离线索引线和在线问答线。离线索引用定时任务触发先把企业内部的文档从各个源拉下来源包括共享目录里的 Word、PDF、Markdown还有内部 Wiki 导出的 HTML。文档拉到本地后先做格式解析和清洗去掉页眉页脚、图表水印、多余空行然后把长文档切成固定大小的块切块时设置重叠区域避免语义被拦腰截断。接下来每个块交给 Embedding 模型转成向量连同原文、文件路径、章节号、更新时间等元数据一起存入向量库。这步完成后知识库就建立起来了。在线问答链路接收到用户问题时先判断是否需要权限过滤。如果系统接入了企业账号体系检索前就要加上部门、密级这类过滤条件确保没人能问到权限之外的内容。通过过滤后问题文本走同一个 Embedding 模型转成向量在向量库里做相似度检索取回 top-k 个文档块。然后把这 k 块文本和用户问题、系统 Prompt 拼在一起发送给 DeepSeek 模型。模型生成答案同时把召回文档的标题和原文路径作为引用来源一并返回。最后把答案渲染到前端界面展示给员工。这个链路里最容易出问题的不是模型而是前面那些看似基础的环节。文档没解析干净、切块切碎了、向量模型跟业务术语不匹配都会导致最后答案不可用。所以我特别建议企业团队在动手写代码前先把文档样本拿出来做一轮小规模验证确认每一环的输出质量再铺开全量数据。2.2 Embedding 模型选型中文场景不要无脑用通用模型Embedding 模型决定了召回的上限生成模型再强召不回相关内容也是白搭。很多团队第一次做 RAG喜欢直接用海外模型的文本向量接口结果在中文企业文档上效果很差。原因不复杂海外模型大部分训练语料以英文为主对中文的理解深度、对中文专业术语的语义把握都不够。我们这次选的是中文语料训练的 bge 系列模型跑下来明显比通用向量接口更懂中文。它的部署也很简单模型文件放在内网服务器上加载到本地进程里调用一次只消耗几百毫秒 CPU比每次调外部向量接口更稳、更省钱也不存在数据外传的问题。唯一需要注意的是模型的输入长度限制一般最长支持 512 token 左右所以文档切块要控制在模型能接受的范围内。Embedding 模型的版本选择也有讲究当时我们对比了 base 和 large 两个规格。large 效果确实好一点但推理耗时和内存占用高不少。企业内部知识库的问题通常不追求极致精度更看重批量索引速度和单机可部署性最后选了 base 规格配合重排模型来弥补精度差距。如果你刚开始搭我建议直接拿 base 用起来先把流程跑通等发现问题再考虑升级。2.3 向量库选型Chroma、FAISS、Milvus 怎么决策向量库的选择主要看数据量和并发场景。我们前期评估过三个主流方案Chroma、FAISS、Milvus。FAISS 是向量检索库不是完整的数据存储服务需要自己管理持久化和并发适合单机小规模实验Chroma 是一个轻量级的向量数据库支持持久化到磁盘API 简单几百个文档几万条向量这个量级跑起来很轻松Milvus 是分布式向量数据库适合千万级向量、高并发生产环境但部署复杂度明显更高。企业内部知识库大部分场景不会超过几十万条向量用户并发也就几十人Chroma 完全够用。我们最终选了 Chroma一个原因是可以直接复用 LangChain 的封装另一个原因是它支持按 metadata 过滤权限隔离实现起来成本很低。如果你的文档量一开始就很大或者预估未来会到百万级向量那建议一步到位上 Milvus避免后面数据迁移。衡量向量库还有一个容易被忽略的指标检索质量的可观测性。Chroma 可以直接把查出来的原文档块打印出来看召回是否合理这在调优阶段太重要了。要是封装的库太复杂你很难判断问题是出在向量库、切分还是 Embedding而 Chroma 的简单性让定位问题变得非常快。2.4 DeepSeek 在链路里的角色定位与关键参数DeepSeek 在整套系统里只干一件事根据检索到的上下文生成最终答案。不要让它承担记忆知识库的作用那是向量库的事。调用参数上我们踩过很多坑最核心的是 temperature 和 max_tokens。temperature 是生成随机性的控制参数刚开始用了默认值结果答案发散、用词飘文档里明明没有的内容也会被编造。后来把 temperature 降到 0.1回答立刻变得克制很多基本能做到资料里有就答资料里没有就直说不知道。max_tokens 也要根据回答长度合理设置。企业制度问题的答案一般不会太长设 512 足够但如果是产品技术文档问答可能要 1024。设太短会把答案截断在半句话上设太长会增加等待时间和费用。另外DeepSeek 的上下文窗口比早期版本大很多但 RAG 场景下千万不要把所有检索结果都塞进去一般取 top-k 的 4 到 6 个文档块、每块几百字总上下文控制在模型合理范围内既省 token也能避免无关信息干扰模型。还有一个容易忽略的点模型版本会迭代。DeepSeek 官方会定期发布新版本不同版本的指令遵循能力可能有差异。我们在代码里把 model 参数从环境变量读取这样升级模型时不用改代码改配置就能切。上线后要留意 API 返回的错误日志尤其是超时和限流需要做重试和降级策略。3. 从零搭建数据准备到问答全流程实操3.1 环境准备与依赖安装我的实操环境是 Python 3.10操作系统用的 LinuxWindows 上也能跑只是路径写法稍有不同。建议新建一个虚拟环境避免依赖冲突。下面这些包是核心依赖装完之后做基础验证。pip install langchain langchain-openai langchain-community langchain-text-splitters pip install chromadb pip install sentence-transformers pip install pypdf版本问题很容易让人崩溃。当前 LangChain 的 API 更新很快很多网上教程用的还是老式链式写法复制下来直接报错。我的建议是安装完成后在 Python 命令行里打印一下langchain.__version__记住版本再配合对应版本的文档写代码。不要盲目追最新版稳定能跑比什么都强。如果遇到ModuleNotFoundError多半是替代了旧包把langchain_community单独装一下就能解决。3.2 文档加载与清洗企业内部文档格式基本是群魔乱舞有 PDF、Word、Markdown、Excel甚至还有扫描件。先看一个最基础的加载方式通过DirectoryLoader指定目录和扩展名把整个目录下的文档一次性读进来。from langchain_community.document_loaders import DirectoryLoader, TextLoader, PyPDFLoader loader DirectoryLoader( ./docs, glob**/*.txt, loader_clsTextLoader, loader_kwargs{encoding: utf-8}, ) docs loader.load() pdf_loader DirectoryLoader( ./docs, glob**/*.pdf, loader_clsPyPDFLoader, ) pdf_docs pdf_loader.load()加载完成后千万别直接切分先做清洗。我见过很多文档里全是页眉页脚、每行末尾的软回车、表格转出来的大量空白字符这些噪音会让向量被严重带偏。清洗函数可以这样写。import re def clean_text(text: str) - str: # 去除页眉页脚常见内容保留正文 text re.sub(r第\s*\d\s*页, , text) text re.sub(r[\u3000\s], , text) # 把连续三个以上的换行压缩成两个 text re.sub(r\n{3,}, \n\n, text) return text.strip() for doc in docs: doc.page_content clean_text(doc.page_content) docs [doc for doc in docs if len(doc.page_content) 50]清洗过程中有一条红线要注意不要过度清洗。有些文档里的换行是有语义的比如表格的每个单元格换行、列表的条目换行全压成空格反而丢失结构。更稳妥的做法是先把 PDF 转成 Markdown 再清洗保留标题层级和列表结构。我们中途换过一次解析工具最终阶段把所有文档统一转成 Markdown效果提升非常明显。3.3 文档切分chunk_size 和 chunk_overlap 到底怎么调切分是整个 RAG 流程里最能决定命运算的一步。切太大检索出来的信息太杂模型抓不到重点切太小一段完整的意思被劈成两半回答起来缺胳膊少腿。我常用的基线配置是chunk_size 500chunk_overlap 100分隔符按中文语言习惯排列。from langchain_text_splitters import RecursiveCharacterTextSplitter text_splitter RecursiveCharacterTextSplitter( chunk_size500, chunk_overlap100, separators[\n\n, \n, 。, , , , , , ], ) chunks text_splitter.split_documents(docs)为什么分隔符要这么排RecursiveCharacterTextSplitter会从左往右依次尝试分隔符优先用双换行保持段落完整如果切出来的块还超过chunk_size就往下用单换行再不行就用句号、感叹号、问号这类句子边界。这样切出来的块尽量在语义完整的地方断开。如果把分隔符顺序写反系统会退化成纯按字符硬切中文句子被从中间砍断的情况非常严重。chunk_size和chunk_overlap没有绝对最优取决于文档类型。制度条文多的用 400 到 500 比较合适技术手册这种上下文依赖强的建议放大到 800 到 1000overlap 150。调参方法很朴素拿 10 个典型问题切完索引后逐个查召回结果打印出每个 chunk 的文本肉眼判断内容是否完整。观察几轮之后你会对自己文档的特性有直觉再调整参数就快了。还有一类文档必须特殊处理表格。普通文本切分会把表格切开导致语义完全丢失。我们的做法是用MarkdownHeaderTextSplitter按标题层级切分并把表格整体保留为一个独立 chunk后面会根据情况把表格单独放到一个命名空间里索引。如果你处理的文档里表格很多建议单独建一条处理管线不要和普通正文混在一起。3.4 向量化与入库把文本变成可检索的数量这一步把切好的块转成向量并写入向量库。我们用HuggingFaceEmbeddings加载本地中文模型这里直接指定模型路径方便内网部署。Chroma 持久化到本地目录下次启动不用重新索引。from langchain_community.embeddings import HuggingFaceEmbeddings from langchain_community.vectorstores import Chroma embedding_model HuggingFaceEmbeddings( model_name./models/bge-base-zh-v1.5, model_kwargs{device: cpu}, encode_kwargs{normalize_embeddings: True}, ) vectorstore Chroma.from_documents( chunks, embedding_model, persist_directory./chroma_db, )这里有一个非常重要的细节normalize_embeddings要设为 True。它会将向量归一化到单位长度这样用余弦相似度计算时数值更稳定对检索质量有正向帮助。代价是额外一点点计算量但完全值得。另外入库时一定要把元数据写全。LangChain 的 Document 对象有metadata字段我们至少会放三个键source记录文件名page记录页号title记录标题或章节。生产环境还要加上department用于权限过滤、updated_at用于增量更新。后面做引用溯源、权限控制、增量重建都依赖这些元数据一开始设计好省得后面返工。写入 Chroma 之后可以用一条测试向量验证一下。把离职流程这类问题转成向量用similarity_search去库里找看召回的前三名是不是真的提到了离职相关内容。如果召回内容完全不搭不要怀疑向量库优先怀疑切分和 Embedding 模型是否匹配这个排查逻辑很重要。3.5 组装检索问答链路LangChain 把它们串起来核心链路代码大概几十行关键是 Prompt 设计。先定义 DeepSeek 模型再挂载检索器最后用create_retrieval_chain把检索生成组装起来。import os from langchain_openai import ChatOpenAI from langchain.prompts import ChatPromptTemplate from langchain.chains import create_retrieval_chain from langchain.chains.combine_documents import create_stuff_documents_chain llm ChatOpenAI( modeldeepseek-chat, # 也可以从环境变量读取 api_keyos.getenv(DEEPSEEK_API_KEY), base_urlhttps://api.deepseek.com, temperature0.1, max_tokens512, ) retriever vectorstore.as_retriever(search_kwargs{k: 5}) prompt ChatPromptTemplate.from_messages([ (system, 你是企业知识库助手。请严格基于以下资料回答问题。 资料中没有的信息请明确回答“资料未提及”不要自行编造。 回答时在句末标注来源格式为[1][2]。 资料 {context}), (human, 问题{input}), ]) combine_docs_chain create_stuff_documents_chain(llm, prompt) rag_chain create_retrieval_chain(retriever, combine_docs_chain) result rag_chain.invoke({input: 新员工入职流程是什么}) print(result[answer]) for doc in result.get(context, []): print(doc.metadata[source], doc.page_content[:100])k5是召回条数取多少直接影响效果。取 3 时答案可能信息不足取 10 时无关信息多模型容易被干扰token 消耗也翻倍。我们最终停在 5配合重排模型后是效果与成本的最佳平衡。这个值没有标准答案你可以用相同的问题集分别设置 3、5、8 做 AB 测试看答案准确率和完整度。调用时result[answer]是生成的答案result[context]是实际召回到的文档块。这两个输出在调试阶段一定要打出来看能直观看到模型到底基于什么内容回答了。前端展示时把metadata[source]拼成引用链接员工点击就能看到原文出处这个功能对企业问答极其重要。3.6 让问答更实用历史对话与上下文记忆原始的单轮问答在真实场景下不够用员工经常会追问那需要什么材料这个流程要几天这类依赖上文的问题。LangChain 提供了消息历史机制让模型能结合之前几轮对话理解当前问题。from langchain_core.chat_history import BaseChatMessageHistory from langchain_core.runnables.history import RunnableWithMessageHistory from langchain_core.messages import HumanMessage, AIMessage store {} def get_session_history(session_id: str) - BaseChatMessageHistory: if session_id not in store: store[session_id] [] return store[session_id] # 简化版用 RunnableWithMessageHistory 包一层 rag_with_history RunnableWithMessageHistory( rag_chain, get_session_history, input_messages_keyinput, history_messages_keychat_history, ) result rag_with_history.invoke( {input: 需要准备什么材料}, config{configurable: {session_id: user_001}}, )加上历史之后要注意一个问题检索只针对当前问题不针对历史消息中的隐含意图。如果用户问那社保要交多久这个问题本身缺少主语向量检索会召回不到。简单的方案是先用一个轻量模型做历史对话改写把当前问题补全成独立问题再检索。这一步能显著提升追问的召回率但同时也多一次模型调用需要评估延迟。若并发不高建议加上。4. 上线后踩过的坑与调优实录4.1 召回质量差先别急着换模型检查三个地方第一次联调时我问公司年假怎么算答案牛头不对马嘴。第一反应是 DeepSeek 模型不够聪明后来打印context一看召回的内容压根没提年假全是团建活动描述。问题出在召回环节跟生成模型没有关系。排查思路分三步先看切分是否把相关段落切碎了再看 Embedding 模型是否理解这个业务领域的说法最后看相似度分数是不是普遍偏低。切碎问题可以通过调整chunk_size解决。Embedding 理解问题比较棘手企业文档里有很多内部简称比如离场在文档里完全没出现过离职但员工提问会写离职。这个对普通中文向量模型来说很难直接匹配。我们做了两层兜底第一层是维护一份同义术语表在提问预处理阶段做同义词扩展把离职替换成离场、离职、离开公司再检索第二层是引入重排模型把 top-20 的候选结果重新打分把真正相关的结果排到前面。这两步加进去之后召回质量肉眼可见提升了一个档次。4.2 回答幻觉Prompt 和温度要一起治就算召回对了模型仍然可能编造。比如文档里只写了试用期六个月模型回答时擅自加了一句试用期工资打八折。这个问题光调温度治标不治本必须让 Prompt 把行为边界说死。我们的最新版 Prompt 明确写着你只能使用资料中的事实。禁止使用常识进行补充。如果资料不足以回答问题请直接回复‘资料库中未找到相关内容建议咨询人力资源部’。这句话效果很明显编造率从接近三成降到个位数。还要注意DeepSeek 有很强的推断能力你让它根据资料回答它会自动补全很多看似合理的细节。所以不要给模型发挥的空间。temperature0.1是经验值如果你发现偶发编造可以继续降到 0同时把max_tokens控制在合理范围避免模型为了凑字数而展开。另外回答末尾强制输出引用来源让模型每次回答都要对着引用检查一遍这个自我约束机制多次验证有效。4.3 文档切碎导致答案缺胳膊少腿用结构化切分补救有一类问题特别暴露切分缺陷问的是试用期请假规定文档里试用期和请假在两个不同章节切分后各自成为独立 chunk单个 chunk 都没有完整答案。表面看是召回不够本质是切分粒度与知识粒度不匹配。解决办法是把知识粒度上移。对于规章制度类文档不要机械按 500 字切而是先用MarkdownHeaderTextSplitter按二级标题切这样整个请假制度章节会作为一个大 chunk 保留。如果章节仍然很长再在这个章节内部按句子边界切。这样切出来的 chunk 虽然大小不均匀但每个 chunk 都是一个完整的知识单元。后来我们甚至把概况和流程做了关联 metadata检索到子章节时同时携带父章节标题上下文信息量大幅增加。4.4 企业落地权限隔离、审计与成本控制企业内部知识库绕不开权限。最粗糙的做法是所有人都能检索所有文档这在制度问答里风险很大。我们用 Chroma 的 metadata 过滤实现部门级隔离文档入库时标记department字段检索时根据当前用户的部门编码生成过滤条件。retriever vectorstore.as_retriever( search_kwargs{ k: 5, filter: {department: current_user_department} } )这个做法的前提是登录系统已经打通了账号体系并拿到了用户部门信息。如果文档密级更高可以在检索前加一层显式校验拒绝无权限用户的请求。审计方面我们记录了每一次问答的输入、输出、召回内容、来源文档和时间戳写入独立日志表。员工可以放心使用管理员可以追踪任何一条回答的依据。成本控制上最大的开销是 API token 消耗。RAG 模式下每次问答需要把 top-k 的文档块都传给模型token 消耗比纯对话大不少。优化手段有两个一是提高检索精度确保传进去的内容都是有用的二是设置缓存相同问题在限定时间内直接返回历史答案命中率提高后排除了很大一部分重复咨询。我们上线一个月后缓存命中率约四成费用下降了三分之一左右。4.5 常见问题速查表症状可能原因解决方向问题有答案但检索不到切块过碎、Embedding 语义弱、术语不一致调整 chunk 参数换中文 Embedding加同义词扩展召回了相关内容但答案乱编Prompt 约束不足、温度过高强化 Prompt 边界temperature 降到 0.1 以下回答总是资料未提及chunk 太小丢上下文、k 值太小增大 chunk_size/overlap提高 k 值引入重排相同问题每次回答不一样temperature 过高temperature 固定为 0开启缓存并发一高就超时报错模型 API 限流、向量检索过慢加本地缓存请求重试必要时升级模型服务并发5. 上线前必做的几件事和个人心得体会5.1 上线前必过的测试清单这套系统交付前我有一套固定的测试清单。第一项是准备 30 个真实员工问题这些问题必须来自实际业务不能自己拍脑袋造。把这些问题跑一遍逐个看检索召回的context是否准确再看答案是否完整、是否用了正确依据。第二项是专门准备几个知识盲区问题比如问一个文档里完全没有的话题看系统会不会硬答。如果它开始编就说明 Prompt 约束还不到位。第三项是权限测试用两个不同部门的测试账号问同样的问题确认结果隔离正常。第四项是并发压测20 个用户同时提问看平均延迟和失败率。前两项直接决定问答质量第三项决定能不能过安全评审第四项决定用户体感。每一项都不能省尤其是在多个部门同时使用的场景下忽略了任何一项都可能上线后翻车。5.2 我再啰嗦几个容易忽视的经验第一文档版本管理一定要做。我们有一段时间发现答案总是引用旧制度排查了半天才发现文档更新后没重新跑索引向量库里还是旧内容。后来把文档的updated_at字段纳入索引定时任务检查到文件变化就只重建那个文件的向量问题才彻底解决。第二不要把知识库等同于一堆 PDF 丢进去。文档的初始质量决定最终上限源文档本身混乱RAG 只能做到在混乱中找相对准确。建议让文档所有者先按模板整理一遍效果立竿见影比调多少参数都管用。第三迭代时不要只改代码不看效果。每一轮修改后都跑一遍那 30 个基础问题对比修改前后的答案变化。我见过太多人调了chunk_size后觉得自己优化了结果召回率反而下降。保留一份基线测试集才能让优化有方向。第四团队里一定要有一个人能看懂 LangChain 的报错日志。生产环境出问题时最常见的情况是 API 超时、依赖版本不匹配、向量库文件损坏。掌握这些问题的排查手法比写新功能更紧急。我们后来专门写了一个健康检查脚本定时检查向量库能否正常加载、API 是否可用、索引是否是最新版本有问题就告警到工作群。这样一套保障做完系统才敢说真正达到了可用的状态。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑