Skip to content

序章

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): 流式输出,返回 AsyncGeneratorReadableStream
    • batch(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 响应,逐个 yield token
  • Token 计算与截断:如何集成 tiktokensentencepiece // 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/Part26
    ts
    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 输入/输出类型全程可推导