Skip to content

LangChain 系统学习文档 ​

适合人群:已经掌握前端或 Node.js 基础,想进入 AI 应用开发、智能体开发、RAG 问答、工具调用和 LLM 全栈项目的学习者。

学习目标:从大模型应用的基本概念入门,逐步掌握 LangChain 的模型接口、消息、提示词、工具、结构化输出、检索增强生成、Agent、流式输出、观测与生产实践。

核对时间:2026-06-25。本文以 LangChain 官方文档当前信息为基础整理。官方当前将 LangChain 定位为可配置的 agent harness,用于组合模型、工具、提示词和中间件;LangChain agents 构建在 LangGraph 之上。

官方资料:


目录 ​

第一篇:基础认知 ​

  1. LangChain 是什么
  2. LLM 应用和传统应用的区别
  3. LangChain、LangGraph、LangSmith 的关系
  4. 前端开发者为什么要学 LangChain
  5. 安装与第一个 Agent

第二篇:核心组件 ​

  1. Chat Model
  2. Message
  3. Prompt
  4. Tool
  5. Structured Output
  6. Streaming
  7. Middleware

第三篇:RAG 与知识库 ​

  1. RAG 是什么
  2. Document Loader
  3. Text Splitter
  4. Embedding
  5. Vector Store
  6. Retriever
  7. RAG 问答链路

第四篇:Agent 应用 ​

  1. Agent 是什么
  2. 工具调用流程
  3. create_agent
  4. 多轮上下文和短期记忆
  5. Human-in-the-loop
  6. Guardrails

第五篇:工程化与生产 ​

  1. LangChain 项目结构
  2. 前端 + 后端 + LangChain 架构
  3. 观测、追踪与评估
  4. 成本、延迟和稳定性
  5. 常见误区
  6. 学习路线和项目实战

第一篇:基础认知 ​

1. LangChain 是什么 ​

LangChain 是一个用于构建 LLM 应用和 Agent 应用的框架。它把大模型应用中常见的能力抽象成组件,例如:

  • 模型调用
  • 消息结构
  • 提示词
  • 工具调用
  • 结构化输出
  • 检索增强生成
  • Agent 执行循环
  • 中间件
  • 流式输出
  • 观测与调试

普通调用大模型可能只是:

python
response = model.invoke("请解释什么是 RAG")

LangChain 更关注完整应用:

text
用户问题
  -> 提示词组装
  -> 检索相关文档
  -> 调用模型
  -> 必要时调用工具
  -> 返回结构化结果或流式文本
  -> 记录 trace,便于调试和评估

如果你从前端转 AI 全栈,可以把 LangChain 理解成“AI 应用层的框架”。它不像 Vue/React 负责页面渲染,而是负责把模型、工具、数据和业务流程组织起来。

2. LLM 应用和传统应用的区别 ​

传统应用更确定:

text
输入 -> 业务逻辑 -> 数据库 -> 输出

同样输入通常得到同样输出。

LLM 应用更不确定:

text
输入 -> Prompt -> 模型推理 -> 可能调用工具 -> 生成输出

它的特点:

  • 输出具有概率性。
  • Prompt 会影响行为。
  • 模型可能误解用户意图。
  • 工具调用可能失败。
  • 成本和延迟不可忽视。
  • 需要观测和评估。

因此 AI 全栈工程师不只是会调 API,还要会设计:

  • 输入边界
  • Prompt
  • 工具权限
  • 数据检索
  • 结构化输出
  • 错误兜底
  • 评估指标
  • 用户体验

3. LangChain、LangGraph、LangSmith 的关系 ​

可以这样理解:

text
LangChain:Agent 和 LLM 应用开发框架,提供模型、工具、Agent harness 等抽象。
LangGraph:底层有状态编排运行时,适合复杂、长期运行、可恢复的 Agent。
LangSmith:观测、追踪、评估、调试和部署相关平台。

选择:

  • 只想快速做一个工具调用 Agent:先用 LangChain。
  • 需要复杂状态流、人类审批、可中断、可恢复:使用 LangGraph。
  • 需要调试、评估、观测:使用 LangSmith。

LangChain 官方当前文档强调:LangChain 的 agents 构建在 LangGraph 之上,因此学习顺序可以是:

text
LLM 基础 -> LangChain 组件 -> LangChain Agent -> LangGraph 状态编排

4. 前端开发者为什么要学 LangChain ​

前端开发者转 AI 全栈有天然优势:

  • 擅长产品交互和用户体验。
  • 理解异步请求、状态管理、流式渲染。
  • 熟悉 TypeScript,适合写类型安全的 AI 前端和 API 层。
  • 能把 AI 能力包装成可用产品,而不是停留在脚本。

