第 27 期 | 生产级利器:LangGraph Cloud 初体验

更新于 2026/4/17

手写后端太累?官方一键托管平台的配置使用解析与 CRON 计划定期的引入。

欢迎回来,各位未来的 AI 架构师们!我是你们的导师。

在前面的 26 期里,我们的「AI 万能内容创作机构 (AI Content Agency)」已经具备了极其强大的能力。我们的 Planner 运筹帷幄,Researcher 掘地三尺,Writer 妙笔生花,Editor 铁面无私。

但是,不知道你们有没有发现一个让人头疼的问题? 每次我们要运行这个庞大的多智能体系统,都要在本地终端里跑脚本;或者,为了把它做成一个服务,你们中有些人可能已经开始手搓 FastAPI 或者 Express 后端了。

手搓后端痛苦吗?太痛苦了! 你要处理 WebSocket 以支持流式输出(Streaming),你要自己配置 PostgreSQL 来存储 Checkpoint(记忆),你要处理长连接超时(多智能体跑个 5 分钟很正常,普通的 HTTP 请求早断了),你还要自己写定时任务来触发流程……

作为一名有 10 年经验的老兵,我今天必须敲黑板提醒大家:不要在非核心业务上重复造轮子! 你的核心价值是设计牛逼的 Agent 工作流,而不是去搞定那些繁琐的基础设施。

今天,我们将引入真正的生产级利器——LangGraph Cloud。我们将把咱们的内容机构整体搬上云端,并利用它的 CRON 功能,给我们的 Planner 加上“每周一早晨自动开早会安排选题”的自动化能力!


🎯 本期学习目标

  1. 破除基建迷思:理解为什么多智能体应用的后端架构与传统 Web 后端不同,以及 LangGraph Cloud 解决了什么痛点。
  2. 掌握核心配置:学会编写 langgraph.json,这是将本地 Graph 转化为云端微服务的“魔法阵”。
  3. 云端 API 交互:使用 LangGraph SDK 与托管的 Agency 交互,体验无缝的流式响应。
  4. 引入 CRON 定时任务:实战配置定时触发器,让我们的 AI 内容机构实现真正的“无人值守,定期产出”。

📖 原理解析

为什么多智能体应用不能简单地套用传统的 HTTP API 模型?

传统的 API 是同步且短寿的:请求进来 -> 查数据库 -> 返回结果,通常在几百毫秒内完成。 但我们的 AI Content Agency 是异步且长寿的:Planner 思考 -> Researcher 搜索网页 -> Writer 写初稿 -> Editor 打回重写…… 这个过程可能长达几分钟,甚至需要等待人类确认(Human-in-the-loop)。

如果你用传统的后端,浏览器早就报 504 Gateway Timeout 了。

LangGraph Cloud 的底层逻辑,是将你的 Graph 包装成一个基于事件驱动的异步任务队列(Task Queue)系统,并自带状态持久化(State Persistence)。

来看看下面这张架构图,看看我们的 Agency 上云后是如何运转的:

sequenceDiagram
    participant Timer as ⏰ CRON 定时器 (每周一 9:00)
    participant Client as 💻 客户端 / LangGraph SDK
    participant Cloud as ☁️ LangGraph Cloud (API Gateway)
    participant Worker as ⚙️ Graph Worker (后台计算)
    participant DB as 🗄️ Checkpoint DB (内置持久化)

    Timer->>Cloud: 触发定时任务: POST /threads/{id}/runs
    Note over Timer, Cloud: 携带 Payload: "开始撰写本周 AI 科技周报"
    
    Client->>Cloud: 手动触发: POST /threads/{id}/runs
    
    Cloud->>DB: 创建新 Run 记录 & 初始化 State
    Cloud-->>Client: 返回 Run ID (HTTP 202 Accepted)
    
    Cloud->>Worker: 将任务推入异步队列
    
    rect rgb(240, 248, 255)
    Note over Worker, DB: AI Content Agency 内部流转
    Worker->>DB: Planner 节点执行完毕,保存 State
    Worker->>DB: Researcher 节点执行完毕,保存 State
    Worker->>DB: Writer 节点执行完毕,保存 State
    Worker->>DB: Editor 节点执行完毕,保存 State
    end
    
    Worker->>DB: 标记 Run 为 Completed
    
    Client->>Cloud: GET /threads/{id}/runs/{run_id}/stream
    Cloud-->>Client: (SSE) 持续推送 Server-Sent Events 直至结束

