langgraph笔记

文章目录

相比于langchain,定制程度更高,按步骤来的。

机制

1、初始化 # builder = StateGraph(AgentState)

2、添加点

3、添加边

4、编译

5、运行 # app.stream()

核心代码是哪些?

AgentState相当于一个共享对象。

python 复制代码
class AgentState(TypedDict):
    messages: Annotated[List[str], operator.add]
    final_answer: str

加入点和边(edge),这样就形成了图。

python 复制代码
builder = StateGraph(AgentState)

# 添加节点
builder.add_node("ai_engine", llm_node)
builder.add_node("human_gate", human_review)

# 定义流程:开始 -> AI -> 人工 -> 结束
builder.add_edge(START, "ai_engine")
builder.add_edge("ai_engine", "human_gate")
builder.add_edge("human_gate", END)

app = builder.compile()
基础示例1

代码:

python 复制代码
import operator
from typing import Annotated, List, TypedDict
from langgraph.graph import StateGraph, START, END


# ==========================================
# 1. 定义状态 (State)
# ==========================================
# 这是整个工作流的"记忆",所有节点都共享这个状态
class AgentState(TypedDict):
    messages: Annotated[List[str], operator.add]  # 消息列表,operator.add 表示新消息会追加到列表
    translation: str  # 存放翻译结果


# ==========================================
# 2. 定义节点 (Nodes)
# ==========================================

def ai_translate(state: AgentState):
    """模拟 AI 翻译节点"""
    print(f"🤖 AI 正在思考: {state['messages'][-1]} ...")

    # 这里模拟一个简单的翻译逻辑(实际项目中你会在这里调用 LLM)
    last_msg = state['messages'][-1]
    if "你好" in last_msg:
        translated = "Hello, how are you doing?"
    else:
        translated = f"Translation of: {last_msg}"

    print(f"🤖 AI 翻译完成: {translated}")

    # 更新状态
    return {
        "messages": ["AI 已生成翻译"],
        "translation": translated
    }


def human_review(state: AgentState):
    """模拟人工审核节点"""
    print("\n--- ⏸️ 暂停:等待人工审核 ---")
    print(f"当前翻译结果是:【 {state['translation']} 】")

    # 在实际应用中,这里会挂起等待 API 回调
    # 这里为了演示,我们直接模拟用户说 "通过"
    print("👤 人类:看起来没问题,通过!(模拟自动通过)")

    return {"messages": ["人类已审核通过"]}


# ==========================================
# 3. 构建图 (Build Graph)
# ==========================================

# 初始化构建器
builder = StateGraph(AgentState)

# 添加节点
builder.add_node("translator", ai_translate)
builder.add_node("reviewer", human_review)

# 定义边(流程控制)
# 流程:开始 -> 翻译 -> 审核 -> 结束
builder.add_edge(START, "translator")
builder.add_edge("translator", "reviewer")
builder.add_edge("reviewer", END)

# 编译成可执行的图
app = builder.compile()

# ==========================================
# 4. 运行
# ==========================================
if __name__ == "__main__":
    print("🚀 启动 LangGraph 工作流...\n")

    # 初始输入
    inputs = {"messages": ["你好"], "translation": ""}

    # 调用 invoke 开始运行
    # stream 模式可以看到每一步的状态变化
    for output in app.stream(inputs):
        # output 是一个字典,key 是节点名,value 是该节点返回的状态更新
        for key, value in output.items():
            print(f"✅ 节点 [{key}] 执行完毕,返回: {value}")

    print("\n🎉 流程结束!")
    print(f"最终结果: {value.get('translation')}")
基础示例2-加入了大模型

代码:

python 复制代码
import torch
from transformers import AutoModelForCausalLM, AutoTokenizer
from langgraph.graph import StateGraph, START, END
from typing import Annotated, List, TypedDict
import operator

# ==========================================
# 1. 加载本地模型 (Qwen2.5-0.5B)
# ==========================================
print("⏳ 正在加载本地模型 (首次运行需下载)...")
model_name = "Qwen/Qwen2.5-0.5B-Instruct"

# 自动检测是否有 GPU
device = "cuda" if torch.cuda.is_available() else "cpu"
print(f"🚀 使用设备: {device}")

tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForCausalLM.from_pretrained(
    model_name,
    torch_dtype=torch.float16 if device == "cuda" else torch.float32,  # 显卡用半精度,CPU用单精度
    device_map="auto"
)


