LangGraph 1.0 学习笔记:生产级Agent开发里程碑

LangGraph 1.0 学习笔记:生产级Agent开发里程碑

> 学习时间:2026-04-13
> 学习来源:掘金技术博客 + CSDN深度好文
> 核心主题:LangGraph 1.0 核心架构升级、原生持久化、人机协同、Middleware中间件
> 前置知识:已学LangGraph基础课程、CrewAI课程、ReAct论文


一、学习来源

来源类型 名称 作者 链接
技术博客 LangGraph 1.0 深度解读:生产级 Agent 的里程碑 Tam(学杂了的前端) 掘金链接
技术博客 LangGraph核心总结,构建可靠可控AI Agent的新范式 小程故事多 CSDN链接

二、核心收获(5个关键点)

  1. 原生持久化与"时间旅行":Checkpointer机制让Agent任务可以断点续传,支持从任意历史状态恢复或重新执行,这是生产级应用的核心能力
  2. 人机协同的终极形态:interrupt() API + Command原语让人类介入Agent执行流程变得像写同步代码一样简单,彻底解决了高风险操作的审批问题
  3. Middleware中间件架构:借鉴Web开发经验,通过before_model/after_model等Hooks实现日志记录、上下文管理、PII过滤等横切关注点
  4. 状态管理范式转变:从Pydantic回归TypedDict,配合Reducer函数实现精细化的状态合并控制
  5. 分层架构清晰化:LangGraph定位为底层运行时,LangChain定位为应用层,两者的分层职责更加明确

三、正文内容:LangGraph 1.0 深度解读

3.1 为什么LangGraph 1.0至关重要?

在过去的一年里,我们见证了AI Agent从实验室的Jupyter Notebook走向了企业的生产环境。然而,这一过程充满了痛苦。开发者发现,用简单的Chain串联起来的Agent脆弱不堪:网络抖动会导致任务丢失,上下文过长会导致模型"发疯",更可怕的是,当Agent决定执行一个危险操作(比如"删除数据库")时,人类往往来不及阻止。

LangGraph 1.0的诞生背景

LangGraph最初就是为了解决"循环"和"控制流"的问题。而LangGraph 1.0更进一步,它不再仅仅是一个图计算库,它定义了一个Agent Runtime(代理运行时)标准。1.0的核心关键词是:Stability(稳定性)。官方明确承诺,核心API(State, Nodes, Edges)将保持长期稳定,不再会有那种"睡一觉起来代码跑不通了"的恐惧。这对于企业级应用来说,是最大的利好。

我的理解:LangGraph 1.0标志着AI Agent开发从"玩具阶段"进入"工程化阶段"。就像Django从1.0到2.0的演进一样,1.0版本通常意味着API的稳定和生态的成熟。

3.2 核心架构升级:稳定压倒一切

3.2.1 核心原语的定型

在0.x时代,我们可能经历过图定义方式的微调。但在1.0中,以下三个概念被永久固化:

  1. State(状态):Agent的大脑,通常是一个TypedDict。所有的组件(Nodes)都通过读写这个状态来通信
  2. Nodes(节点):执行具体逻辑的函数(Python函数)
  3. Edges(边):控制流,决定下一个运行哪个节点
from typing import TypedDict, Annotated
from langgraph.graph.message import add_messages

# LangGraph 1.0 标准状态定义
class AgentState(TypedDict):
    messages: Annotated[list, add_messages]  # 使用Reducer追加消息
    current_step: str                          # 当前执行步骤
    task_result: dict                         # 任务结果

# 节点示例
def chatbot_node(state: AgentState):
    # 读取状态
    messages = state["messages"]
    # 执行逻辑...
    # 更新状态
    return {"current_step": "completed"}

这种设计的精妙之处在于它的透明性。不像某些框架将Agent封装成一个黑盒(Black Box),LangGraph强迫你画出Agent的"思维导图"。每一行代码都在描述Agent的工作流程,这让复杂的Agent行为变得可预测、可调试。

3.2.2 Pregel架构的执行引擎

