ai-orchestration-langchain
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseLangChain.js Patterns
LangChain.js 模式
Quick Guide: Use LangChain.js (v1.x) to build composable LLM applications. Use LCEL () for all chain composition -- never use legacyprompt.pipe(model).pipe(parser). UseLLMChainfor typed responses. UsewithStructuredOutput(zodSchema)(LangGraph-backed) for agentic workflows --createAgent()is legacy. AllAgentExecutorpackages must share the same@langchain/*version or you get cryptic type errors at runtime.@langchain/core
<critical_requirements>
快速指南: 使用LangChain.js(v1.x)构建可组合的LLM应用。所有链组合都使用LCEL()——绝不要使用旧版prompt.pipe(model).pipe(parser)。使用LLMChain获取类型化响应。使用withStructuredOutput(zodSchema)(基于LangGraph)构建Agent工作流——createAgent()已过时。所有AgentExecutor包必须共享相同版本的@langchain/*,否则运行时会出现难以理解的类型错误。@langchain/core
<critical_requirements>
CRITICAL: Before Using This Skill
重要提示:使用本技能前须知
All code must follow project conventions in CLAUDE.md (kebab-case, named exports, import ordering,, named constants)import type
(You MUST use LCEL pipe composition () for all chains -- never use legacy , , or )
prompt.pipe(model).pipe(parser)LLMChainConversationChainSequentialChain(You MUST ensure all packages depend on the same version of -- version mismatches cause cryptic runtime errors)
@langchain/*@langchain/core(You MUST use for structured LLM responses -- never manually parse JSON from completion text)
withStructuredOutput(zodSchema)(You MUST use from for new agent code -- and are legacy patterns)
createAgent()langchainAgentExecutorcreateToolCallingAgent(You MUST never hardcode API keys -- use environment variables (, , etc.))
OPENAI_API_KEYANTHROPIC_API_KEY</critical_requirements>
Auto-detection: LangChain, langchain, @langchain/core, @langchain/openai, @langchain/anthropic, @langchain/google-genai, ChatOpenAI, ChatAnthropic, ChatPromptTemplate, StringOutputParser, RunnableSequence, pipe, withStructuredOutput, createAgent, createToolCallingAgent, AgentExecutor, tool, DynamicStructuredTool, RecursiveCharacterTextSplitter, MemoryVectorStore, OpenAIEmbeddings, LCEL, LangSmith, LANGCHAIN_TRACING_V2
When to use:
- Building LLM applications that compose prompts, models, and output parsers into chains
- Creating agentic workflows where models decide which tools to call
- Implementing RAG pipelines with document loading, splitting, embedding, and retrieval
- Needing structured output from LLMs with type-safe Zod schema validation
- Streaming LLM responses token-by-token to users
- Switching between LLM providers (OpenAI, Anthropic, Google) with a unified interface
- Tracing and debugging LLM applications with LangSmith
Key patterns covered:
- Chat model initialization and provider switching (ChatOpenAI, ChatAnthropic, ChatGoogleGenerativeAI)
- LCEL chain composition with and
.pipe()RunnableSequence - Prompt templates (,
ChatPromptTemplate)MessagesPlaceholder - Structured output with and Zod schemas
withStructuredOutput() - Tool definition with function and Zod schemas
tool() - Agent creation with (LangGraph-backed)
createAgent() - RAG pipelines: document loaders, text splitters, vector stores, retrievers
- Streaming from chains, models, and agents
- LangSmith tracing setup
When NOT to use:
- You only call one LLM provider and want the thinnest wrapper -- use the provider's SDK directly
- You need React-specific chat UI hooks (,
useChat) -- use a framework-integrated AI SDKuseCompletion - You want a simple single-call completion with no chaining -- a direct SDK call is simpler
- You need real-time bidirectional communication -- LangChain does not cover WebSocket/Realtime APIs
所有代码必须遵循CLAUDE.md中的项目约定(短横线命名法、命名导出、导入顺序、、命名常量)import type
(所有链必须使用LCEL管道组合()——绝不要使用旧版、或)
prompt.pipe(model).pipe(parser)LLMChainConversationChainSequentialChain(必须确保所有包依赖相同版本的——版本不匹配会导致难以排查的运行时错误)
@langchain/*@langchain/core(结构化LLM响应必须使用——绝不要手动从补全文本中解析JSON)
withStructuredOutput(zodSchema)(新的Agent代码必须使用中的——和是旧版模式)
langchaincreateAgent()AgentExecutorcreateToolCallingAgent(绝不要硬编码API密钥——使用环境变量(、等))
OPENAI_API_KEYANTHROPIC_API_KEY</critical_requirements>
自动检测项: LangChain、langchain、@langchain/core、@langchain/openai、@langchain/anthropic、@langchain/google-genai、ChatOpenAI、ChatAnthropic、ChatPromptTemplate、StringOutputParser、RunnableSequence、pipe、withStructuredOutput、createAgent、createToolCallingAgent、AgentExecutor、tool、DynamicStructuredTool、RecursiveCharacterTextSplitter、MemoryVectorStore、OpenAIEmbeddings、LCEL、LangSmith、LANGCHAIN_TRACING_V2
适用场景:
- 构建将提示词、模型和输出解析器组合成链的LLM应用
- 创建模型可自主决定调用哪些工具的Agent工作流
- 实现包含文档加载、拆分、嵌入和检索的RAG流水线
- 需要通过类型安全的Zod模式验证获取LLM结构化输出
- 向用户逐令牌流式传输LLM响应
- 通过统一接口在不同LLM提供商(OpenAI、Anthropic、Google)之间切换
- 使用LangSmith追踪和调试LLM应用
涵盖的核心模式:
- 聊天模型初始化与提供商切换(ChatOpenAI、ChatAnthropic、ChatGoogleGenerativeAI)
- 使用和
.pipe()进行LCEL链组合RunnableSequence - 提示词模板(、
ChatPromptTemplate)MessagesPlaceholder - 使用和Zod模式实现结构化输出
withStructuredOutput() - 使用函数和Zod模式定义工具
tool() - 使用(基于LangGraph)创建Agent
createAgent() - RAG流水线:文档加载器、文本拆分器、向量存储、检索器
- 从链、模型和Agent进行流式传输
- LangSmith追踪设置
不适用场景:
- 仅调用一个LLM提供商且需要最精简的封装——直接使用提供商的SDK
- 需要React特定的聊天UI钩子(、
useChat)——使用集成AI的框架SDKuseCompletion - 仅需要简单的单次补全调用,无需链式操作——直接调用SDK更简单
- 需要实时双向通信——LangChain不支持WebSocket/实时API
Examples Index
示例索引
- Core: Setup, LCEL & Chat Models -- Package installation, chat model init, LCEL chains, prompt templates, output parsers
- Structured Output & Tools -- , tool definition, binding tools to models
withStructuredOutput - Agents -- , tool-calling agents, chat history, streaming agents
createAgent - RAG Pipelines -- Document loaders, text splitters, vector stores, retrieval chains
- Streaming -- Model streaming, chain streaming, agent streaming
- Quick API Reference -- Package map, import paths, environment variables, model IDs
<philosophy>
- 核心:设置、LCEL与聊天模型 —— 包安装、聊天模型初始化、LCEL链、提示词模板、输出解析器
- 结构化输出与工具 —— 、工具定义、将工具绑定到模型
withStructuredOutput - Agent —— 、工具调用Agent、聊天历史、流式Agent
createAgent - RAG流水线 —— 文档加载器、文本拆分器、向量存储、检索链
- 流式传输 —— 模型流式传输、链流式传输、Agent流式传输
- 快速API参考 —— 包映射、导入路径、环境变量、模型ID
<philosophy>
Philosophy
设计理念
LangChain.js provides a composable framework for building LLM-powered applications. Its core abstraction is the Runnable -- any component that takes an input and produces an output. Runnables compose via LCEL () to form chains, and every Runnable supports , , uniformly.
.pipe().invoke().stream().batch()Core principles:
- Composability via LCEL -- Chains are built by piping Runnables: . Each step is independently testable and replaceable. Legacy chain classes (
prompt.pipe(model).pipe(parser),LLMChain) are deprecated.ConversationChain - Provider-agnostic models -- Chat models (,
ChatOpenAI,ChatAnthropic) share a common interface. Swap providers by changing one import and model name. UseChatGoogleGenerativeAIfor runtime provider selection.initChatModel() - Type-safe structured output -- constrains LLM responses to your schema. No manual JSON parsing.
model.withStructuredOutput(zodSchema) - Split package architecture -- holds abstractions, provider packages (
@langchain/core,@langchain/openai) hold implementations,@langchain/anthropicholds higher-level composables. All must share the samelangchainversion.@langchain/core - Observability built in -- Set and every chain/agent/tool call is traced to LangSmith automatically.
LANGCHAIN_TRACING_V2=true
When to use LangChain:
- You need to compose multi-step LLM workflows (prompt -> model -> parser -> next step)
- You want to swap LLM providers without rewriting business logic
- You need agent-style tool calling with automatic routing
- You need RAG with document loading, chunking, embedding, and retrieval
- You want built-in tracing and evaluation via LangSmith
When NOT to use:
- Single-provider, single-call use cases -- the provider SDK is simpler and has less overhead
- You want full control over HTTP requests -- LangChain abstracts the transport layer
- Extremely latency-sensitive applications where the abstraction overhead matters
<patterns>
LangChain.js是用于构建LLM驱动应用的可组合框架。其核心抽象是Runnable——任何接受输入并生成输出的组件。Runnable通过LCEL()组合成链,每个Runnable都统一支持、、方法。
.pipe().invoke().stream().batch()核心原则:
- 通过LCEL实现可组合性 —— 链通过管道连接Runnable构建:。每个步骤均可独立测试和替换。旧版链类(
prompt.pipe(model).pipe(parser)、LLMChain)已被弃用。ConversationChain - 与提供商无关的模型 —— 聊天模型(、
ChatOpenAI、ChatAnthropic)共享通用接口。只需更改一处导入和模型名称即可切换提供商。使用ChatGoogleGenerativeAI进行运行时提供商选择。initChatModel() - 类型安全的结构化输出 —— 将LLM响应约束为指定模式。无需手动解析JSON。
model.withStructuredOutput(zodSchema) - 拆分包架构 —— 包含抽象层,提供商包(
@langchain/core、@langchain/openai)包含实现,@langchain/anthropic包含更高阶的可组合组件。所有包必须共享相同版本的langchain。@langchain/core - 内置可观测性 —— 设置后,所有链/Agent/工具调用都会自动追踪到LangSmith。
LANGCHAIN_TRACING_V2=true
何时使用LangChain:
- 需要构建多步骤LLM工作流(提示词 -> 模型 -> 解析器 -> 下一步)
- 希望无需重写业务逻辑即可切换LLM提供商
- 需要具备自动路由功能的Agent式工具调用
- 需要包含文档加载、分块、嵌入和检索的RAG功能
- 希望通过LangSmith实现内置追踪和评估
何时不使用:
- 单一提供商、单一调用场景——提供商SDK更简单且开销更小
- 需要完全控制HTTP请求——LangChain抽象了传输层
- 对延迟极其敏感的应用——抽象层的开销会产生影响
<patterns>
Core Patterns
核心模式
Pattern 1: Chat Model Initialization
模式1:聊天模型初始化
Initialize chat models from any provider. They all share the same interface.
typescript
import { ChatOpenAI } from "@langchain/openai";
const model = new ChatOpenAI({
model: "gpt-4.1",
temperature: 0,
});
const response = await model.invoke("Explain TypeScript generics.");
console.log(response.text);Why good: Explicit model name, temperature set for determinism, accessor for content
.texttypescript
// BAD: Hardcoded API key, no model specified
import { ChatOpenAI } from "@langchain/openai";
const model = new ChatOpenAI({ apiKey: "sk-1234..." });Why bad: Hardcoded API key is a security risk, missing model name uses unpredictable defaults
初始化任意提供商的聊天模型,它们都共享相同接口。
typescript
import { ChatOpenAI } from "@langchain/openai";
const model = new ChatOpenAI({
model: "gpt-4.1",
temperature: 0,
});
const response = await model.invoke("Explain TypeScript generics.");
console.log(response.text);优势: 明确指定模型名称,设置temperature确保确定性,通过访问内容
.texttypescript
// 错误示例:硬编码API密钥,未指定模型
import { ChatOpenAI } from "@langchain/openai";
const model = new ChatOpenAI({ apiKey: "sk-1234..." });问题: 硬编码API密钥存在安全风险,未指定模型名称会使用不可预测的默认值
Provider Switching
提供商切换
typescript
import { ChatAnthropic } from "@langchain/anthropic";
const model = new ChatAnthropic({ model: "claude-sonnet-4-5-20250929" });
// Or use initChatModel for runtime provider selection
import { initChatModel } from "langchain";
const model = await initChatModel("openai:gpt-4.1", { temperature: 0 });See: examples/core.md for full provider examples and configuration options
typescript
import { ChatAnthropic } from "@langchain/anthropic";
const model = new ChatAnthropic({ model: "claude-sonnet-4-5-20250929" });
// 或使用initChatModel进行运行时提供商选择
import { initChatModel } from "langchain";
const model = await initChatModel("openai:gpt-4.1", { temperature: 0 });参考: examples/core.md 获取完整的提供商示例和配置选项
Pattern 2: LCEL Chain Composition
模式2:LCEL链组合
Compose chains using . Every component is a Runnable.
.pipe()typescript
import { ChatOpenAI } from "@langchain/openai";
import { ChatPromptTemplate } from "@langchain/core/prompts";
import { StringOutputParser } from "@langchain/core/output_parsers";
const prompt = ChatPromptTemplate.fromTemplate(
"Summarize this in one sentence: {text}",
);
const model = new ChatOpenAI({ model: "gpt-4.1" });
const parser = new StringOutputParser();
const chain = prompt.pipe(model).pipe(parser);
const result = await chain.invoke({ text: "LangChain is a framework..." });
// result is a plain stringWhy good: Each step is independently testable, streaming propagates through the entire chain, swapping model is one line change
typescript
// BAD: Legacy LLMChain (deprecated)
import { LLMChain } from "langchain/chains";
const chain = new LLMChain({ llm: model, prompt });Why bad: is deprecated, does not support streaming propagation, harder to compose
LLMChainSee: examples/core.md for , ,
RunnableSequence.from()RunnablePassthroughRunnableParallel使用组合链,每个组件都是Runnable。
.pipe()typescript
import { ChatOpenAI } from "@langchain/openai";
import { ChatPromptTemplate } from "@langchain/core/prompts";
import { StringOutputParser } from "@langchain/core/output_parsers";
const prompt = ChatPromptTemplate.fromTemplate(
"将以下内容概括为一句话:{text}",
);
const model = new ChatOpenAI({ model: "gpt-4.1" });
const parser = new StringOutputParser();
const chain = prompt.pipe(model).pipe(parser);
const result = await chain.invoke({ text: "LangChain是一个框架..." });
// result是纯字符串优势: 每个步骤均可独立测试,流式传输可在整个链中传播,只需修改一行代码即可切换模型
typescript
// 错误示例:旧版LLMChain(已弃用)
import { LLMChain } from "langchain/chains";
const chain = new LLMChain({ llm: model, prompt });问题: 已被弃用,不支持流式传输传播,组合难度更高
LLMChain参考: examples/core.md 获取、、的相关内容
RunnableSequence.from()RunnablePassthroughRunnableParallelPattern 3: Structured Output with Zod
模式3:基于Zod的结构化输出
Use for type-safe LLM responses.
withStructuredOutput()typescript
import { ChatOpenAI } from "@langchain/openai";
import { z } from "zod";
const MovieSchema = z.object({
title: z.string().describe("The movie title"),
year: z.number().describe("Release year"),
genres: z.array(z.string()).describe("List of genres"),
});
const structuredModel = new ChatOpenAI({
model: "gpt-4.1",
}).withStructuredOutput(MovieSchema);
const movie = await structuredModel.invoke("Tell me about Inception.");
// movie is typed: { title: string; year: number; genres: string[] }Why good: Output is validated against schema, fully typed, no manual JSON parsing
typescript
// BAD: Manual JSON parsing from completion text
const response = await model.invoke("Return JSON with title and year...");
const data = JSON.parse(response.text); // Fragile, untyped, can throwWhy bad: No schema validation, untyped result, model may return malformed JSON
See: examples/structured-output-tools.md for complex schemas and edge cases
使用获取类型安全的LLM响应。
withStructuredOutput()typescript
import { ChatOpenAI } from "@langchain/openai";
import { z } from "zod";
const MovieSchema = z.object({
title: z.string().describe("电影标题"),
year: z.number().describe("上映年份"),
genres: z.array(z.string()).describe("类型列表"),
});
const structuredModel = new ChatOpenAI({
model: "gpt-4.1",
}).withStructuredOutput(MovieSchema);
const movie = await structuredModel.invoke("介绍一下《盗梦空间》。");
// movie的类型为:{ title: string; year: number; genres: string[] }优势: 输出会根据模式进行验证,完全类型化,无需手动解析JSON
typescript
// 错误示例:手动从补全文本中解析JSON
const response = await model.invoke("返回包含标题和年份的JSON...");
const data = JSON.parse(response.text); // 脆弱、无类型、可能抛出异常问题: 无模式验证,结果无类型,模型可能返回格式错误的JSON
参考: examples/structured-output-tools.md 获取复杂模式和边缘案例的相关内容
Pattern 4: Tool Definition
模式4:工具定义
Define tools with the function and Zod schemas. Use for tool names.
tool()snake_casetypescript
import { tool } from "@langchain/core/tools";
import { z } from "zod";
const getWeather = tool(
async ({ location }) => {
// Call real weather API here
return `Weather in ${location}: 22C, sunny`;
},
{
name: "get_weather",
description: "Get current weather for a city",
schema: z.object({
location: z.string().describe("City name, e.g. 'San Francisco'"),
}),
},
);Why good: Zod schema validates input, guides model's argument generation, name avoids provider compatibility issues
.describe()snake_casetypescript
// BAD: Using DynamicStructuredTool (verbose, legacy pattern)
import { DynamicStructuredTool } from "@langchain/core/tools";
const tool = new DynamicStructuredTool({
name: "getWeather", // camelCase breaks some providers
description: "...",
schema: z.object({ ... }),
func: async (input) => { ... },
});Why bad: is verbose compared to , camelCase name causes issues with some providers
DynamicStructuredTooltool()See: examples/structured-output-tools.md for binding tools to models and handling tool calls
使用函数和Zod模式定义工具,工具名称使用蛇形命名法(snake_case)。
tool()typescript
import { tool } from "@langchain/core/tools";
import { z } from "zod";
const getWeather = tool(
async ({ location }) => {
// 在此调用真实的天气API
return `${location}的天气:22℃,晴天`;
},
{
name: "get_weather",
description: "获取城市当前天气",
schema: z.object({
location: z.string().describe("城市名称,例如'旧金山'"),
}),
},
);优势: Zod模式验证输入,指导模型生成参数,蛇形命名法避免提供商兼容性问题
.describe()typescript
// 错误示例:使用DynamicStructuredTool(冗长的旧版模式)
import { DynamicStructuredTool } from "@langchain/core/tools";
const tool = new DynamicStructuredTool({
name: "getWeather", // 驼峰命名法会导致部分提供商出错
description: "...",
schema: z.object({ ... }),
func: async (input) => { ... },
});问题: 相比更冗长,驼峰命名法会导致部分提供商出现问题
DynamicStructuredTooltool()参考: examples/structured-output-tools.md 获取将工具绑定到模型和处理工具调用的相关内容
Pattern 5: Agents with createAgent()
createAgent()模式5:使用createAgent()
构建Agent
createAgent()Use for agentic workflows. It is backed by LangGraph and handles tool calling loops automatically.
createAgent()typescript
import { createAgent } from "langchain";
import { tool } from "@langchain/core/tools";
import { z } from "zod";
const search = tool(async ({ query }) => `Results for: ${query}`, {
name: "search",
description: "Search for information",
schema: z.object({ query: z.string() }),
});
const agent = createAgent({
model: "openai:gpt-4.1",
tools: [search],
systemPrompt: "You are a helpful research assistant.",
});
const stream = await agent.stream({
messages: [{ role: "user", content: "Find info about LangChain" }],
});
for await (const step of stream) {
console.log(step.messages.at(-1));
}Why good: handles the tool-call loop, supports streaming, manages state via LangGraph
createAgenttypescript
// BAD: Legacy AgentExecutor pattern
import { AgentExecutor, createToolCallingAgent } from "langchain/agents";
const agent = createToolCallingAgent({ llm, tools, prompt });
const executor = new AgentExecutor({ agent, tools });Why bad: is legacy, does not integrate with LangGraph state management, less composable
AgentExecutorSee: examples/agents.md for chat history, custom state, and middleware patterns
使用构建Agent工作流,它基于LangGraph,可自动处理工具调用循环。
createAgent()typescript
import { createAgent } from "langchain";
import { tool } from "@langchain/core/tools";
import { z } from "zod";
const search = tool(async ({ query }) => `搜索结果:${query}`, {
name: "search",
description: "搜索信息",
schema: z.object({ query: z.string() }),
});
const agent = createAgent({
model: "openai:gpt-4.1",
tools: [search],
systemPrompt: "你是一个乐于助人的研究助手。",
});
const stream = await agent.stream({
messages: [{ role: "user", content: "查找LangChain的相关信息" }],
});
for await (const step of stream) {
console.log(step.messages.at(-1));
}优势: 处理工具调用循环,支持流式传输,通过LangGraph管理状态
createAgenttypescript
// 错误示例:旧版AgentExecutor模式
import { AgentExecutor, createToolCallingAgent } from "langchain/agents";
const agent = createToolCallingAgent({ llm, tools, prompt });
const executor = new AgentExecutor({ agent, tools });问题: 已过时,不与LangGraph状态管理集成,可组合性较差
AgentExecutor参考: examples/agents.md 获取聊天历史、自定义状态和中间件模式的相关内容
Pattern 6: RAG Pipeline
模式6:RAG流水线
Load documents, split into chunks, embed, store in a vector store, and retrieve.
typescript
import { RecursiveCharacterTextSplitter } from "@langchain/textsplitters";
import { OpenAIEmbeddings } from "@langchain/openai";
import { MemoryVectorStore } from "@langchain/classic/vectorstores/memory";
const CHUNK_SIZE = 1000;
const CHUNK_OVERLAP = 200;
const splitter = new RecursiveCharacterTextSplitter({
chunkSize: CHUNK_SIZE,
chunkOverlap: CHUNK_OVERLAP,
});
const chunks = await splitter.splitDocuments(docs);
const embeddings = new OpenAIEmbeddings({ model: "text-embedding-3-small" });
const vectorStore = new MemoryVectorStore(embeddings);
await vectorStore.addDocuments(chunks);
// Retrieve
const results = await vectorStore.similaritySearch("query", 3);Why good: Named constants for chunk parameters, explicit embedding model, for prototyping
MemoryVectorStoreSee: examples/rag.md for full RAG chains, agent-based RAG, and production vector stores
加载文档、拆分为块、嵌入、存储到向量存储并进行检索。
typescript
import { RecursiveCharacterTextSplitter } from "@langchain/textsplitters";
import { OpenAIEmbeddings } from "@langchain/openai";
import { MemoryVectorStore } from "@langchain/classic/vectorstores/memory";
const CHUNK_SIZE = 1000;
const CHUNK_OVERLAP = 200;
const splitter = new RecursiveCharacterTextSplitter({
chunkSize: CHUNK_SIZE,
chunkOverlap: CHUNK_OVERLAP,
});
const chunks = await splitter.splitDocuments(docs);
const embeddings = new OpenAIEmbeddings({ model: "text-embedding-3-small" });
const vectorStore = new MemoryVectorStore(embeddings);
await vectorStore.addDocuments(chunks);
// 检索
const results = await vectorStore.similaritySearch("查询内容", 3);优势: 使用命名常量设置分块参数,明确指定嵌入模型,适用于原型开发
MemoryVectorStore参考: examples/rag.md 获取完整的RAG链、基于Agent的RAG和生产级向量存储的相关内容
Pattern 7: Streaming
模式7:流式传输
All Runnables support . Streaming propagates through LCEL chains.
.stream()typescript
const chain = prompt.pipe(model).pipe(parser);
const stream = await chain.stream({ text: "Explain quantum computing." });
for await (const chunk of stream) {
process.stdout.write(chunk);
}Why good: Streaming propagates through the entire chain, progressive output for better UX
typescript
// BAD: Collecting all output then displaying
const result = await chain.invoke({ text: "..." });
console.log(result); // User waits for full responseWhy bad: User waits for full generation before seeing anything, bad UX for long responses
See: examples/streaming.md for model streaming, stream events, agent streaming
所有Runnable都支持,流式传输可在LCEL链中传播。
.stream()typescript
const chain = prompt.pipe(model).pipe(parser);
const stream = await chain.stream({ text: "解释一下量子计算。" });
for await (const chunk of stream) {
process.stdout.write(chunk);
}优势: 流式传输在整个链中传播,渐进式输出提升用户体验
typescript
// 错误示例:收集所有输出后再显示
const result = await chain.invoke({ text: "..." });
console.log(result); // 用户需等待完整响应问题: 用户需等待完整生成才能看到内容,长响应时用户体验较差
参考: examples/streaming.md 获取模型流式传输、流事件、Agent流式传输的相关内容
Pattern 8: LangSmith Tracing
模式8:LangSmith追踪
Enable tracing by setting environment variables. No code changes needed.
bash
LANGCHAIN_TRACING_V2=true
LANGCHAIN_API_KEY=lsv2_...
LANGCHAIN_PROJECT=my-project通过设置环境变量启用追踪,无需修改代码。
bash
LANGCHAIN_TRACING_V2=true
LANGCHAIN_API_KEY=lsv2_...
LANGCHAIN_PROJECT=my-projectRecommended for non-serverless environments:
非无服务器环境推荐设置:
LANGCHAIN_CALLBACKS_BACKGROUND=true
**Why good:** Zero-code setup, traces every chain/model/tool invocation, `LANGCHAIN_CALLBACKS_BACKGROUND=true` reduces latency in long-running processes
**See:** [reference.md](reference.md) for all environment variables
</patterns>
---
<decision_framework>LANGCHAIN_CALLBACKS_BACKGROUND=true
**优势:** 零代码配置,追踪所有链/模型/工具调用,`LANGCHAIN_CALLBACKS_BACKGROUND=true`可减少长运行进程中的延迟
**参考:** [reference.md](reference.md) 获取所有环境变量的相关内容
</patterns>
---
<decision_framework>Decision Framework
决策框架
When to Use LangChain vs Direct SDK
何时使用LangChain vs 直接使用SDK
Do you need multi-step LLM workflows (prompt -> model -> parser -> ...)?
+-- YES -> Use LangChain (LCEL chains)
+-- NO -> Do you need to swap between LLM providers?
+-- YES -> Use LangChain (unified chat model interface)
+-- NO -> Do you need RAG or agent tool calling?
+-- YES -> Use LangChain
+-- NO -> Use the provider SDK directly (simpler, fewer deps)是否需要多步骤LLM工作流(提示词 -> 模型 -> 解析器 -> ...)?
+-- 是 -> 使用LangChain(LCEL链)
+-- 否 -> 是否需要在LLM提供商之间切换?
+-- 是 -> 使用LangChain(统一聊天模型接口)
+-- 否 -> 是否需要RAG或Agent工具调用?
+-- 是 -> 使用LangChain
+-- 否 -> 直接使用提供商SDK(更简单、依赖更少)Which Chat Model Class
选择哪个聊天模型类
Which provider?
+-- OpenAI -> ChatOpenAI from @langchain/openai
+-- Anthropic -> ChatAnthropic from @langchain/anthropic
+-- Google -> ChatGoogleGenerativeAI from @langchain/google-genai
+-- Runtime selection -> initChatModel("provider:model") from langchain
+-- Other -> Check @langchain/community选择哪个提供商?
+-- OpenAI -> 从@langchain/openai导入ChatOpenAI
+-- Anthropic -> 从@langchain/anthropic导入ChatAnthropic
+-- Google -> 从@langchain/google-genai导入ChatGoogleGenerativeAI
+-- 运行时选择 -> 从langchain导入initChatModel("provider:model")
+-- 其他 -> 查看@langchain/communityLCEL vs createAgent
LCEL vs createAgent
Does the model need to autonomously decide when to call tools?
+-- YES -> createAgent() (handles tool-call loops, state management)
+-- NO -> Is it a fixed sequence of steps?
+-- YES -> LCEL chain (prompt.pipe(model).pipe(parser))
+-- NO -> RunnableSequence.from() with branching模型是否需要自主决定何时调用工具?
+-- 是 -> 使用createAgent()(处理工具调用循环、状态管理)
+-- 否 -> 是否为固定步骤序列?
+-- 是 -> 使用LCEL链(prompt.pipe(model).pipe(parser))
+-- 否 -> 使用带分支的RunnableSequence.from()Legacy Chain vs LCEL
旧版链 vs LCEL
Are you writing new code?
+-- YES -> ALWAYS use LCEL (.pipe()) -- never legacy chains
+-- NO -> Is the existing code using LLMChain/ConversationChain?
+-- YES -> Migrate to LCEL when touching the code
+-- NO -> Keep as-is if it works</decision_framework>
<red_flags>
是否在编写新代码?
+-- 是 -> 始终使用LCEL(.pipe())——绝不要使用旧版链
+-- 否 -> 现有代码是否使用LLMChain/ConversationChain?
+-- 是 -> 修改代码时迁移到LCEL
+-- 否 -> 若运行正常则保留原样</decision_framework>
<red_flags>
RED FLAGS
警示事项
High Priority Issues:
- Using legacy chains (,
LLMChain,ConversationChain) instead of LCEL -- these are deprecatedSequentialChain - Mismatched versions across packages -- causes
@langchain/corechecks to fail silently, methods to be undefined, and type errorsinstanceof - Hardcoding API keys instead of using environment variables
- Manually parsing JSON from LLM text output instead of using
withStructuredOutput() - Using for new code instead of
AgentExecutorcreateAgent()
Medium Priority Issues:
- Using camelCase tool names () instead of snake_case (
getWeather) -- some providers reject camelCaseget_weather - Not adding to Zod schema fields for tools -- model gets no guidance on argument format
.describe() - Using /
BufferMemory-- these are deprecated, use LangGraph checkpointing orConversationSummaryMemoryRunnableWithMessageHistory - Not setting in non-serverless environments -- adds latency to every LLM call when tracing is on
LANGCHAIN_CALLBACKS_BACKGROUND=true - Importing from (main package) when the import should come from
langchain/or a provider package@langchain/core/
Common Mistakes:
- Installing without
langchain--@langchain/coreis a required peer dependency@langchain/core - Mixing v0.x with
@langchain/corev1.x -- all packages must be on compatible versionslangchain - Using in a chain and expecting
RunnableLambdato work -- lambda functions do not propagate streaming by default; subclass.stream()and implementRunnableinsteadtransform - Forgetting that creates a single user message -- use
ChatPromptTemplate.fromTemplate()for multi-message prompts with system/assistant/user rolesChatPromptTemplate.fromMessages() - Using in production -- it is in-memory only, all data is lost on restart; use a persistent vector store
MemoryVectorStore
Gotchas & Edge Cases:
- is a peer dependency, not a transitive dependency. You must install it explicitly:
@langchain/core. If you see "cannot resolve @langchain/core" ornpm install @langchain/corechecks failing, you likely have duplicate core versions -- runinstanceofto check.npm ls @langchain/core - uses function calling under the hood, not JSON mode. Not all models support it -- check provider docs. If the model does not support function calling, use
withStructuredOutput()with a prompt instead.JsonOutputParser - uses tuple syntax
ChatPromptTemplate.fromMessages()or["system", "..."]-- the role names are["human", "..."],system,human, notai,developer,user.assistant - from
tool()vs@langchain/core/toolsfromtool()-- both exist. Thelangchainre-export is a convenience wrapper. Use whichever matches your import pattern but be consistent.langchain - requires the provider package to be installed. If you call
initChatModel()withoutinitChatModel("anthropic:claude-sonnet-4-5-20250929")installed, you get a confusing module resolution error, not a clear "package not installed" message.@langchain/anthropic - Zod v4 works with and
StateSchema, butcreateAgentmay have partial Zod v4 support -- test with your version and fall back to Zod v3.x if schema validation fails.withStructuredOutput() - now lives in
RecursiveCharacterTextSplitter(separate package), not@langchain/textsplitters.langchain/text_splitter - When using streaming with , use
createAgent()to get full state at each step, or omit for incremental updates.streamMode: "values"
</red_flags>
<critical_reminders>
高优先级问题:
- 使用旧版链(、
LLMChain、ConversationChain)而非LCEL——这些已被弃用SequentialChain - 不同包之间版本不匹配——会导致
@langchain/core检查静默失败、方法未定义和类型错误instanceof - 硬编码API密钥而非使用环境变量
- 手动从LLM文本输出中解析JSON而非使用
withStructuredOutput() - 新代码使用而非
AgentExecutorcreateAgent()
中优先级问题:
- 使用驼峰命名法()而非蛇形命名法(
getWeather)命名工具——部分提供商不接受驼峰命名get_weather - 工具的Zod模式字段未添加——模型无法获取参数格式指导
.describe() - 使用/
BufferMemory——这些已被弃用,使用LangGraph检查点或ConversationSummaryMemoryRunnableWithMessageHistory - 非无服务器环境未设置——启用追踪时会增加每个LLM调用的延迟
LANGCHAIN_CALLBACKS_BACKGROUND=true - 应从或提供商包导入时,却从
@langchain/core/(主包)导入langchain/
常见错误:
- 安装但未安装
langchain——@langchain/core是必需的对等依赖@langchain/core - 将v0.x与
@langchain/corev1.x混合使用——所有包必须使用兼容版本langchain - 在链中使用并期望
RunnableLambda正常工作——lambda函数默认不传播流式传输;应继承.stream()并实现Runnable方法transform - 忘记仅创建单条用户消息——使用
ChatPromptTemplate.fromTemplate()创建包含系统/助手/用户角色的多消息提示词ChatPromptTemplate.fromMessages() - 在生产环境中使用——它仅在内存中存储,重启后所有数据都会丢失;使用持久化向量存储
MemoryVectorStore
注意事项与边缘案例:
- 是对等依赖,而非传递依赖。必须显式安装:
@langchain/core。若出现"无法解析@langchain/core"或npm install @langchain/core检查失败的情况,很可能存在重复的核心版本——运行instanceof检查。npm ls @langchain/core - 底层使用函数调用,而非JSON模式。并非所有模型都支持此功能——请查看提供商文档。若模型不支持函数调用,可使用带提示词的
withStructuredOutput()替代。JsonOutputParser - 使用元组语法
ChatPromptTemplate.fromMessages()或["system", "..."]——角色名称为["human", "..."]、system、human,而非ai、developer、user。assistant - 中的
@langchain/core/tools与tool()中的langchain——两者都存在。tool()中的重导出是便利封装。选择与导入模式匹配的版本即可,但需保持一致。langchain - 要求安装对应的提供商包。若未安装
initChatModel()就调用@langchain/anthropic,会出现混淆的模块解析错误,而非明确的"包未安装"提示。initChatModel("anthropic:claude-sonnet-4-5-20250929") - Zod v4可与和
StateSchema配合使用,但createAgent对Zod v4的支持可能不完善——请使用你的版本进行测试,若模式验证失败则回退到Zod v3.x。withStructuredOutput() - 现在位于
RecursiveCharacterTextSplitter(独立包)中,而非@langchain/textsplitters。langchain/text_splitter - 使用进行流式传输时,使用
createAgent()可在每个步骤获取完整状态,省略则获取增量更新。streamMode: "values"
</red_flags>
<critical_reminders>
CRITICAL REMINDERS
重要提醒
All code must follow project conventions in CLAUDE.md (kebab-case, named exports, import ordering,, named constants)import type
(You MUST use LCEL pipe composition () for all chains -- never use legacy , , or )
prompt.pipe(model).pipe(parser)LLMChainConversationChainSequentialChain(You MUST ensure all packages depend on the same version of -- version mismatches cause cryptic runtime errors)
@langchain/*@langchain/core(You MUST use for structured LLM responses -- never manually parse JSON from completion text)
withStructuredOutput(zodSchema)(You MUST use from for new agent code -- and are legacy patterns)
createAgent()langchainAgentExecutorcreateToolCallingAgent(You MUST never hardcode API keys -- use environment variables (, , etc.))
OPENAI_API_KEYANTHROPIC_API_KEYFailure to follow these rules will produce fragile, hard-to-debug LLM applications with version conflicts and untyped outputs.
</critical_reminders>
所有代码必须遵循CLAUDE.md中的项目约定(短横线命名法、命名导出、导入顺序、、命名常量)import type
(所有链必须使用LCEL管道组合()——绝不要使用旧版、或)
prompt.pipe(model).pipe(parser)LLMChainConversationChainSequentialChain(必须确保所有包依赖相同版本的——版本不匹配会导致难以排查的运行时错误)
@langchain/*@langchain/core(结构化LLM响应必须使用——绝不要手动从补全文本中解析JSON)
withStructuredOutput(zodSchema)(新的Agent代码必须使用中的——和是旧版模式)
langchaincreateAgent()AgentExecutorcreateToolCallingAgent(绝不要硬编码API密钥——使用环境变量(、等))
OPENAI_API_KEYANTHROPIC_API_KEY不遵循这些规则将导致LLM应用脆弱、难以调试,出现版本冲突和无类型输出等问题。
</critical_reminders>