一、LangChain 生态

1) 一张表对齐

维度 代理框架 代理运行时 代理工具
价值 抽象集成:统一模型、工具、消息与 Agent 循环的写法,降低上手成本。 持久执行流式人工干预、状态持久化低级别编排控制。 预定义工具提示与子代理等开箱能力,面向复杂、长程任务。
场景 快速做 Demo / 内部工具;需要标准化团队构建方式;代理逻辑相对直白、编排不极端复杂。 长期运行、强状态的工作流与代理;要把确定性步骤与 Agent 步骤混编;要上生产的图执行与检查点。 自主的代理;面对复杂、非确定性、需规划分解与多工件(搜索摘要、脚本、中间状态)的任务。
业界选项 LangChain、Vercel AI SDK、CrewAI、OpenAI Agents SDK、Google ADK、LlamaIndex 等。 LangGraph、Temporal、Inngest 等持久/工作流引擎。 Deep Agents SDK、Claude Agent SDK、Manus、各类「编码向」CLI Agent 等。

2) 分层:从协议到封装

层级 组件 核心职能 主要依赖
底层协议(地基) langchain-core RunnableBaseMessage、抽象模型类等契约;LCEL 管道建立在其上。 无(生态内最底抽象)
外部集成(砖块) langchain-community 向量库、Loader、Tool 等第三方集成实现。 langchain-core
逻辑编排(骨架) LangGraph 有状态图执行:循环、分支、Checkpointing、人机协同等运行时能力。 langchain-core
应用框架(大楼) LangChain Chain、RAG、新版 Agent(如 create_react_agent)等高层 API;LangChain 1.0 构建在 LangGraph 之上,但日常用 LangChain 不必先精通 LangGraph。 corecommunitypydantic
高级封装 Deep Agents 基于 LangGraph 的约定式高层封装,减少手写节点与边。 LangChainLangGraph

官方/厂商包不在 社区包langchain-community 之内,而是与 community 并列的独立包。

3) 代理框架(以 LangChain 为例)

  • 希望较快搭出代理或半自主应用。
  • 需要模型、工具、Agent 循环的团队级标准抽象
  • 合理默认、上手友好的框架,又不必一上来就做极重编排。
  • 应用形态偏简单代理,没有复杂长程状态机需求(或愿意先不碰底层图)。

4) 代理运行时(以 LangGraph 为例)

运行时解决的是在生产里怎么跑,常见能力包括:

  • 持久执行:故障后可恢复,长任务从中断点继续。
  • 流式:工作流与模型输出流式透出。
  • 人工干预:检查、改写代理状态,再交回执行。
  • 持久化:线程内与跨线程的状态管理策略。
  • 低级别控制:不依赖高层糖衣,直接编排节点与边。

LangGraph 是面向长期运行、有状态代理的低级别编排 + 运行时;它适合反思、重试、多轮工具调用。

5) 代理工具 / 深度代理 SDK(以 Deep Agents 为例)

  • 规划:待办列表式跟踪多任务进度。
  • 任务委派:子代理分担子任务,主上下文更干净。
  • 文件系统:对可插拔存储后端做读写抽象。
  • 令牌管理:对话摘要、超大工具结果驱逐等上下文工程。

Deep Agents 构建在 LangGraph 之上,面向需要规划与分解的复杂多步任务(搜索工件、脚本、中间状态并存)。

何时优先用 Deep Agents

  • 代理运行时间长、步骤多。
  • 任务复杂、非确定性强,需要内置规划与上下文治理。
  • 想直接用预置工具(如文件、bash 类能力、自动上下文工程)。
  • 希望沿用预置提示与子代理模式,少从零搭图。
二、LangChain 组件架构

1) 核心组件如何串成应用

flowchart TB subgraph LC_IN["输入处理 Input"] A["Text input"] --> B["Document loaders"] B --> C["Text splitters"] C --> D["Documents"] end subgraph LC_ES["嵌入与存储 Embedding"] D --> E["Embedding models"] E --> F["Vectors"] F --> G[("Vector stores")] end subgraph LC_RV["检索 Retrieval"] H["User query"] --> I["Embedding models"] I --> J["Query vector"] J --> K["Retrievers"] K --> G G --> L["Relevant context"] end subgraph LC_GN["生成 Generation"] M["Chat models"] --> N["Tools"] N --> O["Tool results"] O --> M L --> M M --> P["AI response"] end subgraph LC_OC["编排 Orchestration"] Q["Agents"] --> M Q --> N Q --> K Q --> Mem["Memory"] end classDef trigger fill:#DCFCE7,stroke:#16A34A,stroke-width:2px,color:#14532D classDef process fill:#DBEAFE,stroke:#2563EB,stroke-width:2px,color:#1E3A8A classDef output fill:#F3E8FF,stroke:#9333EA,stroke-width:2px,color:#581C87 classDef neutral fill:#F3F4F6,stroke:#9CA3AF,stroke-width:2px,color:#374151 class A,H trigger class B,C,E,I,K,M,N,Q process class D,F,J,L,O,P,Mem neutral class G output