LangGraph的运行时核心借鉴了Google Pregel大规模并行图计算模型。其执行过程分为"超步(Super-step)"迭代:

  1. Plan阶段:系统根据当前状态和边的路由规则,确定本轮需要执行的所有节点,支持多节点并行调度
  2. Execution阶段:所有选中的节点同时执行计算逻辑,节点间不直接通信,仅通过状态通道传递数据,避免了并行执行中的数据竞争
  3. Update阶段:将所有节点的执行结果汇总,通过Reducer函数更新到全局状态,完成一轮超步

技术洞见:Pregel架构的选择让LangGraph天生支持分布式执行。未来可以将不同节点调度到不同服务器执行,支撑大规模Agent集群运行。这是LangGraph区别于其他框架的关键技术决策。

3.3 重磅新功能一:原生持久化与"时间旅行"

这是LangGraph 1.0最具杀伤力的特性。在生产环境中,服务器重启、网络中断是常态。如果你的Agent正在执行一个长达30步的任务,而在第29步服务器挂了,1.0之前的系统通常意味着"从头再来"。

3.3.1 Checkpointer机制详解

Checkpointer是一个保存每一"步"(Super-step)状态快照的组件。LangGraph 1.0提供了多种开箱即用的Checkpointer:

from langgraph.checkpoint.memory import MemorySaver
from langgraph.checkpoint.sqlite import SqliteSaver
from langgraph.checkpoint.postgres import PostgresSaver

# 开发环境:内存检查点(仅用于调试)
dev_checkpointer = MemorySaver()

# 生产环境:SQLite持久化
prod_checkpointer = SqliteSaver.from_conn_string("checkpoints.db")

# 生产环境:PostgreSQL持久化(支持分布式)
prod_checkpointer = PostgresSaver(
    connection_string="postgresql://user:password@host:port/dbname",
    serde=JsonPlusSerializer()  # 支持复杂对象序列化
)

# 编译图时传入checkpointer
graph = builder.compile(checkpointer=prod_checkpointer)

# 运行时传入thread_id
config = {"configurable": {"thread_id": "user-session-123"}}
result = graph.invoke(inputs, config=config)

3.3.2 深入理解thread_id

thread_id是持久化的核心钥匙。只要你提供了相同的thread_id,LangGraph就会自动去数据库里查找上一次的状态,并从那里继续。这不仅实现了"断点续传",还实现了"长期记忆"。

# 第一次运行
config = {"configurable": {"thread_id": "user-123"}}
result = graph.invoke({"messages": [("human", "帮我写一份报告")]}, config=config)

# 第二次运行(自动从上次状态恢复)
# Agent会记得之前的对话历史
result = graph.invoke({"messages": [("human", "继续")]}, config=config)

# 第三次运行(全新会话)
config = {"configurable": {"thread_id": "user-456"}}
result = graph.invoke({"messages": [("human", "你好")]}, config=config)

3.3.3 "时间旅行"(Time Travel)

LangGraph 1.0的持久化不仅仅是"保存"。由于它保存了每一步的快照,你可以通过API查询历史状态,甚至让Agent"回滚"到之前的某一步,修改状态,然后走一条不同的路径。

# 获取所有历史快照
snapshots = []
cursor = None
while True:
    chunk = graph.get_state_history(config, cursor=cursor)
    if not chunk:
        break
    snapshots.append(chunk)
    cursor = chunk.next_cursor

# 恢复到某个历史状态
historical_config = {"configurable": {"thread_id": "user-123", "checkpoint_id": "checkpoint-xxx"}}
graph.update_state(historical_config, {"current_step": "review"})  # 修改状态
graph.invoke(None, config=historical_config)  # 继续执行

生产价值:时间旅行能力在调试复杂Agent行为时是"上帝视角"的体验。想象一下,当你的客服Agent连续对话30轮后出现错误,你不需要重新运行30轮,而是直接定位到第15轮,修改状态,继续执行。这极大提升了调试效率。

3.4 重磅新功能二:人机协同(Human-in-the-Loop)的终极形态

Agent不应该是脱缰的野马。LangGraph 1.0将"人机协同"提升为一等公民(First-class Citizen)。

3.4.1 interrupt() API详解

在1.0之前,实现"暂停"往往需要复杂的逻辑判断(例如抛出异常或设置特殊标志位)。现在,你可以直接在Node内部调用interrupt。

from langgraph.types import interrupt, Command
from typing import TypedDict

class AgentState(TypedDict):
    messages: list
    pending_action: dict | None

