Skip to content

第 3 章:第一个链式应用

章节定位

前两章解决的是“理解 LLM 应用”和“理解 LangChain 的核心抽象”。这一章开始进入真正的工程实践:把 PromptModelParser 组合成一条完整的处理链,做出第一个可维护、可扩展的 AI 学习助手 V1

如果说前两章是在认识零件,这一章就是开始装配。你会看到,LangChain 的价值不在于“多包了一层调用”,而在于它让一个 AI 应用从一开始就具备清晰的数据流和可拆分的结构。

配套示例

  • 目录:examples/chapter-03
  • 入口:examples/chapter-03/main.py
  • 依赖:examples/chapter-03/requirements.txt
  • 运行:cd examples/chapter-03 && python3 main.py

示例层级与边界

  • 层级:教学版
  • 本章重点:理解链式应用的结构拆分,先把输入、Prompt、模型和解析关系讲清楚。
  • 不要误判:这里保留了真实 LangChain 组织方式,但模型调用仍是本地模拟,不是完整生产实现。

本章目标

  • 理解什么是“链式应用”
  • 能把输入、处理、输出拆成清晰步骤
  • 能写出一个最小可运行的学习助手原型
  • 能理解为什么链式结构比直接调用更适合后续扩展
  • 能为后续 RAG、工具调用、LangGraph 预留接口

前置知识

学习本章前,你应该已经知道:

  • LLM 应用的基本构成
  • Prompt、Message、Output Parser 的概念
  • LangChain 的 Runnable 和 LCEL 是什么

如果你还没完全掌握这些概念,也可以先跟着本章代码看一遍,再回头补基础。

核心概念

什么是链

在 LangChain 里,链不是“某个神秘高级特性”,而是把多个处理步骤按顺序连接起来的结构。最常见的链路就是:

输入 -> Prompt 组装 -> 模型调用 -> 输出解析 -> 结果返回

这种方式的价值在于:

  • 每一步职责单一
  • 每一步都能单独调试
  • 后续可以替换任意一环,而不推翻整个应用

为什么不直接写一个函数

直接写一个函数当然也能做出结果,但很快会遇到这些问题:

  • Prompt 越来越长,难以维护
  • 输出格式不稳定,后面处理很痛苦
  • 想替换模型、增加重试、插入日志时,代码会变得混乱

链式结构的本质,就是把这些变化点提前暴露出来。

AI 学习助手 V1 的任务边界

本章的主项目先不做 RAG,也不做工具调用,只做最小可用版本:

  • 输入一个学习主题
  • 输出一份简洁的学习摘要
  • 给出推荐的学习顺序
  • 生成下一步建议

这很重要。第一版不要一口气把所有能力都塞进去,否则你会失去对主流程的控制。

分模块讲解

3.1 什么是第一个可维护的 AI 应用

一个真正可维护的 AI 应用,通常不是“模型直接输出答案”这么简单,而是要区分三类东西:

  • 业务输入
  • 中间处理
  • 业务输出

例如 AI 学习助手 V1 可以定义成:

  • 输入:一个学习主题,比如 LangChain 基础
  • 处理:将主题转成结构化提示,再交给模型生成摘要
  • 输出:学习目标、核心概念、建议顺序、练习方向

这样做的好处是,你以后可以把“摘要生成”替换成“RAG 问答”或者“工具驱动摘要”,而不用改整个入口。

3.2 链路怎么拆

建议把本章的学习助手拆成三层:

输入层

负责接收用户输入,并做最基本的校验。

例如:

  • 主题不能为空
  • 主题不要过长
  • 可以补充一个可选上下文,比如“目标读者是初学者”

编排层

负责把输入转成 Prompt,再把 Prompt 喂给模型,再把模型输出交给解析器。

这层是本章重点,也是后面所有高级能力的基础。

输出层

负责把结果转成用户能理解的内容。

比如:

  • 标题
  • 摘要
  • 学习路径
  • 练习建议

3.3 最小示例应该长什么样

这一章的最小示例,不追求复杂,只追求结构清楚。你可以把它理解成一个“学习计划生成器”。

示例逻辑:

  1. 用户输入主题,例如 LangChain 核心抽象
  2. Prompt 模板把主题注入到固定指令里
  3. 模型返回结构化文本
  4. Parser 提取出标题、要点和练习建议

示意结构如下:

text
用户输入
  -> PromptTemplate
  -> Chat Model
  -> Output Parser
  -> 学习计划结果

你不需要在本章就追求非常复杂的分支和条件判断。重点是让链路第一次真正跑通。

3.4 为什么要尽早引入输出解析

很多初学者会在这个阶段忽略 Parser,理由通常是“模型已经会说话了,直接读文本就行”。问题在于,一旦后续想做页面展示、列表渲染、或者保存成结构化数据,纯文本就会变得很难处理。

所以本章就应该让你建立一个习惯:

  • 只要输出将来可能被程序消费,就尽量约束格式
  • 能结构化就不要一直依赖自然语言自由输出

这会直接影响后面 RAG、Agent、LangGraph 的实现质量。

3.5 主项目如何推进

