Skip to content

第 2 章 环境搭建与最小示例 ​

2.1 Python 环境准备 ​

LangGraph 1.2.x 要求 Python ≥ 3.9,推荐 3.11 或 3.12(类型注解性能、asyncio 调度在该区间表现稳定)。环境隔离有三种常见方式:

uv(推荐):uv 是高性能 Python 包管理器,创建虚拟环境与解析依赖速度显著快于 pip。

bash
# 安装 uv(参考官方文档获取最新安装命令)
curl -LsSf https://astral.sh/uv/install.sh | sh
# 创建项目目录与虚拟环境
mkdir langgraph-handbook && cd langgraph-handbook
uv venv --python 3.11
source .venv/bin/activate  # Windows 使用 .venv\Scripts\activate

pip + venv:Python 自带方式,无需额外安装。

bash
python3.11 -m venv .venv
source .venv/bin/activate
pip install --upgrade pip

conda:适用于已有 conda 生态的数据/科研环境。

bash
conda create -n langgraph python=3.11
conda activate langgraph

最佳实践:项目根目录使用 .python-version(pyenv/uv 识别)锁定解释器版本;依赖通过 pyproject.toml 声明,避免在全局环境安装包。

2.2 核心依赖安装 ​

最小可运行集合包含四个包:

bash
# 使用 uv
uv add langgraph==1.2.* langchain-core langchain-openai python-dotenv
# 或使用 pip
pip install "langgraph~=1.2.0" langchain-core langchain-openai python-dotenv

可选的 Checkpoint 持久化后端(第 8 章详述):

bash
uv add langgraph-checkpoint-sqlite   # 本地文件,开发调试用
uv add langgraph-checkpoint-postgres # 生产推荐

版本说明:langgraph 与 langchain-core 的版本需保持同一发布周期,避免 Pydantic/Runnable 接口不兼容。建议在 pyproject.toml 中对 langgraph 使用 ~=1.2.0 兼容限定。

2.3 API Key 管理 ​

严禁在源码中硬编码 API Key。推荐使用 .env 文件 + python-dotenv:

bash
# .env(加入 .gitignore)
OPENAI_API_KEY=sk-...
# 可选:LangSmith 追踪
LANGSMITH_API_KEY=lsv2_...
LANGSMITH_TRACING=true

在代码入口处加载:

python
from dotenv import load_dotenv
load_dotenv()  # 会读取项目根目录下的 .env,将变量注入 os.environ

2.4 最小可运行示例:笑话生成器 ​

以下示例构建一个两节点 + 条件边 + 循环的图:先生成一个笑话,再由"评委"判断是否好笑;若不好笑则回到生成节点重写,最多 3 次。

python
from typing import TypedDict, Annotated
import operator
from dotenv import load_dotenv
from langgraph.graph import StateGraph, START, END
from langgraph.graph.message import add_messages
from langchain_openai import ChatOpenAI

load_dotenv()

# 1. 定义状态:messages 使用 add_messages reducer(按 id 合并消息列表)
class JokeState(TypedDict):
    messages: Annotated[list, add_messages]
    topic: str
    attempts: int

# 2. 初始化模型
llm = ChatOpenAI(model="gpt-4o-mini", temperature=0.7)

# 3. 定义节点
def generate_joke(state: JokeState) -> dict:
    """根据话题生成或重写一个笑话。"""
    prompt = (
        f"你是一个单口喜剧编剧。围绕话题「{state['topic']}」写一个简短中文笑话。"
        f"当前是第 {state['attempts'] + 1} 次尝试。"
    )
    if state["messages"]:
        prompt += " 上一版被评价为不好笑,请换一个角度重写。"
    resp = llm.invoke(prompt)
    # 返回增量:追加一条 AI 消息,attempts 计数加 1
    return {"messages": [resp], "attempts": state["attempts"] + 1}

def judge_joke(state: JokeState) -> dict:
    """评委:不更新 messages,只返回评价结果。"""
    last_joke = state["messages"][-1].content
    judge_prompt = (
        "你是严格的喜剧评委。请只回复一个词:"
        "如果笑话好笑,回复 FUNNY;不好笑回复 NOT_FUNNY。\n"
        f"笑话:{last_joke}"
    )
    verdict = llm.invoke(judge_prompt).content.strip()
    return {"verdict": verdict}

