LangChain 1.0三大核心概念详解:LCEL、Runnable、content_blocks
2026/7/24 6:05:14 网站建设 项目流程

上篇我们跑通了第一个Agent,但如果你只停留在"能用"的层面,后面遇到复杂场景一定会卡壳。LangChain 1.0的设计哲学和0.x完全不同,理解三个核心概念就够了:LCEL、Runnable、content_blocks。

这三个东西不是孤立的,它们是一条线串下来的:Runnable是组件的统一抽象,LCEL是组件之间的组合语法,content_blocks是组件之间的数据格式。搞懂这条线,你就掌握了1.0的设计骨架。

Runnable:一切皆可执行

1.0里几乎所有东西都是Runnable:模型是Runnable,提示词模板是Runnable,输出解析器是Runnable,检索器也是Runnable。

为什么这么设计?0.x的问题在于,每种组件都有自己的接口和调用方式——模型用llm(prompt),链用chain.run(),Agent用agent.run(),你没法把它们自由组合。

Runnable统一了接口,所有组件都只有三个核心方法:

# 同步调用result = runnable.invoke(input)# 流式调用for chunk in runnable.stream(input): print(chunk)# 异步调用result = await runnable.ainvoke(input)

这意味着什么?你可以把模型、提示词模板、解析器像搭积木一样自由拼装,因为它们的输入输出接口是统一的。

from langchain_core.prompts import ChatPromptTemplatefrom langchain_openai import ChatOpenAIfrom langchain_core.output_parsers import StrOutputParser# 每个组件都是Runnableprompt = ChatPromptTemplate.from_template("用一句话解释{concept}")model = ChatOpenAI(model="gpt-4o-mini")parser = StrOutputParser()# 用LCEL管道组合chain = prompt | model | parser# 统一调用result = chain.invoke({"concept": "量子纠缠"})print(result) # 量子纠缠是两个粒子无论相隔多远,测量其中一个会瞬间影响另一个的状态。

prompt | model | parser,这个管道语法就是LCEL,下一节详细说。

LCEL:LangChain表达式语言

LCEL全称LangChain Expression Language,就是上面那个|管道操作符。它的设计灵感来自Unix管道——把一个命令的输出直接传给下一个命令。

基本用法

# 等价于 bash 里的 cat file | grep keyword | sort# LCEL 里就是 prompt | model | parserchain = prompt | model | parser

看起来简单,但它解决的其实是0.x里一个很烦人的问题:链式调用太死板

0.x里你要创建一条链,得这样写:

# 0.x写法from langchain.chains import LLMChainchain = LLMChain(llm=model, prompt=prompt)result = chain.run(concept="量子纠缠")

问题在于LLMChain是个固定结构,你想在中间加个步骤(比如加个输出格式化),就得写个自定义Chain类,继承BaseChain,实现一堆方法。

LCEL的做法是:不需要固定结构,你自己拼。

# 1.0写法:在模型和解析器之间加一步格式化from langchain_core.runnables import RunnableLambdadef format_output(text): return text.strip().replace("。", "。\n")chain = prompt | model | RunnableLambda(format_output) | parser

想加步骤就|一个Runnable进去,想删就删,灵活度完全不在一个量级。

LCEL的高级用法

1. 并行执行

from langchain_core.runnables import RunnableParallel# 两条链同时跑,结果合并parallel = RunnableParallel({ "summary": summary_chain, "keywords": keyword_chain,})result = parallel.invoke({"text": "一段长文本..."})# result = {"summary": "摘要内容", "keywords": "关键词列表"}

2. 条件路由

from langchain_core.runnables import RunnableBranch# 根据输入选择不同的处理链branch = RunnableBranch( (lambda x: len(x["text"]) > 1000, long_text_chain), (lambda x: "code" in x["text"], code_chain), default_chain, # 默认走这条)

3. 配置化

运行时动态切换组件,不用改代码:

from langchain_core.runnables import ConfigurableFieldmodel = ChatOpenAI(model="gpt-4o-mini").configurable_fields( model_name=ConfigurableField(id="model"))# 运行时选模型result = model.invoke( "你好", config={"configurable": {"model": "deepseek-chat"}})

这些在0.x里要么做不到,要么得写大量模板代码。LCEL用几行就搞定了。