2) 核心流程

  1. 输入处理:把原始数据变成结构化 Document
  2. 嵌入与存储:将文本变为可检索的向量并存入向量库。
  3. 检索:按用户问题召回相关上下文。
  4. 生成:由 Chat 模型生成回答,并可与工具循环交互。
  5. 编排:相对「用户问题 → RetrieversRelevant contextChat models」的单次流水线,Agents 根据观察决定何时调用 Retrievers、何时调用 Tools(如联网搜索);Chat models 综合 Relevant contextTool results,若信息不足,Agents 可再次检索或换工具,形成决策闭环。Memory 保存消息历史与状态,在用户当前问题进入 Embedding models / Retrievers 前补全会话。

3) 官方组件分类表

类别 用途 关键组件 典型场景
Models 推理与生成 Chat models、LLMs、Embedding models 文本生成、推理、语义理解
Tools 外部能力 API、数据库等 联网搜索、取数、计算
Agents 编排与推理 ReAct、tool-calling agents 非确定性工作流、决策
Memory 保留上下文 Message history、custom state 多轮对话、有状态交互
Retrievers 信息访问 Vector retrievers、web retrievers RAG、知识库检索
Document processing 数据摄入 Loaders、splitters、transformers PDF、爬虫等
Vector Stores 语义检索 Chroma、Pinecone、FAISS 等 相似度搜索、向量持久化

4) 常见模式(示意)

RAG(检索增强生成)

graph LR A["User question"] --> B["Retriever"] B --> C["Relevant docs"] C --> D["Chat model"] A --> D D --> E["Informed response"] classDef trigger fill:#DCFCE7,stroke:#16A34A,stroke-width:2px,color:#14532D classDef process fill:#DBEAFE,stroke:#2563EB,stroke-width:2px,color:#1E3A8A classDef neutral fill:#F3F4F6,stroke:#9CA3AF,stroke-width:2px,color:#374151 class A trigger class B,D process class C,E neutral

带工具的 Agent

graph LR A["User request"] --> B["Agent"] B --> C{"Need tool?"} C -->|Yes| D["Call tool"] D --> E["Tool result"] E --> B C -->|No| F["Final answer"] classDef trigger fill:#DCFCE7,stroke:#16A34A,stroke-width:2px,color:#14532D classDef process fill:#DBEAFE,stroke:#2563EB,stroke-width:2px,color:#1E3A8A classDef decision fill:#FEF3C7,stroke:#F59E0B,stroke-width:2px,color:#78350F classDef neutral fill:#F3F4F6,stroke:#9CA3AF,stroke-width:2px,color:#374151 class A trigger class B,D process class C decision class E,F neutral

Agent 与 Memory:如何把环节串成「有状态的」应用

flowchart TB subgraph compare["仅作对照:线性 RAG"] direction LR u0["用户当前问题"] --> r0["Retrievers"] r0 --> v0[("Vector stores")] v0 --> ctx0["Relevant context"] ctx0 --> m0["Chat models"] u0 --> m0 m0 --> p0["AI response"] end subgraph dyn["编排:Agents + Memory 决策环"] direction TB MEM["Memory\n消息历史 / thread state"] U["用户当前问题"]:::trigger MEM -.->|"指代消解、拼上轮对话"| U AG["Agents 调度"]:::process U --> AG AG --> K["Retrievers"]:::process K --> G2[("Vector stores")]:::output G2 --> L2["Relevant context"]:::neutral AG --> N2["Tools\n外部搜索等"]:::process N2 --> O2["Tool results"]:::neutral L2 --> CH["Chat models"]:::process O2 --> CH CH -->|"信息够?不够则再决策"| AG CH --> P2["AI response"]:::neutral end subgraph eg["动态例子(多轮)"] direction TB e1["追问含指代:这种检索在 10 万租户下怎优化?"] e2["Memory 提示:「这种」= 上轮的向量检索"] e3["Agents:先 Retrievers 拿 HNSW 等私有资料"] e4["仍不足:再调 Tools 搜 multi-tenancy 实践"] e5["Chat models:合并私有 Relevant context 与外部 Tool results → 产出 AI response"] e1 --> e2 --> e3 --> e4 --> e5 end classDef trigger fill:#DCFCE7,stroke:#16A34A,stroke-width:2px,color:#14532D classDef process fill:#DBEAFE,stroke:#2563EB,stroke-width:2px,color:#1E3A8A classDef output fill:#F3E8FF,stroke:#9333EA,stroke-width:2px,color:#581C87 classDef neutral fill:#F3F4F6,stroke:#9CA3AF,stroke-width:2px,color:#374151
三、LangChain Memory

