AI 智能体三课汇总:从原理到 LangChain 实战

本文是对「第一课-认识人工智能」「第二课-Ollama 部署与开发环境」「第三课-LangChain 与 Agent 实战」三份学习笔记的整理与扩展。


一. 从「会聊天」到「会干活」

过去两年,大模型的能力边界被快速推进:从单轮问答,到多轮对话,再到能调用工具、自主决策的 Agent(智能体)。这一系列变化背后的核心问题只有两个:

  1. 大模型到底是什么?它为什么会"涌现"出推理与生成能力?
  2. 我们怎么把它装到自己的产品里,让它真正"动手做事"?

三份笔记正好覆盖这两个问题:第一课讲「是什么」,第二课讲「怎么把它跑起来」,第三课讲「怎么让它按我们的方式做事情」。本文按这个顺序,把它们串成一条完整的学习路径。


二. 第一课 · 认识人工智能

2.1 人工智能的三大支柱

AI 智能的核心由三要素构成:模型、算力、数据

  • 模型:决定 AI “怎么想”。当前主流架构是 Transformer(2017 年 Google 在《Attention is all you need》中提出)。
  • 算力:决定 AI “能想多快、多深”。训练一个大模型往往需要上千张 GPU 持续运行数周。
  • 数据:决定 AI “知道什么”。数据规模与质量直接决定模型表现的上限。

2.2 神经网络的基本原理

Transformer 是一种神经网络架构,本质上是模拟人类大脑神经元连接方式的深度神经网络。与传统机器学习"一步处理即结束"不同,深度神经网络通过多层堆叠实现复杂的非线性表达。

一个神经网络通常分为三层:

  • 输入层(Input Layer):入口,接收原始数据(如文本、图像像素)。
  • 隐藏层(Hidden Layers):负责信息处理与学习,可以有很多层,层数越多表达力越强。
  • 输出层(Output Layer):出口,产生最终结果(如分类标签、生成的下一个 token)。
单个神经元的工作方式

每个神经元会做三件事:

  1. 把上一层传来的每个输入乘以一个权重(Weight)
  2. 把所有加权结果求和,再加上一个偏置(Bias)
  3. 把结果交给一个激活函数处理,得到最终输出并传给下一层。

数学上可以表示为:

y = activation( Σ(w_i * x_i) + b )

激活函数的作用是把线性结果"掰弯"——引入非线性,使网络能够拟合复杂的模式。常见激活函数包括 ReLU、Sigmoid、Tanh、Softmax 等。

神经网络如何学习:反向传播

神经网络的核心学习方法是反向传播(Backpropagation),流程如下:

  1. 前向传播(Forward Propagation):数据从输入层逐层加工,直到输出层产生结果。
  2. 计算误差(Loss):对比输出结果与正确答案的差距,常用损失函数包括交叉熵、均方误差等。
  3. 反向追责(Backward Pass):用链式求导法则,倒推计算每一层的每个连接对误差的贡献(梯度)。
  4. 调整权重(Gradient Descent):根据梯度按一定步长更新权重,使误差变小。

这个过程在大量数据上反复迭代,就是训练的本质。

2.3 大语言模型的特殊之处:词向量与自注意力

传统神经网络处理的是结构化数据,而大语言模型处理的是自然语言。这中间有两个关键概念:

词向量(Word Embedding)

把人类语言转换为模型能理解的"数字":

  1. 先把自然语言拆分成一个个片段,称为 Token(可以是字、词或子词)。
  2. 每个 Token 经过模型映射为一个浮点数向量(高维空间中的一个点)。
  3. 目标:让语义相近的词在向量空间中距离更近,不同语义的词落在不同方向上。
自注意力机制(Self-Attention)

问题来了:同一个词在不同上下文里意思不同(如「苹果」既可以指水果也可以指公司)。2017 年的 Transformer 通过自注意力机制解决:让模型在处理一个 Token 时,"看到"并加权考虑句子中所有其他 Token,从而根据上下文动态调整含义理解。

2.4 大模型的生成机制:Temperature 与涌现

概率采样

大模型生成文本的过程,本质上是逐 Token 采样

  1. Softmax 层根据模型计算出的 logits 输出下一个 token 的概率分布。
  2. 基于这个概率分布进行随机采样,挑选一个 token 作为输出。
  3. 把新 token 加入上下文,继续预测下一个 token。

