完整代码

# 第一步:导入需要的包
import os  # 读取环境变量
from langchain_openai import ChatOpenAI  # OpenAI兼容接口的LLM封装
from langgraph.graph import StateGraph, START, END  # LangGraph核心类
from typing import TypedDict  # 类型定义,用于定义`State`

# 第2步:定义(图的状态)
# State 是 LangGraph 的灵魂—所有节点共享这个状态,通过读写状态传递信息
# 我们这个简单的问答机器人,状态里就两个东西:用户问题和 AI 回答
class State(TypedDict):
    """图的状态定义"""
    user_input: str  # 用户输入的问题
    response: str    # AI 的回答

# 第3步:初始化 LLM 模型
# 从环境变量中读取模型名、API Key 和 base_url
# 注意:百炼云用的是 OpenAI 兼容接口,所以用 ChatOpenAI 类
llm = ChatOpenAI(
    model="deepseek-v4-pro",
    api_key=os.getenv("DATA_API_KEY"),
    base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
    temperature=0.7,  # 温度参数:0=最确定,1=最随机,0.7 是比较均衡的值
)

# 第4步:定义节点函数
# 每个节点都是一个函数,输入是 state,输出是更新后的 state
def chat_node(state: State) -> State:
    """
    聊天节点:接收用户问题,调用 LLM,返回回答
    Args:
        state: 当前图的状态,包含 user_input
    Returns:
        更新后的状态,新增 response 字段
    """
    # 从状态中获取用户输入
    user_input = state["user_input"]

    # 调用大模型
    response = llm.invoke(user_input)

    # 返回新的状态(只返回更新了的字段,LangGraph 会自动合并)
    return {"response": response.content}

# 第5步:构建图
# 1. 创建 StateGraph 实例,传入我们定义的 State 类型
builder = StateGraph(State)

# 2. 添加节点:节点名 + 节点函数
builder.add_node("chat", chat_node)

# 3. 添加边:连接节点
# START -> chat: 程序从 START 开始,进入 chat 节点
builder.add_edge(START, "chat")
# chat -> END: chat 节点执行完,程序结束
builder.add_edge("chat", END)

# 第6步:编译图
# 编译做了三件事:拓扑校验、生成执行计划、初始化状态空间
graph = builder.compile()

# 第7步:运行图
# 这是 Python 的标准写法,确保只有直接运行这个文件时才执行下面的代码
if __name__ == "__main__":
    # 用户输入的问题
    user_question = "介绍一下你自己。"

    # 调用图,传入初始状态
    # invoke() 会一次性跑完整个图,返回最终状态
    result = graph.invoke({"user_input": user_question})

    # 打印结果
    print("=" * 50)
    print(f"你问: {user_question}")
    print("-" * 50)
    print(f"AI 回答: {result['response']}")
    print("=" * 50)

代码分步解析

1. 导入依赖

引入环境变量、LangGraph 图组件、TypedDict状态类型、兼容 OpenAI 的 ChatOpenAI 封装。 安装依赖命令:

pip install langgraph langchain-openai

2. 定义 State 状态

LangGraph依靠State在各个节点之间传递数据。这里State包含两个字段:

  • user_input:用户原始提问
  • response:大模型返回的回答

State 是所有节点共享的全局容器,节点只需要返回需要更新的字段,LangGraph 自动合并。

3. 初始化 LLM

使用阿里云百炼 Dashscope 的 OpenAI 兼容接口,通过环境变量读取 API 密钥,避免硬编码泄露密钥。temperature=0.7兼顾回答的创造性与稳定性。

4. 节点函数 chat_node

LangGraph 里节点本质就是 Python,入参是当前 State,返回需要更新的 State 字典。

  • 读取 state 里的user_input
  • 调用 LLM 获取回答
  • 返回{"response": 回答文本},LangGraph 自动合并进状态

5. 构建图

  1. 实例化StateGraph,绑定我们定义的State
  2. add_node:注册节点,绑定名称和处理函数
  3. add_edge:定义流转路径:START入口 → chat 节点 → END结束

6. compile 编译图

编译会自动校验图的拓扑结构,生成执行计划,完成图的初始化。

7. invoke 执行图

调用graph.invoke(),传入初始状态{"user_input":用户问题},一次性完整跑完整个图,拿到最终状态并打印输出。

整体执行流程

START(入口) → chat节点(调用LLM生成回答,写入state.response) → END(结束)

整个流程是单节点线性图,没有分支、循环,是 LangGraph 最小可用 demo。

小结

  • State:图的共享内存,节点之间传递数据的载体
  • Node:业务逻辑单元,就是普通 Python 函数
  • Edge:控制节点流转路径
  • invoke:触发图运行

拓展:后续可以增加条件边、多节点、工具调用,实现可以自主调用工具的 Agent。

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