搭建智能客服机器人:langgraph实现用户订单管理

news2024/9/23 23:30:16

image.png

大家好,今天我们将创建一个智能客服机器人,它能够记录用户的食物订单到真实数据库中,并允许用户查看他们的订单。这是一个相对高级的Langgraph项目,大家可以先看一下前面介绍的Langgraph的基础课程。

项目概述

我们要构建的系统是一个模拟登录的用户,可以创建订单或查看订单,其他功能则被屏蔽。首先我们会用一个虚拟令牌设置用户,并通过系统消息给机器人一个身份。然后我们会分类处理用户的意图:

  1. 离题意图:完全屏蔽。

  2. 获取所有订单:查询数据库,按用户过滤并返回订单。

  3. 创建订单:首先验证请求,缺失信息则提示用户补充。如果信息完整,将时间格式化为有效的时间戳,然后创建订单并写入数据库,最后给用户一个友好的响应。

这整个过程分步骤进行,下面我们详细介绍实现过程。

数据库设置

由于我们使用真实数据库,第一步是设置数据库。需要Docker支持。我们使用docker-compose文件设置一个PostgreSQL数据库,并在5433端口运行。运行docker-compose up命令启动数据库,可以通过docker ps确认数据库是否运行。

用户和产品表

我们用SQLAlchemy创建用户和订单表。首先加载API密钥,并安装SQLAlchemy:

pip install SQLAlchemy

我们创建一个基础类Base,并继承自declarative_base,然后创建用户表、订单表和食物项表。用户表和订单表通过关系关联。我们在食物项表中提供一些示例食物,如比萨等等。

from sqlalchemy import create_engine, Column, Integer, String, ForeignKey
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import relationship, sessionmaker

Base = declarative_base()

class Customer(Base):
    __tablename__ = 'customers'
    id = Column(Integer, primary_key=True)
    name = Column(String)
    orders = relationship("Order", back_populates="customer")

class Order(Base):
    __tablename__ = 'orders'
    id = Column(Integer, primary_key=True)
    customer_id = Column(Integer, ForeignKey('customers.id'))
    food_item_id = Column(Integer, ForeignKey('food_items.id'))
    delivery_address = Column(String)
    order_date = Column(String)
    customer = relationship("Customer", back_populates="orders")
    food_item = relationship("FoodItem")

class FoodItem(Base):
    __tablename__ = 'food_items'
    id = Column(Integer, primary_key=True)
    name = Column(String)

创建表后,我们插入一个示例用户和一些食物项。

engine = create_engine('postgresql+psycopg2://user:password@localhost:5433/mydatabase')
Base.metadata.create_all(engine)
Session = sessionmaker(bind=engine)
session = Session()

# 创建示例用户和食物项
new_customer = Customer(name="John")
session.add(new_customer)
session.commit()

pizza = FoodItem(name="Pizza")
salami = FoodItem(name="Salami")
session.add_all([pizza, salami])
session.commit()
代理状态和验证逻辑

为了在节点间传递数据,我们需要一个代理状态AgentState。这个状态包含用户问题、系统消息、用户消息、客户名、工具调用、生成的最终输出等信息。我们通过一系列函数对用户请求进行检查和处理。

class AgentState:
    def __init__(self):
        self.question = ""
        self.messages = []
        self.customer_name = ""
        self.tool_calls = []
        self.order_check = ""
        self.generation = ""
        self.system_message = ""

验证用户请求的示例如下:

def validate_order(question):
    # 假设这是一个调用LLM的函数,返回验证结果
    if "food items" not in question or "delivery address" not in question or "order date" not in question:
        return False
    return True
工具调用和函数

我们需要一些工具函数来处理数据库查询和订单创建。使用LangChain框架中的工具装饰器来定义这些函数。

@tool
def create_order(customer_name, food_items, delivery_address, order_date):
    session = Session()
    customer = session.query(Customer).filter_by(name=customer_name).first()
    if not customer:
        return "Customer not found"

    food_item = session.query(FoodItem).filter_by(name=food_items).first()
    if not food_item:
        return "Food item not found"

    new_order = Order(customer_id=customer.id, food_item_id=food_item.id, delivery_address=delivery_address, order_date=order_date)
    session.add(new_order)
    session.commit()
    return "Order placed successfully"

@tool
def get_all_orders(customer_name):
    session = Session()
    customer = session.query(Customer).filter_by(name=customer_name).first()
    if not customer:
        return "Customer not found"

    orders = session.query(Order).filter_by(customer_id=customer.id).all()
    if not orders:
        return "No orders found"

    return [{"order_id": order.id, "food_item": order.food_item.name, "delivery_address": order.delivery_address, "order_date": order.order_date} for order in orders]
系统消息和用户消息

接下来我们需要创建系统消息和用户消息,并通过LangChain框架绑定工具。

system_message = "You are an order bot. You can help users create and view food orders."

def create_human_message(question):
    return {"role": "user", "content": question}