LangChain 对你有三类价值:

  1. 学会 AI 后端如何组织模型、工具和数据。
  2. 理解前端聊天 UI 背后的 Agent 运行机制。
  3. 能做 RAG、智能客服、文档问答、代码助手、业务自动化工具。

5. 安装与第一个 Agent ​

Python 安装:

bash
pip install -U langchain

如果使用特定模型提供商,需要安装对应集成包。例如:

bash
pip install -U "langchain[openai]"

示例:

python
from langchain.agents import create_agent

def get_weather(city: str) -> str:
    """Get weather for a given city."""
    return f"{city} 今天适合学习 AI 全栈。"

agent = create_agent(
    model="openai:gpt-5.5",
    tools=[get_weather],
    system_prompt="你是一个简洁可靠的助手。",
)

result = agent.invoke({
    "messages": [
        {"role": "user", "content": "上海天气怎么样?"}
    ]
})

print(result["messages"][-1].content_blocks)

注意:本文使用的 create_agent、content_blocks、middleware 等 API 属于 LangChain 1.0,请安装 langchain>=1.0(0.x 版本没有这些 API)。示例中的模型名称要根据你实际使用的模型提供商配置;工程中不要把 API Key 写进代码,应使用环境变量。

5.1 深入:create_agent 的完整签名与内部循环 ​

create_agent(langchain.agents,Since v1.0)返回的不是黑盒对象,而是一个编译好的 LangGraph 图(CompiledStateGraph)。完整参数:

参数类型作用
modelstr | BaseChatModel模型字符串(如 "openai:gpt-5.5")或 chat model 实例
toolsSequence[...] | None工具列表;为空时退化成纯模型节点(无 tool loop)
system_promptstr | SystemMessage | None字符串会被自动转成 SystemMessage 放到消息列表开头
middlewareSequence[AgentMiddleware]中间件序列(见第 12 章)
response_formatstrategy / type / dict结构化输出配置(见第 10 章)
state_schematype[AgentState]扩展默认状态字段
context_schematype[ContextT]运行时 context 的 schema
checkpointer / store-短期(thread 内)/ 长期(跨 thread)记忆
interrupt_before / interrupt_afterlist[str] | None静态断点节点名(调试用)
namestr | None作为子图嵌入大图时的节点名
cacheBaseCache | None图执行缓存

模型字符串写法是 "<provider>:<model>"(例如 "openai:gpt-5.5"),需要安装对应集成包;想显式控制初始化参数,用 init_chat_model("openai:gpt-5.5", ...) 拿到实例再传给 model。

官方文档描述的循环:

text
agent 节点:应用 system prompt 后调用模型
  -> AIMessage 含 tool_calls?
     是 -> tools 节点执行工具,结果作为 ToolMessage 追加进 messages
          -> 回到 agent 节点再次调用模型
     否 -> 循环结束,返回完整 messages 列表

💡 因为返回值就是 LangGraph 编译图,invoke / stream / astream / get_state_history / checkpointer 等图级 API 全部可用——这就是"LangChain agents 构建在 LangGraph 之上"的具体含义。


第二篇:核心组件 ​

6. Chat Model ​

Chat Model 是聊天模型接口。它接收消息列表,返回模型消息。

概念上类似:

python
messages = [
    {"role": "system", "content": "你是一个后端架构师"},
    {"role": "user", "content": "如何设计 RAG 系统?"}
]

模型接口要关注:

  • 模型提供商
  • 模型名称
  • temperature
  • max tokens
  • timeout
  • retry
  • streaming
  • tool calling 支持情况

在 AI 全栈项目中,模型层最好封装,避免业务代码到处直接依赖某个供应商。

6.1 补充:init_chat_model 与 provider:model 字符串 ​

跨供应商统一入口是 init_chat_model:init_chat_model("openai:gpt-5.5") 形式的 provider:model 字符串会自动解析到对应集成包(需已安装 langchain-openai 等)。工程建议:在 services/ 层集中一处把配置(模型名、temperature、timeout)转成 chat model 实例,业务代码只接收实例;这样换供应商或加 ModelFallbackMiddleware 都不用改调用点。⚠️ temperature 等参数是否生效取决于具体模型(部分推理模型不接受该参数),以提供商文档为准。

7. Message ​

Message 是 LLM 应用的基本上下文单位。

常见角色:

  • system:系统指令,定义助手身份、规则和边界。
  • user:用户输入。
  • assistant:模型回复。
  • tool:工具执行结果。

多轮对话不是简单字符串拼接,而是一组消息:

python
[
    {"role": "system", "content": "你是客服助手"},
    {"role": "user", "content": "我想退款"},
    {"role": "assistant", "content": "请提供订单号"},
    {"role": "user", "content": "订单 123"}
]

