当前位置: 首页 > news >正文

langchain学习总结(1)LCEL

使用书籍为《 AI Agent 开发与应用》 我用的是25年4月第一次印刷的书籍,但是里面的代码完全不能用,langchain版本 1.0以上的和书里面的内容几本就不搭噶了。因此我使用各种模型去生成代码,然后找到一个我觉得最好的代码进行记录。同时也把我调试过程中遇到的问题进行积累记录。 1、LCEL (LangChain Expression Language) langchain当中所有的数据传递都是以字典的格式进行传递的。 (1)基础链 最经典的写法就是“三件套”:
# 一个基础链,通常包含提示词、模型和输出解析器chain=prompt|model|StrOutputParser()

然后通过 chain.invoke({“input”: “…”}) 来运行它。

完整示例:

fromlangchain_core.promptsimportChatPromptTemplatefromlangchain_core.output_parsersimportStrOutputParserfromlangchain_openaiimportChatOpenAI# 1. 定义组件prompt=ChatPromptTemplate.from_template("用一句话描述{topic}的魅力。")###prompt写法model=ChatOpenAI(model="gpt-4o-mini")####这里一般现在不这么调用,全部都是KEY+API网址。见下:#######################API_KEY="sk-xxxxxx"# ⚠️ 请替换为你自己的有效 keyBASE_URL="https://api.deepseek.com"#### 模型写法model=ChatOpenAI(model="deepseek-chat",openai_api_key=API_KEY,openai_api_base=BASE_URL,temperature=0.7)#######################parser=StrOutputParser()# 2. 构建链chain=prompt|model|parser# 3. 运行链result=chain.invoke({"topic":"LangChain"})print(result)

StrOutputParser()的作用是只获取AIMessage当中的content。并且可以处理类似\n这种转义符。

(2)顺序链
语法:A | B | C | D (管道符就是顺序)
多个基础链串起来即可。注意当中的参数传递:

# 第一步:提取问题关键词step1=ChatPromptTemplate.from_template("提取关键词:{question}")|model|StrOutputParser()# 第二步:用关键词回答step2=ChatPromptTemplate.from_template("根据关键词回答:{key_words}")|model|StrOutputParser()# 拼接成顺序链:自动按顺序执行seq_chain=step1|{"key_words":lambdax:x}|step2###{"key_words": lambda x: x} 这个代码的含义就是把step1的输出打包塞到key_words里。# 调用seq_chain.invoke({"question":"缅因猫掉毛怎么办"})

question我理解就是占位符,将“缅因猫掉毛怎么办”传入到step1当中,过LLM处理后解析格式,然后将输出结果传入到key_words,作为step2 的入参。

(3)并行链
语法:RunnableParallel({ key: 子链 })

fromlangchain_core.runnablesimportRunnableParallel# 定义两个并行任务chain1=ChatPromptTemplate.from_template("总结:{question}")|model|StrOutputParser()chain2=ChatPromptTemplate.from_template("提取关键词:{question}")|model|StrOutputParser()# 并行链:同时执行 chain1 和 chain2parallel_chain=RunnableParallel({"总结":chain1,"关键词":chain2})# 调用 → 同时返回两个结果result=parallel_chain.invoke({"question":"缅因猫掉毛怎么办"})# 从字典里拿 chain1 的结果print(result["总结"])print(result["关键词"])

注意,这里的并行,本质上是异步IO。一个线程,单线程并发。

(4)分支链
语法:RunnableBranch( (条件函数, 子链), 默认链 )

# 1. 定义条件函数:判断是不是动物问题defis_animal_question(input_dict):return"猫"ininput_dict["question"]or"狗"ininput_dict["question"]#返回bool值,并且下面的分支链必须以布尔值作为判断。# 2. 定义两个分支链animal_chain=ChatPromptTemplate.from_template("你是宠物专家:{question}")|model normal_chain=ChatPromptTemplate.from_template("正常回答:{question}")|model# 3. 分支链(条件判断)branch_chain=RunnableBranch((is_animal_question,animal_chain),# 满足条件走这里normal_chain# 否则走这里)|StrOutputParser()# 调用branch_chain.invoke({"question":"缅因猫掉毛怎么办"})