def create_system_message():
    return {"role": "system", "content": system_message}
意图识别和路由

通过LangChain框架,我们可以识别用户意图,并根据意图进行相应的处理。

def identify_intent(question):
    if "order" in question:
        return "create_order"
    elif "view" in question or "see" in question:
        return "get_all_orders"
    else:
        return "off_topic"

def route_intent(intent, state):
    if intent == "off_topic":
        return "I can only help you with creating or viewing orders."
    elif intent == "create_order":
        if validate_order(state.question):
            return create_order(state.customer_name, state.order_check["food_items"], state.order_check["delivery_address"], state.order_check["order_date"])
        else:
            return "Your order information is incomplete."
    elif intent == "get_all_orders":
        return get_all_orders(state.customer_name)
生成最终消息

最后一步是生成最终消息,告知用户订单创建的结果或显示用户的所有订单。

def generate_final_message(state):
    if state.intent == "create_order":
        if validate_order(state.question):
            return create_order(state.customer_name, state.order_check["food_items"], state.order_check["delivery_address"], state.order_check["order_date"])
        else:
            return "Your order information is incomplete."
    elif state.intent == "get_all_orders":
        return get_all_orders(state.customer_name)
    else:
        return "I can only help you with creating or viewing orders."
测试与运行

我们可以通过一系列测试来验证系统的功能是否正常。

state = AgentState()
state.customer_name = "John"
state.question = "我需要预定一个披萨,地址是北京路123号4栋506,时间为明天上午10点"

# 更新系统消息和用户消息
state.messages.append(create_system_message())
state.messages.append(create_human_message(state.question))

# 识别意图并路由
state.intent = identify_intent(state.question)
response = route_intent(state.intent, state)
print(response)

通过以上步骤,我们成功创建了一个智能客服机器人,它能够处理用户的食物订单请求并返回相应的结果。这是一个复杂而强大的系统,展示了现代科技在客户服务领域的巨大潜力。

关注我,每天带你开发一个AI应用,每周二四六直播,欢迎多多交流。

image.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2071265.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C程序设计——运算符1

条件运算符 这是一个三目运算符,用于条件求值(?:)。 来源:百度百科 这是C语言里,唯一三目(即三个表达式)运算符。具体格式如下: (表达式1) ? (表达式2) : (表达式3) ; 翻译成人话,就是&…

测试资料4444

一、HTML 1、HTML介绍 1.1web前端三大核心技术 HTML:负责网页架构 CS&#xff1a;负责网页的样式、美化 JS:负责网页的行为 1.2 HTML标签 单标签:<标签名 > 双标签内容 标签属性&#xff1a; 2 常用标签 script:js标签 style:css标签 link:外部加载css标签

SyntaxError: Unexpected token ‘??=‘ 解决办法

问题 原因 Node 15, 及 以上版本才能使用 ?? 操作符 我的版本&#xff1a; 解决 尝试升级node版本 参考 windows下node升级到最新版本&#xff08;亲测有效&#xff09; 有错误&#xff0c;但也创建成功了。 错误以后再改吧…

初识LLM大模型:入门级工程知识探索与解析

前言 源自脉脉上面刷到的大模型业务工程落地可以做的方向。其实如果不是接触相关工作&#xff0c;有的人可能不会想了解这方面&#xff0c;自己实习做的方向与之相关&#xff0c;因此想调研总结一下行业热点方向与基础入门知识&#xff0c;还有一些的专业词汇的解释。包括但不…

异常—python

一、异常 当检测到一个错误时&#xff0c;Python解释器就无法继续执行了&#xff0c;反而出现了一些错误的提示&#xff0c;这就是异常, 也就是我们常说的BUG&#xff0c;那BUG是怎么由来的呢&#xff1f; 例如&#xff1a; print(1/0) 我们在小学的时候就知道0不能作除数&a…

线段树+二分,CF 431E - Chemistry Experiment

目录 一、题目 1、题目描述 2、输入输出 2.1输入 2.2输出 3、原题链接 二、解题报告 1、思路分析 2、复杂度 3、代码详解 一、题目 1、题目描述 2、输入输出 2.1输入 2.2输出 3、原题链接 431E - Chemistry Experiment 二、解题报告 1、思路分析 贪心的考虑&…

NYX靶机笔记

NYX靶机笔记 概述 VulnHub里的简单靶机 靶机地址&#xff1a;https://download.vulnhub.com/nyx/nyxvm.zip 1、nmap扫描 1&#xff09;主机发现 # -sn 只做ping扫描&#xff0c;不做端口扫描 nmap -sn 192.168.84.1/24 # 发现靶机ip为 MAC Address: 00:50:56:E0:D5:D4 (V…

文心快码(Baidu Comate)初体验

文心快码&#xff08;Baidu Comate&#xff09;初体验 1文心快码简介和安装&#xff1a;简要介绍文心快码&#xff08;Baidu Comate&#xff09;、安装方法、使用方法等&#xff1b; Baidu Comate 是由百度自主研发&#xff0c;基于文心大模型&#xff0c;结合百度丰富的编程现…