def human_approval_node(state: AgentState) -> Command:
    """高风险操作审批节点"""
    pending = state.get("pending_action")
    
    if not pending:
        return Command(goto="normal_processing")
    
    tool_call = pending.get("tool")
    if tool_call in ["delete_database", "transfer_money", "send_email"]:
        # 核心API:interrupt
        # 程序运行到这里会立即挂起,并将当前状态保存到Checkpointer
        # 参数是返回给前端/用户的提示信息
        user_decision = interrupt(
            f"Agent想要执行危险操作: {tool_call}。是否批准?\n"
            f"参数: {pending.get('args')}"
        )
        
        # 当Agent被"恢复"时,user_decision将包含用户输入的数据
        if user_decision == "approve":
            return Command(goto="execute_dangerous_tool")
        else:
            return Command(goto="reject_action")
    
    return Command(goto="normal_processing")

3.4.2 恢复执行:Command与resume

当interrupt被触发后,Agent处于"挂起"状态。要恢复它,你需要再次调用invoke或stream,并传入Command对象。

# 第一次运行,触发interrupt
config = {"configurable": {"thread_id": "user-123"}}
result = graph.invoke(
    {"messages": [("human", "删除所有测试数据")], "pending_action": {"tool": "delete_database", "args": {"table": "test_data"}}},
    config=config
)

# 输出:__interrupt__: "Agent想要执行危险操作: delete_database。是否批准?"

# 用户在UI点击"批准"按钮后,恢复运行
# 注意:我们不需要重新输入之前的消息,只需要提供resume的值
result = graph.invoke(
    Command(resume="approve"),
    config=config
)

# 继续执行到下一个节点
result = graph.invoke(
    Command(resume="继续完成其他任务"),
    config=config
)

架构思考:这种模式彻底改变了HITL(Human-in-the-Loop)的开发体验。传统实现往往需要轮询、外部状态机、甚至独立的worker进程。而LangGraph 1.0让你用同步代码的思维写异步审批流,状态自动持久化,恢复自动续接。这是一种真正意义上的"协程式"人机协作。

3.5 架构剧变:从create_react_agent到langchain.agents.create_agent

这是1.0版本中最大的Deprecation(弃用)和迁移点。

3.5.1 为什么弃用langgraph.prebuilt?

旧世界 (LangGraph 0.x):我们经常使用langgraph.prebuilt.create_react_agent来快速创建一个ReAct Agent。

新世界 (LangGraph 1.0 + LangChain 1.0):这个功能被移动并增强到了langchain.agents.create_agent。

为什么? langgraph定位为底层的运行时(Runtime),它只关心图的执行。而create_react_agent包含了很多关于Prompt、Model选择的高级逻辑,这些属于应用层,因此被移入langchain。

# 旧代码 (Deprecated in 1.0)
from langgraph.prebuilt import create_react_agent
from langchain_openai import ChatOpenAI

model = ChatOpenAI()
agent = create_react_agent(
    model,
    tools,
    state_modifier="You are a helpful assistant"  # 比较隐晦
)

# 新代码 (LangGraph 1.0 / LangChain 1.0)
from langchain.agents import create_agent
from langchain_openai import ChatOpenAI

model = ChatOpenAI()
agent = create_agent(
    model=model,
    tools=tools,
    system_prompt="You are a helpful assistant"  # 更加清晰
)

3.5.2 LangChain与LangGraph的关系:分层架构

这次拆分体现了清晰的分层架构思维

┌─────────────────────────────────────────────────────────────┐
│                    LangChain 1.0 (应用层)                    │
├─────────────────────────────────────────────────────────────┤
│  ├─ create_agent: 高级Agent构建API                         │
│  ├─ Chain: 预置的链式组合                                  │
│  ├─ PromptTemplate: 提示词管理                              │
│  ├─ Tool: 工具定义和集成                                    │
│  └─ Middleware: 中间件系统                                  │
├─────────────────────────────────────────────────────────────┤
│                    LangGraph 1.0 (运行时层)                  │
├─────────────────────────────────────────────────────────────┤
│  ├─ StateGraph: 图结构定义                                 │
│  ├─ Nodes/Edges: 核心原语                                  │
│  ├─ Checkpointer: 持久化机制                               │
│  ├─ interrupt(): 人机协同                                  │
│  └─ Pregel Engine: 执行引擎                                │
└─────────────────────────────────────────────────────────────┘

