LangChain 1.3入门实战:从LCEL基础链到RAG文档问答 这是一份 LangChain 1.3 入门与实战技术长文结构、章节、代码、表格、排查和最佳实践均按 CSDN 技术博客标准构建没有主标题符合约束要求。在实际的 AI 应用开发中LangChain 已经被大量项目当作连接大语言模型与应用逻辑的中间层。很多人第一次接触 LangChain 时以为它只是封装 OpenAI 接口的工具真正进入项目开发后才发现问题往往集中在 Prompt 组织、模型调用、输出解析、记忆管理和链式调用这几个环节。LangChain 1.3 在这个背景下进一步收敛了核心 API把过去容易混淆的模块边界整理得更清楚同时保留了对常见模型、向量库和工具链的扩展能力。本文面向已经了解 Python 和基本 API 调用、但还没有系统写过 LangChain 应用的开发者从核心概念开始逐步完成一个可运行的实战项目并给出排查链路、参数说明和生产环境建议。学习完这篇文章后你可以完成三件事第一理解 LangChain 1.3 中模型、Prompt、输出解析器和链之间的关系第二用最小代码跑通一个带有对话记忆的文档问答应用第三遇到配置错误、模型调用失败和版本兼容问题时知道按什么顺序排查。整个过程不依赖复杂框架所有示例都可以在本地 Python 环境直接运行。1. 先理解 LangChain 1.3 到底解决了什么问题1.1 没有 LangChain 时调用大模型接口缺少的是什么直接通过模型厂商 SDK 调用大模型时代码一般长这样拼接 Prompt 字符串、调用 chat 接口、拿到返回文本。单个请求这样做没有问题但进入真实业务后会发现几个重复劳动每次请求都要自己组装 system、user 等消息结构。不同模型厂商的请求格式、超时策略和错误码不一致。需要把模型返回的文本转换成结构化数据时每次都要写解析逻辑。要支持多轮对话时必须自己维护历史消息列表。要接入检索、计算器、数据库等外部工具时调用逻辑会越写越乱。LangChain 的价值不是替代大模型而是把这些通用逻辑抽象成标准组件。开发者在做业务开发时只需要关注 Prompt 设计和业务链路不需要反复处理模型接口细节。1.2 LangChain 1.3 的核心组件边界LangChain 1.3 延续了“组件化”设计思路核心组件可以这样理解组件作用典型实现Chat Models负责与语言模型交互输入消息列表输出消息对象ChatOpenAI、ChatOllamaPrompt Templates负责把用户输入转换成结构化的 PromptChatPromptTemplate、PromptTemplateOutput Parsers负责把模型原始输出解析成字符串、结构化对象或列表StrOutputParser、PydanticOutputParserMemory负责记录和存取对话历史ConversationBufferMemory、ConversationBufferWindowMemoryChains负责把组件串联起来形成可执行流程LCEL 表达式构建的链RAG 相关组件负责文档加载、切分、向量化和检索DocumentLoader、TextSplitter、VectorStore在 1.3 版本中LCELLangChain Expression Language是链式调用最推荐的方式。它用管道运算符把组件连接起来代码可读性高也方便把中间结果单独输出做调试。1.3 先建立一个最小链路认知一个基础链路的输入输出关系可以这样表示输入用户问题。Prompt Template把用户问题嵌入到模板中生成消息列表。模型接收消息列表返回模型消息。输出解析器从模型消息中提取最终文本。输出字符串或结构化数据。这个链路虽然简单却是后面 RAG、Agent 和记忆功能的地基。建议在正式开始项目前先用代码把这个链路跑通然后再逐步加记忆和检索。2. 环境准备与依赖版本确认2.1 Python 环境和虚拟环境LangChain 1.3 需要 Python 3.9 以上环境。推荐使用虚拟环境隔离项目依赖避免把依赖安装到全局环境。python -m venv langchain_demo source langchain_demo/bin/activateWindows 环境下激活命令是langchain_demo\Scripts\activate。激活后命令行前缀会变成(langchain_demo)此时再安装依赖。2.2 安装核心依赖本文示例会用到 LangChain 核心包、OpenAI 兼容接口包、文档加载包和一个轻量向量库。pip install langchain langchain-core langchain-openai langchain-community langchain-text-splitters chromadb安装时注意版本输出pip show langchain pip show langchain-core原始教程材料没有给出固定版本号落地前建议确认当前环境实际解析到的版本并锁定到项目requirements.txt中。若使用 Ollama 本地模型还需要安装ollama并且保证本地服务已经启动。注意LangChain 1.3 对依赖包的命名和导入路径比旧版本更严格。如果看到ModuleNotFoundError优先检查是否安装了对应子包而不是直接重装整个 langchain。2.3 模型服务的两种准备方式学习阶段可以使用远程模型 API也可以使用本地方案。两种方式的环境要求差别较大。方式适用阶段需要准备的内容优点缺点OpenAI 兼容 API开发调试API Key、Base URL、模型名请求稳定省去本地资源需要网络有费用Ollama 本地模型学习实验、离线环境安装 Ollama拉取模型数据不出本机便于调试需要机器内存和显存如果使用 OpenAI 兼容接口环境变量可以这样设置export OPENAI_API_KEYyour-api-key export OPENAI_BASE_URLhttps://api.example.com/v1示例中的 Base URL 要根据实际服务提供方填写。不要在生产环境把密钥写死在代码或前端配置里应通过密钥管理服务或部署平台的环境变量注入。3. 用一个最小项目跑通 LangChain 1.3 基础调用3.1 项目目录结构建议按下面的结构组织代码。目录拆分不需要过度设计但至少要把配置、主逻辑、数据文件和测试脚本分开。langchain_demo/ ├── .env ├── requirements.txt ├── main.py ├── rag_demo.py └── data/ └── sample.txtmain.py用于跑通基础链路rag_demo.py用于演示文档问答data/sample.txt是待检索的文档内容。3.2 第一个 LCEL 链路创建一个main.py写入以下代码from langchain_core.prompts import ChatPromptTemplate from langchain_openai import ChatOpenAI from langchain_core.output_parsers import StrOutputParser prompt ChatPromptTemplate.from_messages([ (system, 你是一个擅长用简洁语言解释技术概念的助手。), (human, {question}) ]) model ChatOpenAI( modelgpt-4o-mini, temperature0.2, ) parser StrOutputParser() chain prompt | model | parser if __name__ __main__: result chain.invoke({question: LangChain 1.3 是什么}) print(result)这段代码展示了 LangChain 1.3 中最小的完整链路ChatPromptTemplate接收一个包含 system 和 human 消息的模板列表。ChatOpenAI负责调用模型接口。StrOutputParser把模型消息对象转换为普通字符串。|运算符把三个组件串联成链。invoke方法接收字典类型的输入执行整条链路。3.3 运行结果与验证方式在项目根目录执行python main.py预期输出是模型返回的解释文本。首次运行如果出现连接超时或认证失败检查OPENAI_API_KEY和OPENAI_BASE_URL是否配置正确。若使用本地模型ChatOpenAI需要改成ChatOllama并把base_url指向本机的 Ollama 服务地址。验证链是否正常不只看是否打印出文本还要检查三点输入参数名question是否和模板中的变量一致。模型返回内容是否完整。解析器是否输出了纯字符串。这里的常见错误是模板变量名写成user_input但invoke时传入question运行时会抛出要求补齐变量的异常。4. 加入对话记忆让链路支持多轮问答4.1 为什么记忆不能直接放在模型里大模型接口本身是无状态的。同一个模型不会自动记住上一轮对话内容。要实现多轮对话必须由应用层把历史消息保存下来在每次请求时重新发送给模型。LangChain 1.3 中的记忆组件承担这个职责。它需要配合一条链在每次调用前读取历史消息在调用后写入新消息。4.2 使用 RunnableWithMessageHistory 构建带记忆的链LangChain 1.3 推荐使用RunnableWithMessageHistory包装基础链而不是直接访问全局 session 历史。from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder from langchain_openai import ChatOpenAI from langchain_core.output_parsers import StrOutputParser from langchain_core.runnables.history import RunnableWithMessageHistory from langchain_community.chat_message_histories import ChatMessageHistory prompt ChatPromptTemplate.from_messages([ (system, 你是一个耐心的技术客服。), MessagesPlaceholder(variable_namehistory), (human, {question}) ]) model ChatOpenAI(modelgpt-4o-mini, temperature0.3) parser StrOutputParser() base_chain prompt | model | parser history_store {} def get_session_history(session_id: str): if session_id not in history_store: history_store[session_id] ChatMessageHistory() return history_store[session_id] chain_with_history RunnableWithMessageHistory( base_chain, get_session_history, input_messages_keyquestion, history_messages_keyhistory ) if __name__ __main__: config {configurable: {session_id: demo_session}} result1 chain_with_history.invoke( {question: 我叫张三是一名后端工程师。}, configconfig ) print(result1) result2 chain_with_history.invoke( {question: 我刚才说我叫什么名字}, configconfig ) print(result2)这段代码的关键点MessagesPlaceholder告诉 Prompt 模板在哪个位置插入历史消息。history_store用 session_id 保存不同会话的历史记录。RunnableWithMessageHistory负责在每次调用前拼装完整消息列表。第二次提问没有再次给出名字模型也能从历史中读取。4.3 对话记忆的常见参数与取舍参数或组件作用注意事项session_id区分不同用户或会话生产环境建议用用户 ID 加会话编号组合ChatMessageHistory在内存中保存消息服务重启后丢失生产环境要换持久化存储history_messages_key模板中历史变量名必须和 MessagesPlaceholder 的 variable_name 一致input_messages_key当前提问字段名必须和 invoke 传入的键名一致学习阶段用内存存储即可。生产环境必须把历史消息写入 Redis、数据库或其他持久化中间件否则每次服务重启都会丢失所有会话上下文。5. 从基础链升级为文档问答完整 RAG 实现5.1 为什么要用 RAG而不是把所有文档灌给模型把大段业务文档塞进 Prompt会遇到三个问题Token 长度限制、成本过高、模型容易忽略长文本中的关键信息。RAG 的思路是先检索出与问题最相关的片段再把片段拼进 Prompt让模型基于这些片段回答。LangChain 1.3 中的 RAG 链路由加载、切分、向量化、检索、问答五步组成。5.2 准备示例文档与加载器在data/sample.txt中放入一段说明文字内容可以是一段产品说明或技术规范。下面用一段通用文本演示LangChain 是一个用于构建大语言模型应用的开源框架。 它提供模型调用、提示词管理、记忆、检索和工具调用等模块。 其中 RAG 能力可以帮助开发者基于私有文档进行问答。LangChain 支持多种文档格式常用方式如下from langchain_community.document_loaders import TextLoader loader TextLoader(data/sample.txt, encodingutf-8) docs loader.load() print(docs)TextLoader返回的是文档对象列表。如果原始材料是 PDF、Markdown 或网页需要分别选用PyPDFLoader、UnstructuredMarkdownLoader、WebBaseLoader等不同加载器。5.3 文档切分为什么不能全文作为一个块切分的目的是让每个检索单元足够小从而获得更高精度的相关性匹配。切分参数需要根据文档长度和语义粒度调整。from langchain_text_splitters import RecursiveCharacterTextSplitter text_splitter RecursiveCharacterTextSplitter( chunk_size200, chunk_overlap20, ) splits text_splitter.split_documents(docs) print(f切分后块数量: {len(splits)})参数含义chunk_size控制每个块的最大字符数。chunk_overlap让相邻块保留部分重叠内容避免关键信息被截断在块边界。chunk_size设置过小碎片化严重设置过大检索精度可能下降。实际项目需要通过测试文档样例确定合理值。5.4 向量化与向量存储文本不能直接和用户问题比较相似度需要先转换成向量。from langchain_openai import OpenAIEmbeddings from langchain_community.vectorstores import Chroma embeddings OpenAIEmbeddings(modeltext-embedding-3-small) vectorstore Chroma.from_documents( documentssplits, embeddingembeddings, ) retriever vectorstore.as_retriever(search_kwargs{k: 2})Chroma会在当前目录生成持久化数据。search_kwargs中的k表示每次检索返回的文档块数量。k太大Prompt 会变长增加成本k太小可能遗漏相关信息。调试阶段先用 2再根据回答质量调整。注意向量模型必须和实际部署环境兼容。如果代码从 OpenAI 向量模型切换到本地向量模型需要统一修改embeddings对象并清除旧的向量库缓存否则会出现维度不一致或检索结果为空的问题。5.5 构建完整 RAG 链完整 RAG 链把检索和问答组合在一起代码如下from langchain_core.prompts import ChatPromptTemplate from langchain_openai import ChatOpenAI from langchain_core.output_parsers import StrOutputParser from langchain_core.runnables import RunnablePassthrough prompt ChatPromptTemplate.from_messages([ (system, 请根据以下参考资料回答问题。如果参考资料中没有相关信息请直接说明不知道。), (human, 参考资料\n{context}\n\n问题{question}) ]) model ChatOpenAI(modelgpt-4o-mini, temperature0.1) parser StrOutputParser() def format_docs(docs): return \n\n.join([doc.page_content for doc in docs]) chain ( {context: retriever | format_docs, question: RunnablePassthrough()} | prompt | model | parser ) if __name__ __main__: result chain.invoke(LangChain 的 RAG 能力有什么作用) print(result)这段代码的链路结构值得仔细理解第一个字典表达式同时启动两个分支。retriever | format_docs把检索结果转换为纯文本。RunnablePassthrough把用户原问题直接透传给 Prompt。最后把 context 和 question 填充到模板进入模型调用。运行后的预期输出应该围绕sample.txt中“RAG 能力帮助开发者基于私有文档进行问答”这句内容展开。6. 关键参数说明与调试工具6.1 模型参数速查参数作用调大影响调小影响temperature控制随机性输出更多样但可能不准确更确定适合抽取和摘要max_tokens限制输出长度可生成更长内容内容可能被截断timeout请求超时时间更适合慢模型请求失败更快误伤率高model指定模型版本能力更强成本更低对于文档问答类任务建议temperature保持在 0.1 到 0.3 之间降低模型自由发挥概率。6.2 调试链路的通用方法LangChain 1.3 支持两种常见调试方式。第一种是打印中间结果。如果chain.invoke返回内容不符合预期可以把链路拆开逐步执行。prompt_result prompt.invoke({ context: format_docs(retriever.invoke(LangChain 的 RAG 能力有什么作用)), question: LangChain 的 RAG 能力有什么作用 }) print(prompt_result.to_string())第二种是启用 LangSmith 或简单日志输出。在生产环境没有接入追踪系统的情况下至少要给retriever和model调用增加日志记录检索到的文档块和模型输出片段。6.3 学习环境与生产环境的差异关注点学习环境生产环境密钥管理.env文件密钥管理服务或部署平台环境变量向量库Chroma 本地持久化可扩展的向量数据库或云服务历史消息内存存储Redis、数据库、消息队列落库日志print 输出结构化日志收集、链路追踪限流与重试手动重试集成重试、退避、熔断机制文档更新重新运行脚本定时任务或事件驱动更新向量库学习阶段不要追求复杂架构但写代码时就要预留接口边界避免后面把Chroma换成生产向量库时大面积改动。7. 常见问题排查从现象倒推原因7.1 模型调用报错认证失败、超时、模型不存在问题现象常见原因检查方式处理建议401 认证失败API Key 为空或错误检查环境变量是否加载重新配置密钥不要在代码中硬编码请求超时网络不通或模型响应慢增加 timeout先 curl 测试接口确认服务地址可达超时时间设为 30 到 60 秒模型不存在模型名不在当前账号权限内打印 model 名称核对服务商文档换成已开通或已拉取的模型最简单的验证方法是直接使用模型 SDK 发一次请求。如果 SDK 成功但 LangChain 失败再检查 LangChain 的base_url和model参数。7.2 模板变量错误报错信息通常包含变量名缺失提示。检查模板占位符、invoke传入的键名、RunnableWithMessageHistory的input_messages_key是否完全一致。# 示例错误日志中的关键行 one or more required variables were not provided: question此时不要只改链要从 Prompt Template 里的变量名开始排查。7.3 向量检索结果为空或与问题无关先确认三件事加载器是否拿到正确内容。切分后块数量是否合理。检索返回的内容是否命中问题关键词。打印检索结果是最直接的排查方式retrieved_docs retriever.invoke(LangChain 的 RAG 能力有什么作用) for i, doc in enumerate(retrieved_docs): print(f第 {i 1} 块{doc.page_content})如果检索结果为空优先检查向量库文件是否损坏、chunk_size是否过小、向量模型是否更换过。如果检索结果有关键词但回答跑偏问题往往在 Prompt 指令不够明确。7.4 依赖版本不兼容LangChain 1.3 拆分了多个子包安装完整依赖时可能出现版本冲突。统一把依赖锁定在一个版本区间pip freeze requirements.txt再次部署时使用pip install -r requirements.txt注意升级 LangChain 后如果from langchain.xxx import yyy报错优先改成from langchain_xxx import yyy。1.3 中大量模块从主包迁移到了独立命名空间。8. 常见开发陷阱与最佳实践8.1 三个容易踩的坑第一个坑是忽略向量模型匹配。文本向量化时使用text-embedding-3-small后面换成其他模型后没有重建向量库。旧的向量和新的向量维度或语义空间不一致检索结果会变得不可用。第二个坑是把所有历史消息无限拼进 Prompt。对话越久Prompt 越长成本和延迟都会上升。推荐使用ConversationBufferWindowMemory或自定义裁剪逻辑只保留最近若干轮。第三个坑是生产环境直接使用内存ChatMessageHistory。服务端多实例部署后用户请求被分发到不同实例会话历史会丢失。生产环境必须把历史存储外置到 Redis 或数据库中。8.2 可复用的开发清单每次提交 LangChain 代码前可以对照以下清单检查密钥是否只存在环境变量中。Prompt 模板变量名与 invoke 参数是否一致。模型名是否与当前环境匹配。向量模型是否与向量库数据一致。历史消息存储是否持久化。检索返回的文档块是否需要过滤重复或无关内容。输出解析器是否能处理模型返回格式异常。日志是否记录了模型调用耗时和检索块数量。文档更新后向量库是否同步重建或增量更新。异常分支是否明确返回给用户而不是堆栈直接透出。8.3 下一步扩展方向跑通基础 RAG 后可以按如下顺序扩展把ChatOpenAI替换成 Ollama 或其他本地模型验证模型无关性。把Chroma替换成支持分布式部署的向量数据库。在 RAG 链中增加查询改写先对用户问题进行改写再检索。加入流式输出把chain.stream接入业务前端。集成工具调用让模型可以根据问题决定是否检索或查询数据库。扩展时要保持每个模块独立不要在业务代码里直接耦合模型 SDK。9. 从学习到生产LangChain 1.3 项目的落地建议9.1 建议的学习路径建议按照以下顺序练习而不是直接跳到复杂项目用官方 Chat 模型跑通最小链路。手动实现一次多轮历史拼接再替换成官方记忆组件。用本地 markdown 文档完成 RAG。打印检索结果理解k值对回答的影响。把链改造成异步调用和流式输出。加入异常处理和日志。接入外部工具尝试 Agent 场景。每一步都验证清晰再进入下一步。遇到报错时先看异常栈中的模块名再判断是配置问题还是版本问题。9.2 生产落地时的最低保障生产环境最低限度需要做到所有配置外置化。所有调用增加超时和重试。所有关键链路输出结构化日志。历史消息和业务数据分离存储。文档更新能够定时触发向量库更新。模型输出经过基础校验后才返回给用户。具备回滚能力依赖升级前用固定版本重新跑一遍回归用例。这些保障不依赖框架本身但决定项目能否长期稳定运行。9.3 最后的实践建议LangChain 1.3 的学习重点不是背 API而是理解组件之间的数据流。建议用本文的 RAG 项目作为模板替换成自己业务中的真实文档记录检索耗时、回答质量和失败场景。每次修改只改动一个变量比如只调整chunk_size或只更换向量模型观察结果变化。对比记录可以整理成一张简单表格文档块大小、检索数量、回答完整度、是否出现幻觉、平均耗时。通过这种方式才能把一个能跑的 Demo逐步打磨成一个可上线的 AI 应用。