前端聊天 UI 中的消息状态,最终也会转换成后端模型可理解的消息格式。

8. Prompt ​

Prompt 不只是“提示词”,而是模型行为的配置入口。

好的 Prompt 包含:

  • 角色
  • 任务目标
  • 输入上下文
  • 输出格式
  • 约束条件
  • 示例
  • 异常处理方式

示例:

text
你是一个技术文档助手。
任务:根据给定资料回答用户问题。
要求:
1. 只基于资料回答。
2. 不确定时说不知道。
3. 输出 Markdown。
4. 最后列出引用来源。

Prompt 设计要避免:

  • 指令过长但没有结构。
  • 输出格式不明确。
  • 要求模型做精确计算。
  • 没有说明无法回答时怎么办。

9. Tool ​

Tool 让模型能调用外部能力,例如:

  • 查询数据库
  • 搜索文档
  • 调用 API
  • 执行计算
  • 创建工单
  • 查询订单状态

工具本质上是有输入和输出的函数。模型决定何时调用工具,应用负责真正执行工具。

示例:

python
def get_order_status(order_id: str) -> str:
    """查询订单状态。"""
    return "订单已发货"

工具设计原则:

  • 名称清晰。
  • 描述准确。
  • 参数结构明确。
  • 返回结果简洁。
  • 权限边界严格。
  • 不把危险操作直接暴露给模型。

例如删除订单、退款、发送邮件这类操作要加入人工确认或审批。

9.1 底层机制:tool calling 在 API 层发生了什么 ​

模型拿到的不是函数本身,而是函数的 JSON Schema 描述。完整链路:

text
1. 你定义 @tool 函数 -> LangChain 转成工具 schema(name / description / args JSON Schema)
2. 请求模型 API:schema 列表随 messages 一起发给模型提供商
3. 模型决定调用与否:返回带 tool_calls 字段的 AIMessage(name、args、id)
4. 应用侧(ToolNode)真正执行:按 name 找到本地函数、校验并填入 args
5. 结果包装为 ToolMessage(带上对应 tool_call_id)追加进 messages
6. 再次把消息列表发给模型,直到某轮响应不再出现 tool_calls,循环结束

关键认知:

  • 模型从不执行任何代码,它只是“写出调用申请”。执行、校验、错误处理都是应用的责任——这也是工具错误消息要写成“可恢复提示”而不是裸 failed 的原因。
  • tool_calls / ToolMessage 是 LangChain 统一抽象后的消息字段,不同提供商(OpenAI 的 tools、Anthropic 的 tool_use)由集成包在底层做格式翻译。
  • 模型可以一次返回多个 tool_calls(并行工具调用)。⚠️ 每个 tool_call_id 都必须有对应的 ToolMessage 返回,缺一个就可能在提供商侧报错或被模型误读为工具丢失。

9.2 @tool 装饰器与 ToolRuntime ​

python
from langchain.tools import tool

@tool
def search_database(query: str, limit: int = 10) -> str:
    """Search the customer database for records matching the query."""
    return f"Found {limit} results for '{query}'"

要点:

  • docstring 自动成为工具描述,类型注解生成输入 schema——这两者是模型选择和调用工具的核心依据,要像写 API 文档一样写它们。
  • 工具名建议 snake_case:部分提供商会拒绝或异常处理含空格、特殊字符的名字。可用 @tool("web_search") 覆盖名字、description= 覆盖描述。
  • 复杂参数用 @tool(args_schema=WeatherInput) 配 Pydantic 模型 + Field(description=...)。
  • ⚠️ 参数名 config 和 runtime 是保留名,用作工具入参会在运行时报错。
  • 工具内访问运行时信息的推荐方式是声明 runtime: ToolRuntime 参数(取代旧的 InjectedState、InjectedStore、get_runtime())。该参数由 ToolNode 注入,对模型不可见:runtime.state 读当前会话状态、runtime.context 读本次调用的只读配置(如 user_id)、runtime.store 读写跨会话长期记忆。
python
from langchain.tools import tool, ToolRuntime

@tool
def get_user_preference(pref_name: str, runtime: ToolRuntime) -> str:
    """Get a user preference value."""
    preferences = runtime.state.get("user_preferences", {})
    return preferences.get(pref_name, "Not set")
  • 返回值类型决定行为:返回 str → 转成人读的 ToolMessage;返回 dict → 序列化为结构化工具输出,模型可按字段推理;返回 Command → 直接写图状态(记得同时带上 ToolMessage 并填 tool_call_id=runtime.tool_call_id,让模型看到结果)。

10. Structured Output ​

结构化输出让模型返回可解析的数据,而不是自由文本。