(5)数据转换链(插入自己的函数)

fromlangchain_core.runnablesimportRunnableLambdafromlangchain_core.promptsimportChatPromptTemplatefromlangchain_openaiimportChatOpenAIfromlangchain_core.output_parsersimportStrOutputParser# 1. 大模型API_KEY="sk-xxxxxx"# ⚠️ 请替换为你自己的有效 keyBASE_URL="https://api.deepseek.com"#### 模型写法model=ChatOpenAI(model="deepseek-chat",openai_api_key=API_KEY,openai_api_base=BASE_URL,temperature=0.7)# 2. 你的自定义函数(字典进→字典出)defmy_custom_func(input_dict):question=input_dict["question"]clean_question=question.replace("哎","").replace("啊","")return{"clean_question":clean_question}# 3. 包装成LCEL组件data_transform_chain=RunnableLambda(my_custom_func)# 4. 提示词模板(核心!填充字典数据) 两种写法。第二种是带系统提示词的。prompt=ChatPromptTemplate.from_template("回答问题:{clean_question}")# 不带系统提示词prompt=ChatPromptTemplate.from_messages([# -------- 【系统提示词】固定人设/规则 --------("system","你是专业的宠物医生,只回答科学靠谱的内容"),# -------- 【用户提示词】用户的问题 --------("user","{clean_question}")])# 带系统提示词。# 5. LCEL链式拼接(全部用 | 串联)full_chain=data_transform_chain|prompt|model|StrOutputParser()# 6. 调用(输入字典)result=full_chain.invoke({"question":"哎啊缅因猫掉毛怎么办"})print(result)

注意:1、自己定义的函数必须是字典进,字典出。
2、数据流入:question->data_transform_chain->prompt (“回答问题:{clean_question}”)->model->格式转换

(6)工业级别组合链。

# 1. 导入所有核心依赖fromlangchain_core.promptsimportChatPromptTemplatefromlangchain_openaiimportChatOpenAIfromlangchain_core.output_parsersimportStrOutputParserfromlangchain_core.runnablesimport(RunnableLambda,RunnableParallel,RunnableBranch,RunnablePassthrough)# 2. 初始化大模型API_KEY="sk-xxxxxx"# ⚠️ 请替换为你自己的有效 keyBASE_URL="https://api.deepseek.com"#### 模型写法model=ChatOpenAI(model="deepseek-chat",openai_api_key=API_KEY,openai_api_base=BASE_URL,temperature=0.7)# ==============================================# 【模块1】自定义数据转换链(清洗用户废话)# ==============================================defclean_user_question(input_dict:dict)->dict:"""清洗用户输入的废话,提纯问题"""question=input_dict["question"]# 过滤冗余词useless_words=["哎","啊","请问","我想知道","谢谢"]forwordinuseless_words:question=question.replace(word,"")return{"clean_question":question.strip()}# 包装成LCEL组件clean_chain=RunnableLambda(clean_user_question)# ==============================================# 【模块2】分支链:判断问题类型,走不同逻辑# ==============================================# 分支1:判断是否是宠物问题defis_pet_question(input_dict:dict)->bool:return"猫"ininput_dict["clean_question"]or"狗"ininput_dict["clean_question"]# 宠物专家提示词(系统+用户)pet_prompt=ChatPromptTemplate.from_messages([("system","你是专业宠物医生,回答科学、简洁、有耐心"),("user","请回答宠物问题:{clean_question}")])# 通用问答提示词normal_prompt=ChatPromptTemplate.from_messages([("system","你是通用AI助手,礼貌回答所有问题"),("user","请回答问题:{clean_question}")])# 构建分支链branch_chain=RunnableBranch((is_pet_question,pet_prompt),# 宠物问题 → 走专家逻辑normal_prompt# 其他问题 → 走通用逻辑)# ==============================================# 【模块3】并行链:模拟RAG检索上下文(同时传参+检索)# ==============================================parallel_chain=RunnableParallel({"clean_question":RunnablePassthrough(),# 原样传递清洗后的问题# 模拟向量库检索上下文(真实RAG替换为retriever)"context":lambdax:"宠物护理通用知识:掉毛可通过梳理、饮食改善"})# ==============================================# 【终极组合链】把所有模块串起来(LCEL核心)# ==============================================final_chain=(clean_chain# 第一步:清洗数据(自定义函数)|branch_chain# 第二步:分支判断|parallel_chain# 第三步:并行获取问题+上下文|model# 第四步:大模型生成|StrOutputParser()# 第五步:转纯文本)# ==============================================# 测试调用# ==============================================if__name__=="__main__":# 测试1:宠物问题(带废话)print("【测试1:宠物问题】")res1=final_chain.invoke({"question":"哎请问啊,我家缅因猫掉毛怎么办?"})print(res1)print("\n"+"-"*50)# 测试2:非宠物问题print("【测试2:通用问题】")res2=final_chain.invoke({"question":"Python是什么?"})print(res2)