相关新闻

最新新闻

Win32窗口跟随实践:为Codex打造自动贴靠的辅助面板

Win32窗口跟随实践:为Codex打造自动贴靠的辅助面板

如果你经常用 Codex 这类 AI 编程代理工具,大概率遇到过这种场景:主窗口占据了屏幕的左侧,你想看的状态面板却固定停在屏幕右侧,你拖动主窗口换个位置后,辅助面板仍然悬在原处,就像一张贴错了位置的便利贴。…

2026/8/31 11:20:00
GPT Image 2实战:从提示词到API批量生成与自动化配图

GPT Image 2实战:从提示词到API批量生成与自动化配图

最近很多技术群和评论区都在聊 GPT Image 2,但大家的关注点其实不太一样:一部分人把它当成“更好看的 Midjourney”,拿来生成头像和壁纸;另一部分人在讨论怎么把它接入自己的内容生产流程、设计工作流,甚至直接通过 AP…

2026/8/31 11:20:00
VMware Workstation 虚拟机安装与实战指南

VMware Workstation 虚拟机安装与实战指南

很多开发者第一次接触 Linux,并不是因为工作单位配了一台云服务器,而是因为自己电脑上装了一个 VMware Workstation,然后在里面创建了一台 Ubuntu 虚拟机。这个看似简单的操作,其实解决了开发者成长过程中一个大问题: …

