libs/core 第一轮精读
摘要
libs/core 对应发布包 langchain-core,它是 LangChain 生态的基础抽象层,明确不承载第三方 provider 集成。当前最重要的阅读结论是:langchain_core.runnables 是统一调用协议与 LCEL 的核心入口,而真正的实现重心主要位于 langchain_core/runnables/base.py 与 config.py。
仓库定位
包级身份
- 包名:
langchain-core - 版本:
1.3.0 - Python 要求:
>=3.10,<4.0 - 描述:
Building applications with LLMs through composability
官方定位
根据 libs/core/README.md 与 langchain_core/__init__.py:
langchain-core定义 LangChain 生态的基础抽象- 包含 chat models、LLMs、retrievers、vector stores 等接口
- 统一调用协议(Runnables)和组合语法也定义在这里
- 不包含第三方 integrations,依赖刻意保持轻量
目录结构(第一轮)
libs/core/langchain_core/ 下目前最值得优先关注:
runnables/:统一调用协议与 LCELprompts/:Prompt 抽象language_models/:模型接口messages/:消息类型output_parsers/:输出解析tools/:Tool 抽象retrievers.py:检索器接口documents/:文档类型callbacks/、tracers/:回调与追踪
Runnable 入口与导出面
入口文件
libs/core/langchain_core/runnables/__init__.py
入口作用
该文件主要负责:
- 暴露 Runnable 公共 API
- 通过动态导入将 API 分发到具体实现文件
- 定义 LCEL 相关的公开符号
公开导出的重点对象
RunnableRunnableSequenceRunnableParallelRunnableLambdaRunnableGeneratorRunnablePassthroughRunnableAssignRunnableWithFallbacksRunnableWithMessageHistoryRunnableConfigchain
Runnable 主定义
核心文件
libs/core/langchain_core/runnables/base.pylibs/core/langchain_core/runnables/config.py
关键类行号
Runnable:base.py:124RunnableSequence:base.py:2817RunnableParallel:base.py:3565RunnableLambda:base.py:4399
Runnable 的执行模型
抽象基类
Runnable 被定义为:
- 一个可
invoke - 可
batch - 可
stream - 可组合
- 可暴露 schema/config 信息 的通用工作单元。
关键公共方法
在 Runnable 基类中:
invoke是抽象方法,要求子类实现ainvoke默认通过run_in_executor包装同步invokebatch默认用线程池并行调用多个invoke
这说明:
invoke是真正的最小执行核心- 异步默认不是“原生 async”,而是 sync fallback + executor
batch是默认并行策略,适合 IO bound 场景- 子类如果能更高效批处理,需要自己 override
RunnableConfig 的作用
runnables/config.py 中的 RunnableConfig 是整个执行协议的重要胶水层。
关键字段
tagsmetadatacallbacksrun_namemax_concurrencyrecursion_limitconfigurablerun_id
当前理解
RunnableConfig 不只是“配置对象”,它还是:
- tracing 元数据载体
- 并发控制入口
- 运行时可配置字段注入入口
- 父子 runnable 配置传播机制的一部分
尤其重要的是:
var_child_runnable_config用ContextVar在调用栈中传播配置- tracing 上下文会跟随 config 传播
两个最重要的组合原语
1. RunnableSequence
- 定义位置:
base.py:2817 - 语义:前一个 Runnable 的输出,作为下一个 Runnable 的输入
- 构建方式:最常见是通过
|运算符 - 结构:内部拆成
first/middle/last - 特点:自动支持 sync / async / batch
关键理解
- 它是 LangChain 中“最重要的组合算子”之一
- 几乎所有 chain 都会落到这个抽象上
- sequence 的 schema 由整条链推导
- streaming 能否贯通,取决于链中各节点是否实现
transform
很重要的一点
RunnableLambda 默认不支持 transform,所以如果链路中塞了 lambda,可能会阻断 streaming 的贯通。
2. RunnableParallel
- 定义位置:
base.py:3565 - 语义:同一个输入并发喂给多个 Runnable,输出按 key 聚合成 dict
- 构建方式:可直接构造,也可在 sequence 中使用 dict literal 自动 coercion
关键理解
- 这是另一条核心组合原语
- 它会把多个 step 的 input schema / output schema 聚合起来
- 很适合 fan-out 结构:同一个输入并发跑多个链路
RunnableLambda 的作用
- 定义位置:
base.py:4399 - 作用:把普通 Python callable 包装成 Runnable
- 优点:接入门槛低、组合方便、自动接 tracing
- 限制:默认更适合非 streaming 逻辑
特别注意
如果一个 RunnableLambda 返回的是另一个 Runnable,那么这个返回值会在运行时继续被 invoke / stream。
测试层线索
当前最值得优先阅读的测试
libs/core/tests/unit_tests/runnables/test_runnable.pylibs/core/tests/unit_tests/runnables/test_runnable_events_v2.pylibs/core/tests/unit_tests/runnables/test_runnable_events_v1.pylibs/core/tests/unit_tests/runnables/test_history.pylibs/core/tests/unit_tests/runnables/test_fallbacks.py
为什么先看这些
test_runnable.py是 Runnable 总测试入口,覆盖面最广test_runnable_events_v2.py能反推 tracing / event stream 的真实对外契约- 测试中大量使用
Fake*模型与 retriever,说明 LangChain 在 core 层很重视“协议先行、假对象验证”
第一轮结论
libs/core是全生态基础抽象层,不是具体 provider 实现层。langchain_core.runnables是当前最值得优先精读的中心模块。base.py是 Runnable 体系的真正核心大文件。invoke是最小执行原语,ainvoke/batch/stream都是围绕它扩展。RunnableSequence和RunnableParallel是两大组合原语。RunnableConfig是执行、追踪、并发、配置传播的统一入口。- 想理解真实行为,必须结合
tests/unit_tests/runnables/一起看。
下一步建议
- 精读
RunnableSequence.invoke/batch/stream的具体实现 - 看
RunnableParallel如何做并发和 schema 聚合 - 深挖
transform/astream_events/ tracing 的关系 - 对照
prompts、language_models、tools看它们如何实现 Runnable 协议
未解问题
transform的默认行为和 override 机制到底怎么组织?stream/astream_log/astream_events的边界分别是什么?tools与Runnable在 core 层的关系是继承、适配还是包装?langchain_v1里哪些高层抽象只是对 core Runnable 的组合封装?