我的理解:分层架构的好处是职责清晰。LangChain负责"做什么"(工具集成、提示词工程),LangGraph负责"怎么做"(状态管理、执行控制)。这让两个项目可以独立演进,同时保持互操作性。

3.6 全新概念:Middleware(中间件)—— Agent的"插件系统"

这是LangGraph 1.0配合LangChain 1.0推出的最激动人心的功能之一。如果你熟悉Web开发(如Express.js或Django),你会秒懂Middleware。

3.6.1 为什么需要Middleware?

在Agent的运行循环中(思考 -> 行动 -> 观察),我们经常需要插入一些通用逻辑,比如:

在1.0之前,这些逻辑往往要硬编码在Node里,导致业务逻辑与基础设施代码耦合。

3.6.2 Middleware架构:洋葱模型

Middleware采用了经典的"洋葱模型"(Onion Model),提供了三个核心Hooks:

┌─────────────────────────────────────────────────────────────┐
│                    Middleware 洋葱模型                        │
├─────────────────────────────────────────────────────────────┤
│  before_model (进入洋葱)                                    │
│  ├─ ┌─────────────────────────────────────────────────┐    │
│  │  │  after_model (进入洋葱)                          │    │
│  │  │  ├─ ┌─────────────────────────────────────────┐  │    │
│  │  │  │  │  modify_model_request (核心层)          │  │    │
│  │  │  │  └─────────────────────────────────────────┘  │    │
│  │  │  └─────────────────────────────────────────────┘  │    │
│  │  └─────────────────────────────────────────────────┘    │
│  └────────────────────────────────────────────────────    │
└─────────────────────────────────────────────────────────────┘
  1. before_model:在调用LLM之前触发。可以修改Prompt,或者直接返回结果(缓存命中)
  2. after_model:在LLM返回结果后触发。可以修改输出,或者阻断执行
  3. modify_model_request:专门用于修改发给LLM的参数(如temperature、max_tokens)

3.6.3 实战:编写Middleware

from langchain.agents.middleware import Middleware
from typing import TypedDict, Optional

class AutoSummarizeMiddleware(Middleware):
    """自动摘要中间件:当消息超过10条时,生成摘要"""
    
    def before_model(self, state, config):
        messages = state.get("messages", [])
        
        # 如果消息超过10条,生成摘要
        if len(messages) > 10:
            summary = self._summarize(messages[:-10])  # 摘要历史消息
            
            # 返回修改后的状态(不调用LLM)
            return {
                "messages": [summary] + messages[-2:]  # 保留摘要+最近2条
            }
        
        return None  # 返回None表示继续正常流程
    
    def _summarize(self, messages):
        """实际项目中调用LLM生成摘要"""
        from langchain_openai import ChatOpenAI
        llm = ChatOpenAI(model="gpt-4o-mini")
        
        prompt = f"请摘要以下对话的核心内容(不超过100字):\n{messages}"
        summary = llm.invoke(prompt)
        return summary
    
    def after_model(self, state, config, output):
        """LLM返回后触发"""
        # 可以在这里添加输出验证、日志记录等
        return output  # 返回原始输出


class PIIFilterMiddleware(Middleware):
    """PII过滤中间件:检测并过滤敏感信息"""
    
    PII_PATTERNS = {
        "phone": r"\d{11}",
        "email": r"[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}",
        "id_card": r"\d{17}[\dXx]"
    }
    
    def before_model(self, state, config):
        import re
        
        messages = state.get("messages", [])
        last_message = messages[-1] if messages else None
        
        if last_message and hasattr(last_message, "content"):
            content = last_message.content
            
            # 检测PII
            for pii_type, pattern in self.PII_PATTERNS.items():
                matches = re.findall(pattern, content)
                if matches:
                    print(f"⚠ 检测到{pii_type}信息: {len(matches)}处")
                    # 替换为占位符
                    content = re.sub(pattern, f"[{pii_type}_redacted]", content)
            
            # 更新消息
            messages[-1] = type(last_message)(content=content)
            return {"messages": messages}
        
        return None


# 使用中间件
from langchain.agents import create_agent

agent = create_agent(
    model=model,
    tools=tools,
    system_prompt="You are a helpful assistant",
    middleware=[
        AutoSummarizeMiddleware(),
        PIIFilterMiddleware()
    ]
)

