序章
LangChain V3 TS版本:从 LLM 调用到生产级应用的工程化跃迁
第一阶段:重新理解 LangChain V3 的设计哲学
- V3 的核心目标:标准化、可组合、可流式、类型安全(尤其 TS) // LangChain/Part01
不再是“工具集合”,而是“LLM 应用的基础设施” - “Everything is a Runnable”:新的统一接口 // LangChain/Part02
PromptTemplate,LLM,Parser,Chain,Retriever都实现了.invoke(),.stream(),.batch() - LCEL(LangChain Expression Language):不是新语言,而是函数式组合 DSL // LangChain/Part03 使用
|操作符连接Runnable,声明式定义执行流程 - 为什么移除
call()和run()?统一为invoke()的工程意义 // LangChain/Part04 接口收敛,便于中间件(Middleware)、监控、重试逻辑注入 - 异步优先:所有 API 默认返回 Promise,拥抱 Node.js 流与 Web Streams // LangChain/Part05
第二阶段:深入 Runnable 原语与执行契约
Runnable接口三要素:invoke,stream,batch// LangChain/Part06 -invoke(input): 单次执行,返回Promise<Output>stream(input): 流式输出,返回AsyncGenerator或ReadableStreambatch(inputs[]): 批量处理,返回Promise<Output[]>
RunnableConfig:贯穿执行链的上下文对象 // LangChain/Part07 包含callbacks,metadata,maxConcurrency,timeout,实现日志、追踪、限流- 错误处理:
Runnable如何抛出结构化错误? // LangChain/Part08 继承BaseLLMError,携带llmInput,originalError - 超时与取消:如何利用
AbortSignal实现请求中断? // LangChain/Part09 传递config.signal到底层 HTTP 客户端(如fetch)
第三阶段:穿透 LCEL 的组合机制
- LCEL 的本质:函数式管道(Pipeline)与范畴论(Category Theory)的实践 // LangChain/Part10
f | g | h等价于h(g(f(x))),但支持异步和流 |操作符的实现:pipe()方法的重载 // LangChain/Part11- 输入/输出 Schema 的自动推导 // LangChain/Part12 TypeScript 泛型 + Zod 风格校验,实现类型安全的链式调用
- 分支与条件:
RunnableBranch如何实现路由? // LangChain/Part13
基于输入或前序输出选择不同子链 - 循环与递归:
RunnableLoop与 Agent 的自我修正机制 // LangChain/Part14
ReAct 模式中的Thought → Action → Observation循环
第四阶段:掌握核心组件的现代化实现
PromptTemplate
- 不再是字符串模板,而是
Runnable<string, string>// LangChain/Part15 实现.format()作为.invoke()的别名 - 支持 partial、自定义格式器、安全转义 // LangChain/Part16
- 动态提示:如何根据输入选择不同模板? // LangChain/Part17
LLM & ChatModel
- 统一接口:
BaseLanguageModel抽象generate,streamGenerate// LangChain/Part18 支持 OpenAI、Anthropic、本地模型(Ollama) - 流式实现:
stream()返回ReadableStream<ChatCompletionChunk>// LangChain/Part19 分块解析 SSE 响应,逐个yieldtoken - Token 计算与截断:如何集成
tiktoken或sentencepiece? // LangChain/Part20
OutputParser
- 从“后处理字符串”到“结构化输出生成器” // LangChain/Part21
JsonOutputParser,PydanticOutputParser,XMLOutputParser .parse()成为.invoke()的一部分,错误时抛出OutputParserException// LangChain/Part22- 流式解析:
transform()方法如何处理增量文本? // LangChain/Part23
Retrieval Chain
VectorStoreRetriever作为Runnable<Query, Document[]>// LangChain/Part23 实现.invoke()即向量搜索ContextualCompressionRetriever:在检索后压缩上下文 // LangChain/Part24 使用LLMChainExtractor移除无关句子- 多查询生成:
MultiQueryRetriever如何提升召回率? // LangChain/Part25
第五阶段:生产级流水线(Pipeline)构建
- 使用 LCEL 声明式构建复杂工作流 // LangChain/Part26ts
const ragChain = retriever .pipe(formatDocuments) .pipe(prompt) .pipe(llm) .pipe(parser) .withRetry({ maxAttempts: 3 }); - 中间步骤的日志与监控:通过
RunnableConfig.callbacks注入 // LangChain/Part27 集成 LangSmith、自定义 Logger - 批处理优化:
.batch()如何并行化请求? // LangChain/Part28 控制maxConcurrency避免压垮 LLM API - 缓存机制:
RunnableCache如何避免重复调用? // LangChain/Part29 基于输入哈希缓存输出,支持 Redis、In-Memory - A/B 测试:
RunnableParallel并行执行多个版本,比较结果 // LangChain/Part30
第六阶段:与前端和全栈架构的衔接
- 在 NestJS 中暴露 LangChain 流式 API // LangChain/Part31 使用
@Sse()装饰器返回ReadableStream - 前端消费流式响应:
Response.body.pipeTo(ReadableStreamDefaultReader)// LangChain/Part32 实现打字机效果 - 身份验证与速率限制:如何在
RunnableConfig中传递用户信息? // LangChain/Part33 - 持久化会话:
RunnableWithMessageHistory如何管理chat_history? // LangChain/Part34 需要实现BaseChatMessageHistory存储适配器 - 微服务化:将不同
Runnable部署为独立服务,通过 HTTP/gRPC 调用 // LangChain/Part35
第七阶段:未来趋势与深度集成
- Agent 2.0:基于 LCEL 的自主代理 // LangChain/Part36
Plan-and-Execute,ReAct模式作为可组合链 - Tool Calling:如何让 LLM 调用函数并解析参数? // LangChain/Part37 OpenAI Functions / Tools 格式生成
- LangGraph:用有向图构建状态化 Agent // LangChain/Part38 将
Runnable连接成图,支持循环、条件跳转 - 与 DevOps 集成:CI/CD 流程中测试 Prompt 变更的影响 // LangChain/Part39 自动化评估、金丝雀发布
- TypeScript 类型即文档:利用泛型实现 IDE 智能提示 // LangChain/Part40 输入/输出类型全程可推导