content_blocks:统一的消息内容格式

这个概念我在第一篇里提过,这里展开讲讲为什么它重要、怎么用。

它解决什么问题?

不同大模型返回消息的格式各不相同:

  • OpenAI返回content字符串 +function_call对象
  • Anthropic返回多个content_block,文本和工具调用分开
  • DeepSeek返回content+tool_calls列表

0.x时代,你要处理不同模型的输出,就得写适配代码。比如判断response.additional_kwargs.get("function_call")response.tool_calls等,每个模型还不一样。

1.0用content_blocks统一了这一切:

response = model.invoke("帮我查一下北京天气")# 不管底层是什么模型,都用同一套方式访问for block in response.content_blocks: match block["type"]: case "text": print(f"文本: {block['text']}") case "tool_call": print(f"调用工具: {block['name']}, 参数: {block['args']}") case "reasoning": print(f"推理过程: {block['text']}") # DeepSeek的思考链 case "image": print(f"图片: {block.get('url', '')}")

实际开发中怎么用?

场景1:你想从模型回复中提取工具调用

tool_calls = [ block for block in response.content_blocks if block["type"] == "tool_call"]

场景2:你想拿到DeepSeek的思考过程

reasoning = ""answer = ""for block in response.content_blocks: if block["type"] == "reasoning": reasoning = block["text"] elif block["type"] == "text": answer = block["text"]print(f"思考过程: {reasoning}")print(f"最终回答: {answer}")

场景3:多模态输出处理

for block in response.content_blocks: if block["type"] == "image": # 懒加载,图片不会在content_blocks里直接加载 image_data = block.load() # 需要时才下载 image_data.save(f"output_{block['id']}.png")

content_blocks和旧版content属性的关系

1.0里AIMessage同时保留了content(字符串)和content_blocks(列表)两个属性,向下兼容:

# content还是能用的,返回纯文本print(response.content) # "北京今天晴,气温28℃"# content_blocks是结构化视图print(response.content_blocks) # [{"type": "text", "text": "北京今天晴..."}]

日常简单场景用content就行,需要细粒度处理再用content_blocks

三者的关系:一张图搞定

用户输入 ↓[Prompt Template (Runnable)] ← LCEL定义 ↓[Chat Model (Runnable)] ← content_blocks统一输出格式 ↓[Output Parser (Runnable)] ↓最终输出
  • Runnable让每个组件都有统一的调用接口(invoke/stream/ainvoke)
  • LCEL让组件之间可以用|自由组合
  • content_blocks让组件之间的数据传递有了统一的格式

三件事,一个目标:让AI应用的开发像搭积木一样灵活。

学AI大模型的正确顺序,千万不要搞错了

🤔2026年AI风口已来!各行各业的AI渗透肉眼可见,超多公司要么转型做AI相关产品,要么高薪挖AI技术人才,机遇直接摆在眼前!

有往AI方向发展,或者本身有后端编程基础的朋友,直接冲AI大模型应用开发转岗超合适!

就算暂时不打算转岗,了解大模型、RAG、Prompt、Agent这些热门概念,能上手做简单项目,也绝对是求职加分王🔋

📝给大家整理了超全最新的AI大模型应用开发学习清单和资料,手把手帮你快速入门!👇👇

学习路线:

✅大模型基础认知—大模型核心原理、发展历程、主流模型(GPT、文心一言等)特点解析
✅核心技术模块—RAG检索增强生成、Prompt工程实战、Agent智能体开发逻辑
✅开发基础能力—Python进阶、API接口调用、大模型开发框架(LangChain等)实操
✅应用场景开发—智能问答系统、企业知识库、AIGC内容生成工具、行业定制化大模型应用
✅项目落地流程—需求拆解、技术选型、模型调优、测试上线、运维迭代
✅面试求职冲刺—岗位JD解析、简历AI项目包装、高频面试题汇总、模拟面经

以上6大模块,看似清晰好上手,实则每个部分都有扎实的核心内容需要吃透!

我把大模型的学习全流程已经整理📚好了!抓住AI时代风口,轻松解锁职业新可能,希望大家都能把握机遇,实现薪资/职业跃迁~

这份完整版的大模型 AI 学习资料已经上传CSDN,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询