Temperature 参数控制概率分布的"平缓程度":

  • Temperature 高:概率分布更均匀,结果更多样、更具创造性,但可能跑偏。
  • Temperature 低:概率分布更集中,结果更确定、更可预测。
涌现能力(Emergent Abilities)

当模型规模和训练数据量突破某个临界点时,模型会突然具备复杂推理、代码生成、跨任务迁移等能力,这种现象被称为"涌现"。具备这种能力的超大规模语言模型,就是大语言模型(LLM)

2.5 GPT 的含义与 ChatGPT 的定位

GPT 三个字母的含义:

  • G — Generative(生成式):根据上文预测下一个 Token,从而生成连续文本。
  • P — Pre-trained(预训练):通过大规模文本数据进行预训练,让模型掌握人类语言的语法、词性与常识。
  • T — Transformer:依赖的核心神经网络架构。

ChatGPT 是什么? 是一个基于 GPT 的对话式应用——它结合了大模型的推理 / 分析 / 生成能力,与传统编程的精确控制能力,最终形成的产品。

2.6 大模型服务的两种部署方式

维度公共大模型(云服务)私有大模型(本地/私有云)
前期成本低,开箱即用高,需购置硬件
数据隐私数据需上传到第三方数据不出本地
网络依赖强依赖外网可离线运行
长期成本随用量增长一次投入后边际成本低
定制能力受限于 API 能力可深度微调与定制
部署方式调用厂商 APIOllama / vLLM / TGI 等

本地部署的最简方案是 Ollama,官网 https://ollama.com 。最简单的私有化路径:

# 安装并启动 Ollama 服务后
ollama run qwen2.5:7b

2.7 开发框架生态:工欲善其事,必先利其器

学完原理,来看当前主流的 LLM 应用开发框架。三者关系可以理解为:LangChain 是"零件",Deep Agents 是"半成品",LangSmith 是"车间与质检台"

  • LangChain:智能体开发组件库,提供模型接入、工具封装、链式调用等通用能力。
  • LangSmith / LangSmith Agent Builder:调试与部署平台,支持 Agent 的可视化观测、评估与零代码搭建脚手架。
  • Deep Agents:面向多智能体协作场景的高级智能体框架,内置复杂任务的追踪与记忆能力。

第二课会带你把模型本地跑起来,第三课会用这些框架真正动手构建 Agent。


三. 第二课 · 本地部署与开发环境

3.1 Ollama 本地部署大模型

Ollama 是当前最易用的本地大模型运行工具,把模型下载、加载、推理封装成一条命令。

安装步骤
  1. 下载安装包:去官网 https://ollama.com 下载对应版本(Windows / Linux / macOS)。

  2. 指定安装路径(推荐):默认会装到 C 盘,建议用控制台命令安装到其他盘:

    # 在安装包所在目录打开终端执行
    OllamaSetup.exe /DIR=D:\Tools\Ollama
    
  3. 入口程序ollama.exe(或 macOS/Linux 上的 ollama),用作后台服务与 CLI 入口。

  4. 修改模型存储位置:打开 Ollama → Settings → 修改 Model location,把模型下载到空间充足的盘。

  5. 部署模型,两种方式任选其一:

    方式 1(推荐,便于管理)

    • 打开官网 Models 页面,选一个模型。

    • 重要:模型 Size 必须小于你的共享显存 / 共享内存,否则会失败。

    • 复制 CLI 命令,控制台执行:

      ollama run qwen2.5:7b
      

    方式 2(试用体验)

    • 直接在 Ollama 应用首页选择模型聊天,会自动下载,但不方便版本管理。
  6. 通过 API 调用:部署完成后,Ollama 默认在 http://localhost:11434 提供 OpenAI 兼容的接口,可以直接用任何 OpenAI SDK 调用。

官方文档

详细参数与高级用法:https://docs.ollama.com/

3.2 Ollama 接口规范

Ollama 同时支持自己的 /api/chat/api/generate 原生接口,以及与 OpenAI 完全兼容的 /v1/chat/completions/v1/embeddings 接口。后者意味着我们可以用 OpenAI 官方 SDK 直接对接本地模型,零迁移成本。

以下分别是 DeepSeek 与通义千问的请求示例,两者结构完全相同,只是 URL 和 API Key 不同:

# DeepSeek
curl -X POST https://api.deepseek.com/chat/completions \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <DeepSeek API Key>" \
  -d '{
    "model": "deepseek-chat",
    "messages": [
      {"role": "system", "content": "You are a helpful assistant."},
      {"role": "user", "content": "Hello!"}
    ],
    "stream": false
  }'

# 通义千问(阿里)
curl -X POST https://dashscope.aliyuncs.com/v1/chat/completions \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <DASHSCOPE_API_KEY>" \
  -d '{
    "model": "qwen-plus",
    "messages": [
      {"role": "system", "content": "You are a helpful assistant."},
      {"role": "user", "content": "你是谁?"}
    ],
    "stream": false
  }'

请求参数含义:

  • model:模型名称。
  • messages:发送给模型的消息列表,每条包含 rolecontent
  • stream:消息发送模式,false 为阻塞返回,true 为流式返回。

3.3 开发环境:UV 一站式工具链

UV 是新一代 Python 项目管理工具,集成了:

  • 虚拟环境管理(替代 venv
  • 依赖管理(替代 pip / poetry
  • 工具安装(替代 pipx
  • 打包发布(替代 setuptools

中文文档:https://uv.doczh.com/

初始化项目
# 在项目文件夹下执行
uv init                       # 初始化一个 Python 项目
uv init -p 3.13               # 指定 Python 版本(可选)

# 配置国内镜像源(加速下载)
# Windows (PowerShell):
setx UV_DEFAULT_INDEX "https://pypi.tuna.tsinghua.edu.cn/simple"
# Linux / macOS:
export UV_DEFAULT_INDEX="https://pypi.tuna.tsinghua.edu.cn/simple"

# 安装 Jupyter Notebook
uv add notebook

3.4 用 OpenAI SDK 调用本地 Ollama 模型

由于 Ollama 兼容 OpenAI 接口协议,我们只需把 base_url 指向本地服务即可。

# curl 形式(调用任意兼容 OpenAI 的模型)
curl -X POST https://api.deepseek.com/chat/completions \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <DeepSeek API Key>" \
  -d '{
    "model": "deepseek-chat",
    "messages": [
      {"role": "system", "content": "You are a helpful assistant."},
      {"role": "user", "content": "Hello!"}
    ],
    "stream": false
  }'

Python SDK 形式:

import os
from openai import OpenAI

client = OpenAI(
    # 调本地 Ollama 时
    base_url="http://localhost:11434/v1",
    api_key="ollama",                 # Ollama 不校验,任意非空字符串即可

    # 调 DeepSeek 等云服务时
    # api_key=os.environ.get("DEEPSEEK_API_KEY"),
    # base_url="https://api.deepseek.com"
)

response = client.chat.completions.create(
    model="qwen2.5:7b",
    messages=[
        {"role": "system", "content": "你是一个简洁的中文助手。"},
        {"role": "user", "content": "用一句话解释 Transformer 的自注意力机制。"}
    ],
    stream=False
)
print(response.choices[0].message.content)

这样写的好处是:同一份代码,切换云端 OpenAI、Azure、DeepSeek 或本地 Ollama,只需改 base_urlmodel 两个字段。


四. 第三课 · LangChain 与 Agent 实战

4.1 生态全景:先看清地图

在动手写代码之前,先看清 LangChain 生态的分工:

  • LangChain:智能体开发组件库。提供模型接入、工具封装、链式调用、记忆管理等通用模块,适合自定义 Agent 的各个模块。
  • LangSmith:Agent 的调试、评估与部署平台。包含四大能力:
    • Observability:监控调试 Agent 行为。
    • Evaluation:测试与评估 Agent 输出。
    • Prompt Engineering:在线优化提示词。
    • Deployment:一键部署企业级生产 Agent。
  • LangSmith Fleet:零代码开发脚手架,给非工程师使用。
  • LangGraph:可以自定义 Agent 每一个细节的图编排框架,适合有状态、多分支、人机协同的复杂场景。
  • Deep Agents:快速开发复杂任务的 Agent 框架,自带任务跟踪与记忆能力,可视为"半成品 Agent"。

LangChain 支持市面上大部分主流 LLM,并为每个模型提供对应的适配包。推荐使用统一入口 init_chat_model,但更常见的写法是直接导入具体模型类。
1
选型建议:

需求推荐框架
简单问答 / 单步工具调用LangChain create_agent
多步状态、循环、分支、人机协同LangGraph
复杂多智能体协作Deep Agents
调试 / 评估 / 生产部署LangSmith(搭配上面任何一个)

4.2 Agent 是什么

Agent(智能体)是一种能够感知环境、进行推理、自主决策并采取行动以实现特定目标的智能系统。

与传统程序"输入 → 输出"的固定路径不同,Agent 在运行时自主决定下一步做什么。一个完整的 Agent 至少包含两部分:

  • 模型:推理、分析、规划任务——是 Agent 的大脑
  • 工具:执行、交互、操作外部世界——是 Agent 的手脚
特性传统聊天机器人 / LLMAI Agent
交互模式被动响应,问一句答一句下达命令,自主执行
执行力停留在文本生成层面能操作软件、发送邮件、联网搜索
自主性需要人类给出详细步骤只需给定最终目标,自主寻找路径

在这里插入图片描述

4.3 模型:先把"大脑"接好

LangChain 调用模型通常分三步:安装依赖、配置环境变量、初始化模型。

# 1. 安装依赖
uv add langchain
uv add langchain-deepseek          # 或 langchain-openai / langchain-ollama
# 2. 配置环境变量
DEEPSEEK_API_KEY=sk-xxx
# 3. 初始化模型(推荐方式:统一入口,自动按模型名推断厂商)
from langchain.chat_models import init_chat_model

model = init_chat_model(model="deepseek-chat")

# 或者更明确的写法
from langchain_deepseek import ChatDeepSeek
from langchain_openai import ChatOpenAI

model = ChatDeepSeek(model="deepseek-chat")
model = ChatOpenAI(model="gpt-4o-mini")
模型调用的两种方式

LangChain 提供两种访问模型的方式:

  • invoke:阻塞调用,一次性返回完整结果。
  • stream:流式调用,逐 token 输出(适合聊天界面展示打字效果)。
# 阻塞调用
response = model.invoke("你是谁?")
print(response.content)

# 流式调用
for chunk in model.stream("写一首关于秋天的诗"):
    print(chunk.content, end="", flush=True)

4.4 消息:Agent 的基本上下文单元

在 LangChain 中,所有发给 LLM 的消息和 LLM 返回的消息都统一封装为 BaseMessage,它是 Agent 中最基本的上下文单元。LangChain 已经按照角色(Role)封装好了四个子类:

类型角色用途
SystemMessagesystem设定模型角色与交互背景
HumanMessageuser用户输入的消息
AIMessageassistant模型生成的响应,包含:文本、工具调用、元数据
ToolMessagetool工具调用后产生的结果

示例:

from langchain_core.messages import SystemMessage, HumanMessage, AIMessage

messages = [
    SystemMessage(content="你是一位严谨的翻译官,只输出译文。"),
    HumanMessage(content="把下面这句话翻译成英文:行百里者半九十。"),
    AIMessage(content="Those who travel ninety miles are only halfway done."),
    HumanMessage(content="再翻译:千里之行始于足下。")
]

response = model.invoke(messages)

(消息类型关系图见「第三课/图片和附件/image 13.png」。)

多模态消息

只要模型支持多模态(如 GPT-4o、Qwen-VL),可以把图片作为消息内容传入。

方式 1:通过图片 URL

from langchain_core.messages import HumanMessage

message = HumanMessage(
    content=[
        {"type": "text", "text": "描述以下这张图片的内容。"},
        {"type": "image_url", "image_url": {"url": "https://example.com/dog_and_girl.jpeg"}}
    ]
)
response = model.invoke([message])

方式 2:通过 Base64 编码

import base64

with open("city.jpeg", "rb") as f:
    img_b64 = base64.b64encode(f.read()).decode("utf-8")

multimodal_question = HumanMessage(content=[
    {"type": "image", "base64": img_b64, "mime_type": "image/jpeg"},
    {"type": "text", "text": "给我讲讲图片中的城市"}
])

for chunk, metadata in agent.stream({"messages": [multimodal_question]}, stream_mode="messages"):
    print(chunk.content, end="", flush=True)

4.5 提示词工程:让模型听懂"人话"

系统提示词的最佳实践

一份高质量的 System Prompt 通常包含四部分:

  1. 身份角色(Identity):描述 AI 的职责、沟通风格和总体目标。
  2. 指令说明(Instructions):具体要做什么、遵守什么规则、绝对不能做什么。
  3. 对话示例(Examples):提供可能的输入示例以及期望的输出。
  4. 背景信息(Context):生成响应所需的额外信息,如 RAG 检索出的知识库数据。

格式建议:Markdown 标题/列表 + XML 标签组合

  • Markdown:标记提示的不同部分,传达层级结构,提升可读性。
  • XML 标签:明确区分参考内容(如 <context>...</context>)的起止边界。
system_prompt = """
# 角色
你是一位严谨的法律助理,专注中国《公司法》领域。

# 指令
- 仅基于 <context> 内的条款回答,不引入外部知识。
- 若条款不足,明确回复"信息不足"。
- 输出格式:先结论,再引用条款编号。

# 示例
问:股东会决议需要多少表决权通过?
答:必须经代表三分之二以上表决权的股东通过。引用:第66条。

<context>
《中华人民共和国公司法》第66条:……
</context>
"""

创建 Agent 时直接传入 system_prompt 参数即可:

from langchain.agents import create_agent

agent = create_agent(
    model="deepseek-chat",
    system_prompt="你以海盗的口吻来回答用户问题。",
)
结构化输出

让模型按指定 Schema 返回数据,便于程序解析:

from pydantic import BaseModel
from langchain.agents import create_agent

class CapitalInfo(BaseModel):
    country: str
    capital: str
    population: int

agent = create_agent(
    model="deepseek-chat",
    tools=[],
    system_prompt="你是一个科幻作家,根据用户的要求创建一个太空之都。",
    response_format=CapitalInfo   # 设置结构化输出的格式
)

4.6 工具:给 Agent 装上手脚

工具的本质

工具是一个可调用的函数,但不是我们去调用,而是给模型调用。因此除了函数本身,还需要让模型清楚地知道:

  1. 工具名(name)
  2. 工具作用(description)
  3. 工具需要的参数(args schema)

这三项写得是否清晰,直接影响模型能不能"用对"。

定义工具的三种描述方式

方式 1:@tool 装饰器 + description 参数

from langchain.tools import tool

@tool(description="用于查询城市天气,输入城市名,返回天气描述")
def get_weather(city: str) -> str:
    return f"{city}: sunny"

方式 2:函数名 + 文档注释

from langchain_core.tools import tool

@tool
def square_root(x: float) -> float:
    """Calculate the square root of a number."""
    return x ** 0.5

LangChain 会自动把函数名与 docstring 作为工具的 name / description。

方式 3:用 Pydantic Model 描述参数

from pydantic import BaseModel, Field
from langchain_core.tools import tool
from typing import Literal

class WeatherInput(BaseModel):
    """查询天气的输入参数。"""
    location: str = Field(description="City name or coordinates")
    units: Literal["celsius", "fahrenheit"] = Field(
        default="celsius",
        description="Temperature unit preference"
    )
    include_forecast: bool = Field(
        default=False,
        description="Include 5-day forecast"
    )

@tool(args_schema=WeatherInput)
def get_weather(location: str, units: str = "celsius", include_forecast: bool = False) -> str:
    """Get current weather and optional forecast."""
    temp = 22 if units == "celsius" else 72
    result = f"Current weather in {location}: {temp} degrees {units[0].upper()}"
    if include_forecast:
        result += "\nNext 5 days: Sunny"
    return result

Pydantic 方式适合参数较多、需要校验与默认值的工具。

预定义工具:Tavily 搜索

LangChain 内置了很多开箱即用的工具,最常用的是 Tavily(专为 AI 优化的搜索 API):

# 1. 注册 https://tavily.com,创建 API Key
# 2. 配置环境变量
export TAVILY_API_KEY=tvly-xxxxxx

# 3. 安装依赖
uv add langchain-tavily
from langchain_tavily import TavilySearch

tools = [TavilySearch(max_results=3)]
agent = create_agent("deepseek-chat", tools=tools)

4.7 5 分钟跑通一个 Agent:把组件拼起来

了解了模型、消息、Prompt、工具四件套后,我们把它们拼成一个最小可运行的 Agent。

安装依赖
uv add langchain langchain-deepseek
加载环境变量
from dotenv import load_dotenv
load_dotenv()   # 从 .env 文件中读取 DEEPSEEK_API_KEY 等环境变量
定义工具
from langchain.tools import tool

@tool
def get_weather(location: str) -> str:
    """查询指定地点的当前天气。输入城市名,返回简短描述。"""
    # 实际项目中替换为真实天气 API
    return f"Current weather in {location} is sunny, 25°C"
创建并调用 Agent
from langchain.agents import create_agent
from langchain_core.messages import SystemMessage, HumanMessage, AIMessage

# 方式 1:用模型对象创建
model = init_chat_model("deepseek-chat")
agent = create_agent(model=model, tools=[get_weather])

# 方式 2:直接传模型名称,由 LangChain 自动初始化
agent = create_agent(model="deepseek-chat", tools=[get_weather])

# 调用:阻塞方式
response = agent.invoke({
    "messages": [
        SystemMessage("请使用工具来获取天气信息。"),
        HumanMessage("你好,我是虎哥。"),
        AIMessage("你好,虎哥,很高兴认识你。"),
        HumanMessage("北京今天天气如何?")
    ]
})
print(response["messages"][-1].content)

# 调用:流式方式
for chunk in agent.stream({"messages": [HumanMessage("上海明天会下雨吗?")]}):
    print(chunk.content, end="", flush=True)

4.8 Agent 的执行流程

一次完整的 Agent 调用遵循"感知 → 决策 → 行动 → 反馈"的循环:

  1. 用户提问:原始问题进入 Agent。
  2. 模型分析:LLM 阅读问题与可用工具,决定是否需要调用工具。
  3. 调用工具:若需要,模型返回工具调用指令;LangChain 执行工具拿到结果。
  4. 感知分析:把工具结果作为新上下文再次交给模型。
  5. 生成结果:模型综合所有信息给出最终答案。
    在这里插入图片描述

4.9 Agent 如何调用工具:底层机制

把上面流程拆细一点:

  1. 用户提问 → 进入 Agent。
  2. LangChain 把用户消息工具元信息(名称 + 描述 + 参数 schema) 组装成请求参数。
  3. 模型接收请求,判断"是否需要调用工具?调用哪一个?参数是什么?"。
  4. 模型返回结构化的工具调用请求(如 {tool: "get_weather", args: {location: "北京"}})。
  5. LangChain 根据模型指令执行对应工具函数。
  6. 工具结果封装为 ToolMessage 追加到消息列表,再次交给模型。
  7. 模型基于完整上下文生成最终回复。
    在这里插入图片描述

理解这一点很重要:工具描述写得是否清楚,决定了模型是否会在正确的时候用对的工具

4.10 短期记忆:让 Agent "记得"上一句

为什么大模型本身没有记忆

每次 LLM 调用都是独立的——所谓"多轮对话",其实是我们在每次请求时把历史消息拼到 prompt 里再发出去。这是 LangChain 引入 Memory / Checkpointer 机制的根因。

两种记忆类型

Agent 的记忆分为两类:

  • 短期记忆(Short-term Memory):当前任务或会话的上下文。
  • 长期记忆(Long-term Memory):跨任务或跨会话的经验与知识(通常基于向量数据库实现)。
短期记忆的底层实现

LangChain 的短期记忆通过 AgentState 实现,而**会话历史(消息列表)**是 AgentState 的一部分。

LangChain 提供 Checkpointer 对象来持久化 AgentState:每一次用户与 AI 的交互都会生成一个快照(checkpoint);同一会话的多个 checkpoint 用同一个 thread_id 关联。

from langchain.agents import create_agent
from langgraph.checkpoint.memory import InMemorySaver

# 内存级 checkpointer(重启即失效,仅用于测试)
agent = create_agent(
    model="deepseek-chat",
    tools=[get_weather],
    checkpointer=InMemorySaver()
)

config = {"configurable": {"thread_id": "thread_1"}}

# 第一次调用,告知 AI 我的信息
response = agent.invoke(
    {"messages": [HumanMessage(content="你好,我叫虎哥,我最喜欢猫猫。")]},
    config
)

# 第二次调用,模型能"记得"上一轮的信息
response = agent.invoke(
    {"messages": [HumanMessage(content="我最喜欢什么?")]},
    config
)
短期记忆的持久化存储

InMemorySaver 只在内存里存,重启进程就清空。要让记忆真正持久,可以换成 SQLite / Postgres 等后端:

# 安装 SQLite 持久化依赖
uv add langgraph-checkpoint-sqlite
import sqlite3
from langgraph.checkpoint.sqlite import SqliteSaver

# 连接 SQLite
connection = sqlite3.connect("resources/checkpoint.db", check_same_thread=False)

# 初始化 checkpointer,自动建表
checkpointer = SqliteSaver(connection)
checkpointer.setup()

# 创建 Agent 并注入持久化 checkpointer
agent = create_agent(
    model="deepseek-chat",
    tools=[get_weather],
    checkpointer=checkpointer
)

4.11 记忆管理策略:避免上下文爆炸

多轮对话会导致历史消息越来越多,最终超出模型的上下文限制。LangChain 提供了一些记忆管理策略来解决这个问题。

三种典型策略
  1. 修剪(Trim):按"保留最近 N 条 / 丢弃最早 N 条"规则裁剪消息列表。

    from langchain_core.messages import trim_messages
    
    trimmed = trim_messages(
        messages,
        max_tokens=2000,             # 保留大约 2000 tokens
        strategy="last",             # 保留最新的
        token_counter=llm
    )
    
  2. 删除(Delete):永久删除某个 checkpoint 快照,让对话"清零"。

    checkpointer.delete_thread(config["configurable"]["thread_id"])
    
  3. 总结摘要(Summarize):让模型把早期消息压缩成摘要,再和最近消息一起送入。

    from langchain.agents import create_agent
    from langchain.agents.middleware import SummarizationMiddleware
    
    agent = create_agent(
        model="gpt-4.1",
        tools=[your_weather_tool, your_calculator_tool],
        middleware=[
            SummarizationMiddleware(
                model="gpt-4.1-mini",
                trigger=("tokens", 4000),
                keep=("messages", 20)
            )
        ]
    )
    

适合需要保留"长期要点"但又控制 token 消耗的场景。


五. 总结:一条完整的学习路径

把三课串起来,本质上是三步走:

第一步(第一课):理解原理
  Transformer / 自注意力 / 词向量 / Temperature / 涌现
        ↓
第二步(第二课):跑起来
  Ollama 本地部署 + UV 工程化 + OpenAI SDK 调用
        ↓
第三步(第三课):让它干活
  LangChain Agent + Tools + Prompt + Memory + LangSmith 观测

每一层的核心问题与推荐工具:

问题答案
AI 是什么?大语言模型 = Transformer 架构 + 海量数据 + 大规模算力 + 涌现能力
怎么用上 AI?云端调用 OpenAI / DeepSeek API,或本地 Ollama 部署
怎么让 AI 按我的方式工作?LangChain + LangSmith + LangGraph
怎么让 AI 持续做事不健忘?Checkpointer + 记忆管理策略
怎么调试 AI?LangSmith 的 Observability + Evaluation

六. 下一步建议

如果你想把"会用"推进到"能造",可以按这个顺序继续深入:

  1. LangGraph 状态编排:处理多分支、循环、重试、人机协同的复杂 Agent。
  2. RAG(检索增强生成):给 Agent 接入私有知识库,回答业务专属问题。
  3. Deep Agents 多智能体协作:把多个 Agent 组装成团队,拆解复杂任务。
  4. 生产化:用 LangSmith 评估 + 部署 + 监控,把 Demo 推到线上。
  5. 私有化微调:用 LoRA / QLoRA 微调本地模型,让它真正"懂你的业务"。

每一步都建议先用 LangSmith 跑通再优化 Prompt:观察 Agent 卡在哪一步,比盲目调参高效得多。


附录:常见问题速查

Q1:本地跑不动大模型怎么办?
A:选小于你共享内存的小模型(如 qwen2.5:1.5b / qwen2.5:3b)。CPU 也能跑,只是慢。

Q2:Tool 写完了模型不调用?
A:99% 是工具的 description 不够具体。补一句"什么时候用 / 什么时候不要用"。

Q3:流式输出到一半断了?
A:检查 stream() 是否放在正确的循环里;同时确认服务端 keep-alive 配置。

Q4:想换模型,代码要改多少?
A:换厂商就改 base_url + model;换 LangChain 集成包就改 import。业务逻辑零改动。

Q5:记忆越用越卡?
A:上"修剪 + 总结"组合策略;冷数据搬到长期记忆(向量库)。


本文是对三份原始笔记的整理与扩展。如发现具体技术细节已过时(例如 LangChain 新版本 API 变化),以官方文档 https://python.langchain.com/ 为准。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