(4.22学习笔记)

链式工作流核心认知

LCEL 的三大核心流水线模式:

1. 顺序执行流水线 (RunnableSequence / |)
  • 核心逻辑: 串联。上一道工序的产出,严丝合缝地作为下一道工序的原料。

  • 生动比喻: 汽车制造流水线。底盘造好 -> 装发动机 -> 上漆。

  • 代码直觉: chain = prompt | llm | output_parser

  • 工程价值: 以后写得最多的代码。它极大降低了代码的嵌套层级,数据流向一目了然。

2. 动态路由分支 (RunnableBranch)
  • 核心逻辑: 分流。根据输入的内容特征,把任务派发给不同的处理管线。

  • 生动比喻: 公司的前台接线员。“请问您是咨询业务还是售后?咨询请按1(转交销售链),售后请按2(转交技术链)。”

  • 实际应用: 假设系统收到用户的查询。你可以先用一个小模型判断意图:如果是“写代码”,路由给 Code-Agent;如果是“查资料”,路由给 Search-Agent。

3. 并行处理引擎 (RunnableParallel / RunnableMap)
  • 核心逻辑: 齐头并进。把同一个输入,同时发给多个不同的处理链条,最后把结果打包成一个字典返回。

  • 生动比喻: 专家评审团。面对同一份项目书,财务专家评估成本,技术专家评估可行性,法律专家评估风险。三人同时工作,最后汇总报告。

  • 绝佳实操场景: 在分析大型旅游 IP(如哈尔滨冰雪大世界)的舆情文本时。你可以拿到一段游客评论后,利用并行链:

    • 分支 A:调用模型提取这段话的核心主题(冰雕、排队、价格)。

    • 分支 B:调用模型评估这段话的情感极性(正向、负向)。

    • 最后,RunnableParallel 会同时执行这两个动作,并完美合并输出:{"topic": "排队体验", "sentiment": "负向"}。这比让模型分两次处理要节约一半的时间

组件名称 (Component) 执行机制与核心逻辑 关键操作符 / 用法 典型适用场景 生动比喻

RunnableSequence

 

(顺序链)

串行执行。多个组件按固定顺序串联,前一个组件的输出自动作为后一个组件的输入。

管道符 |

 

.invoke()

 

.stream()

流水线式任务

 

例如:“提取关键信息 → 基于信息生成摘要 → 翻译成指定语言”。

工厂流水线

 

(底盘 → 引擎 → 喷漆)

RunnableBranch

 

(路由分支)

条件分发。根据输入内容或预设的判断条件,将请求动态路由(分配)到不同的处理分支上。 依据条件判断 (True/False) 进行分支选择

多场景/意图路由任务

 

例如:智能客服系统中,识别用户意图后,订单问题走“查单链”,技术问题走“排障链”。

前台接线员

 

(售后请按1,投诉请按2)

RunnableParallel /

 

RunnableMap

 

(并行链)

齐头并进。对同一个输入,同时(并行)执行多个独立的子组件,最终将所有子组件的返回结果拼装成一个字典 (dict) 输出。

通常以字典形式组织:

 

{"任务A": 链A, "任务B": 链B}

多维度并发分析任务

 

例如:面对同一段文本,同时并行提取“逻辑核心”、“情感倾向”和“语法错误”。

专家评审团

 

(财务、法务、技术同时审阅同一份报告)

基于 RunnableSequence / | 运算符:

字典输入 ➡️ Prompt 1 ➡️ PromptValue ➡️ LLM 1 ➡️ AIMessage ➡️ StrOutputParser ➡️ 纯字符串 ➡️ Prompt 2 ➡️ PromptValue ➡️ LLM 2 ➡️ AIMessage ➡️ StrOutputParser ➡️ 最终字符串

基础实践:单输入输出线性流转:

 进阶实践:多输入多输出复杂线性任务:

组件名称 工程隐喻 核心功能与机制 最典型应用场景 极简代码释义

RunnableLambda

 

(函数适配器)

“万能转换插头” 将任何普通的 Python 函数(或匿名函数 lambda)包装成符合 Runnable 协议的组件,使其能无缝接入 | 流水线。

