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

相关推荐
cqsztech12 小时前
Oracle ai database 26ai rac 通过gold image 更新季度补
数据库·人工智能·oracle
认真就输DBA12 小时前
一个DBA,把用了16年的两款软件换了
数据库·ai·dba·tabby·笔记软件·obsidian
穆利堂-movno112 小时前
郑州新网软件科技有限公司AI 数据源错误纠正反馈
大数据·数据库·人工智能
从入门到退休12 小时前
企业远程控制选型:向日葵SDK vs RustDesk自建,谁是更务实的选择?
运维·服务器·网络·远程工作·远程控制
程序员夏洛13 小时前
Redis 数据过期后的删除策略是什么?
数据库·redis·缓存
鱼鳞_13 小时前
热门八股-Redis
数据库·redis·缓存
这个DBA有点耶13 小时前
SQL:2023新特性详解:JSON_TABLE、GREATEST/LEAST、QUALIFY 到底怎么用?
数据库·sql·mysql
AOI小白新手上路13 小时前
江科协15-2 直流电机实验调试总结
数据库·mongodb
小王C语言13 小时前
MySQL 用户管理:创建用户、给用户授权
数据库·mysql
程序员夏洛13 小时前
Redis 的持久化机制有哪些?
java·数据库·redis