@langchain/classic 完整指南:LangChain.js v1.0 中旧版抽象的兼容包定位、迁移路径与源码级实现
【免费下载链接】langchainjsThe agent engineering platform项目地址: https://gitcode.com/GitHub_Trending/la/langchainjs
在 LangChain.js v1.0 的架构重构中,原有的 legacy Chains、Indexing API 与大量社区集成被从主包langchain中剥离,形成了独立维护的@langchain/classic包。本文基于仓库内的 libs/langchain-classic/README.md 并结合包源码、依赖声明与新版 libs/langchain 的结构,完整讲解这个兼容包的使用场景、安装依赖要求、模块构成、导入规范,以及从旧版链式 API 迁移到 v1.0createAgent的实操路径,帮助你在维护存量应用与启动新项目之间做出正确的选型决策。
1. 包的定位:为什么会有 @langchain/classic
@langchain/classic的官方定位是:存放 LangChain.js v0.x 时代的功能,这些功能在 v1.0 发布时被移出主包langchain。它存在的目的只有一个——为仍在使用旧抽象的既有应用提供向后兼容,而核心的langchain包则聚焦于现代 Agent 开发所需的最小组件集合。
这一点从新版主包的源码结构可以得到印证。libs/langchain/src/index.ts 的根导出只保留了消息类型(BaseMessage、AIMessage、HumanMessage等)、统一模型入口initChatModel、工具原语(tool、StructuredTool)、Agent 体系(createAgent及其预置 middleware)、InMemoryStore、Document与测试工具等"必要组件",完全不含LLMChain、SequentialChain这类旧版链。换言之,v1.0 的 API 边界是通过"瘦身主包 + 独立 classic 包"这一物理拆分来实现的。
当前仓库中该包的版本与基本元信息可在 libs/langchain-classic/package.json 中确认:包名为@langchain/classic,描述为 "Old abstractions from LangChain.js",许可证为 MIT。
2. 适用场景与禁用场景
README 对"何时使用"给出了非常明确的边界。
2.1 应当使用 @langchain/classic 的情况
如果你的项目满足以下任一条件,就应使用@langchain/classic:
- 存量代码使用 legacy chains,例如
LLMChain、ConversationalRetrievalQAChain、RetrievalQAChain; - 使用 Indexing API(
RecordManager及相关的向量化文档更新能力); - 依赖此前从
langchain主包再导出的@langchain/community功能; - 仍在维护既有应用、暂时不具备迁移到
createAgent新 API 的条件。
2.2 不应当使用的情况:新项目直接用 langchain v1.0
README 的立场非常直接:新项目请使用langchainv1.0,理由包括:
createAgent:更简洁且功能更强的 Agent 构建方式,支持 middleware 机制;- 更好的性能:面向现代 Agent 工作流优化;
- 更聚焦的 API 面:复杂度更低、学习成本更小;
- 活跃开发:新特性与改进将集中在 v1.0 API 上。
新版 Agent 的实现位于 libs/langchain/src/agents/index.ts,其周边还配套了完整的 middleware 体系(HITL、上下文编辑、工具重试、模型回退等,见 libs/langchain/src/agents/middleware),这是 classic 包中旧版 agent executor 所不具备的。
3. 安装与依赖要求
基本安装方式:
npm install @langchain/classic该包将@langchain/core声明为 peer dependency,需要单独安装:
npm install @langchain/core结合 libs/langchain-classic/package.json 的声明,还有几个实操中必须注意的依赖事实:
- Node 版本:
engines要求node >= 20; - 可选 peer 依赖:
cheerio(HTML 解析)、peggy(表达式解析语法)、typeorm(SQL 相关功能)均标记为optional: true,只在用到对应功能时才需要安装; - 内置依赖:包依赖
@langchain/openai、@langchain/textsplitters,以及handlebars、js-yaml、jsonpointer、openapi-types、yaml等工具库; - zod 双兼容:
zod的依赖声明为^3.25.76 || ^4,即同时支持 zod v3 与 v4 项目; - 可选依赖:
langsmith(>=0.4.0 <1.0.0)作为 optionalDependency 引入,用于 LangSmith 追踪集成。
4. 包内容构成:从 README 到源码逐一对照
README 将包内容分为四类,以下逐一展开并对照源码目录验证。
4.1 Legacy Chains(旧版链实现)
这是 classic 包最核心的部分,README 列举了 v0.x 的全部链实现,包括:
LLMChain—— 使用提示模板调用 LLM 的基础链;ConversationalRetrievalQAChain—— 面向文档的会话式问答链;RetrievalQAChain—— 无会话记忆的文档问答链;StuffDocumentsChain—— 将文档整体塞入提示的文档组合链;MapReduceDocumentsChain—— 对文档做 map-reduce 的链;RefineDocumentsChain—— 对文档做迭代精炼的链。
在源码目录 libs/langchain-classic/src/chains 中可以找到与之一一对应的实现:llm_chain.ts、conversational_retrieval_chain.ts、retrieval_qa.ts、combine_documents/(含stuff.ts、reduce.ts)、question_answering/(含 map-reduce、refine、stuff 三套提示词)等。此外还包括sequential_chain.ts、conversation.ts、sql_db/、router/、constitutional_ai/、graph_qa/等旧版能力,配套的单元测试与集成测试也一并保留(如llm_chain.int.test.ts、retrieval_chain.test.ts)。仓库的 examples/src/langchain-classic 目录下还保留了这些旧链的完整可运行示例(chains、memory、callbacks、prompts 等子目录),是理解 legacy API 用法的最好参照。
4.2 Indexing API(索引/文档增量更新)
README 说明包中包含RecordManager及相关索引能力,用于管理向量库中文档的更新。从源码看,libs/langchain-classic/src/indexes/index.ts 将index、CleanupMode、IndexOptions、_batch、_deduplicateInOrder等符号从@langchain/core/indexing再导出,即 classic 包通过@langchain/classic/indexes入口提供索引能力。
底层的RecordManager抽象定义在 libs/langchain-core/src/indexing/record_manager.ts,其接口要求实现以下方法:
| 方法 | 作用 |
|---|---|
createSchema() | 在记录管理器中创建 schema |
getTime() | 返回当前时间戳 |
update(keys, { groupIds, timeAtLeast }) | 更新键,timeAtLeast提供乐观并发校验 |
exists(keys) | 按序返回每个键是否已存在 |
listKeys({ before, after, groupIds, limit }) | 按时间/分组过滤列出键 |
deleteKeys(keys) | 删除键 |
这套"记录管理器 + 文档哈希键"的设计使增量索引可以幂等地重放:index流程通过_deduplicateInOrder、_getSourceIdAssigner等内部工具(同样从 indexes 入口导出)计算文档源 ID 与哈希,再用exists/update/deleteKeys判定新增、变更与删除,这正是 v0.x 文档增量更新管线的工作机制。
4.3 社区集成再导出
README 提到包内包含"此前从主包langchain可用、现归属于@langchain/community的功能再导出"。从源码结构看,libs/langchain-classic/src/util/entrypoint_deprecation.ts 提供了带newPackageName: "@langchain/community"的弃用提示工具,用于在用户经由旧路径导入相关功能时提示新包位置;chains/graph_qa/cypher.ts等文件同样携带该指向。这说明 classic 包对社区集成的角色是"过渡性入口 + 明确的重定向提示",而非长期承载这些集成的仓库。
4.4 其他弃用功能
README 概括为"被 v1.0 中更优替代品取代的各类工具与抽象"。结合 libs/langchain-classic/src 的目录结构与 package.json 的exports映射,可以确认包内还完整保留了:
- memory/:
BufferMemory、BufferWindowMemory、EntityMemory、SummaryMemory、VectorStoreMemory等旧版记忆实现; - output_parsers/:
StructuredOutputParser、CommaSeparatedListOutputParser、表达式解析(基于peggy)等; - retrievers/:
EnsembleRetriever、ParentDocumentRetriever、MultiQueryRetriever、SelfQueryRetriever等高级检索器; - evaluation/、experimental/(autogpt、babyagi、generative_agents 等实验性 agent);
- document_loaders/(fs 目录、JSON/JSONL/文本加载器)、agents/(旧版 agent executor、ReAct/OpenAI tools 等 executor 工厂)、storage/、vectorstores/memory(内存向量库)等。
package.json 的exports映射把这些模块都暴露为规范的子路径入口,例如./chains、./chains/combine_documents、./agents、./memory、./indexes、./evaluation、./retrievers/parent_document、./document_loaders/fs/directory、./cache/file_system等,开发者可以按模块做细粒度导入,而不必加载整个包。
5. 导入规范:入口警告与子路径入口
README 的迁移示例展示了两类导入写法:
// 子路径入口 import { LLMChain } from "@langchain/classic/chains"; import { ConversationalRetrievalQAChain } from "@langchain/classic/chains"; // 根入口 import { LLMChain } from "@langchain/classic";这里需要结合源码补充一个重要的实现事实:从源码结构看,libs/langchain-classic/src/index.ts 的根入口当前只输出一条警告而不导出任何符号:
console.warn( `[WARNING]: The root "langchain" entrypoint is empty. Please use a specific entrypoint instead.` );也就是说,运行时从根入口@langchain/classic导入会得到空模块并看到该警告。因此实际编码时应当优先使用@langchain/classic/chains、@langchain/classic/memory、@langchain/classic/indexes等具体子路径入口(均可在 libs/langchain-classic/package.json 的exports字段中查到完整清单),这也是源码警告明确建议的用法。
6. 实战示例
6.1 使用 LLMChain
README 给出的标准示例:
import { LLMChain } from "@langchain/classic/chains"; import { ChatOpenAI } from "@langchain/openai"; import { PromptTemplate } from "@langchain/core/prompts"; const model = new ChatOpenAI({ model: "gpt-4" }); const prompt = PromptTemplate.fromTemplate( "Tell me a {adjective} joke about {content}." ); const chain = new LLMChain({ llm: model, prompt }); const result = await chain.call({ adjective: "funny", content: "chickens", }); console.log(result.text);结合 libs/langchain-classic/src/chains/llm_chain.ts 的源码,这个示例背后的关键机制是:
- 输入/输出键:
LLMChain的inputKeys直接取prompt.inputVariables,outputKey默认为"text"(可由构造参数覆盖),这就是示例中result.text的来源; - callKeys 分流(
_call,见 llm_chain.ts#L185-L229):call()传入的参数中,属于模型callKeys的键(如temperature)会被分流给模型调用参数,其余键交给提示模板渲染; - 两种执行路径:若模型实现了
generatePrompt,走generatePrompt生成后再经 outputParser 解析;否则将llm.pipe(outputParser)组成 runnable 后invoke; - outputParser 约束:构造时若同时设置了
outputParser与prompt.outputParser会直接抛错,二者只能取其一; - 便捷方法
predict(llm_chain.ts#L243-L249):等价于call后直接返回output[outputKey],省去取键操作; - 序列化支持:
LLMChain实现lc_serializable,可通过serialize()/static deserialize()参与 LangChain 的 JSON 序列化体系,_chainType()返回"llm"。
6.2 使用 ConversationalRetrievalQAChain
README 给出的会话式 RAG 示例:
import { ConversationalRetrievalQAChain } from "@langchain/classic/chains"; import { ChatOpenAI } from "@langchain/openai"; import { OpenAIEmbeddings } from "@langchain/openai"; import { MemoryVectorStore } from "langchain/vectorstores/memory"; // 创建向量库 const vectorStore = await MemoryVectorStore.fromTexts( ["Document 1 text...", "Document 2 text..."], [{ id: 1 }, { id: 2 }], new OpenAIEmbeddings() ); // 创建链 const model = new ChatOpenAI({ model: "gpt-4" }); const chain = ConversationalRetrievalQAChain.fromLLM( model, vectorStore.asRetriever() ); // 调用 const result = await chain.call({ question: "What is in the documents?", chat_history: [], }); console.log(result.text);源码 libs/langchain-classic/src/chains/conversational_retrieval_chain.ts 揭示了它的内部结构:该链由三部分组合——retriever(检索器)、combineDocumentsChain(文档组合链,即 Stuff/MapReduce/Refine 之一)与questionGeneratorChain(一个LLMChain),输入键默认是question与chat_history。其中问题改写使用的默认模板(conversational_retrieval_chain.ts#L15-L20)为:
Given the following conversation and a follow up question, rephrase the follow up question to be a standalone question. Chat History: {chat_history} Follow Up Input: {question} Standalone question:即每次调用先用 LLMChain 把带指代/省略的追问改写为独立问题,再交给检索器与文档组合链作答。源码 JSDoc 还给出了更精细的等价写法:用createHistoryAwareRetriever处理问题改写、用createStuffDocumentsChain与createRetrievalChain组合完成 RAG(均从@langchain/classic/chains/...子路径导入),说明ConversationalRetrievalQAChain本质上是"历史感知检索器 + 文档组合链 + 检索链"这三块可独立替换的构件。
7. 从旧版链迁移到 createAgent
README 建议:新开发请直接使用createAgent替代 legacy chains。其给出的LLMChain→createAgent迁移对照:
// Before (using LLMChain) import { LLMChain } from "@langchain/classic/chains"; import { ChatOpenAI } from "@langchain/openai"; import { PromptTemplate } from "@langchain/core/prompts"; const model = new ChatOpenAI({ model: "gpt-4" }); const prompt = PromptTemplate.fromTemplate( "What is a good name for a company that makes {product}?" ); const chain = new LLMChain({ llm: model, prompt }); const result = await chain.call({ product: "colorful socks" }); // After (using createAgent) import { createAgent } from "langchain"; const agent = createAgent({ model: "openai:gpt-4", systemPrompt: "You are a creative assistant that helps name companies.", }); const result = await agent.invoke({ messages: [ { role: "user", content: "What is a good name for a company that makes colorful socks?", }, ], });两者的范式差异值得注意:
- 输入形态:
LLMChain接收与模板变量对应的扁平键值对象({ product: ... }),而createAgent接收消息列表({ messages: [...] }),角色(system/user)由消息结构显式表达; - 模型指定:旧 API 需要实例化具体的 provider 模型类(
ChatOpenAI),新 API 支持"openai:gpt-4"这样的统一模型串(配合主包的initChatModel体系); - 扩展方式:旧链通过 memory、outputParser、callback 等参数拼装行为,新 Agent 通过 middleware 组合行为,实现与测试可独立演化。
createAgent的具体实现与类型定义位于 libs/langchain/src/agents/index.ts,配套的 middleware(如toolRetry、summarization、hitl等)位于 libs/langchain/src/agents/middleware,更复杂的迁移场景可参考仓库中 examples/src/createAgent 目录下按主题组织的示例(streaming、structuredOutput、middleware 各场景等)。
8. 维护策略与配套资源
README 明确了@langchain/classic的维护政策——它处于维护模式:
- 会接收关键 bug 修复;
- 会接收安全漏洞补丁;
- 不再增加新特性,新能力集中在
langchainv1.0 API 上。
这意味着选型逻辑很清晰:存量 legacy 应用继续用 classic 包并保持补丁更新;任何新增功能模块都建议直接落在 v1.0 API 上。
包内其他可继续深入的资源:
- 变更历史:libs/langchain-classic/CHANGELOG.md;
- 完整可运行示例(旧链、记忆、回调、提示词等):examples/src/langchain-classic;
- 许可证:MIT,见仓库根目录 LICENSE。
9. 小结
@langchain/classic是 LangChain.js v1.0 架构演进中的兼容性落点:它原样保留了 v0.x 的 legacy chains、Indexing API、社区集成再导出与各类弃用抽象,并通过规范的子路径入口暴露(如@langchain/classic/chains、@langchain/classic/indexes),同时以维护模式(仅修 bug 与安全补丁)运行。掌握它的关键在于三点:其一,明确它与新版langchain主包的边界——新项目用createAgent,存量应用用它;其二,注意根入口仅有警告输出,务必使用具体子路径导入;其三,理解LLMChain的键值分流与ConversationalRetrievalQAChain的三段式内部结构后,才能判断哪些旧代码值得保留、哪些可以平滑改写为新的 Agent API。
【免费下载链接】langchainjsThe agent engineering platform项目地址: https://gitcode.com/GitHub_Trending/la/langchainjs
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考