资讯动态

基于InternLM与LangChain构建本地智能知识库:从RAG原理到工程实践

发布时间:2026/8/6 5:54:19 来源:尧图企业网站定制
1. 项目概述为什么选择 InternLM 和 LangChain 来搭建知识库最近在折腾个人和团队的知识管理发现了一个挺普遍的问题文档越堆越多但想找点东西时要么记不清文件名要么得在一堆PDF和Word里大海捞针。传统的搜索只能匹配关键词稍微换个说法就找不到了。直到我开始接触大语言模型和RAG技术才感觉找到了出路。这个项目就是基于开源的InternLM大模型和LangChain框架动手搭建一个真正“能理解你问题”的智能知识库。简单来说这个知识库的核心能力是你不再需要记住文档里确切的词句可以用自然语言提问比如“我们去年Q3关于市场推广的复盘报告里提到了哪些用户增长瓶颈”系统能自动从你上传的所有文档中找到相关片段并组织成通顺的答案回复你。这背后依赖两个关键技术LangChain负责整个流程的编排比如文档加载、切分、向量化存储和检索而InternLM则作为理解问题和生成答案的“大脑”。选择它们组合主要是看中了InternLM优秀的开源中文理解能力以及LangChain在构建AI应用链路上极高的灵活性和丰富的工具生态。对于开发者、技术团队或者任何有大量非结构化文档需要管理的个人来说这都是一套能显著提升信息获取效率的实用方案。2. 核心架构与工具选型解析搭建一个可用的知识库远不止是调个API那么简单。它是一套系统工程需要仔细考虑每个环节的工具和技术选型。下面这张图概括了从原始文档到智能问答的完整流程也是我们本次搭建的核心架构flowchart TD A[原始文档brPDF/Word/TXT等] -- B[文档加载与解析] B -- C[文本分割br按语义切块] C -- D[向量化嵌入brText Embedding Model] D -- E[向量数据库存储] F[用户自然语言提问] -- G[问题向量化] G -- E E -- H[相似性检索brTop-K相关文本块] H -- I[构建提示词模板] I -- J[大语言模型理解与生成brInternLM] J -- K[返回结构化答案]接下来我们详细拆解每个环节的选型考量。2.1 大模型核心为什么是 InternLM在中文场景下模型的选择至关重要。我们放弃了直接调用闭源API如GPT-4的方案主要基于成本、数据隐私和定制化需求考虑。在开源模型中InternLM系列特别是 InternLM2脱颖而出原因如下卓越的中文能力InternLM 由上海人工智能实验室开发在训练语料中包含了高质量、大规模的中文数据使其在中文理解、推理和生成任务上表现非常出色远超同规模的其他开源模型。对于知识库问答这种需要精准理解用户意图和文档内容的场景这是基础保障。宽松的开源协议InternLM2 采用了 Apache 2.0 许可证这意味着我们可以自由地将其用于商业项目、进行修改和分发没有法律风险。优秀的上下文长度最新版本支持长达200K的上下文窗口。虽然单次问答可能用不到这么长但对于需要处理长文档或进行复杂推理的任务这是一个巨大的优势。丰富的量化版本官方和社区提供了多种量化版本如 4bit, 8bit可以大幅降低模型运行对GPU显存的要求。例如7B参数的模型经过4bit量化后仅需约4GB显存即可运行使得在消费级显卡上部署成为可能。实操心得模型版本选择对于知识库问答场景通常不需要模型具备极强的创意写作或代码生成能力核心是可靠的阅读理解与信息整合。因此InternLM2-7B 或 InternLM2-20B 的对话版本-chat后缀是性价比很高的选择。20B模型能力更强但需要更多的计算资源。个人建议从7B开始如果对答案质量不满意再考虑升级。2.2 应用框架LangChain 的核心价值与替代方案LangChain在这个项目中扮演着“胶水”和“调度中心”的角色。它的核心价值在于组件化将文档加载、文本分割、向量化、检索、提示词构建、模型调用等步骤抽象成独立的模块Component。我们可以像搭积木一样组合它们而无需从零编写每一段管道代码。链Chain这是LangChain的核心概念。它定义了上述组件执行的顺序和逻辑。我们构建的“检索问答链”RetrievalQA Chain就是一个标准链它自动化地执行“检索相关文档 - 组合成提示词 - 调用模型 - 返回答案”的完整流程。丰富的集成LangChain 集成了数百种工具包括各种文档加载器PDF, Word, Markdown, 网页、向量数据库Chroma, Pinecone, Weaviate、大模型接口等极大减少了适配工作量。那么Dify、LangGraph和LangChain是什么关系这是当前热词中的一个常见困惑。LangChain是基础框架提供底层组件和链。灵活性最高但需要一定的开发能力。Dify是一个开源的AI 应用开发平台它提供了可视化的界面让你可以通过拖拽的方式配置工作流包括知识库。Dify 的后端可能使用了 LangChain 或其他类似框架。它的优点是开箱即用降低了门槛缺点是对底层流程的控制不如直接编码灵活。LangGraph是 LangChain 的一个扩展库用于构建有状态、多步骤的复杂代理Agent。如果你的知识库问答需要穿插使用搜索引擎、计算器等工具或者需要多轮对话记忆LangGraph 就派上用场了。对于基础的“检索-生成”问答标准的 LangChain 链已经足够。选型建议如果你是开发者希望深入理解原理并拥有完全控制权直接从 LangChain 开始是最好的选择。如果你追求快速上线且对界面有要求Dify 是更友好的工具。本项目选择 LangChain旨在深入技术细节。2.3 向量数据库从 Chroma 到 PGVector 的选型思考向量数据库负责存储和快速检索经过向量化的文本块。选型主要考虑易用性、性能和可扩展性。Chroma入门首选。它是一个轻量级的嵌入式向量数据库无需单独部署服务器几行代码就能集成到Python程序中。非常适合原型验证、个人项目或中小规模知识库。它的API和LangChain集成得非常好学习成本极低。PGVector生产级推荐。它是 PostgreSQL 的一个扩展使得 PostgreSQL 可以直接存储和查询向量。选择它意味着数据一致性你的向量数据和原始的元数据如文档ID、文件名、段落标题可以存储在同一张关系型数据库表中利用事务保证一致性这是嵌入式数据库难以做到的。成熟生态可以直接利用 PostgreSQL 的所有功能如备份、复制、权限管理、复杂的SQL查询结合元数据过滤。可扩展性PostgreSQL 的集群方案成熟可以应对未来数据量增长。部署稍复杂需要单独部署和维护 PostgreSQL 实例。实操心得如何选择对于个人知识库或项目初期强烈建议使用Chroma。它能让你在5分钟内跑通整个流程把精力集中在核心逻辑上。当知识库文档量超过万级或者需要与现有业务系统用户数据、权限等深度集成时再考虑迁移到PGVector。本项目的后续实操部分将以 Chroma 为例因为它最能体现快速搭建的精髓。2.4 嵌入模型文本向量化的关键嵌入模型负责将文本转换成高维向量一组数字。检索的质量很大程度上取决于嵌入模型的好坏。好的嵌入模型能让语义相似的文本在向量空间中的距离更近。开源选择text2vec、BGEBAAI General Embedding系列是目前中文社区评价很高的开源嵌入模型。例如BGE-small-zh模型在中文语义相似度任务上表现好且体积小、速度快。API选择OpenAI 的text-embedding-ada-002曾是行业标杆但需要付费且可能涉及数据出境。国内一些大模型平台也提供了嵌入API。选型考量对于本地化部署的项目使用开源的BGE模型是更独立、可控的选择。我们可以通过Hugging Face或ModelScope轻松下载和加载这些模型。3. 环境准备与依赖安装在开始编码之前我们需要准备好Python环境和项目依赖。这里我推荐使用conda或venv创建独立的虚拟环境避免包冲突。3.1 创建并激活虚拟环境# 使用 conda推荐 conda create -n langchain-kb python3.10 conda activate langchain-kb # 或使用 venv python -m venv langchain-kb # Windows .\langchain-kb\Scripts\activate # Linux/Mac source langchain-kb/bin/activate3.2 安装核心依赖库创建一个requirements.txt文件内容如下。这里包含了LangChain、本地模型运行、向量数据库、文档解析等核心库。langchain0.1.0 langchain-community0.0.10 # 社区贡献的组件 langchain-chroma0.1.0 # Chroma向量数据库集成 chromadb0.4.22 # Chroma客户端 sentence-transformers2.2.2 # 用于运行开源嵌入模型 unstructured0.10.30 # 强大的文档解析库 pdf2image1.16.3 # 用于PDF解析如果unstructured需要 poppler-utils # PDF处理工具系统级依赖需单独安装 pypdf3.17.4 # PDF文本提取 markdown3.5.1 docx2txt0.8 # 处理Word文档 # 模型运行相关 transformers4.36.0 accelerate0.25.0 bitsandbytes0.41.3 # 用于模型量化降低显存消耗 torch2.1.0 # 根据你的CUDA版本选择此处以CPU/CUDA11.8为例然后使用pip安装pip install -r requirements.txt注意poppler-utils是系统依赖。在Ubuntu/Debian上可以用sudo apt-get install poppler-utils安装在Mac上可以用brew install popplerWindows用户可以从官网下载二进制包并添加至PATH。3.3 准备模型文件我们需要准备两个模型嵌入模型例如BAAI/bge-small-zh。LangChain 在第一次使用时会自动从 Hugging Face 下载但国内网络可能较慢。建议提前下载或使用镜像。大语言模型InternLM2。可以从ModelScope魔搭社区或Hugging Face下载。ModelScope 在国内的下载速度通常更快。提前下载 InternLM2-7B-Chat 模型示例# 使用 modelscope pip install modelscope from modelscope import snapshot_download model_dir snapshot_download(Shanghai_AI_Laboratory/internlm2-chat-7b, cache_dir./models) # 或者直接从Hugging Face需配置网络环境 # from huggingface_hub import snapshot_download # snapshot_download(repo_idinternlm/internlm2-chat-7b, local_dir./models/internlm2-chat-7b)将模型保存在本地目录如./models中后续加载时指定本地路径即可避免每次运行都下载。4. 分步实现构建你的第一个智能知识库现在我们开始动手编码。整个过程可以分为五个步骤文档加载、文本分割、向量化与存储、检索链构建、问答交互。4.1 第一步文档加载与解析知识库的“原料”是你的文档。LangChain 通过DocumentLoader来统一处理不同格式的文件。我们将文档加载为Document对象该对象包含页面内容page_content和元数据metadata如来源、页码。from langchain_community.document_loaders import DirectoryLoader, TextLoader, PyPDFLoader, UnstructuredWordDocumentLoader from langchain.schema import Document import os # 设置文档目录 doc_directory ./my_docs # 方法1使用 DirectoryLoader 自动识别和加载多种格式 # 需要为每种格式指定对应的加载器 loaders { .txt: TextLoader, .pdf: PyPDFLoader, .docx: UnstructuredWordDocumentLoader, .doc: UnstructuredWordDocumentLoader, } documents [] for ext, loader_cls in loaders.items(): loader DirectoryLoader(doc_directory, globf**/*{ext}, loader_clsloader_cls, show_progressTrue) loaded_docs loader.load() documents.extend(loaded_docs) print(fLoaded {len(loaded_docs)} documents with extension {ext}) print(fTotal documents loaded: {len(documents)}) # 方法2分别加载更清晰 # txt_files DirectoryLoader(doc_directory, glob**/*.txt, loader_clsTextLoader).load() # pdf_files DirectoryLoader(doc_directory, glob**/*.pdf, loader_clsPyPDFLoader).load() # ... 然后合并注意事项PyPDFLoader对纯文本PDF效果好但对扫描版或复杂排版的PDF解析能力有限。Unstructured库更强大但依赖更多系统组件如popplertesseractOCR。加载时尽量为每个Document保留有用的元数据如source文件路径这便于后续追溯答案来源。4.2 第二步文本分割分块我们不能将整篇长文档直接向量化因为大模型的上下文长度有限且检索精度会下降。需要将文档分割成大小适中的“块”。from langchain.text_splitter import RecursiveCharacterTextSplitter # 创建文本分割器 text_splitter RecursiveCharacterTextSplitter( chunk_size500, # 每个块的最大字符数 chunk_overlap100, # 块之间的重叠字符数避免语义被割裂 length_functionlen, # 计算长度的方法 separators[\n\n, \n, 。, , , , , 、, , ] # 分割符优先级 ) # 执行分割 all_splits text_splitter.split_documents(documents) print(f原始文档数: {len(documents)} 分割后块数: {len(all_splits)})参数详解与心得chunk_size这是最重要的参数。太小会丢失上下文太大会降低检索精度并增加模型负担。对于中文500-800是一个不错的起点。InternLM2支持长上下文但检索时我们通常只取前几个最相关的块所以块不宜过大。chunk_overlap重叠部分能保证一个完整的句子或概念不会因为恰好处于边界而被切断。通常设为chunk_size的10%-20%。separators递归分割器会按这个列表的顺序尝试分割。对于中文我们加入了中文标点。确保最后一个分隔符是空字符串作为最后的手段。4.3 第三步向量化与存储到 Chroma这一步我们将文本块转换为向量并存入向量数据库。from langchain.embeddings import HuggingFaceEmbeddings from langchain.vectorstores import Chroma # 1. 初始化嵌入模型 # 使用本地下载的 BGE 模型或者直接指定名称会自动下载 embed_model_name ./models/bge-small-zh # 假设模型已下载到本地 # 或者: embed_model_name BAAI/bge-small-zh embeddings HuggingFaceEmbeddings( model_nameembed_model_name, model_kwargs{device: cpu}, # 如果没有GPU使用cpu。有GPU可改为cuda encode_kwargs{normalize_embeddings: True} # 归一化有助于提升相似度计算效果 ) # 2. 创建向量数据库并持久化 # persist_directory 指定持久化目录这样下次启动无需重新计算向量 persist_directory ./chroma_db vectordb Chroma.from_documents( documentsall_splits, embeddingembeddings, persist_directorypersist_directory ) # 显式持久化 vectordb.persist() print(f向量数据库已创建并保存至 {persist_directory} 包含 {vectordb._collection.count()} 个向量。)实操心得设备选择嵌入模型推理相对轻量。如果只有CPU速度会慢一些但完全可以接受。如果有GPU即使是消费级的将device改为cuda会快很多。持久化persist()操作非常重要。首次创建向量库耗时较长尤其是文档多时。保存后下次启动应用可以直接加载现有数据库无需重新处理文档。# 后续加载已有数据库 vectordb Chroma(persist_directorypersist_directory, embedding_functionembeddings)4.4 第四步构建检索问答链这是连接向量数据库和大模型的核心。我们使用 LangChain 的RetrievalQA链。from langchain.chains import RetrievalQA from langchain.prompts import PromptTemplate from langchain_community.llms import HuggingFacePipeline from transformers import AutoTokenizer, AutoModelForCausalLM, pipeline import torch # 1. 加载本地 InternLM2 模型 model_path ./models/internlm2-chat-7b # 本地模型路径 tokenizer AutoTokenizer.from_pretrained(model_path, trust_remote_codeTrue) # 加载模型使用量化以节省显存 model AutoModelForCausalLM.from_pretrained( model_path, torch_dtypetorch.float16, # 半精度 device_mapauto, # 自动分配模型层到可用的GPU/CPU trust_remote_codeTrue ) # 创建文本生成管道 pipe pipeline( text-generation, modelmodel, tokenizertokenizer, max_new_tokens512, # 生成答案的最大长度 temperature0.1, # 较低的温度使输出更确定、更聚焦 do_sampleTrue, ) # 包装成 LangChain 的 LLM 接口 llm HuggingFacePipeline(pipelinepipe) # 2. 定义自定义提示词模板 # 这是控制模型行为的关键一个好的模板能显著提升答案质量。 prompt_template 请根据以下上下文信息回答问题。如果你不知道答案就诚实地回答不知道不要编造信息。 上下文 {context} 问题{question} 请根据上下文给出详细、准确的回答 PROMPT PromptTemplate( templateprompt_template, input_variables[context, question] ) # 3. 创建检索器 # search_kwargs 控制检索行为 retriever vectordb.as_retriever( search_typesimilarity, # 相似度检索 search_kwargs{k: 4} # 返回最相关的4个文本块 ) # 4. 创建检索问答链 qa_chain RetrievalQA.from_chain_type( llmllm, chain_typestuff, # 最简单的方式将所有检索到的上下文塞进提示词 retrieverretriever, chain_type_kwargs{prompt: PROMPT}, # 使用自定义提示词 return_source_documentsTrue # 返回源文档便于追溯 ) print(智能知识库问答链构建完成)关键点解析device_map”auto”让transformers库自动处理模型层在多个GPU或GPU与CPU之间的分配对于显存不足的情况非常有用。提示词模板模板中的{context}和{question}是占位符LangChain 会自动替换。我们明确要求模型“根据上下文”回答并“不知道就说不知道”这能有效减少模型幻觉胡编乱造。检索器参数k这个值需要权衡。k越大提供给模型的上下文信息越多但可能引入不相关噪声且可能超过模型上下文限制。通常从3-5开始尝试。chain_type”stuff”是最直接的方式。还有其他如”map_reduce”先分别处理每个块再汇总、”refine”迭代精炼等适用于极长文档但更复杂。对于大多数场景”stuff”足够了。4.5 第五步运行与测试现在我们可以与知识库进行交互了。# 定义一个简单的问答函数 def ask_question(qa_chain, query): print(f\n用户问题: {query}) print(---) result qa_chain({query: query}) print(fAI回答: {result[result]}) print(\n参考来源:) for i, doc in enumerate(result[source_documents][:2]): # 展示前2个来源 print(f [{i1}] {doc.metadata.get(source, N/A)} (片段: {doc.page_content[:100]}...)) print(---) # 测试几个问题 if __name__ __main__: # 示例问题应与你的文档内容相关 test_queries [ 我们公司今年的主要战略目标是什么, 在项目管理办法中关于风险管理流程是如何规定的, 请总结一下上周技术分享会的主要内容。 ] for query in test_queries: ask_question(qa_chain, query)运行这段代码你应该能看到模型基于你的文档内容生成的答案并附上了答案片段的出处。至此一个最基本的本地化智能知识库就搭建完成了。5. 性能优化与高级技巧基础版本跑通后我们可以从多个维度进行优化提升系统的准确性、速度和用户体验。5.1 提升检索质量超越简单相似度搜索默认的相似度搜索search_type”similarity”有时会漏掉关键信息。我们可以尝试更高级的检索策略最大边际相关性MMR在保证相关性的同时增加结果之间的多样性避免返回多个高度重复的片段。retriever vectordb.as_retriever( search_typemmr, # 使用MMR search_kwargs{k: 4, fetch_k: 10, lambda_mult: 0.7} # fetch_k: 初始检索的文档数 lambda_mult: 多样性权重0-11表示完全多样性 )元数据过滤如果你的文档元数据丰富如文档类型、部门、日期可以在检索时增加过滤条件实现更精准的搜索。# 假设你的文档有 doc_type 元数据字段 retriever vectordb.as_retriever( search_kwargs{k: 4, filter: {doc_type: 技术报告}} # 只检索技术报告 )混合搜索结合传统的关键词搜索如BM25和向量搜索取长补短。关键词搜索对精确术语匹配好向量搜索对语义匹配好。LangChain 可以通过EnsembleRetriever实现。5.2 优化模型推理速度与显存占用在本地运行7B甚至20B的模型对资源是挑战。除了使用量化还有以下技巧使用vLLM或TGI部署对于生产环境或需要高并发可以将模型部署为独立的推理服务。vLLm以其极高的吞吐量和高效的PagedAttention内存管理而闻名。这样你的LangChain应用只需通过API调用模型服务。调整生成参数max_new_tokens根据答案长度合理设置不要过长。temperature问答场景下设置为较低值如0.1-0.3以获得更确定、更聚焦的答案。top_p(nucleus sampling)与temperature配合使用例如top_p0.9。启用注意力缓存在pipeline中设置use_cacheTrue默认开启可以加速连续的生成过程。5.3 构建带历史记录的对话链基础的RetrievalQA是无状态的每次问答都是独立的。要实现多轮对话需要引入记忆Memory。from langchain.memory import ConversationBufferMemory from langchain.chains import ConversationalRetrievalChain # 创建记忆体保存对话历史 memory ConversationBufferMemory(memory_keychat_history, return_messagesTrue, output_keyanswer) # 创建对话式检索链 conversational_qa_chain ConversationalRetrievalChain.from_llm( llmllm, retrieverretriever, memorymemory, chain_typestuff, combine_docs_chain_kwargs{prompt: PROMPT}, # 仍然使用自定义提示词 verboseFalse # 设为True可以看到链的详细执行过程 ) # 使用示例 query1 我们项目的截止日期是什么时候 result1 conversational_qa_chain({question: query1}) print(fAI: {result1[answer]}) query2 那之前有哪些主要的里程碑 # 这里的“那之前”指代上一个问题的项目 result2 conversational_qa_chain({question: query2}) # 链会自动将历史对话和当前问题组合 print(fAI: {result2[answer]})这样系统就能理解上下文中的指代关系了。6. 常见问题排查与实战心得在实际搭建和运行过程中你肯定会遇到各种问题。这里记录了一些典型坑点和解决方案。6.1 模型加载与运行问题问题OutOfMemoryError (CUDA)显存不足。解决方案使用量化在from_pretrained中增加参数load_in_4bitTrue或load_in_8bitTrue。需要bitsandbytes库支持。使用CPUdevice_map”cpu”但推理速度会慢很多。使用vLLM部署它管理显存更高效。换用更小的模型如InternLM2-1.8B。问题生成速度非常慢。排查首先确认是否使用了GPU。在代码中打印torch.cuda.is_available()和model.device。优化确保torch安装了CUDA版本。尝试减小max_new_tokens。对于嵌入模型如果文档很多且频繁调用可以考虑将其也部署为独立服务或使用更轻量的模型。6.2 检索与问答质量问题问题答案与文档内容无关幻觉。排查首先检查source_documents看检索到的上下文是否真的与问题相关。如果不相关问题在检索端。优化检索调整文本分割的chunk_size通常调小尝试不同的嵌入模型如换用BGE-large-zh使用MMR或混合搜索。优化提示词在提示词中加强指令如“必须严格依据上下文回答上下文未提及的内容一律回答‘不知道’”。问题答案不完整只复述了检索到的一个片段。优化增加检索的k值让模型看到更多上下文。在提示词中要求“综合所有上下文信息给出完整回答”。6.3 工程化与部署问题问题每次启动都要重新生成向量库太慢。解决确保正确使用了persist_directory和vectordb.persist()。加载时使用Chroma(persist_directory..., embedding_function...)。问题如何增量更新知识库新增文档后不想全部重做。解决Chroma 支持增量添加。将新文档分割后调用vectordb.add_documents(new_splits)即可。注意这不会自动删除旧文档如果需要“更新”某个源文件最好先根据元数据如source路径删除旧的向量再添加新的。一个重要的心得评估与迭代搭建知识库不是一蹴而就的。准备一个由“问题-标准答案”组成的测试集QA pairs定期运行测试评估答案的准确率、相关性和完整性。根据评估结果系统地调整以下“旋钮”文本分割策略块大小、重叠。嵌入模型的选择。检索策略相似度/MMRk值过滤条件。提示词模板的措辞。大模型的生成参数temperature等。这是一个持续的优化过程也是让知识库真正变得好用的关键。7. 从原型到生产进阶考量当你的知识库原型验证有效准备投入团队或生产环境使用时需要考虑更多问题。7.1 前端界面与API服务命令行交互不友好。你可以使用Gradio或Streamlit快速构建一个Web界面。这两个库与Python生态结合紧密百行代码内就能做出一个包含文件上传、问答交互的UI。构建API使用FastAPI将问答链封装成RESTful API供其他前端应用如微信小程序、内部系统调用。这提供了最大的灵活性。7.2 文档解析与预处理增强对于复杂格式的文档如扫描PDF、表格、PPT基础的解析器可能不够。使用Unstructured库它功能强大支持多种格式并能提取元素类型标题、正文、列表等。OCR集成对于扫描件可以集成Tesseract或PaddleOCR。专用解析器对于表格可以使用tabula-pyPDF表格或pandas直接读取Excel。7.3 架构升级走向微服务随着负载增加单体应用可能成为瓶颈。可以考虑微服务架构模型服务使用vLLM或TGI单独部署大模型和嵌入模型提供高性能API。向量数据库服务将Chroma或PGVector部署为独立服务。业务逻辑服务用FastAPI编写核心的检索、提示词组装、链调用逻辑。任务队列对于文档解析、向量化等耗时操作引入Celery或Dramatiq异步处理避免阻塞请求。7.4 安全与权限在企业环境中知识库可能有权限要求。文档级权限在向量化时将权限信息如可访问部门/角色作为元数据存入向量数据库。在检索时根据当前用户身份在search_kwargs中添加对应的filter条件。答案审计记录所有的用户问答日志包括问题、答案、来源文档、用户ID和时间戳用于内容审计和效果分析。搭建基于 InternLM 和 LangChain 的知识库是一个从理论到实践不断调优和迭代的过程。这套组合提供了从零到一搭建智能知识检索系统所需的所有核心组件和灵活性。

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

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

免费获取报价