架构价值:Middleware让横切关注点(Cross-cutting Concerns)从业务代码中分离出来。这不仅是代码组织的问题,更是架构设计的问题。当你的团队有10个Agent需要添加日志记录时,只需要实现一个LoggingMiddleware,而不是修改10个Node。

3.7 数据标准化:Standard Content Blocks

在Agent开发中,不同模型提供商(OpenAI、Anthropic、Gemini)对"工具调用"、"思维链(Chain of Thought)"的返回格式定义各不相同。这导致开发者要写大量的if/else来适配。

LangChain/LangGraph 1.0引入了Standard Content Blocks。无论底层用的是Claude还是GPT-4,所有的Message对象现在都有一个统一的.content_blocks属性。

# 不同模型返回格式统一
message = response.message

# 统一的content_blocks结构
for block in message.content_blocks:
    if block.type == "reasoning":
        print(f"推理过程: {block.reasoning}")
    elif block.type == "tool_call":
        print(f"工具调用: {block.name}")
        print(f"参数: {block.args}")
    elif block.type == "text":
        print(f"文本输出: {block.text}")

这种标准化带来的价值是:编写一套代码,无缝切换OpenAI和Anthropic的模型,而不用担心解析逻辑崩溃。

3.8 状态管理:告别Pydantic,拥抱TypedDict

在LangGraph早期版本,我们经常争论State应该用Pydantic Model还是TypedDict。1.0做出了裁决:AgentState默认且推荐使用TypedDict

3.8.1 为什么放弃Pydantic?

Pydantic虽然验证功能强大,但在图的流转中(尤其涉及状态合并、Reducer逻辑时),其严格的校验机制往往会带来不必要的运行时错误。

# Deprecated / 不推荐
from pydantic import BaseModel

class MyState(BaseModel):
    messages: list[BaseMessage]  # Pydantic验证可能导致状态合并失败

# 推荐 (LangGraph 1.0)
from typing import TypedDict, Annotated
from langgraph.graph.message import add_messages

class MyState(TypedDict):
    # 使用Annotated和add_messages reducer是标准范式
    messages: Annotated[list, add_messages]
    user_info: dict
    step: int

3.8.2 Reducer函数详解

Reducer是LangGraph状态管理的精髓。在多节点并行执行场景中,多个节点可能同时更新同一状态字段,Reducer函数定义了更新规则:

from typing import Annotated, TypedDict
from langgraph.graph.message import add_messages
import operator

class TaskState(TypedDict):
    # add_messages reducer: 追加消息,不覆盖历史
    messages: Annotated[list, add_messages]
    
    # operator.add reducer: 累加重试次数
    retry_count: Annotated[int, operator.add]
    
    # LastValue reducer (默认): 直接覆盖更新
    current_step: str
    
    # 自定义Reducer示例
    aggregated_result: Annotated[list, lambda x, y: x + [y]]  # 追加单个元素

# 节点更新示例
def task_node(state: TaskState):
    # 每次执行累加1(通过operator.add reducer)
    return {
        "retry_count": 1,  # 实际会累加到现有值
        "current_step": "processing",
        "aggregated_result": "新结果"  # 追加到列表
    }

最佳实践:如果需要数据校验(Validation),请将其放入Middleware或Tool的定义中,而不是放在全局State里。保持State的纯粹性,让Reducer逻辑简单可预测。

3.9 流式输出(Streaming)的增强

Agent的响应速度往往较慢,因此流式输出是提升用户体验的关键。LangGraph 1.0对stream方法进行了精细化控制。

# 三种stream_mode对比
# 1. values: 每次状态更新时,流式返回完整的State
async for chunk in graph.astream(inputs, config=config, stream_mode="values"):
    print(f"完整状态: {chunk}")

# 2. updates: 仅流式返回增量更新的部分
async for chunk in graph.astream(inputs, config=config, stream_mode="updates"):
    print(f"状态更新: {chunk}")  # 只打印变化的字段

# 3. messages: 专门用于流式传输LLM的Token(打字机效果)
async for event in graph.astream_events(inputs, config=config, version="v1"):
    kind = event["event"]
    if kind == "on_chat_model_stream":
        token = event["data"]["chunk"].content
        print(token, end="|", flush=True)
    elif kind == "on_chain_end":
        print(f"\n[Node完成]: {event['name']}")