【数模修炼之旅】08 支持向量机模型 深度解析(教程+代码)

【数模修炼之旅】08 支持向量机模型 深度解析&#xff08;教程代码&#xff09; 接下来 C君将会用至少30个小节来为大家深度解析数模领域常用的算法&#xff0c;大家可以关注这个专栏&#xff0c;持续学习哦&#xff0c;对于大家的能力提高会有极大的帮助。 1 支持向量机模型…

C++ TinyWebServer项目总结(10. 信号)

信号是由用户、系统、进程发送给目标进程的信息&#xff0c;以通知目标进程某个状态的改变或系统异常。Linux信号可由以下条件产生&#xff1a; 对于前台进程&#xff0c;用户可通过输入特殊终端字符来给它发送信号&#xff0c;如输入CtrlC通常会给进程发送一个中断信号。系统…

学习笔记 韩顺平 零基础30天学会Java(2024.8.24)

P532 Map接口特点2 P533 Map接口方法 P534 Map六大遍历方式 方法一&#xff1a;通过KeySet()&#xff0c;取出所有的Key&#xff0c;把取出的Key放到Set中&#xff0c;再通过Key取出对应的Value 到这里又有两种方式遍历Set&#xff1a;迭代器、增强for 方法二&#xff1a;通过v…

svn使用教程学习

如何撤销未提交的本地修改&#xff1f; 点击svn提交&#xff0c;双击文件&#xff0c;可以查看准备提交的修改内容。 如何撤销已经提交的内容&#xff1f; 选择‘复原此版本做出的修改’&#xff1a; 但是&#xff0c;这个只是复原在本地了&#xff0c;我们需要提交上去&…

pycharm远程调试服务器代码提示,运行‘test’时出错,illegal char at index

pycharm远程调试服务器代码提示&#xff0c;运行‘test’时出错&#xff0c;illegal char at index &#xff0c;illegal char at index 0:4ba0d3dd-ad57-46cb-83d6-dc4e2d307520>/DETR/test.py 并不是在pycharm的右侧remote Host选择服务器上的文件&#xff0c;然后点击执行…

R6RS标准之重要特性及用法实例(三十八)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 新书发布&#xff1a;《Android系统多媒体进阶实战》&#x1f680; 优质专栏&#xff1a; Audio工程师进阶系列…

java计算机毕设课设—企业电子投票系统(附源码、文章、相关截图、部署视频)

这是什么系统&#xff1f; java计算机毕设课设—企业电子投票系统(附源码、文章、相关截图、部署视频) 企业电子投票系统是一款高效便捷的在线投票平台包括前端普通用户和后端管理员两大模块&#xff0c;普通用户可登录投票、查看结果&#xff0c;管理员则负责后台管理&#…

利用 Windows CryptoAPI 中的关键欺骗漏洞

背景 三个月前,在我们 2022 年 10 月补丁星期二分析中,我们分享了 Windows CryptoAPI 中一个严重欺骗漏洞 CVE-2022-34689 的基本描述。据微软称,此漏洞允许攻击者“欺骗其身份并以目标证书的身份执行身份验证或代码签名等操作”。 CryptoAPI 是 Windows 中用于处理与加密…

IEEE T-ASLP | 利用ASR预训练的Conformer模型通过迁移学习和知识蒸馏进行说话人验证

近期&#xff0c;昆山杜克大学在语音旗舰期刊 IEEE/ACM Transactions on Audio, Speech and Language Processing (TASLP)上发表了一篇题为“Leveraging ASR Pretrained Conformers for Speaker Verification Through Transfer Learning and Knowledge Distillation”的论文。论…

Wireshark Lab: TCP v7.0

Wireshark Lab: TCP v7.0 1. Capturing a bulk TCP transfer from your computer to a remote server 步骤 打开浏览器&#xff0c;在url中输入http://gaia.cs.umass.edu/wiresharklabs/alice.txt &#xff0c;然后右键点击另存为下载文本。 访问http://gaia.cs.umass.edu/w…

【JVM】类加载器、双亲委派、SPI(一)

类加载器、双亲委派、SPI 类加载器 JVM中有两种类型的类加载器&#xff0c;由C编写的及由Java编写的。除了启动类加载器(BootstrapClassLoader)是由C编写的&#xff0c;其他都是由Java编写的&#xff0c;由Java编写的类加载器都继承自类java.lang.ClassLoader.JVM还支持自定义…

父子进程资源问题+vfork

一、从内存的角度分析父子进程资源问题 父子进程在内存资源使用上既共享又独立。它们通过写时复制技术实现地址空间的共享&#xff0c;但在修改数据时各自维护独立副本。代码段共享以节省内存&#xff0c;同时继承并打开的文件描述符等系统资源需注意同步和互斥问题。这种特殊…