1) Memory 是什么

Memory是让系统记住先前交互信息的机制。对 AI Agent 而言,记忆能保留对话脉络、从反馈中学习并适应用户偏好;任务越复杂、交互越多,记忆越影响效率与体验。

召回范围可分为两大类:

  • 短期记忆:又称 thread(线程)范围记忆——在同一会话内维护消息与状态;由 LangGraph 纳入 Agent 的 state,通过 checkpointer 持久化,使线程可随时恢复。图每执行一步会更新 state,下一步开始时会读取该 state。
  • 长期记忆:跨会话、跨 thread 共享的用户级或应用级数据;可在任意时刻、任意 thread 中召回;按自定义 namespace 划分,不限于单一 thread id。LangGraph 通过 Store

2) 短期记忆与管理

短期记忆让应用在单个 thread / 会话内记住先前轮次。Thread 将多次交互组织在一起。LangGraph 把短期记忆作为 Agent state 的一部分,用 thread 粒度的 checkpoint 持久化;state 中除对话历史外,还可包含上传文件、检索结果、生成工件等,从而在隔离不同 thread 的同时为当前对话提供完整上下文。

为何要主动管理对话历史?全文历史可能超出上下文窗口导致报错;即使模型支持超长上下文,过长历史也常带来分心、变慢与成本上升。因此需要在工程上裁剪、摘要或遗忘陈旧内容。

消息过滤与管理(官方示意图)

3) 长期记忆

类型 存什么 人类例子 Agent 例子
Semantic(语义记忆) 事实与概念 学校里学到的知识 关于用户的稳定事实
Episodic(情节记忆) 经历与事件 我做过的事 过去 Agent 行为轨迹
Procedural(程序记忆) 规则与做法 本能或熟练技能 系统提示、代码与「如何做」

4) 语义记忆

注意:心理学意义上的「语义记忆」≠ 工程里的「语义检索(semantic search)」;后者是用向量等手段按含义检索,前者指存事实与知识。

Profile:单一、持续更新的实体画像(如用户/组织),常为受控 schema 的 JSON;每次在旧 profile 上用模型生成新 profile 或 JSON Patch 更新。体量大时易出错,可考虑拆文档或强制结构化解码。

Update profile memory(官方示意图)

Collection:多条独立记忆文档,随时间追加;单条更窄、更易模型生成,一般更容易保留信息、下游召回更好,但需处理删除/更新与「过增/过改」倾向;检索侧依赖 Store 的语义搜索与过滤。多碎片可能不如单一 profile 那样自带全局语境,组合进 prompt 时需自行设计。

Update list / collection memory(官方示意图)

5) 情节记忆与程序记忆

情节记忆:常通过 few-shot 示例 把「过去怎么做」注入提示;可选用 Store 存示例,或用 LangSmith Dataset 自建检索逻辑。

程序记忆:权重、代码与(尤其)系统提示共同决定行为;实践中多见用 Reflection / meta-prompting 迭代系统提示。官方给出基于 Store 更新 instructions 的伪代码思路:call_model 从 Store 读当前指令;update_instructions 结合对话与旧指令生成新指令并 store.put 回去。

Update instructions / procedural memory(官方示意图)
# 官方文档伪代码示意(节点拆分)
def call_model(state: State, store: BaseStore):
    namespace = ("agent_instructions", )
    instructions = store.get(namespace, key="agent_a")[0]
    prompt = prompt_template.format(instructions=instructions.value["instructions"])
    ...