场景:

  • 表单抽取
  • 分类
  • 评分
  • 路由
  • 生成数据库字段
  • 前端组件渲染数据

示例目标:

json
{
  "intent": "refund",
  "order_id": "123",
  "confidence": 0.92
}

结构化输出对前端很重要,因为 UI 通常需要稳定字段,而不是一段不可控文本。

建议:

  • 用 schema 描述输出结构。
  • 对枚举值做约束。
  • 对模型输出做校验。
  • 校验失败要有重试或兜底。

10.1 内部机制:两种实现策略 ​

create_agent 用 response_format 参数处理结构化输出,结果放在最终 state 的 structured_response 键里。底层有两条路径(langchain.agents.structured_output):

策略机制适用
ProviderStrategy走提供商原生 structured output(OpenAI、Anthropic、Gemini、xAI 等支持),由提供商侧保证 schema 合规模型支持时最可靠,优先用
ToolStrategy把 schema 包装成一个“伪工具”注入 tool calling,诱导模型调用它来“提交”结果,本地再做 Pydantic 校验其余所有支持 tool calling 的模型

直接传 schema 类型时,LangChain 根据模型能力自动选策略;⚠️ 裸 JSON Schema dict 必须显式包一层 strategy,不会被自动识别。

python
from pydantic import BaseModel, Field
from typing import Literal
from langchain.agents import create_agent
from langchain.agents.structured_output import ToolStrategy

class ProductReview(BaseModel):
    """Analysis of a product review."""
    rating: int | None = Field(description="The rating of the product", ge=1, le=5)
    sentiment: Literal["positive", "negative"] = Field(description="The sentiment of the review")

agent = create_agent(
    model="gpt-5.5",
    tools=tools,
    response_format=ToolStrategy(ProductReview),
)
result = agent.invoke({"messages": [...]})
result["structured_response"]  # ProductReview 实例(Pydantic)或 dict(dataclass/TypedDict)

Schema 类型支持:Pydantic 模型(返回校验后的实例)、dataclass / TypedDict(返回 dict)、JSON Schema(返回 dict)。ToolStrategy 还有 handle_errors 参数控制校验失败后的重试行为(True 默认用错误模板消息让模型重试 / 自定义 str / 异常类型 / callable / False 直接抛异常),对应异常如 StructuredOutputValidationError、MultipleStructuredOutputsError。

⚠️ 注意事项:

  • 同时给了 tools 和 response_format 时,模型必须支持 tools 与 structured output 并用,个别提供商会冲突。
  • ToolStrategy 的结果本质仍是“模型调了一个工具”,不是提供商级硬约束,务必保留本地校验 + 重试。
  • 结构化输出约束的是最终提交格式,不保证中间推理正确——字段内容质量仍要靠评测。

11. Streaming ​

Streaming 是流式输出。它让用户不必等待完整回复生成完才看到结果。

前端体验:

text
模型一边生成,页面一边显示。

常见实现:

  • Server-Sent Events
  • WebSocket
  • fetch readable stream

流式输出要处理:

  • loading 状态
  • 中断请求
  • token 增量渲染
  • 工具调用中间状态
  • 错误提示
  • 最终消息落库

AI 产品的体验差异,很大一部分来自流式交互是否顺滑。

12. Middleware ​

Middleware 用于在 Agent 执行过程中插入横切逻辑,例如:

  • 日志
  • 重试
  • 输入过滤
  • 输出校验
  • 工具调用限制
  • 模型路由
  • 成本统计
  • 安全策略

前端开发者可以类比:

  • Express/NestJS 中间件
  • Vue Router guard
  • Axios interceptor

AI 应用中的中间件能让你把业务逻辑和治理逻辑分开,避免 Agent 主流程越来越乱。

12.1 内部机制:两类钩子 ​

中间件不是独立运行时——钩子跑在 create_agent 编译出的那张 LangGraph 图内部。官方把钩子分成两种风格:

Node-style(顺序执行,在固定切点):

钩子触发时机
before_agent每次调用开始前一次
before_model每次模型调用前
after_model每次模型响应后
after_agent每次调用结束后一次

Wrap-style(环绕执行,自己决定 handler 调 0/1/N 次):

钩子触发时机
wrap_model_call包住每次模型调用(可做重试、缓存、改写请求)
wrap_tool_call包住每次工具调用(可做监控、动态工具)

用装饰器或类实现,节点式钩子返回 dict 直接经 reducer 合入 state:

python
from langchain.agents.middleware import before_model, AgentState
from langchain.messages import AIMessage
from langgraph.runtime import Runtime
from typing import Any