2026/8/31 11:20:00
智谱面试官问:40 个内部 API 该全变 MCP 工具吗?

智谱面试官问:40 个内部 API 该全变 MCP 工具吗?

匿名复盘里,把 40 个内部接口全包成 MCP 工具丢给 Agent,看着省事。但是到了上线,账单变贵、调用变乱、出错查不清,问题才一起冒出来。这一课只讲一件事:这 40 个接口,哪些值得挂给模型,哪些该留…

2026/8/31 11:20:00
基于51单片机的无线烟雾报警器设计:MQ2传感器与ADC0809模数转换实战

基于51单片机的无线烟雾报警器设计:MQ2传感器与ADC0809模数转换实战

简介:本资源是一套基于单片机的无线烟雾报警器完整开发资料,面向嵌入式初学者、电子设计课程实践者及智能安防项目开发者,解决烟雾浓度实时采集、阈值判断与无线报警触发等核心问题。压缩包共26个文件,436KB,涵盖C语言…

2026/8/31 11:20:00
论文润色降AIGC:DeepSeek Harness与Codex Skills技术对比

论文润色降AIGC:DeepSeek Harness与Codex Skills技术对比

论文润色、降重、降 AIGC,是很多写作者绕不开的日常任务。围绕这两个需求,目前社区里出现了两条不完全相同的技术路线:DeepSeek Harness 插件和 Codex Skills。前者把 DeepSeek 模型接入编辑器,将提示词、模型参数和批量处理封装成…

2026/8/31 11:14:59