# 4. 条件路由
def route_after_judge(state: JokeState) -> str:
    if state.get("verdict") == "FUNNY":
        return END
    if state["attempts"] >= 3:
        return END  # 达到上限,结束
    return "generate_joke"

# 5. 构图
builder = StateGraph(JokeState)
builder.add_node("generate_joke", generate_joke)
builder.add_node("judge_joke", judge_joke)
builder.add_edge(START, "generate_joke")
builder.add_edge("generate_joke", "judge_joke")
builder.add_conditional_edges("judge_joke", route_after_judge)

graph = builder.compile()

# 6. 调用
if __name__ == "__main__":
    result = graph.invoke({"topic": "程序员", "attempts": 0, "messages": []})
    print("最终笑话:", result["messages"][-1].content)
    print("尝试次数:", result["attempts"])

invoke 的执行过程:START → generate_joke → judge_joke →(条件路由)→ 若 NOT_FUNNY 且 attempts < 3,则回到 generate_joke 开启下一轮 Superstep;若 FUNNY 或达到上限则走到 END。

2.5 图可视化与交互式调试 ​

编译后的图可导出为 Mermaid 或 PNG,便于快速检查结构:

python
from IPython.display import Image, display

# 输出 Mermaid 源码文本
mermaid_src = graph.get_graph().draw_mermaid()
print(mermaid_src)

# 渲染为 PNG(需要额外安装:pip install pygraphviz 或使用 mermaid.ink)
png_bytes = graph.get_graph().draw_mermaid_png()
display(Image(png_bytes))

LangGraph Studio 是官方提供的本地可视化调试 UI,通过 langgraph-cli 启动:

bash
# 安装 CLI
pip install langgraph-cli
# 在项目根目录启动(需要存在 langgraph.json 配置文件)
langgraph dev

启动后浏览器打开默认地址,可看到图结构、线程列表、每一步 State 快照、可手动触发 interrupt 恢复等,适合调试复杂循环。

2.6 IDE 配置建议 ​

VS Code 用户建议开启以下配置:

  • 安装 Pylance 插件,并将 python.analysis.typeCheckingMode 设为 "basic" 或 "strict",State Schema 的类型错误可在编写期被捕获;
  • 安装 Python、Mypy Type Checker 插件,对 reducer 函数签名做静态检查;
  • 在 .vscode/settings.json 中指定解释器路径为项目 .venv/bin/python,避免导包错配。

本章小结 ​

环境搭建分三步:准备 3.11+ 的隔离环境、安装 langgraph~=1.2.0 等核心依赖、通过 .env 注入密钥。最小示例展示了 StateGraph 的标准五要素:State Schema 定义、节点函数、边与条件边、compile、invoke。Mermaid 可视化与 LangGraph Studio 分别服务于静态结构审查与动态单步调试。

常见错误 ​

  1. API Key 未配置。现象:调用时报 AuthenticationError 或环境变量读取为空。原因:未创建 .env,或 load_dotenv() 在导入模型之后才调用。修复:在入口文件最顶部调用 load_dotenv(),并确认 .env 位于工作目录。
  2. 模型名错误。现象:NotFoundError: The model ... does not exist。原因:拼写错误或使用了部署不可见的模型名。修复:核对提供商控制台中的模型 ID,Azure OpenAI 需额外传 deployment_name。
  3. Python 版本不兼容。现象:SyntaxError 或 Pydantic v2 校验异常。原因:解释器版本 < 3.9。修复:python --version 确认版本,必要时重建虚拟环境。
  4. 缺少类型注解导致 reducer 报错。现象:编译期或运行期抛出 InvalidUpdateError。原因:TypedDict 字段未使用 Annotated[..., reducer] 却在多节点写入同字段。修复:对需要合并的字段显式声明 reducer(见第 4 章)。

生产建议 ​

  • 使用 uv 管理依赖与锁文件(uv.lock),将 .python-version 与 pyproject.toml 一同提交代码库;
  • .env 加入 .gitignore,部署时通过平台环境变量或 Secret Manager 注入密钥;
  • 开发期始终保持 LANGSMITH_TRACING=true,每条 trace 可对应到一次完整的图调用;
  • 团队内统一使用 VS Code + Pylance 的 basic 模式类型检查,在 CI 中追加 mypy 检查 State Schema 相关代码。