@before_model(can_jump_to=["end"])
def check_message_limit(state: AgentState, runtime: Runtime) -> dict[str, Any] | None:
    if len(state["messages"]) >= 50:
        return {"messages": [AIMessage("Conversation limit reached.")], "jump_to": "end"}
    return None

wrap 式示例(模型调用重试):

python
from langchain.agents.middleware import wrap_model_call, ModelRequest, ModelResponse
from typing import Callable

@wrap_model_call
def retry_model(request: ModelRequest, handler: Callable[[ModelRequest], ModelResponse]) -> ModelResponse:
    for attempt in range(3):
        try:
            return handler(request)
        except Exception:
            if attempt == 2:
                raise

12.2 内置中间件清单 ​

官方提供一批生产可用的 prebuilt middleware(langchain.agents.middleware),常用:

中间件用途
ToolRetryMiddleware / ModelRetryMiddleware工具/模型调用指数退避重试
ModelFallbackMiddleware主模型失败自动切换备用模型
SummarizationMiddleware接近 token 上限时自动摘要历史
HumanInTheLoopMiddleware指定工具调用前暂停等人工审批(interrupt_on={"send_email": True},按工具 .name 匹配)
PIIMiddlewarePII 检测与脱敏
ModelCallLimitMiddleware / ToolCallLimitMiddleware限制模型/工具调用次数防失控
TodoListMiddleware给 Agent 加任务规划清单
LLMToolSelectorMiddleware先用一次 LLM 挑选相关工具再进主调用(大工具集省 token)

💡 中间件让 create_agent 生成的整个 Agent(含全部钩子)可以作为节点/子图嵌入更大的 StateGraph,HITL 暂停、摘要、PII 脱敏都会跟着子图走——这是 LangChain 与 LangGraph 组合使用的官方姿势。

⚠️ 注意:多个中间件都改同一非 reducer 状态字段时,最外层(outer)的值胜出;messages 这类带 reducer 的字段则是叠加。若外层中间件重试导致 handler() 被调多次,之前那次调用产生的状态更新会被丢弃。


第三篇:RAG 与知识库 ​

13. RAG 是什么 ​

RAG 是 Retrieval-Augmented Generation,检索增强生成。

它解决的问题:

text
模型不知道你的私有文档、公司制度、项目代码和数据库内容。

RAG 流程:

text
用户问题
  -> 向量化
  -> 检索相关文档
  -> 把文档塞进 Prompt
  -> 模型基于文档回答

RAG 不是“把所有资料都丢给模型”。它的关键是检索出足够相关、足够少、足够可信的上下文。

14. Document Loader ​

Document Loader 负责读取资料来源:

  • Markdown
  • PDF
  • Word
  • HTML
  • Notion
  • 数据库
  • Git 仓库
  • 网页

读取后通常得到 Document:

text
page_content:正文
metadata:来源、标题、路径、页码、更新时间

metadata 很重要。没有来源信息,回答就很难追溯。

15. Text Splitter ​

Text Splitter 负责切分文档。

为什么要切分:

  • 文档太长,不能全部放入上下文。
  • 检索需要更小粒度。
  • 模型需要集中上下文。

切分策略:

  • 按标题切分。
  • 按段落切分。
  • 按固定 token 长度切分。
  • 保留 overlap,避免上下文断裂。

切分过小会丢上下文,切分过大又会降低检索精度。工程中需要根据文档类型调参。

15.1 内部机制与常见陷阱 ​

  • chunk 大小和 overlap 都以 token 计(RecursiveCharacterTextSplitter 按分隔符列表递归尝试,默认 ["\n\n", "\n", " ", ""]——从段落、换行到字符逐级退化,优先保住语义边界),而不是按字符数硬切——这是它比朴素定长切分好的原因。
  • ⚠️ 表格、代码块、列表被拦腰切断是 RAG 最常见的静默故障:切片本身 embedding 得分不低,检索也能召回,但模型拿到的是残缺结构,答非所问。Markdown 文档要按标题层级切(保留 heading 路径作为前缀或 metadata),代码按函数/类边界切。
  • embedding 模型对输入长度有截断上限;chunk 太大不会报错,只会“悄悄只编码前半段”,检索质量无声下降。⚠️ 入库和查询必须用同一个 embedding 模型和维度——换模型 = 全量重建索引,否则新旧向量不在同一空间。
  • 把标题、来源、更新时间拼进 chunk 文本(而不只放 metadata),往往比调 overlap 更有效,因为 embedding 只“看得见”文本。

16. Embedding ​

Embedding 把文本变成向量。

语义相似的文本,向量距离更近。

例如:

text
"如何退款" 和 "我要申请退货退款" 语义接近

Embedding 模型选择要考虑:

  • 中文效果
  • 多语言效果
  • 向量维度
  • 成本
  • 速度
  • 是否支持本地部署