图解核心概念:

  1. Thread (线程):代表一次对话或一个任务流的上下文。
  2. Run (运行):在特定 Thread 上执行一次 Graph 的过程。它是异步的。
  3. CRON (定时任务):LangGraph Cloud 原生支持的触发器,可以定期向指定的 Thread 发起新的 Run。
  4. Worker & DB:云端自动帮你扩展计算资源(Worker)并管理 Checkpoint 数据库(DB),你完全不需要写 SQL。

💻 实战代码演练

接下来,我们将把咱们的 AI Content Agency 部署配置好,并写一个脚本来设定定时任务。

Step 1: 准备项目结构与核心 Graph

假设我们现有的项目结构如下:

ai_content_agency/
├── agent/
│   ├── __init__.py
│   ├── graph.py       # 我们的核心 Graph 定义
│   ├── nodes.py       # Planner, Researcher 等节点逻辑
│   └── state.py       # AgencyState 定义
├── requirements.txt
├── .env
└── langgraph.json     # 🌟 今天的重点!

为了演示完整性,我们先快速看一眼 agent/graph.py 里的抛出接口(这是前几期我们已经写好的):

# agent/graph.py
from langgraph.graph import StateGraph, START, END
from agent.state import AgencyState
from agent.nodes import planner_node, researcher_node, writer_node, editor_node

# 1. 初始化图 / Initialize the graph
builder = StateGraph(AgencyState)

# 2. 添加节点 / Add nodes
builder.add_node("planner", planner_node)
builder.add_node("researcher", researcher_node)
builder.add_node("writer", writer_node)
builder.add_node("editor", editor_node)

# 3. 定义边 (简化版流转) / Define edges (simplified flow)
builder.add_edge(START, "planner")
builder.add_edge("planner", "researcher")
builder.add_edge("researcher", "writer")
builder.add_edge("writer", "editor")
builder.add_edge("editor", END)

# 4. 编译图!注意,这里不需要我们自己传 checkpointer 了!
# LangGraph Cloud 会在运行时自动注入分布式的 checkpointer。
# Compile the graph! Note: We don't need to pass a checkpointer here.
# LangGraph Cloud automatically injects a distributed checkpointer at runtime.
agency_graph = builder.compile()

Step 2: 编写魔法配置文件 langgraph.json

这是 LangGraph Cloud 识别你项目的唯一凭证。它告诉云平台:“我的环境是什么,我的 Graph 在哪里”。

在根目录下创建 langgraph.json

{
  "dependencies": ["."],
  "graphs": {
    "agency_graph": "./agent/graph.py:agency_graph"
  },
  "env": ".env",
  "python_version": "3.11"
}

讲师锐评:就这么简单。"graphs" 字典里的 key 是你在云端 API 调用的名字,value 是 文件路径:变量名。不要再花两百行代码去写 FastAPI 的路由了,这四行 JSON 直接帮你生成了全套的 RESTful API 和 Streaming 接口!

Step 3: 引入 CRON 定时任务 (使用 LangGraph SDK)

现在,我们的代码已经推送到 LangGraph Cloud(或通过 LangGraph Studio 本地运行)。 我们的业务需求是:让 Planner 每周一上午 9 点,自动启动本周的《AI 科技前沿周报》的创作。

我们将使用 Python 的 langgraph-sdk 来配置这个 CRON 任务。你可以在你本地的任何管理脚本中运行这段代码。

首先安装 SDK:

pip install langgraph-sdk

然后编写 setup_cron.py

# setup_cron.py
import asyncio
from langgraph_sdk import get_client

async def setup_weekly_newsletter():
    # 1. 初始化客户端 / Initialize the client
    # 在生产环境中,URL 会是 LangGraph Cloud 提供的地址
    # In production, the URL will be the one provided by LangGraph Cloud
    client = get_client(url="http://localhost:8123") # 本地 Studio 默认端口

    # 2. 创建一个持久化的 Thread / Create a persistent Thread
    # 这个 Thread 将专门用于存放"每周科技周报"的上下文
    # This Thread will be dedicated to the context of the "Weekly Tech Newsletter"
    thread = await client.threads.create()
    print(f"✅ 成功创建专属 Thread ID: {thread['thread_id']}")

    # 3. 定义 CRON 表达式 / Define the CRON expression
    # "0 9 * * 1" 表示每周一上午 9:00 (服务器时间, 通常为 UTC)
    # "0 9 * * 1" means every Monday at 9:00 AM (Server time, usually UTC)
    cron_expression = "0 9 * * 1"

    # 4. 定义触发时传递给 Graph 的输入 / Define the input passed to the Graph upon trigger
    payload = {
        "messages": [
            {
                "role": "user", 
                "content": "请 Planner 开始规划本周的《AI科技前沿周报》,重点关注大模型架构演进和开源生态。"
            }
        ]
    }

    # 5. 创建 CRON 任务 / Create the CRON job
    try:
        cron_job = await client.crons.create(
            thread_id=thread["thread_id"],
            assistant_id="agency_graph", # 对应 langgraph.json 中的 key
            schedule=cron_expression,
            input=payload
        )
        print(f"🚀 CRON 定时任务设置成功!Job ID: {cron_job['cron_id']}")
        print(f"⏰ 调度规则: {cron_job['schedule']}")
        
    except Exception as e:
        print(f"❌ 设置失败: {e}")

