Skip to content

先维护 LLMChain,再比较 LCEL 迁移 ​

旧项目的 LLMChain 把 prompt、模型、输出键和 memory 组合在类里。维护它时先辨认输入变量与输出字典,不能看到弃用警告就直接替换。当前环境用 langchain-classic 的兼容实现运行此存量编程方式,不宣称重现所有历史0.x版本。

在原抽象内修复变量不匹配 ​

复用第一章环境,完整实验使用真实 FakeListLLM,它只返回固定文本,适合检查链的调用合同,不证明模型质量。

python
from langchain_classic.chains import LLMChain
from langchain_core.prompts import PromptTemplate
from langchain_core.language_models.fake import FakeListLLM
prompt=PromptTemplate.from_template("Explain {topic} in {language}.")
chain=LLMChain(llm=FakeListLLM(responses=["idempotency"]),prompt=prompt,output_key="answer")
try: chain.invoke({"topic":"idempotency"})
except ValueError: print("missing language")
else: raise AssertionError("missing variable accepted")
r=chain.invoke({"topic":"idempotency","language":"Chinese"})
assert r["answer"] == "idempotency" and r["topic"] == "idempotency"
print(r)

原问题是缺 language,并非模型不理解。修复调用输入即可;invoke 的结果字典通常同时包含输入和 output_key,业务若只读 answer,应保留这个合同。弃用警告是维护信号,不是这个实验失败。

相同任务迁移到 Runnable ​

独立实验复用相同环境:

python
from langchain_core.prompts import PromptTemplate
from langchain_core.language_models.fake import FakeListLLM
from langchain_core.output_parsers import StrOutputParser
from langchain_core.runnables import RunnablePassthrough
prompt=PromptTemplate.from_template("Explain {topic} in {language}.")
text=prompt | FakeListLLM(responses=["idempotency"]) | StrOutputParser()
compatible=RunnablePassthrough.assign(answer=text)
r=compatible.invoke({"topic":"idempotency","language":"Chinese"})
assert r == {"topic":"idempotency","language":"Chinese","answer":"idempotency"}
print(r)

直接 prompt|model|parser 只返回字符串,和旧 LLMChain 字典不等价。assign 明确保留输入并增加 answer,才能维持调用方合同。对比还应测试异步、批量、异常和回调,不能只看一句输出相同。

旧 Memory 可能在链调用前加载变量、调用后保存历史;迁移到消息历史或 checkpointer 时先确认会话键与追加时机,避免保存两次。旧 AgentExecutor 常返回 output 与 intermediate_steps,而 create_agent 返回含 messages 的状态;调用方解析必须改,工具回填和停止条件也要回归。预构建 create_react_agent 与现代 create_agent 的迁移不只是导入改名,middleware 与状态字段不同。

版本升级先锁核心、供应商、classic与graph依赖,记录弃用、接口与序列化变化。Python 对象可在进程里调用不表示能跨版本反序列化;持久状态保存数据与版本,不保存任意执行对象。遇到抽象问题,依次读消息、Runnable、工具、Agent,再读具体provider和retriever的实现与测试。

练习 ​

把旧链output_key改成summary,并在LCEL端保持相同的完整返回字典,输入仍为topic和language。断言两个结果相同。

核对本章答案

下一章

用心记录每一步成长