langgraph实操

一、schema 数据结构

1.定义全局共享数据的容器

2.可以自定义输入和输出的内容和结构

复制代码
from langgraph.graph import StateGraph, START, END
from typing_extensions import TypedDict


#定义输入Schema
class InputState(TypedDict):
    question: str

# 定义输出Schema
class OutputState(TypedDict):
    answer: str

# 结合输入和输出,定义总体模式
class OverallState(InputState, OutputState):
    pass

# 定义处理输入并生成答案的节点
def answer_node(state: InputState):
    return {"answer": "hello!", "question": state["question"]}

# 使用指定的输入和输出模式构建图形
builder = StateGraph(OverallState, input_schema=InputState, output_schema=OutputState)

builder.add_node(answer_node)
builder.add_edge(START, "answer_node")
builder.add_edge("answer_node", END)

graph = builder.compile()

print(graph.invoke({"question": "hi"}))

二、reducer消息归约器

1.消息的追加存储

2.后续只需要把新的消息加入字段

下面两种归约器等价,

在进行消息返回的时候,一定要指定明确是那个角色的消息

复制代码
# #使用内置归约器
# class BuiltInReducerState(TypedDict):
#     messages: Annotated[list[AnyMessage], add_messages]
#     extra_field: int

# #使用预构建状态,已经包含内置归约器
# class PreBuildState(MessagesState):
#     extra_field: int

消息调用示例,两种格式,注意是列表格式

复制代码
# 1
conversation.invoke({
    "messages": [
        ("user", "你好"), 
        ("assistant", "你好!我是你的 AI 助手,有什么我可以帮你的吗?")
    ]
})

# 2
input_data = {
    "messages": [
        SystemMessage(content="你是一个专业的翻译官"),
        HumanMessage(content="Hello"),
        AIMessage(content="你好"),
        HumanMessage(content="How are you?")
    ]
}
print(conversation.invoke(input_data))

规约器使用示例,消息的叠加展示

复制代码
from typing import TypedDict, Annotated, Sequence
from langchain_core.messages import HumanMessage, AIMessage, BaseMessage, SystemMessage, AnyMessage
from langchain_openai import ChatOpenAI
from langgraph.graph import StateGraph, END, add_messages, MessagesState
import operator
import os

from agent01.app.utils.get_llm_model import get_llm_model

model = get_llm_model()

# ================== 类型定义 ==================

# #使用内置归约器
# class BuiltInReducerState(TypedDict):
#     messages: Annotated[list[AnyMessage], add_messages]
#     extra_field: int

# #使用预构建状态,已经包含内置归约器
class PreBuildState(MessagesState):
    extra_field: int



# ================== 节点函数优化 ==================
def handle_user_input(state: PreBuildState):
    """处理用户输入节点"""
    try:
        print(f"handle_user_input_node state:{state}")
        user_input = input("\n用户输入(输入'退出'结束): ").strip()
        if user_input.lower() == "退出":
            print("正在结束对话...")
        # 保留历史记录并追加新消息
        return {"messages": [HumanMessage(content=user_input)]}
    except KeyboardInterrupt:
        return END

def generate_ai_response(state: PreBuildState):
    """生成AI响应节点(增加错误处理)"""
    try:
        print(f"generate_ai_response_node state:{state}")
        # 使用最近6条消息保持上下文连贯性
        recent_history = state["messages"][-6:]
        response = model.invoke(recent_history)
        # print("模型答复:",response)
        return {"messages": [response]}
    except Exception as e:
        error_msg = f"系统暂时无法响应,请稍后再试(错误代码:{str(e)[:30]})"
        return {"messages": [AIMessage(content=error_msg)]}

# ================== 对话图构建 ==================
# 1. 增加一个路由函数,决定是继续还是结束
def should_continue(state: PreBuildState):
    last_message = state["messages"][-1].content
    if last_message == "退出":
        return END
    return "ai_response"

# 2. 调整图的构建逻辑
builder = StateGraph(PreBuildState)
builder.add_node("user_input", handle_user_input)
builder.add_node("ai_response", generate_ai_response)

builder.set_entry_point("user_input")

# 使用条件边:用户输入后,判断是去 AI 还是结束
builder.add_conditional_edges(
    "user_input",
    should_continue
)

# AI 回答完后,跳回用户输入,等待下一句
builder.add_edge("ai_response", "user_input")

conversation = builder.compile()

# 3. 外部只需要调用一次 invoke
# 系统消息作为初始状态传入,之后它会一直留在 state["messages"] 里
final_result = conversation.invoke({
    "messages": [("system", "你是一个对话助手")]
})
print(final_result)
print("最终对话结束。")

aa

相关推荐
中云DDoS CC防护蔡蔡6 小时前
DDOS和CC攻击谁更可怕
运维·服务器·经验分享·网络安全·ddos
Ruiery6 小时前
Linux 6.6内核内存管理深度解析(十六):mmap — 用户态“申请内存“的真相
linux·运维·服务器
ClickHouseDB7 小时前
ClickHouse Cloud 与 Snowflake 实时性价比对比:CostBench 测试中的 412 倍差距来
运维·数据库·系统架构
m0_639906947 小时前
Redis入门|五种数据结构、使用场景、持久化RDB&AOF
数据结构·数据库·redis
欧米欧7 小时前
Linux系统篇(七),环境变量的底层溯源,核心获取机制与安全应用
linux·运维·服务器
Ruiery7 小时前
Linux 6.6内核内存管理深度解析(十八):KASLR 内核地址空间随机化
linux·运维·服务器·安全
时间售卖铺8 小时前
触发器与函数实战:MySQL高效编程秘诀
运维·数据库·mysql·云原生
qetfw8 小时前
UOS MariaDB 数据库:安装、最小权限与备份验证
linux·数据库·mariadb·uos
前端精髓8 小时前
调用大模型API
运维·服务器·microsoft
数智园区合作社9 小时前
问数平台怎么把同一个指标锁成一个数
大数据·数据库·人工智能·ai