3.10 与主流Agent框架的差异化对比

3.10.1 LangGraph vs LangChain

维度 LangChain LangGraph
抽象级别 高级(Chain抽象) 低级(图结构)
状态管理 开发者自行实现 内置State + Reducer
持久化 无内置 Checkpoint原生支持
故障恢复 断点续传
Human-in-loop 有限支持 interrupt原生支持
适用场景 快速原型验证 生产级系统

3.10.2 LangGraph vs CrewAI

维度 CrewAI LangGraph
核心范式 角色驱动(Role-based) 状态驱动(State-based)
思维模式 "谁做什么" "何时发生什么"
执行流程 抽象化(框架处理) 显式化(开发者定义)
上手难度 低(配置式) 高(图论基础)
条件分支 受限 原生支持
故障恢复 无内置 Checkpoint持久化
人类介入 基础(human_input) 原生(interrupt)
适用场景 内容生成、快速原型 生产系统、复杂流程

选型建议


四、相关链接

  1. LangGraph 1.0 深度解读:生产级 Agent 的里程碑 - 掘金
  2. LangGraph核心总结,构建可靠可控AI Agent的新范式 - CSDN
  3. LangChain官网
  4. LangGraph官方文档
  5. DeepLearning.AI - AI Agents in LangGraph

💭 五、思考与实践

5.1 对看宝AI项目的启发

基于LangGraph 1.0的学习,我对看宝AI项目有了新的架构思考:

┌─────────────────────────────────────────────────────────────┐
│                     看宝AI LangGraph架构                      │
├─────────────────────────────────────────────────────────────┤
│  State (状态)                                                │
│  ├─ messages: Annotated[list, add_messages]                │
│  ├─ user_context: dict  # 用户偏好、历史                      │
│  ├─ session_memory: list  # 当前会话上下文                    │
│  ├─ pending_approval: dict | None  # 待审批操作              │
│  └─ task_state: Literal["understand", "respond", "review"] │
├─────────────────────────────────────────────────────────────┤
│  Nodes (节点)                                                │
│  ├─ understand_node: 理解用户意图和情感                        │
│  ├─ retrieve_knowledge: RAG知识检索                          │
│  ├─ plan_response: 规划响应策略                              │
│  ├─ generate_response: 生成最终响应                          │
│  ├─ safety_check: 安全检查                                   │
│  └─ human_review: 人工审批(如有敏感内容)                    │
├─────────────────────────────────────────────────────────────┤
│  Middleware                                                 │
│  ├─ ContextSummarizeMiddleware: 长对话自动摘要               │
│  ├─ PIIFilterMiddleware: 敏感信息过滤                        │
│  └─ LoggingMiddleware: 全链路日志                            │
└─────────────────────────────────────────────────────────────┘

5.2 迁移计划建议

对于已有的LangGraph 0.x项目,迁移到1.0的建议步骤:

  1. 状态定义迁移:将Pydantic Model改为TypedDict
  2. Checkpointer添加:为所有图添加MemorySaver或SQLiteSaver
  3. thread_id设计:为每个用户会话设计唯一的thread_id策略
  4. interrupt集成:识别高风险操作节点,添加interrupt
  5. Middleware抽象:将横切逻辑从Node移到Middleware

5.3 未来展望

LangGraph 1.0的发布预示着几个重要趋势:

  1. Agent工程化:从"能跑就行"到"生产可用",这是所有技术成熟的必经之路
  2. 人机协同标配:AI不能脱离人类控制,HITL将成为Agent的标准能力
  3. 持久化成基础:断点续传、时间旅行将从"高级特性"变成"基础要求"
  4. 中间件生态:类似Web开发,Agent中间件生态将蓬勃发展

5.4 立即行动的3件事

  1. 升级依赖:将langgraph升级到1.0版本,体验新特性
  2. 添加Checkpointer:为现有Agent添加持久化支持
  3. 设计审批流:识别需要人工介入的操作,用interrupt实现

学习完成时间:2026-04-13
下一步:结合LangGraph 1.0重写看宝AI的核心对话逻辑,添加持久化和人机协同能力
核心理念:从"玩具"到"工具",LangGraph 1.0是AI Agent工程化的重要里程碑