数据清洗与格式转换

 

例如:扒掉大模型输出的外壳只留文本,或者截取字符串的前100个字符,甚至是在中途调用一个外部 API 获取数据。

prompt | llm | RunnableLambda(lambda x: x.content.strip())

RunnableMap

 

(并行容器)

 

(等同于 RunnableParallel)

“多线分拣打包机” 接收同一个输入数据,将它并行喂给内部定义的多个子链(子组件)。等所有子链处理完毕后,按预设的 Key 打包成一个大字典 (dict) 往下传。

多变量准备与并发处理

 

例如:下一步的 Prompt 需要 contextquestion 两个变量,你可以用它同时去数据库查 context,并透传 question。

RunnableMap({"摘要": chain1, "翻译": chain2})

RunnablePassthrough

 

(透传组件)

“直达特快电梯” 充当一个透明的管道,不对数据做任何实质性修改,原封不动地向下游传递。也常结合 assign 用于在原字典基础上追加新数据。

保护原始数据不丢失

 

在经过 RunnableMap 并行处理时,确保最原始的用户提问(或变量)能越过中间步骤,直接传递给最后的大模型组装环节。

{"原始问题": RunnablePassthrough(), "计算结果": tool_chain}

路由链设计与异常处理:

 RouterChain(路由链)核心原理:

步骤 负责组件 动作与数据流转 核心意义
第一步:语义判别 大模型 (LLM) 接收用户输入(如:“帮我查下明天的天气”)。LLM 内部做一次极快的单步推理,仅输出一个词汇标签(如:"weather_query")。 将人类复杂的自然语言,降维打击成计算机能直接处理的标准枚举值。
第二步:条件路由 RunnableBranch

拿到标签后,执行类似 Switch-Case 的逻辑。

 

if 标签 == "weather_query" -> 走天气链

 

if 标签 == "order_query" -> 走订单链

纯代码逻辑层的分流,速度极快,且确保数据精准进入下一条流水线。
第三步:目标执行 特定的子链 (在这个例子中)天气链启动,调用查天气的工具,最后生成回复。 专链专用,隔离了无关提示词和工具,大幅降低了主模型的幻觉概率。

RouterChain 实践案例:

链式工作流的错误处理机制:
解决方案:重试机制、异常捕获与分支降级:

1. 重试机制(解决临时API错误):