17. Vector Store ​

Vector Store 用于存储和检索向量。

常见选择:

  • Chroma
  • FAISS
  • Milvus
  • Qdrant
  • Weaviate
  • pgvector
  • Elasticsearch/OpenSearch 向量检索

前端 AI 全栈路线中,建议先用轻量方案:

text
本地学习:Chroma 或 FAISS
全栈项目:PostgreSQL + pgvector 或托管向量库

18. Retriever ​

Retriever 负责根据用户问题取回相关文档。

常见策略:

  • 相似度检索
  • MMR 去冗余
  • metadata 过滤
  • hybrid search
  • rerank

示例:

text
用户问:“如何配置 Docker Compose?”
Retriever 返回 Docker 文档中最相关的几个片段。

检索质量直接决定 RAG 回答质量。很多 RAG 项目失败不是模型不行,而是检索上下文错了。

18.1 策略的底层逻辑与选择 ​

策略解决什么问题机制
相似度(vector search)语义改写、同义词查询向量与文档向量的距离排序;对专有名词/ID/罕见词不敏感
BM25 / keyword精确词命中词频统计,纯字面匹配;不懂同义
hybrid search上面两者的盲区互补两路召回后融合排序(如 RRF),需要向量库支持
MMRtop-k 里全是近重复片段相关性 × 多样性联合选择,牺牲一点精度换覆盖
metadata filter全库检索噪音大、权限过滤先用结构化条件缩小候选集,属于 pre-filter,效果稳定
rerank召回快但排序粗两阶段:向量粗召回 N 条 -> cross-encoder 精排取 top-k,延迟换精度

⚠️ 常见陷阱:

  • “相似度分数高”不等于“对回答有用”:向量检索对数字、代码符号、专有名词区分力弱,这类查询优先 hybrid。
  • 盲目加大 top-k 会让上下文膨胀,模型在长上下文中间部分注意力反而下降(lost in the middle),常见最优区间其实很小(几条到十几条),要靠评测集找拐点,不要拍脑袋。
  • filter 条件和 embedding 是两个正交机制:权限、时效这类硬约束必须走 metadata filter,绝不能指望模型“自己注意”。

19. RAG 问答链路 ​

一个最小 RAG 系统包含:

text
文档导入
  -> 切分
  -> embedding
  -> 入库
  -> 用户提问
  -> 检索
  -> 组装 Prompt
  -> 模型回答
  -> 前端展示引用来源

生产级 RAG 还要考虑:

  • 文档增量更新
  • 权限过滤
  • 引用来源
  • 幻觉控制
  • 评估集
  • 召回率和准确率
  • 用户反馈

第四篇:Agent 应用 ​

20. Agent 是什么 ​

Agent 是能根据目标自主选择步骤、调用工具并完成任务的系统。

普通聊天:

text
用户问 -> 模型答

Agent:

text
用户目标
  -> 模型判断需要什么工具
  -> 调用工具
  -> 观察结果
  -> 继续推理
  -> 最终回答或执行动作

例如:

text
“帮我查订单 123 的物流,并判断是否需要安抚用户”

Agent 可能会:

  1. 调用订单查询工具。
  2. 调用物流查询工具。
  3. 判断物流延迟。
  4. 生成客服回复。

21. 工具调用流程 ​

工具调用通常包含:

  1. 模型根据用户意图选择工具。
  2. 模型生成工具参数。
  3. 应用执行工具。
  4. 工具结果返回模型。
  5. 模型基于结果继续回答。

风险点:

  • 参数错误。
  • 工具失败。
  • 工具返回太长。
  • 工具结果被模型误解。
  • 工具权限过大。

工程中要对工具调用做:

  • 参数校验
  • 超时控制
  • 错误处理
  • 权限控制
  • 日志追踪
  • 高风险操作确认

22. create_agent ​

LangChain 当前提供 create_agent 用于创建可配置 Agent。

核心输入:

  • model
  • tools
  • system_prompt
  • middleware

示例结构:

python
agent = create_agent(
    model=model,
    tools=[search_docs, query_order],
    system_prompt="你是一个企业知识库助手。",
)

建议先用 LangChain Agent 做快速验证。如果流程变得复杂,例如需要状态图、可中断审批、持久化恢复,再切到 LangGraph。

23. 多轮上下文和短期记忆 ​

多轮对话需要保存上下文。

最简单方式:

text
把最近 N 轮消息传给模型

问题:

  • 上下文越来越长。
  • 成本越来越高。
  • 无关历史干扰当前回答。

优化方式:

  • 只保留最近窗口。
  • 摘要历史。
  • 结构化保存用户偏好。
  • 把长期记忆放入数据库或向量库。