# ==========================================
# 2. 定义 LangGraph 状态
# ==========================================
class AgentState(TypedDict):
    messages: Annotated[List[str], operator.add]
    final_answer: str


# ==========================================
# 3. 定义节点
# ==========================================

def llm_node(state: AgentState):
    """调用本地 Qwen 模型进行推理"""
    user_input = state['messages'][-1]
    print(f"🤖 [LLM] 收到输入: {user_input}")

    # 构造 Qwen 的对话提示词格式
    messages = [
        {"role": "system", "content": "你是一个聪明的助手,请简短回答问题。"},
        {"role": "user", "content": user_input}
    ]

    # 应用聊天模板
    text = tokenizer.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)
    model_inputs = tokenizer([text], return_tensors="pt").to(device)

    # 生成回答
    generated_ids = model.generate(
        model_inputs.input_ids,
        max_new_tokens=512,
        do_sample=True,
        temperature=0.7
    )

    # 解码输出
    generated_ids = [
        output_ids[len(input_ids):] for input_ids, output_ids in zip(model_inputs.input_ids, generated_ids)
    ]
    response = tokenizer.batch_decode(generated_ids, skip_special_tokens=True)[0]

    print(f"🤖 [LLM] 回答: {response}")
    return {"messages": ["AI已回复"], "final_answer": response}


def human_review(state: AgentState):
    """人工审核节点"""
    print("\n--- ⏸️ 暂停:等待人工审核 ---")
    print(f"👀 AI 生成的回答是:【 {state['final_answer']} 】")

    # 模拟人工确认
    confirm = input("👤 是否满意?(输入 y 继续,其他退出): ")
    if confirm.lower() == 'y':
        return {"messages": ["用户确认通过"]}
    else:
        print("❌ 用户拒绝,流程终止。")
        # 这里简单处理,实际可以跳转到重写节点
        exit()


# ==========================================
# 4. 构建并运行图
# ==========================================
builder = StateGraph(AgentState)

# 添加节点
builder.add_node("ai_engine", llm_node)
builder.add_node("human_gate", human_review)

# 定义流程:开始 -> AI -> 人工 -> 结束
builder.add_edge(START, "ai_engine")
builder.add_edge("ai_engine", "human_gate")
builder.add_edge("human_gate", END)

app = builder.compile()

if __name__ == "__main__":
    print("\n🚀 === LangGraph + Qwen 本地智能体启动 ===\n")
    while True:
        query = input("👤 请输入问题 (输入 'quit' 退出): ")
        if query == 'quit': break

        inputs = {"messages": [query], "final_answer": ""}

        # 运行工作流
        for output in app.stream(inputs):
            for node_name, values in output.items():
                if values.get('final_answer'):
                    print(f"✅ 最终结果: {values['final_answer']}")
        print("-" * 30)
为什么叫边不叫线?

点和边是图中两个核心概念。

之所以不叫线,是因为线是没有方向的,但是边有方向(图概念里面的边和平行四边形的边可不一样)。

相关推荐
xiami_world2 小时前
AI Agent生成PPT技术解析:从一键生成到意图理解,Agent模式如何重构PPT工作流?
人工智能·经验分享·ai·信息可视化·powerpoint
切糕师学AI2 小时前
PostgreSQL 中的 pg_trgm GIN 索引详解
数据库·postgresql·gin·索引·pg_grgm
我是胡杨学长2 小时前
ChatGPT 连续三月流量下滑,是热度凉了还是 AI 泡沫要来了?
人工智能·ai·chatgpt
剑穗挂着新流苏3122 小时前
207_深度学习调优:透彻理解权重衰退(L2 正则化)
人工智能·机器学习
爱丽_2 小时前
MySQL 锁与死锁:行锁、间隙锁、Next-Key Lock 与排查手册
数据库·mysql
一叶萩Charles2 小时前
GitHub AI Agent 开源生态概览
人工智能·开源·github
皙然2 小时前
Redis 持久化机制超详细详解(RDB+AOF 双方案 + 生产实战)
数据库·redis·bootstrap
易连EDI—EasyLink2 小时前
以自主技术破局–聚信万通EasyLink赋能中国汽车供应链高质量发展
大数据·人工智能·汽车·edi·制造·电子数据交换·as2
看山还是山,看水还是。2 小时前
消控室五方对讲接听操作流程
经验分享·笔记·搜索引擎·pdf·百度云·印象笔记·有道云笔记