def update_instructions(state: State, store: BaseStore):
    namespace = ("instructions",)
    instructions = store.search(namespace)[0]
    prompt = prompt_template.format(
        instructions=instructions.value["instructions"],
        conversation=state["messages"])
    output = llm.invoke(prompt)
    new_instructions = output['new_instructions']
    store.put(("agent_instructions",), "agent_a", {"instructions": new_instructions})
    ...

6) 写入记忆:

  • 热路径:运行中即时写入——新记忆马上用于后续轮次、可对用户透明;但可能增加工具与推理复杂度、拉高延迟,且与「主要任务」争用注意力。
  • 后台:异步提炼记忆——主路径延迟低、职责分离;但确定记忆写入的频率变得至关重要,因为不频繁的更新可能会导致其他线程没有新的上下文。确定何时触发记忆形成也很重要。常见的策略包括在设置的时间段后安排(如果发生新的事件则重新安排),使用 cron 计划,或允许用户或应用程序逻辑手动触发。
Hot path vs background memory writing(官方示意图)

7) 存储结构(Store)

长期记忆在 LangGraph 中以 JSON 文档 存入 storenamespace(类似目录)+ key(类似文件名);namespace 常含 user id、org id 等便于分层与检索。可跨 namespace 用内容过滤等策略搜索。

from langgraph.store.memory import InMemoryStore

def embed(texts: list[str]) -> list[list[float]]:
    return [[1.0, 2.0] * len(texts)]

store = InMemoryStore(index={"embed": embed, "dims": 2})
user_id = "my-user"
application_context = "chitchat"
namespace = (user_id, application_context)
store.put(
    namespace,
    "a-memory",
    {
        "rules": [
            "User likes short, direct language",
            "User only speaks English and python",
        ],
        "my-key": "my-value",
    },
)
item = store.get(namespace, "a-memory")
items = store.search(
    namespace, filter={"my-key": "my-value"}, query="language preferences"
)
四、LangChain 上下文

1) 上下文工程

上下文工程(context engineering)指搭建动态系统,在正确时机以正确格式提供正确信息与工具,使应用能完成任务。描述「上下文」常用两个维度:

  • 可变性静态上下文在执行中不变(用户元数据、数据库连接、工具注册等);动态上下文随运行演变(对话历史、中间结果、工具观测等)。
  • 生命周期运行时限定在单次 invoke/单次运行内;跨会话则在多轮对话、多 thread 之间持久存在。

2) 分清:

强调:运行时上下文是代码侧的依赖与数据,不是

  • 写进 LLM 提示里的那段文字(「LLM 上下文」);
  • 模型能接收的 最大 token 数(「上下文窗口」)。

运行时上下文更像一种依赖注入:在 invoke/stream 时把用户 ID、客户端、连接等传给工具与节点,再按需写入真正的提示或状态。

3) LangGraph 管理上下文的三种方式

类型 含义 可变 生命周期 典型访问方式
静态运行时上下文 启动时注入、运行中不变(元数据、工具、DB 连接等) 静态 单次运行 invoke / streamcontext 参数;代理里 context_schema;图节点里 Runtime[...];工具里 ToolRuntime[...]
动态运行时上下文(状态) 单次运行内可变:消息、中间量、工具产出等 动态 单次运行 LangGraph state(短期记忆、与 checkpoint 配合可持久到 thread)
动态跨会话上下文(存储) 跨对话持久:画像、偏好、历史事实等 动态 跨会话 LangGraph Store(长期记忆)

4) 静态运行时上下文

在调用图或代理时通过 context=... 传入;类型可用 @dataclass 等声明为 context_schema。工具与节点通过 runtime.context 读取,避免把连接与用户标识硬编码进工具体。

@dataclass
class ContextSchema:
    user_name: str

graph.invoke(
    {"messages": [{"role": "user", "content": "hi!"}]},
    context={"user_name": "John Smith"},
)

代理侧可为中间件动态拼系统提示(request.runtime.context);图节点签名为 def node(state, runtime: Runtime[ContextSchema]);工具侧常用 ToolRuntime[ContextSchema] 注入依赖。

5) 动态运行时上下文(状态)

由 LangGraph 的 state 承载,在一次运行内读写;对应「短期记忆」与多步编排中的中间结果。需要跨多次调用持久化同一 thread 时,结合 Memory 一节中的 checkpointer

6) 动态跨会话上下文(存储)

Store 管理跨 thread、跨会话的数据,对应长期记忆;与上一节「长期记忆 / namespace」一致,可与静态、运行时状态配合:静态上下文决定「谁在读」,存储里放「跨会话记住了什么」。