前端聊天系统要区分:

  • UI 消息历史
  • 模型上下文
  • 数据库存档
  • 长期记忆

它们不是同一个东西。

23.1 上下文工程(context engineering):LangChain 官方框架 ​

官方文档把“Agent 为什么不可靠”归结为两点:模型能力不够,或喂给模型的上下文不对——实践里绝大多数失败是后者,因此上下文工程被称为 AI 工程师的第一职责。LangChain 把可控对象分成三类:

上下文类型控制什么暂态/持久
Model Context进入模型调用的内容:指令、历史、工具列表、response format暂态(只影响本次调用,不改存档)
Tool Context工具能读写什么:state、store、runtime context持久(写入状态)
Life-cycle Context步骤之间发生什么:摘要、guardrails、日志持久

对应三个数据源,别混淆:

数据源别名作用域例子
Runtime Context静态配置会话内只读user_id、权限、连接配置
State短期记忆会话内可写messages、工具结果、计数器
Store长期记忆跨会话用户偏好、抽取的事实

LangChain 的实现抓手正是第 12 章的 middleware:wrap_model_call 里 request.override(system_message=..., tools=...) 修改暂态上下文而不污染 state;要持久修改则返回带 Command 的 ExtendedModelResponse 走 reducer 合入。常见陷阱:

  • ⚠️ 把检索到的大段文档、工具原始 JSON 全量塞进 messages 并留在 state 里:每一轮都重复计费,还会挤掉真正重要的指令。正确做法是暂态注入(本轮可见)或摘要/落盘引用。
  • ⚠️ 用 SummarizationMiddleware 时,摘要是有损压缩——工具调用对(AIMessage tool_calls + ToolMessage)不能被拆散摘要,否则消息历史非法、提供商直接报错。
  • 长上下文不等于更多信息利用:官方建议控制进入模型的 token 总量(context editing / trimming 中间件就是干这个的),质量优先于数量。

24. Human-in-the-loop ​

Human-in-the-loop 指人类参与 Agent 流程,常见于:

  • 审批退款
  • 确认发送邮件
  • 修改自动生成内容
  • 审核数据库变更
  • 确认高风险工具调用

前端要提供:

  • 暂停状态展示
  • 审批按钮
  • 修改输入框
  • 操作记录
  • 继续执行入口

复杂 HITL 流程更适合 LangGraph,因为它更擅长保存状态、暂停和恢复。

24.1 LangChain 层的现成方案:HumanInTheLoopMiddleware ​

在 create_agent 里不用手写暂停逻辑——内置的 HumanInTheLoopMiddleware 按工具名拦截,命中即触发 LangGraph interrupt 等待外部决策:

python
from langchain.agents import create_agent
from langchain.agents.middleware import HumanInTheLoopMiddleware

agent = create_agent(
    model="gpt-5.5",
    tools=[read_email, send_email],
    middleware=[HumanInTheLoopMiddleware(interrupt_on={"send_email": True})],
)

机制上它就是第 12 章 wrap_tool_call 类钩子的官方预置实现:interrupt_on 的 key 匹配工具的 .name(@tool 装饰的函数默认取函数名)。调用方看到 interrupt payload 后,用 Command(resume=...) 传回 approve/edit/reject 决策。⚠️ 前提与 LangGraph 相同:必须配 checkpointer 和稳定的 thread_id,否则暂停后无法恢复。

25. Guardrails ​

Guardrails 是保护栏,用于限制模型行为。

常见方式:

  • 输入过滤
  • 输出校验
  • 工具权限控制
  • 敏感信息脱敏
  • 结构化输出 schema
  • 人工审批
  • 策略提示词

不要只依赖 Prompt 安全。真正可靠的系统要在代码层、工具层、权限层和产品层共同限制风险。

25.1 分层实施与 prompt injection ​

Guardrails 按拦截位置分层,各层能力不同,缺一不可:

层时机手段特点
输入层模型调用前before_model 钩子:内容过滤、PII 检测(PIIMiddleware)、长度/语言校验便宜,但挡不住语义级攻击
决策层工具调用前HumanInTheLoopMiddleware、ToolCallLimitMiddleware、工具参数 schema 校验唯一能拦“合法格式、非法意图”的层
输出层模型响应后after_model / 结构化输出校验(ToolStrategy + handle_errors)、敏感词与泄露检查防不合规内容到达用户
权限层工具执行时API Key 最小权限、只读凭证、写操作 dry-run模型被说服也越不过去