AI 学习助手 V1 不是最终产品,它只是整个课程的第一个落地点。你可以把它理解成一个会逐步长大的壳:

  • 现在:生成学习摘要
  • 下一章:通过更好的 Prompt 让输出稳定
  • 再下一阶段:接入课程资料做 RAG
  • 再后面:接入工具和工作流编排

这条主线是整套课程最重要的设计。不要每章都换一个新项目,否则学到的是碎片,不是能力。

最小示例说明

下面是一个概念化的示意,不要求你现在就照抄某个 SDK 版本,重点是理解链路组织方式。

python
from langchain_core.prompts import PromptTemplate
from langchain_core.output_parsers import StrOutputParser

prompt = PromptTemplate.from_template(
    "你是一个学习助手。请围绕主题 {topic} 生成一份简洁学习摘要。"
)

parser = StrOutputParser()

# model 代表具体的聊天模型实例
# chain 代表 prompt -> model -> parser 的完整流
chain = prompt | model | parser

result = chain.invoke({"topic": "LangChain 核心抽象"})
print(result)

这个示例背后的重点,不是语法细节,而是链路意识:

  • prompt 负责组织输入
  • model 负责生成内容
  • parser 负责把内容变成后续可处理的数据

如果你未来替换模型,只需要改模型实例;如果你想改输出格式,只需要改 Prompt 或 Parser,而不必推倒全部代码。

真实框架版对照

如果你已经理解了教学版链路,可以继续看 examples/chapter-03/main.py 里的 真实框架版。它把同样的学习计划生成器改成更接近工程代码的写法:

  • ChatPromptTemplate 代替纯字符串 Prompt
  • JsonOutputParser 输出结构化结果
  • 保留可替换模型接口,方便后续接入真实聊天模型

这一步的意义不是让代码变复杂,而是让“链的输出”更容易直接交给页面渲染、API 返回或下一条链继续消费。

本章实践

建议你亲自完成下面这个练习:

任务

实现一个 AI 学习助手 V1,满足以下条件:

  • 输入一个学习主题
  • 输出 4 个部分:学习目标、核心概念、学习顺序、练习建议
  • 输出内容尽量简洁
  • 如果输入为空,给出明确提示

你应该关注的点

  • 输入和输出是否有明确边界
  • Prompt 是否足够清晰
  • 输出格式是否能被后续页面直接使用
  • 是否能方便地插入日志或重试机制

推荐检查方式

不要只看“模型有没有回答”,而要看:

  • 结果是否稳定
  • 结构是否清晰
  • 后续是否容易拆分成页面模块

常见坑

把链写成一个巨大的函数

如果一开始就把输入处理、Prompt、模型调用、后处理全塞进一个函数,后面你会很难插入新能力。建议尽早拆开。

过度追求复杂输出

第一版不需要华丽的多层 JSON,也不需要几十个字段。越复杂,越容易在你还没学会核心结构前就被格式问题拖住。

忽略输入校验

只要输入来自用户,就有可能为空、过长、或不符合预期。即使是教学项目,也要把输入校验作为基本习惯。

忽略主项目连续性

本章不是独立 demo,而是 AI 学习助手 的第一版。你写的每一步都应该能自然接到下一章,而不是做成一次性的脚本。

练习题

  1. AI 学习助手 V1 的输出改成适合网页展示的 4 段结构。
  2. 给链增加一个输入校验步骤,要求主题为空时直接返回错误提示。
  3. 尝试把模型输出中的建议学习顺序改成列表格式。
  4. 思考如果未来要加入 RAG,这条链里哪些部分最可能保持不变。

本章总结

这一章的核心不是“学会某个 API”,而是建立链式应用的工程思维。你已经完成了从“调用模型”到“组织流程”的第一次跃迁。

本章结束后,你应该清楚三件事:

  • 一个 AI 应用可以拆成多个职责单一的步骤
  • Prompt、Model、Parser 组合起来能形成稳定的数据流
  • AI 学习助手 可以从这个最小版本开始逐步长大

学完本章,你现在应该会

  • 说明“链”为什么比单个大函数更容易维护和扩展
  • 搭一个最小的 AI 学习助手 V1 链路并明确输入输出边界
  • 判断哪些逻辑该放在 Prompt,哪些该放在 Parser 或前置校验里
  • 说出如果后面接入 RAG,当前链里哪些部分可以直接复用

最小验收 checklist

  • [ ] 我能写出一个接收主题并返回结构化学习建议的最小链
  • [ ] 我给链补了输入为空时的保护逻辑
  • [ ] 我能解释为什么链式结构更适合插日志、重试和替换模型
  • [ ] 我能说出本章链路和上一章抽象之间的对应关系

建议你动手改一版

  • 把输出 4 个部分改成适合页面卡片展示的字段结构
  • 新增一个“学习顺序最多 3 步”的限制,练习如何同时改 Prompt 和 Parser
  • 给链增加一个简单日志,打印输入主题和生成结果,提前为后面调试做准备

卡住时先回看这里

下一章预告

下一章会进入 Prompt 工程与输出控制。你会学习如何把模型输出做得更稳定、更可控、更适合程序消费。那一章会直接强化本章的链路结构,让 AI 学习助手 从“能用”走向“好用”。