# 运行异步脚本
if __name__ == "__main__":
    asyncio.run(setup_weekly_newsletter())

代码深入剖析: 你看,传统的定时任务(比如 Celery Beat),你需要自己维护一套消息队列。而在 LangGraph Cloud 中,client.crons.create 直接把时间触发器特定的 Thread 上下文绑定在了一起。 这意味着,每周一生成的周报,都会累积在这个 Thread 的记忆中!如果 Planner 需要参考上周写了什么,它天然就能在这个 Thread 的历史记录里找到。这就是状态持久化基建的降维打击!


坑与避坑指南

作为你们的导师,我不仅要教你们怎么跑通,还要告诉你们在生产环境中会踩什么坑。以下是我用发际线换来的血泪教训:

💣 坑一:环境变量的“裸奔”与丢失

在本地跑的时候,你的 .env 文件随时起效。但上云之后,很多人忘记在 LangGraph Cloud 的控制台里配置 Secrets。 避坑langgraph.json 中的 "env": ".env" 主要是给本地 LangGraph Studio 用的。在云端生产环境,必须在项目设置的 "Environment Variables" 面板里手动填入 OPENAI_API_KEYTAVILY_API_KEY 等关键密钥,否则你的 Graph 一启动就会因为鉴权失败而崩溃。

💣 坑二:CRON 时区的时差陷阱

你在代码里写了 "0 9 * * 1",满心欢喜等周一早上 9 点发周报,结果到了下午 5 点才发出来。为什么? 避坑:LangGraph Cloud 的 CRON 调度器默认使用的是 UTC 时间!北京时间是 UTC+8。如果你想在设定北京时间周一早上 9:00 执行,你的 CRON 表达式应该减去 8 小时,即 UTC 的周一凌晨 1:00,对应的表达式应为 "0 1 * * 1"。切记!

💣 坑三:依赖包版本的“幽灵冲突”

LangGraph Cloud 构建镜像时,会读取你目录下的 requirements.txtpyproject.toml。如果你本地没有锁定版本(比如只写了 langchain),云端可能会拉取到带有破坏性更新的最新版。 避坑:永远使用精确的版本号!在推上云端前,执行 pip freeze > requirements.txt,确保云端构建的环境与你本地测试的环境 100% 一致。

💣 坑四:死循环导致破产 (Recursion Limit)

虽然云端帮你管理了异步任务,但如果你的 Editor 和 Writer 因为互相看不顺眼,陷入了无限的“打回-重写”死循环,云端资源会被持续消耗,你的 API 账单会爆炸。 避坑:在调用云端 API 或设置 CRON 时,可以通过 config 参数强制设定 recursion_limit。比如限制最多流转 20 步强制终止。

# 在 CRON 中加入 config 限制
cron_job = await client.crons.create(
    ...
    config={"recursion_limit": 20} 
)

📝 本期小结

同学们,今天这节课是我们架构演进的一个重要分水岭。

在此之前,我们是在“做玩具”——所有的 Agent 挤在我们本地电脑的内存里,一关终端就灰飞烟灭。 而今天之后,我们在“做产品”——借助 LangGraph Cloud,我们用极简的 langgraph.json 彻底摆脱了手搓后端的泥潭;我们利用内置的持久化数据库和异步队列,保证了长耗时多智能体任务的稳定运行;我们更通过 CRON 定时任务,让我们的 AI Content Agency 拥有了自驱力,成为了一台真正 24/7 运转的自动化内容机器。

“不要用战术上的勤奋,掩盖战略上的懒惰。” 别再花时间去调教 WebSocket 和数据库连接池了,把精力放在优化你的 Agent Prompt 和 Graph 逻辑上吧!

下期预告:既然我们的 Agency 已经上云并开始自动跑任务了,万一 Writer 胡说八道怎么办?难道直接发出去吗?第 28 期,我们将探索云端架构下的 Human-in-the-loop (人类循环干预),教你如何在云端截停任务,人工审批后再继续!

下课!我们下期见!