组件地图、环境与 LCEL 最小调用
本节目标
学完后,你应能把“LangChain 项目”拆成普通 Python、langchain-core 组件、LangChain 高层 Agent、LangGraph 运行时和提供商集成包,并能写出一个不调用模型的 LCEL(LangChain Expression Language)组合。重点不是背类名,而是看清每一步的输入、输出和失败边界。
先从问题而不是框架出发
假设任务是“收到工单文本,标准化内容,分类,再决定是否调用查询工具”。至少有四种实现层级:
| 层级 | 适合什么 | 不该承担什么 |
|---|---|---|
| 普通 Python 函数 | 步骤固定、逻辑确定、无需框架观测 | 不必为了“像 Agent”而包装 |
| Runnable / LCEL | 需要统一 invoke、batch、异步、流式或组合契约 | 不自动获得自主决策与持久状态 |
LangChain create_agent | 标准“模型决定是否调用工具”的循环和中间件 | 不适合隐藏复杂拓扑与副作用语义 |
| LangGraph | 显式状态、分支、循环、并行、检查点、暂停恢复 | 不替你定义授权、幂等和业务真相 |
LangChain v1 把顶层 langchain 命名空间收敛到 Agent、消息、工具、模型和 Embedding 等核心入口;旧的 LLMChain 等历史 chain API 已移到 langchain-classic。因此,遇到旧教程先核对版本,不要机械改导入路径。
包之间是什么关系
langchain-core:模型、消息、Prompt、工具、Retriever、Runnable 等接口和组合协议;不包含第三方提供商实现。langchain:当前高层 Agent API,包括create_agent、Agent 状态和中间件入口。langgraph:有状态、可持久化的图运行时;LangChain 的高层 Agent 建立在它之上。langchain-<provider>:模型提供商集成,独立安装并按各自文档配置。langchain-classic:迁移期兼容旧链、旧 retriever 等功能,不是新项目默认起点。
Deep Agents 是更高层的长任务 harness。它不是每个 LangChain 初学项目的必选依赖,且其版本策略比已进入 1.x 的 LangChain/LangGraph 更容易变化。
环境与版本基线
官方当前安装页要求 LangChain 使用 Python 3.10+。Windows 11 / PowerShell 7 中先使用 venv + pip:
py -3.12 -m venv .venv # 用兼容的 Python 3.12 在练习项目中创建隔离环境。
.\.venv\Scripts\Activate.ps1 # 激活该环境,使当前会话的 python 与 pip 指向 .venv。
python -m pip install --upgrade pip # 先升级环境内的解析器,减少安装期依赖问题。
python -m pip install langchain # 安装 LangChain 主包;模型提供商包按实际选择另装。再按项目所选模型安装独立提供商包。教程不要写入真实密钥;密钥由环境变量或密钥管理服务注入。安装成功后记录解析出的完整依赖:
python -m pip freeze | Set-Content -Encoding utf8 requirements.lock.txt # 记录当前解析出的完整依赖快照。
python -c "import langchain_core; print(langchain_core.__version__)" # 输出实际安装的核心包版本以便核对。2026-07-19 的 PyPI 资料快照是 langchain 1.3.14、langgraph 1.2.9 与 langchain-core 1.4.9。这是核对点,不是要求手工拼接三个版本;让包解析器求解,再用锁文件和测试固定可工作组合。
LCEL 的最小直觉
Runnable 是“接收输入并产生输出的工作单元”。LCEL 的 | 把前一步输出送给后一步,得到 RunnableSequence;字典形式可形成并行分支。统一协议常见方法包括 invoke、batch、stream 及其异步版本。下面的示例没有模型和密钥:
from langchain_core.runnables import RunnableLambda, RunnableParallel # 导入可组合的函数 Runnable 与并行分支容器。
normalize = RunnableLambda(lambda text: " ".join(text.strip().split())) # 去除首尾和重复空白,形成规范化输入。
features = RunnableParallel( # 对同一规范化文本并行计算多个无副作用特征。
text=lambda text: text, # 保留规范化后的文本供下游使用。
length=lambda text: len(text), # 计算文本字符数作为第二个输出字段。
)
pipeline = normalize | features # 将前一步的字符串输出连接到并行特征分支。
print(pipeline.invoke(" hello agent ")) # 同步运行管道并打印结构化结果。
# {'text': 'hello agent', 'length': 11}同样的可运行文件在 examples/lcel_no_key.py。基础环境不常驻安装 langchain-core;2026-07-19 已在隔离的 langchain-core==1.4.9 环境真实运行并得到上方结果。依赖缺失分支仍会以明确退出码结束,不能把跳过误报为通过。
LCEL 不等于“自动正确”
|只表达组合。上一步输出形状与下一步输入不匹配、并行步骤写同一外部资源、重试重复副作用,仍是应用需要解决的问题。先写类型和契约,再追求紧凑表达式。
何时不用 LCEL
- 两三个纯函数且没有统一运行协议需求:普通 Python 更直接。
- 模型需要动态决定工具和步数:使用
create_agent,不要手写无限循环。 - 需要持久化、interrupt、显式路由或恢复:使用 LangGraph。
- 只是为了复用旧教程中的
LLMChain:先阅读 v1 迁移指南,避免为历史抽象新增依赖。
动手练习
- 用普通 Python 写“去空格→转小写→统计长度”。
- 把三个步骤改为 Runnable,并分别运行
invoke与batch。 - 故意让第二步期待字典却收到字符串,记录错误发生在哪个边界。
- 为“固定分类流程”和“模型自主查资料”分别选择普通 Python、LCEL、Agent 或 LangGraph,并说明理由。
自测
- 能解释
langchain、langchain-core、提供商包与langgraph的关系。 - 能说明 LCEL 的
|和RunnableParallel表达什么、不表达什么。 - 能识别 v0.x 旧教程中的
LLMChain,并先查 v1 迁移资料。 - 能在锁定版本前区分“当前文档示例”与“本项目已验证接口”。
下一步
进入 模型、消息、Prompt 与结构化输出,给模型交互建立清晰契约。
资料基线
官方事实核对日期:2026-07-14。