
学习时间2026年5月5天 |核心主题Model I/O → RAG 系统构建 → Agent 与工具系统 → 中间件架构一、本周学习路线总览本周以从单模型调用到构建完整的智能应用系统为主线按以下路径递进模型抽象与调优 → 文档加载与分割 → 向量嵌入与检索 → 工具定义与 ReAct → Agent 标准入口与中间件 Day1 Day2 Day3 Day4 Day5如果说第 1 周是学会如何用 LCEL 搭积木那么第 2 周的核心命题是——如何让模型接入外部世界。RAG 给模型接上知识库Agent 给模型接上工具两者叠加让模型从会说话的百科全书进化为能做事、能查资料的智能助手。二、Day 1Model I/O 与模型抽象2.1 BaseLanguageModel一套接口所有模型本周第一个重要认知LangChain 通过BaseLanguageModel将不同厂商的模型统一在同一套接口下。无论用 OpenAI、Anthropic还是通过硅基流动接入的国产模型上层的 Chain 和 Agent 只依赖invoke()/stream()/batch()这些方法签名底层实现可以随意切换。fromlangchain_openaiimportChatOpenAIfromlangchain_anthropicimportChatAnthropic# 两个不同厂商的模型调用方式完全一致llm_openaiChatOpenAI(modelgpt-5.5,temperature0.1)llm_claudeChatAnthropic(modelclaude-3-5-sonnet)这种设计的哲学是面向接口编程切换模型只需改一行 import 和初始化参数管道的其余代码一行不动。这是第 1 周协议胜于继承思想在模型层的延续。2.2 参数调优四个旋钮的艺术理解四个核心参数对模型行为的影响是写出高质量应用的前提参数作用建议值temperature随机性控制RAG: 0.0, 创作: 0.7-0.9max_tokens最大输出长度按场景设定成本控制 安全兜底top_pnucleus sampling 候选词截断默认 1.0frequency_penalty抑制重复需要时 0.1-0.3关键理解temperature和top_p二选一调优为主不建议同时大幅偏离默认值temperature0在学习阶段尤为重要——确保每次运行结果可复现调试时不会因为随机性而困惑frequency_penalty是解决模型复读机问题的利器2.3 多模型路由RunnableBranch 的实战应用RunnableBranch不仅是第 1 周学到的条件分支组件它在模型路由场景中找到了最佳的用武之地——根据输入特征文本长度、任务类型、复杂度动态选择最合适的模型routerRunnableBranch((is_long_context,llm_powerful),# 长文本 → 强模型(is_code_task,llm_powerful),# 代码任务 → 强模型(is_complex_question,llm_powerful),# 复杂问题 → 强模型llm_fast# 默认 → 快速模型)RunnableBranch本身也是Runnable可以用|接入任何 LCEL 管道——这让原本线性的管道具备了分叉能力是构建非平凡 Agent 的基础。三、Day 2RAG 系统构建上——文档加载与文本分割3.1 RAG 六步流程从今天开始进入 LangChain 最具工程价值的领域——RAG。一个完整的 RAG 系统可以概括为六个字Source → Load → Transform → Embed → Store → Retrieve 源 载 转 嵌 存 检Day 2 聚焦在前两步 Load 和 Transform这是整个 RAG 系统的地基。3.2 文档加载统一接口下的多格式支持langchain_community.document_loaders提供了上百种加载器覆盖 PDF、Markdown、CSV、HTML 等所有常见格式共享同一套调用契约——load()返回List[Document]加载器用途关键细节TextLoader纯文本需要显式指定encodingutf-8PyPDFLoaderPDF自动按页拆分metadata 含页码UnstructuredMarkdownLoaderMarkdown识别标题层级并写入 metadataDirectoryLoader批量加载通过glob匹配文件loader_cls指定加载器3.3 文本分割RecursiveCharacterTextSplitter 的设计智慧分割的核心矛盾chunk 太大会丢失检索精确性chunk 太小会割裂语义。RecursiveCharacterTextSplitter通过递归降级分隔符的设计解决了这个问题splitterRecursiveCharacterTextSplitter(chunk_size500,chunk_overlap50,separators[\n\n,\n,。,,, ,],)关键参数理解separators的优先级顺序先尝试段落边界\n\n→ 行边界\n→ 中文标点。→ 空格 → 最终兜底逐字符切割。中文文档必须加入中文标点否则会退化到字符级切割。chunk_overlap相邻 chunk 之间的重叠部分推荐值为chunk_size的 10%~20%解决了关键信息恰好落在切割边界上的问题。chunk_size500 是工程上的常用起点在精度和上下文之间取得平衡。四、Day 3RAG 系统构建下——嵌入、存储与检索4.1 向量嵌入让机器理解文本向量嵌入的本质是将自然语言映射到高维向量空间语义相近的文本在高维空间中几何上彼此靠近。LangChain 中所有 embedding 模型遵循统一的Embeddings接口提供两个核心方法embed_documents(texts)— 批量嵌入待存储的文档embed_query(text)— 嵌入用户查询重要踩坑使用硅基流动等非 OpenAI 服务商时必须设置check_embedding_ctx_lengthFalse。默认True会让 OpenAIEmbeddings 使用tiktoken将文本转为 token ID 数组发送但硅基流动不支持这种格式会返回 20015 “参数无效” 错误。4.2 向量存储与检索策略三种检索策略各有适用的场景策略search_type原理适用场景相似度similarity默认余弦相似度排序返回 Top-K通用场景MMRmmr在fetch_k候选中做多样性筛选避免结果同质化阈值过滤similarity_score_threshold只返回相似度超过score_threshold的结果生产环境质量兜底VectorStore本身不实现Runnable接口需通过as_retriever()包装为Retriever对象后才能接入 LCEL 管道。这个设计体现了检索器是比向量存储更通用的抽象——无论数据来自向量库、搜索引擎还是外部 API都可以统一封装。4.3 完整 RAG Chain一条管道串联全部环节rag_chain({context:retriever,question:RunnablePassthrough()}|prompt|llm|StrOutputParser())数据流分析RunnablePassthrough()将用户输入同时传给retriever执行检索和原样透传保留原始问题prompt模板将检索到的上下文注入 system 消息原始问题注入 user 消息llm在上下文辅助下推理回答StrOutputParser提取纯文本关键习惯把上下文放在 system 消息中而非 user 消息中让 system 承载背景信息user 保持用户的原始意图不被干扰。五、Day 4Agent 系统上——工具与 ReAct5.1 工具定义给模型装上手脚工具是 Agent 系统中最基础的单元。tool装饰器把一个普通 Python 函数自动转化为模型可理解的结构化接口tooldefsearch_database(query:str,limit:int10)-str:搜索客户数据库中的匹配记录。returnf在数据库中找到了{limit}条与 {query} 相关的结果。tool做了三件事类型标注 → JSON Schemadocstring → 用途描述函数名 → 全局唯一工具名。对于复杂参数场景通过args_schema传入 Pydantic 模型可以获得更精细的控制classWeatherInput(BaseModel):city:strField(description城市名称)units:Literal[celsius,fahrenheit]Field(defaultcelsius,description温度单位)tool(args_schemaWeatherInput)defget_weather(city:str,units:strcelsius)-str:获取指定城市的当前天气信息。...每个字段的Field(description...)是模型决定如何填充参数的关键依据——描述模糊会导致模型在错误的情境下调用工具或填入不合理的参数。5.2 ReAct 模式推理与行动交替进行这是 Agent 系统最经典的思想框架。它的执行流程是一条优雅的循环链条Question → Thought → Action → Observation → Thought → ... → Final Answer以一个具体场景为例用户问北京今天多少度华氏度是多少Thought模型意识到需要先获取温度 → 决定调用get_weatherAction调用get_weather(city北京)Observation收到 “北京晴25°C”Thought模型判断还需要换算华氏度 → 决定调用calculateAction调用calculate(expression25 * 9/5 32)Observation收到 “77.0”Final Answer“北京今天 25°C约 77°F”ReAct 的美妙之处在于——把推理和行动统一为可迭代、可观测的过程。每一步思考都有文本记录每一次工具调用都有可追溯的输入输出。5.3 错误处理当工具出错时生产环境中的 Agent 不可能一帆风顺。wrap_tool_call中间件像一个透明的拦截器将工具异常转化为模型可理解的ToolMessagewrap_tool_calldefhandle_tool_errors(request,handler):try:returnhandler(request)exceptExceptionase:returnToolMessage(contentf工具执行出错请检查输入参数后重试。错误详情{e},tool_call_idrequest.tool_call[id],)这贯彻了 ReAct 的核心理念——把一切包括失败都转化为可推理的信息。模型收到错误消息后会像处理正常结果一样分析它然后决定重试、换参数还是告知用户。六、Day 5Agent 系统下——Function Calling 与 create_agent6.1 Function Calling模型与工具的通信协议bind_tools()是连接模型和工具世界的桥梁。在create_agent内部框架自动完成工具绑定——你不需要显式调用bind_tools()。ReAct vs Function Calling 的本质区别维度ReActFunction Calling实现方式提示词工程模型输出带格式的文本模型原生能力输出结构化 JSON解析方式正则/解析器从文本中提取确定性 JSON 解析调用准确率依赖提示词质量有格式偏差风险通常是训练内置能力更稳定适用场景无原生 FC 支持的模型学术追溯思考过程有 FC 支持的模型生产首选在 LangChain v1 中create_agent自动根据模型能力选择最优策略——支持 tool calling 就走 Function Calling 路径否则退回文本推理模式。你不需要改变构建代码。6.2 create_agentLangChain v1 的 Agent 标准入口create_agent统一了过去分散在create_react_agent、AgentExecutor、AgentAction中的功能把所有复杂性封装进由 LangGraph 驱动的高层抽象。核心参数参数作用model模型标识字符串或已初始化的聊天模型实例tools工具列表框架自动完成绑定和注册system_promptAgent 的行为基调response_formatPydantic 模型约束最终输出格式checkpointer持久化对话状态InMemorySaver用于开发PostgresSaver用于生产context_schema定义每次调用的不可变上下文数据类型middleware可插拔的中间件列表checkpointer thread_id是实现多轮对话的关键agentcreate_agent(modelllm,tools[...],checkpointerInMemorySaver())# 同一 thread_id 下的多次调用自动累积对话历史result_1agent.invoke({messages:[{role:user,content:北京天气怎么样}]},config{configurable:{thread_id:conversation-001}})result_2agent.invoke({messages:[{role:user,content:我刚才问了什么}]},config{configurable:{thread_id:conversation-001}}# 同一个 thread_id)# Agent 能记住之前的对话6.3 MiddlewareAgent 的可插拔扩展层这是create_agent最令人惊艳的设计。中间件分为节点式和包裹式两种风格节点式钩子在特定时间点运行before_agent— Agent 调用开始前全局状态初始化before_model— 每次模型调用前注入动态上下文如当前时间戳after_model— 每次模型响应后日志记录、响应校验after_agent— Agent 调用结束后清理、汇总包裹式钩子环绕调用控制执行零次/一次/多次wrap_model_call— 环绕模型调用重试、缓存、动态切换模型wrap_tool_call— 环绕工具调用错误转换、日志、限流一个经典的before_model中间件——为 Agent 注入时间感知能力before_modeldefadd_timestamp(state:AgentState,runtime:Runtime):nowdatetime.now().strftime(%Y年%m月%d日 %H:%M:%S)state[messages].append(HumanMessage(contentf[系统信息] 当前时间{now}))returnNone中间件执行顺序遵循洋葱模型before_*按列表正序执行after_*按列表反序执行wrap_*形成嵌套结构列表前面的包裹在最外层。官方预置中间件覆盖了完整场景ModelRetryMiddleware模型重试、ToolRetryMiddleware工具重试、ModelFallbackMiddleware模型降级、HumanInTheLoopMiddleware人工审批、SummarizationMiddleware对话历史压缩、TodoListMiddleware任务规划追踪等。七、核心概念的个性化理解7.1 对文档 → 向量 → 检索 → 生成管道的感悟RAG 本质上就是在 LLM 管道的前端插入了一个检索步骤retriever | prompt | llm | parser。第 1 周学到的 LCEL 知识在这里被完整复用——管道的可组合性让插入新组件极其自然。这印证了一个设计理念好的抽象能经得起场景扩展的考验。7.2 对 Agent Model Harness 的理解create_agent的官方定义 “Agent Model Harness” 精准概括了 Agent 的本质。Model 负责思考推理是否调用工具、如何填充参数、何时给出最终答案Harness包括工具绑定、状态管理、中间件、循环控制负责为模型提供正确的上下文和行动框架。这种分离让 Agent 的大脑和身体可以独立演进而互不影响。7.3 ReAct 与 Function Calling 的关系两者不是替代关系而是分层关系。ReAct 定义的是逻辑范式推理-行动-观察的循环Function Calling 提供的是底层实现用结构化 JSON 替代文本解析。在 LangChain v1 中create_agent为上层提供了统一的抽象底层的选择只影响执行效率而不影响功能接口——这正是优秀的框架设计。7.4 Middleware 与 Runnable 的设计共性中间件系统和 LCEL 的Runnable接口共享同一个设计哲学协议胜于继承。Runnable只要实现invoke就能接入管道Middleware 只要实现before_model或wrap_tool_call就能插入 Agent 生命周期。两者都通过定义协议 自由组合的方式实现了极高的扩展性。八、踩坑记录与经验check_embedding_ctx_lengthFalse的重要性使用硅基流动等非 OpenAI 服务商时必须显式设置此参数为False。默认True会让OpenAIEmbeddings使用tiktoken将文本转换为 token ID 数组发送给 API但硅基流动不支持 token 化输入会返回 20015 “参数无效” 错误。这个问题 debug 了很久才定位到。langchain-community被标记为 deprecated在使用langchain_community.document_loaders和langchain_community.vectorstores时会收到 DeprecationWarning提示该包正在被逐步淘汰。官方建议迁移到独立的集成包如langchain-chroma、langchain-pdf等。学习阶段不影响使用但生产项目需要注意迁移路径。中文文档的 separators 必须定制RecursiveCharacterTextSplitter默认分隔符是英文导向的\n\n,\n, ,。处理中文文档时如果不在 separators 中加入。、、分割器会跳过所有中文标点直接退化到空格或字符级切割导致语义碎片化。VectorStore不是Runnable向量存储对象不能直接用|接入管道必须通过as_retriever()包装。这个细节容易忽略直接写vectorstore | prompt会报类型错误。工具名应使用 snake_case部分模型提供商会拒绝包含空格或特殊字符的函数名。tool装饰器默认使用函数名作为工具名保持 Python 原生命名习惯即可。before_model返回 None 的含义当中间件通过修改state[messages]原地生效后返回None表示不需要额外更新 state。如果返回一个 dict框架会用它来部分更新 state。九、下周展望第 3 周的主题是高级特性与生产级应用。从本周的认知出发RAG 的检索质量可以通过多路检索融合、重排序Re-ranking、HyDE 假设文档嵌入等高级策略进一步提升Agent 的可靠性可以通过更多的中间件组合如SummarizationMiddleware自动压缩长对话历史、HumanInTheLoopMiddleware在关键操作前暂停审批来保障checkpointerthread_id的多轮对话能力将在实际应用中发挥核心作用context_schema让 Agent 能感知用户身份、权限级别等运行时上下文是构建多租户应用的基础十、本周学习成果自检理解BaseLanguageModel的统一抽象设计能对比不同模型在同一 prompt 下的输出差异掌握 temperature / max_tokens / top_p / frequency_penalty 四个参数的作用与调优哲学能使用RunnableBranch实现基于任务特征的模型路由器能使用至少 3 种文档加载器加载不同格式的文档理解RecursiveCharacterTextSplitter的递归降级分割机制能为中文文档定制 separators掌握 embedding 模型的使用理解check_embedding_ctx_length参数的含义能构建完整的 RAG ChainLoad → Split → Embed → Store → Retrieve → Generate理解三种检索策略similarity / MMR / threshold的原理与适用场景能使用tool装饰器和args_schema定义结构化的工具接口理解 ReAct 循环Thought → Action → Observation的运作机制能使用create_agent()构建完整的 Agent 系统理解checkpointerthread_id实现多轮对话的原理能编写自定义 middlewarebefore_model/wrap_tool_call理解 ReAct 与 Function Calling 的异同及create_agent的自动适配策略