2. 异常捕获(解决可预知的错误 :

3. 分支降级(错误时切换备用方案):

RAG 核心原理与应用价值:

维度分类 核心要点 深度解析与机制说明 生动比喻
一、大模型原生痛点

1. 知识滞后

 

2. 事实性错误(幻觉)

知识是“死”的:知识固化在训练参数中,无法实时更新。模型只懂训练截止日(如2023年)前的信息。

 

缺乏事实校验:会“一本正经地胡说八道”(编造文献、伪造作者等);极易受“语料污染”影响导致误判,甚至被恶意利用。

知识滞后:像一个很久没上网、与世隔绝的人。

 

幻觉:像一个为了面子瞎编答案、不懂装懂的考生。

二、RAG 核心逻辑

 

(Retrieval-Augmented Generation)

检索 (Retrieve)

 

⬇️

 

增强 (Augment)

 

⬇️

 

生成 (Generate)

本质:知识补充 + 事实校验(赋能而非替代大模型)

 

检索:从外部库(公司文档、最新新闻)中找出与提问相关的信息。

 

增强:将检索出的真实信息与提问组装,作为“参考资料”放入提示词。

 

生成:大模型被强制要求基于参考资料,生成有依据的准确答案。

相当于给大模型一场**“开卷考试”**。遇到不会的题,监考老师直接给一本精准的参考书,让它照着书本逻辑作答。
三、RAG 核心价值

1. 提升准确性

 

2. 拓展知识边界

 

3. 降低微调成本

降幻觉:答案溯源于真实资料,绝不瞎编,满足企业级安全要求。

 

破边界:打破训练数据的时间和隐私壁垒,轻松获取最新数据(如2025年报告)和企业私有资产。

 

省成本:无需花费几十万重新训练(微调)模型,更新知识库只需简单上传新文档即可,效率极高。

将“给大模型做昂贵的开颅换脑手术”(微调),降维成了“给大模型塞一张即插即用的外置U盘”(RAG)。

RAG 系统构建全流程实操:

4个核心步骤:文档加载→文本分割→向量存储→检索与生成

1.文档加载

实操:多格式文档加载代码实现

TXT文档加载

PDF文档加载

 Word文档加载、Markdown文档加载

批量加载多格式文档:

2. 文本分割

常见分割策略与LangChain推荐实现

1.默认推荐:RecursiveCharacterTextSplitter(智能语义分割)

2. 基础备选:CharacterTextSplitter(按字符数分割)

3. 针对性分割:MarkdownTextSplitter(保留MD标题层级)

3. 向量存储与嵌入

核心概念:嵌入模型
向量数据库选择:faiss(轻量易上手)
实操:文本嵌入与向量存储完整流程:

4.检索器配置与检索策略优化

基础检索器:FAISSRetriever

进阶检索策略:相似性检索 vs MMR检索:

 实操案例:检索器参数配置与检索效果验证

第一步:环境准备与向量数据库加载→第二步:配置不同参数的检索器→第三步:执行检索并对比结果

5.检索-生成(Retrieval-Generation)全流程整合

核心原理:检索与生成的协同逻辑:
为什么新版强烈推荐 LCEL 架构?

在早期的 LangChain 中,开发者通常用 RetrievalQA.from_chain_type()create_retrieval_chain() 这种打包好的黑盒函数。

优势维度 LCEL 架构特性 带来的实际工程价值
极致透明 | 将检索器、大模型、解析器像搭积木一样串联。 数据每流经一个节点变成了什么样,你都清清楚楚,排错(Debug)极其方便。
高度解耦 可以随时在管道中间插入自定义的 RunnableLambda 如:你可以轻松在“检索后、生成前”插入一段代码,专门过滤掉带有脏话的文档片段,黑盒函数根本做不到。
天然支持流式 只要底层大模型支持,整条链自动支持 .stream() 输出。 用户在前端提问后,答案可以像打字机一样一个字一个字蹦出来,极大提升用户体验。
RAG 数据流转的“五步协同逻辑”

放入真实场景:假设我们正在构建一个用于分析哈尔滨冰雪大世界历年舆情与游客情感演化的系统。用户提问:“相比上一季,2024-2025雪季游客对冰滑梯的评价有什么变化?

数据在 LCEL 链条中的流转是这样的:

  1. 入口准备 (RunnableMap / RunnablePassthrough): 系统接收到用户的问题。兵分两路:一路把问题透传下去,另一路拿着问题去 FAISS 向量库找答案。

  2. 检索执行 (Retriever): FAISS 根据问题,瞬间找出了 3 篇相关的开题报告片段或新闻文档(比如找到了 521 米超长冰滑梯的游客评价数据)。此时返回的是 [Document, Document, Document] 列表。

  3. 格式化清洗 (RunnableLambda): 大模型不认识 Document 对象,它只认纯文本。所以这里必须有一个自定义函数,把这 3 个片段里的文字全部提取出来,拼接成一段长文本。

  4. 组装提示词 (PromptTemplate): 将拼好的“参考资料”和“用户原始问题”,完美填入预设的 Prompt 模板中。

  5. 模型生成与解析 (LLM + StrOutputParser): 大模型基于这些确凿的冰雪大世界评价数据进行总结,最后通过解析器输出纯文本答案。

 实操:完整RAG系统代码实现:

第一步:环境准备与组件初始化→第二步:用LCEL构建检索-生成链→第三步:测试RAG系统并验证结果→第四步:运行结果与系统验证

6.RAG系统常见问题与优化方向

RAG 系统常见问题排查(Troubleshooting)

常见问题症状 🔍 核心排查方向(可能原因) 💡 对应解决策略(实操调优)

1. 检索结果不相关

 

(答非所问)

切块问题:片段过大或过小,语义断裂。

 

模型不匹配:嵌入模型不擅长中文。

 

参数失控:召回数量(k)太大,或MMR强制要求的多样性过高。

调分割:设 chunk_size=200-500,用 RecursiveCharacterTextSplitter

 

换模型:改用专门优化中文的模型(如 Qwen-Embedding)。

 

缩参数:调低 k=2-3,降低 MMR 多样性权重(lambda_mult=0.7-0.8)。

2. 答案遗漏关键信息

 

(回答太片面)

召回不足:检索到的片段根本没覆盖全考点。

 

提示词缺陷:没明确命令大模型要“全面”。

 

温度过低temperature 太低导致大模型像挤牙膏,话太少。

扩召回:调大 k=4-5,改用纯相似性检索以保证火力集中。

 

改 Prompt:增加强制指令“全面覆盖参考资料中的所有关键要点”。

 

升温度:适当调高 temperature 到 0.4-0.5。

3. 答案包含编造信息

 

(出现“幻觉”)

边界不清:提示词没限制大模型“不许瞎编”。

 

资料太差:找出的片段没用,大模型只能靠自己脑补。

 

温度过高:大模型发散思维太强。

严厉 Prompt:加入“禁止编造,无相关信息则明确回复‘无法回答’”。

 

提精度:回炉优化切块和 Embedding 模型,确保喂给它的资料是精准的。

 

降温度:降级 temperature 到 0.2-0.3,让它变严谨。

4. 系统响应速度慢

 

(一直转圈圈)

数据包太大:召回片段(k)太多,阅读负担重。

 

数据库卡顿:向量库未优化,冗余数据太多。

 

大模型太重:选用的 LLM 推理速度本身就慢。

减负:缩小 k=2-3

 

清内存:使用 FAISS 等高效库,定期清理无效片段。

 

换轻量级:把千亿参数大模型换成轻量级/推理极速的模型。

RAG 系统进阶优化方向(Advanced Optimization)

优化维度 ⚡ 核心进阶技术 🎯 预期效果与解决的痛点

一、 检索层优化

 

(找得更准)

1. 混合检索 (Hybrid Search)

 

将“向量语义检索”与“传统关键词匹配 (BM25)”结合。

 

2. 检索重排 (Reranking)

 

引入交叉编码器 (Cross-Encoder),对初筛的几十个片段进行二次精准打分排序。

彻底解决“语义相近但专有名词对不上”或“包含专有名词但上下文无关”的漏召回痛点,极大提升检索的天花板。

二、 提示词优化

 

(问得更精)

1. 思维链 (CoT) 引导

 

在 Prompt 中要求大模型“一步步分析参考资料”。

 

2. 领域专属模板

 

为法律、医疗等垂直行业定制专属格式和身份约束。

让大模型的推理逻辑更透明、更严密;提升最终输出答案的专业度、格式规范性和行业契合度。

三、 知识库优化

 

(底子更厚)

1. 文档生命周期管理

 

建立资料库的自动更新与过期淘汰机制。

 

2. 数据深度预处理

 

入库前清洗废话、提取元数据、甚至让大模型先做一遍知识点摘要 (Summary) 再入库。

“Garbage in, garbage out”。从源头提升切分和向量化的质量,防止知识库变成垃圾场,保障长期运行的稳定性。

7.人工评估与自动化评估工具

动化评估工具:高效迭代优化

😭失败(明天再试)

刚刚用 pip install ragas 下载的是 Ragas 的最新大版本(v0.2.x),而在这个新版本中,官方做了一个API 升级

以前,只需要把指标放在列表里,最后统一交给 evaluate 就可以了。但在新版中,官方要求你必须在“点名”这些评估指标的时候,就当面把“裁判”(大模型)和“词典”(嵌入模型)发给它们

Ragas 框架在最近的 v0.2.x 版本中,进行了一次更新。

报错信息 Collections metrics only support modern InstructorLLM. Found: LangchainLLMWrapper 明确宣告了:Ragas 新版本为了更稳定地输出 JSON 数据,已经全面抛弃了 LangChain 的包装器。它现在强制要求你使用 Python 原生的 openai 客户端,并通过它自带的 llm_factory 来创建“裁判”大模型。

Ragas 新版还悄悄改了数据集的列名(把 question 改成了 user_input 等)

 调优方向:1.文本分割策略优化、2.向量模型选择与优化、3. 检索参数配置优化

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