就像搭积木一样简单。

http://www.jsqmd.com/news/675318/

相关文章:

  • iperf3 UDP/TCP混合压测避坑指南:在嵌入式Linux上如何准确评估多网口性能
  • 万象熔炉 | Anything XL完整指南:支持AnimateDiff的图生视频扩展能力前瞻
  • 告别玄学调试:用逻辑分析仪抓包解析ESP32与BLE模块的AT指令交互全过程
  • SDMatte镜像部署一文详解:从CSDN GPU实例开通到7860服务稳定运行
  • 注意力机制模块:引入 DiNA(空洞邻域注意力),扩大模型感受野且不增加自注意力计算复杂度
  • 别再手动查色值了!用Python+Pandas一键生成你的专属颜色对照表(含16进制、RGB、CMYK、HSV)
  • RISC-V三种模式详解:M-mode、S-mode、U-mode在系统启动中的权限控制
  • Dify 2026微调方法论深度拆解(2026 Q1官方未公开的梯度压缩协议与显存优化参数)
  • 08-第六篇-超越-Coding-的泛化
  • 3分钟上手!赛博朋克2077存档编辑器完全指南 [特殊字符]
  • YOLO-v5新手教程:手把手教你计算mAP,快速掌握模型性能评估
  • Real Anime Z图像质量评测:SSIM/NIQE指标下真实系风格量化优势
  • 注意力机制模块:老树发新芽:SE 注意力结合硬件友好型 Swish 激活函数,在边缘端模型中的极限优化
  • RVC模型浏览器插件开发构想:实现网页音频实时变声
  • S2-Pro C语言学习助手:代码调试与算法理解一键部署指南
  • 别再搞混了!Linux用户组管理:useradd、usermod、gpasswd命令的保姆级对比与实战避坑
  • 【Axure视频教程】中继器表格自适应行高
  • AI人脸隐私卫士升级指南:从单张处理到批量脱敏进阶
  • 掌握ezdxf:用Python构建专业级CAD图纸的5个实战技巧
  • SpringBoot项目里,用Jodconverter+LibreOffice把Word/Excel转PDF,我踩过的那些坑都帮你填平了
  • Dify容器化国产部署失败率骤降83%的关键动作:K8s准入策略+国产CA证书链注入+SELinux策略白名单配置
  • github 443 错误 OpenSSL SSL_connect: SSL_ERROR_SYSCALL 或者LibreSSL
  • 高校如何高效推动科研成果转化?
  • Multi-Agent 系统容错机制:节点故障与任务失败的快速恢复策略
  • CoPaw模型生成高质量技术文档与API说明效果展示
  • VCAM虚拟摄像头:5分钟掌握Android摄像头替换的终极解决方案
  • AI 日报 - 2026年4月20日
  • 荣耀“闪电”50分26秒破半马纪录,具身智能技术再突破
  • 冥想第一千八百五十四天(1854)
  • 为什么你的Dify工业知识库召回率不足62%?——来自航天/轨交/能源三大行业配置基线报告(限时开放)