Files
ai-agent-dev/04_LangChain概述.ipynb
2026-07-08 10:09:42 +08:00

304 lines
9.5 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# 04 LangChain 概述\n",
"\n",
"## 学习目标\n",
"1. 理解 LangChain 产生的背景和解决的问题\n",
"2. 掌握 LangChain 的核心架构与组件组成\n",
"3. 能够运行第一个 LangChain 程序,体验链式调用的便利性\n",
"4. 了解 LangChain 生态中的相关工具LangServe、LangSmith 等)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 1. 为什么需要 LangChain\n",
"\n",
"前两节课中,我们直接通过 openai 或 anthropic SDK 调用大模型 API。这种方式简单直接但当应用变得复杂时会遇到以下问题\n",
"\n",
"- **Prompt 管理混乱**:硬编码在代码中,难以维护和复用\n",
"- **代码重复**:每次调用都要写重复的 API 初始化、参数配置\n",
"- **模型切换困难**:换一个模型提供商需要重写大量代码\n",
"- **缺乏标准流程**:没有统一的输入处理、输出解析规范\n",
"\n",
"**LangChain** 就是为了解决这些问题而生的框架。它将大模型应用的开发流程抽象为标准化组件,让开发者可以像搭积木一样构建复杂的 AI 应用。"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 2. LangChain 是什么\n",
"\n",
"LangChain 是一个用于构建基于大语言模型LLM应用的 Python/JS 框架,由 Harrison Chase 于 2022 年创建。\n",
"\n",
"### 核心设计思想\n",
"\n",
"- **组件化**:将大模型应用拆解为可复用的标准组件\n",
"- **链式组合**:通过管道(|)将多个组件串联成处理流程\n",
"- **模型无关**:同一套代码可以切换不同厂商的模型\n",
"- **生态丰富**:提供大量预集成工具(向量库、搜索引擎、数据库等)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 3. LangChain 核心架构\n",
"\n",
"LangChain 将大模型应用抽象为四大核心模块:\n",
"\n",
"### 四大核心模块\n",
"\n",
"| 模块 | 作用 | 本课程对应章节 |\n",
"| --- | --- | --- |\n",
"| **Model I/O** | 模型输入输出管理Prompt、Model、Output Parser | 05-07 节 |\n",
"| **Retrieval** | 检索增强生成RAG文档加载、向量化、检索 | 11-13 节 |\n",
"| **Chains** | 链式组合,将多个组件串联成工作流 | 05、08 节 |\n",
"| **Agents** | 智能体:让模型自主决策、调用工具完成任务 | 09-10 节 |\n",
"\n",
"### 组件关系图\n",
"\n",
"用户输入 -> Prompt模板 -> LLM模型 -> 输出解析 -> 最终结果\n",
"\n",
"例如:\n",
"\n",
"chain = prompt | llm | parser\n",
"result = chain.invoke({'input': '用户问题'})"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 4. 第一个 LangChain 程序\n",
"\n",
"我们先看一个对比示例:直接调用 API vs 使用 LangChain。"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 方式一:直接调用 API传统方式"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from openai import OpenAI\n",
"import os\n",
"from dotenv import load_dotenv\n",
"\n",
"load_dotenv()\n",
"\n",
"\n",
"client = OpenAI(\n",
" base_url=os.getenv('OPENAI_BASE_URL'),\n",
" api_key=os.getenv('OPENAI_API_KEY')\n",
")\n",
"\n",
"response = client.chat.completions.create(\n",
" model='qwen3.6-35b-A3b',\n",
" messages=[\n",
" {'role': 'system', 'content': '你是一个翻译助手,将中文翻译成英文。'},\n",
" {'role': 'user', 'content': '你好,世界'}\n",
" ]\n",
")\n",
"print(response.choices[0].message.content)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 方式二:使用 LangChain推荐方式\n",
"\n",
"LangChain 将 Prompt、模型调用、输出解析封装成标准组件代码更简洁、更易维护。"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from langchain_openai import ChatOpenAI\n",
"from langchain_core.prompts import ChatPromptTemplate\n",
"import os\n",
"\n",
"# 1. 创建模型(自动读取环境变量 OPENAI_BASE_URL 和 OPENAI_API_KEY\n",
"llm = ChatOpenAI(\n",
" model='qwen3.6-35b-A3b',\n",
" temperature=0.7\n",
")\n",
"\n",
"# 2. 创建 Prompt 模板\n",
"prompt = ChatPromptTemplate.from_messages([\n",
" ('system', '你是一个翻译助手,将中文翻译成英文。'),\n",
" ('user', '{input}')\n",
"])\n",
"\n",
"# 3. 构建链Prompt -> LLM\n",
"chain = prompt | llm\n",
"\n",
"# 4. 运行链\n",
"result = chain.invoke({'input': '你好,世界'})\n",
"print(result.content)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 对比总结\n",
"\n",
"| 特性 | 直接 API | LangChain |\n",
"| --- | --- | --- |\n",
"| Prompt 管理 | 硬编码在 messages 中 | 模板化,支持变量复用 |\n",
"| 代码可读性 | 每次都要写完整 API 调用 | 语义清晰prompt \\| llm |\n",
"| 模型切换 | 重写 SDK 初始化代码 | 换一行 model= 即可 |\n",
"| 输出处理 | 手动解析 choices[0] | 自动解析,支持结构化输出 |\n",
"| 扩展性 | 难以添加后续处理步骤 | 可继续追加 \\| parser 等组件 |"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 5. LangChain 核心组件速览\n",
"\n",
"本课程后续章节会逐一深入讲解,这里先建立整体印象。"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 5.1 Model模型\n",
"\n",
"LangChain 封装了各大厂商的模型,统一接口:\n",
"\n",
"```python\n",
"from langchain_openai import ChatOpenAI # OpenAI 兼容格式\n",
"from langchain_anthropic import ChatAnthropic # Anthropic Claude\n",
"from langchain_community.llms import Tongyi # 阿里通义千问\n",
"\n",
"llm = ChatOpenAI(model='qwen3.6-35b-A3b')\n",
"```\n",
"\n",
"所有模型都支持 .invoke()、.stream()、.batch() 等统一方法。"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 5.2 Prompt提示模板\n",
"\n",
"将 Prompt 模板化,支持变量插入和复用:\n",
"\n",
"```python\n",
"from langchain_core.prompts import ChatPromptTemplate\n",
"\n",
"prompt = ChatPromptTemplate.from_messages([\n",
" ('system', '你是一个{role}。'),\n",
" ('user', '请{task}{content}')\n",
"])\n",
"\n",
"prompt.format(role='翻译助手', task='翻译', content='Hello')\n",
"```"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 5.3 Output Parser输出解析器\n",
"\n",
"将模型输出的文本解析为结构化数据JSON、列表、Pydantic 对象等):\n",
"\n",
"```python\n",
"from langchain_core.output_parsers import JsonOutputParser\n",
"\n",
"parser = JsonOutputParser()\n",
"chain = prompt | llm | parser # 模型输出自动解析为 JSON\n",
"```"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 5.4 Chain\n",
"\n",
"链是 LangChain 的核心概念,表示数据的处理流程。使用 | 运算符组合:\n",
"\n",
"```python\n",
"chain = prompt | llm | parser\n",
"result = chain.invoke({'input': '用户输入'})\n",
"```\n",
"\n",
"数据流:用户输入 -> Prompt模板 -> LLM -> 输出解析 -> 最终结果"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 6. LangChain 生态工具\n",
"\n",
"| 工具 | 作用 |\n",
"| --- | --- |\n",
"| **LangGraph** | 构建复杂状态图和多智能体工作流(本课程核心内容) |\n",
"| **LangServe** | 将 LangChain 链部署为 REST API 服务 |\n",
"| **LangSmith** | 调试、监控和评估 LangChain 应用的可观测性平台 |\n",
"| **LangChain Hub** | 社区共享的 Prompt 模板市场 |\n",
"\n",
"本课程重点讲解 LangChain 核心组件 + LangGraph 智能体LangSmith 会在最后的部署评估环节介绍。"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 7. 本节课练习\n",
"\n",
"1. 对比直接调用 API 和 LangChain 的代码,体会 LangChain 的便利性\n",
"2. 修改上面的 LangChain 示例,将 system 提示改为「你是一个诗人」,将输入改为「写一句关于月亮的诗」\n",
"3. 尝试在 ChatOpenAI 中切换 temperature0.0、1.0、2.0),观察输出变化\n",
"4. 尝试将 prompt | llm 链保存为一个变量,多次调用 invoke() 传入不同输入"
]
}
],
"metadata": {
"kernelspec": {
"display_name": ".venv",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.14.4"
}
},
"nbformat": 4,
"nbformat_minor": 4
}