💡 prompt injection 的核心认识:检索到的文档、网页、用户文件里的“指令”会进入模型上下文,模型无法从根本上区分“老板的指示”和“恶意网页里藏的一句话”。⚠️ 所以防线不可能全在 prompt 层(写“忽略注入指令”只是提高成本,不是保证),真正可靠的是让被注入的模型手里没有危险能力:写操作走 HITL 审批、凭证按工具粒度下发、外部内容永远不解锁新工具。这也是第 9 章“权限边界严格、不把危险操作直接暴露给模型”的工程理由。


第五篇:工程化与生产 ​

26. LangChain 项目结构 ​

推荐结构:

text
ai-service/
├── app/
│   ├── agents/
│   ├── tools/
│   ├── retrievers/
│   ├── prompts/
│   ├── schemas/
│   └── services/
├── data/
├── tests/
└── pyproject.toml

职责:

  • agents:Agent 组装。
  • tools:工具函数。
  • retrievers:检索器。
  • prompts:提示词模板。
  • schemas:结构化输入输出。
  • services:业务服务和数据库访问。

27. 前端 + 后端 + LangChain 架构 ​

适合你的方向:

text
Vue/Nuxt 前端
  -> NestJS API 网关
  -> Python FastAPI AI 服务
  -> LangChain/LangGraph
  -> PostgreSQL + pgvector
  -> Redis/队列

为什么不一定把 AI 全写在 Node.js:

  • Python AI 生态更完整。
  • 很多模型、向量库、数据处理工具优先支持 Python。
  • 前端/Node 仍然负责产品体验、鉴权、业务 API 和系统集成。

但 TypeScript 也有 LangChain JS,可用于轻量 AI 能力、前端原型、Node API 中的简单 Agent。

28. 观测、追踪与评估 ​

LLM 应用必须可观测。

要记录:

  • 输入
  • Prompt
  • 检索到的文档
  • 模型名称
  • 工具调用
  • 输出
  • token 成本
  • 延迟
  • 错误

评估:

  • 回答是否正确。
  • 是否引用了来源。
  • 是否遵守输出格式。
  • 是否拒绝了不该回答的问题。
  • 工具调用是否合理。

没有评估的 Agent 很难稳定迭代。

29. 成本、延迟和稳定性 ​

成本来源:

  • 输入 token
  • 输出 token
  • embedding
  • rerank
  • 工具/API 调用
  • 向量库和服务器

优化:

  • 缩短 Prompt。
  • 检索更少但更准。
  • 缓存 embedding。
  • 常见问题缓存答案。
  • 小任务用便宜模型。
  • 复杂任务再用强模型。

稳定性:

  • 超时重试。
  • 降级模型。
  • 工具失败兜底。
  • 输出校验。
  • 结构化错误返回。

30. 常见误区 ​

误区一:LangChain 会让模型更聪明。

纠正:LangChain 负责组织应用流程,不会神奇提升模型能力。

误区二:所有 AI 应用都要 Agent。

纠正:简单分类、抽取、问答不一定需要 Agent。能用确定流程解决,就不要过度 Agent 化。

误区三:RAG 就是向量库。

纠正:RAG 包括文档处理、切分、检索、重排、Prompt、回答、引用和评估。

误区四:Prompt 写好了就能上线。

纠正:上线还需要日志、评估、错误处理、权限、安全和成本控制。

31. 学习路线和项目实战 ​

第一阶段:LLM 调用

  • 学消息格式。
  • 学模型参数。
  • 写简单聊天接口。
  • 实现流式输出。

第二阶段:工具调用

  • 写查询天气/订单/数据库工具。
  • 学参数 schema。
  • 学工具错误处理。

第三阶段:RAG

  • 导入 Markdown 文档。
  • 切分和 embedding。
  • 用向量库检索。
  • 前端展示引用来源。

第四阶段:Agent

  • 用 create_agent 组合模型和工具。
  • 加入短期记忆。
  • 加入人工确认。

第五阶段:生产

  • 加 trace。
  • 建评估集。
  • 统计 token 成本。
  • 做降级和超时。

项目建议:

text
个人知识库 AI 助手
- 前端:Nuxt/Vue + Tailwind
- 后端:NestJS
- AI 服务:Python + LangChain
- 数据库:PostgreSQL + pgvector
- 功能:文档上传、RAG 问答、引用来源、流式输出、反馈评分

快速记忆清单 ​

  • LangChain 是 LLM/Agent 应用框架,不是模型。
  • 核心组件是 model、message、prompt、tool、structured output、retriever、agent。
  • RAG 的关键不是向量库,而是检索质量和上下文控制。
  • Tool 要有明确输入输出和权限边界。
  • 简单流程先用 LangChain,复杂状态编排再用 LangGraph。
  • AI 应用必须做观测、评估、成本控制和错误兜底。

基于 VitePress 构建的个人学习文档知识库