探索LangGraph:如何创建一个既智能又可控的航空客服AI

这种设计既保持了用户控制权,又确保了对话流程的顺畅。但随着工具数量的增加,单一的图结构可能会变得过于复杂。我们将在下一节中解决这个问题。

第三部分的图将类似于下面的示意图:

第三部分示意图

状态定义

首先,定义图的状态。我们的状态和LLM调用与第二部分相同

python
复制代码
from typing import Annotatedfrom langchain_anthropic import ChatAnthropic
from langchain_community.tools.tavily_search import TavilySearchResults
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.runnables import Runnable, RunnableConfig
from typing_extensions import TypedDictfrom langgraph.graph.message import AnyMessage, add_messagesclass State(TypedDict):messages: Annotated[list[AnyMessage], add_messages]user_info: strclass Assistant:def __init__(self, runnable: Runnable):self.runnable = runnabledef __call__(self, state: State, config: RunnableConfig):while True:result = self.runnable.invoke(state)# 如果LLM碰巧返回了一个空响应,我们将重新提示它# 以获得一个实际的响应。if not result.tool_calls and (not result.contentor isinstance(result.content, list)and not result.content[0].get("text")):messages = state["messages"] + [("user", "请给出真实的输出。")]state = {**state, "messages": messages}messages = state["messages"] + [("user", "请给出真实的输出。")]state = {**state, "messages": messages}else:breakreturn {"messages": result}# Haiku更快更便宜,但准确性较低
# llm = ChatAnthropic(model="claude-3-haiku-20240307")
llm = ChatAnthropic(model="claude-3-sonnet-20240229", temperature=1)
# 你可以更新LLMs,尽管你可能需要更新提示
# from langchain_openai import ChatOpenAI# llm = ChatOpenAI(model="gpt-4-turbo-preview")assistant提示 = ChatPromptTemplate.from_messages([("system","你是一位乐于助人的瑞士航空客户支持助手。"" 使用提供的工具搜索航班、公司政策和其他信息以协助用户的查询。"" 当搜索时,要坚持不懈。如果第一次搜索没有结果,扩大你的查询范围。"" 如果搜索空手而归,请在放弃之前扩大你的搜索。""\n\n当前用户:\n<User>\n{user_info}\n</User>""\n当前时间:{time}。",),("placeholder", "{messages}"),]
).partial(time=datetime.now())# "阅读"仅工具(例如检索器)不需要用户确认即可使用
part_3_safe_tools = [TavilySearchResults(max_results=1),fetch_user_flight_information,search_flights,lookup_policy,search_car_rentals,search_hotels,search_trip_recommendations,
]# 这些工具都改变了用户的预订。
# 用户有权控制做出什么决定
part_3_sensitive_tools = [update_ticket_to_new_flight,cancel_ticket,book_car_rental,update_car_rental,cancel_car_rental,book_hotel,update_hotel,cancel_hotel,book_excursion,update_excursion,cancel_excursion,
]
sensitive_tool_names = {t.name for t in part_3_sensitive_tools}
# 我们的LLM不需要知道它必须路由到哪个节点。在它的"思维"中,它只是在调用函数。
part_3_assistant_runnable = assistant_prompt | llm.bind_tools(part_3_safe_tools + part_3_sensitive_tools
)

图的定义

现在,创建图。我们的图与第二部分几乎相同,只是我们将工具分为了两个不同的节点。我们只在实际更改用户预订的工具之前进行中断。

python
复制代码
from typing import Literalfrom langgraph.checkpoint.sqlite import SqliteSaver
from langgraph.graph import END, StateGraph
from langgraph.prebuilt import tools_conditionbuilder = StateGraph(State)def user_info(state: State):return {"user_info": fetch_user_flight_information.invoke({})}# 新增:fetch_user_info节点首先运行,这意味着我们的助手可以在
# 不需要采取行动的情况下看到用户的航班信息
builder.add_node("fetch_user_info", user_info)
builder.set_entry_point("fetch_user_info")
builder.add_node("assistant", Assistant(part_3_assistant_runnable))
builder.add_node("safe_tools", create_tool_node_with_fallback(part_3_safe_tools))
builder.add_node("sensitive_tools", create_tool_node_with_fallback(part_3_sensitive_tools)
)
# 定义逻辑
builder.add_edge("fetch_user_info", "assistant")def route_tools(state: State) -> Literal["safe_tools", "sensitive_tools", "__end__"]:next_node = tools_condition(state)# 如果没有调用工具,返回用户if next_node == END:return ENDai_message = state["messages"][-1]# 这假设是单个工具调用。要处理并行工具调用,你将想要# 使用ANY条件first_tool_call = ai_message.tool_calls[0]if first_tool_call["name"] in sensitive_tool_names:return "sensitive_tools"return "safe_tools"builder.add_conditional_edges("assistant",route_tools,
)
builder.add_edge("safe_tools", "assistant")
builder.add_edge("sensitive_tools", "assistant")memory = SqliteSaver.from_conn_string(":memory:")
part_3_graph = builder.compile(checkpointer=memory,# 新增:图将在执行"tools"节点之前始终停止。# 用户可以在助手继续之前批准或拒绝(甚至更改请求)interrupt_before=["sensitive_tools"],
)

示例对话

接下来,让我们尝试新修订的聊天机器人!我们将在以下对话列表上运行它。这次,我们将减少确认的次数。

python
复制代码
import shutil
import uuid# 使用备份文件更新,以便我们可以从每个部分的原始位置重新启动
shutil.copy(backup_file, db)
thread_id = str(uuid.uuid4())config = {"configurable": {# passenger_id在我们的航班工具中使用# 以获取用户的航班信息"passenger_id": "3442 587242",# 通过thread_id访问检查点"thread_id": thread_id,}
}tutorial_questions = ["嗨,我的航班是什么时候?","我可以更新我的航班到更早的时间吗?我想今天晚些时候离开。","那就更新到下周的某个时间","下一个可用的选项很好","关于住宿和交通呢?","是的,我想要一个负担得起的酒店,用于我为期一周的住宿(7天)。我还想要租一辆车。","好的,可以为你推荐的酒店预订吗?听起来不错。","是的,继续预订任何中等费用且有可用性的酒店。","现在对于汽车,我的选择是什么?","太棒了,我们只需要最便宜的选项。继续预订7天","好的,现在你对旅行有什么建议?","在我在那里的时候,它们可用吗?","有趣 - 我喜欢博物馆,有什么选择?","好的,选一个并在我到达的第二天为我预订。",
]_printed = set()
# 我们可以重用第一部分的教程问题,看看它的表现如何。
for question in tutorial_questions:events = part_3_graph.stream({"messages": ("user", question)}, config, stream_mode="values")for event in events:_print_event(event, _printed)snapshot = part_3_graph.get_state(config)while snapshot.next:# 我们有中断!代理试图使用工具,用户可以批准或拒绝它# 注意:此代码都在图之外。通常,你会将输出流到UI。# 然后,当用户提供输入时,你会通过API调用触发新的运行。user_input = input("你是否批准上述操作?输入'y'继续;"" 否则,请说明你请求的更改。\n\n")if user_input.strip() == "y":# 只是继续result = part_3_graph.invoke(None,config,)else:# 通过提供有关请求更改/改变主意的说明# 满足工具调用result = part_3_graph.invoke({"messages": [ToolMessage(tool_call_id=event["messages"][-1].tool_calls[0]["id"],content=f"API调用被用户拒绝。理由:'{user_input}'。继续协助,考虑用户的输入。",)]},config,)snapshot = part_3_graph.get_state(config)

第三部分回顾

现在,我们的聊天机器人工作得很好,你可以通过LangSmith跟踪来检查它的最新运行情况。这个设计可能已经满足了你的需求。代码是封闭的,并且它的行为符合预期。

然而,这个设计的一个潜在问题是,它对单个提示施加了很大压力。如果我们想要添加更多工具,或者每个工具变得更加复杂,那么机器人使用工具的效率和整体行为可能会受到影响。

如何系统的去学习大模型LLM ?

作为一名热心肠的互联网老兵,我意识到有很多经验和知识值得分享给大家,也可以通过我们的能力和经验解答大家在人工智能学习中的很多困惑,所以在工作繁忙的情况下还是坚持各种整理和分享。

但苦于知识传播途径有限,很多互联网行业朋友无法获得正确的资料得到学习提升,故此将并将重要的 AI大模型资料 包括AI大模型入门学习思维导图、精品AI大模型学习书籍手册、视频教程、实战学习等录播视频免费分享出来

😝有需要的小伙伴,可以V扫描下方二维码免费领取🆓

在这里插入图片描述

一、全套AGI大模型学习路线

AI大模型时代的学习之旅:从基础到前沿,掌握人工智能的核心技能!

img

二、640套AI大模型报告合集

这套包含640份报告的合集,涵盖了AI大模型的理论研究、技术实现、行业应用等多个方面。无论您是科研人员、工程师,还是对AI大模型感兴趣的爱好者,这套报告合集都将为您提供宝贵的信息和启示。

img

三、AI大模型经典PDF籍

随着人工智能技术的飞速发展,AI大模型已经成为了当今科技领域的一大热点。这些大型预训练模型,如GPT-3、BERT、XLNet等,以其强大的语言理解和生成能力,正在改变我们对人工智能的认识。 那以下这些PDF籍就是非常不错的学习资源。

img

在这里插入图片描述

四、AI大模型商业化落地方案

img

阶段1:AI大模型时代的基础理解

  • 目标:了解AI大模型的基本概念、发展历程和核心原理。
  • 内容
    • L1.1 人工智能简述与大模型起源
    • L1.2 大模型与通用人工智能
    • L1.3 GPT模型的发展历程
    • L1.4 模型工程
      - L1.4.1 知识大模型
      - L1.4.2 生产大模型
      - L1.4.3 模型工程方法论
      - L1.4.4 模型工程实践
    • L1.5 GPT应用案例

阶段2:AI大模型API应用开发工程

  • 目标:掌握AI大模型API的使用和开发,以及相关的编程技能。
  • 内容
    • L2.1 API接口
      - L2.1.1 OpenAI API接口
      - L2.1.2 Python接口接入
      - L2.1.3 BOT工具类框架
      - L2.1.4 代码示例
    • L2.2 Prompt框架
      - L2.2.1 什么是Prompt
      - L2.2.2 Prompt框架应用现状
      - L2.2.3 基于GPTAS的Prompt框架
      - L2.2.4 Prompt框架与Thought
      - L2.2.5 Prompt框架与提示词
    • L2.3 流水线工程
      - L2.3.1 流水线工程的概念
      - L2.3.2 流水线工程的优点
      - L2.3.3 流水线工程的应用
    • L2.4 总结与展望

阶段3:AI大模型应用架构实践

  • 目标:深入理解AI大模型的应用架构,并能够进行私有化部署。
  • 内容
    • L3.1 Agent模型框架
      - L3.1.1 Agent模型框架的设计理念
      - L3.1.2 Agent模型框架的核心组件
      - L3.1.3 Agent模型框架的实现细节
    • L3.2 MetaGPT
      - L3.2.1 MetaGPT的基本概念
      - L3.2.2 MetaGPT的工作原理
      - L3.2.3 MetaGPT的应用场景
    • L3.3 ChatGLM
      - L3.3.1 ChatGLM的特点
      - L3.3.2 ChatGLM的开发环境
      - L3.3.3 ChatGLM的使用示例
    • L3.4 LLAMA
      - L3.4.1 LLAMA的特点
      - L3.4.2 LLAMA的开发环境
      - L3.4.3 LLAMA的使用示例
    • L3.5 其他大模型介绍

阶段4:AI大模型私有化部署

  • 目标:掌握多种AI大模型的私有化部署,包括多模态和特定领域模型。
  • 内容
    • L4.1 模型私有化部署概述
    • L4.2 模型私有化部署的关键技术
    • L4.3 模型私有化部署的实施步骤
    • L4.4 模型私有化部署的应用场景

学习计划:

  • 阶段1:1-2个月,建立AI大模型的基础知识体系。
  • 阶段2:2-3个月,专注于API应用开发能力的提升。
  • 阶段3:3-4个月,深入实践AI大模型的应用架构和私有化部署。
  • 阶段4:4-5个月,专注于高级模型的应用和部署。
这份完整版的大模型 LLM 学习资料已经上传CSDN,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费

😝有需要的小伙伴,可以Vx扫描下方二维码免费领取🆓

在这里插入图片描述

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

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

相关文章

homography原理和图像相似度计算

1. homography 讲homography原理 讲homography应用 2. 图像相似度计算 20230621-计算两幅图像的相似度 20221205-有史以来最全的图像相似度算法 20231112-图像相似度对比方法

C++:List的使用和模拟实现

✨✨✨学习的道路很枯燥&#xff0c;希望我们能并肩走下来! 文章目录 目录 文章目录 前言 一 list的介绍及使用 1.1 list的介绍 1.2 list的使用 1.2.1 list的构造 1.2.2 list iterator的使用 1.2.3 list capacity 1.2.4 list element access 1.2.5 list modifiers …

golang+redis的延时队列

网址 https://github.com/cfanbo/delay-queue-redis 代码结构很简单&#xff0c;简单代表着自由度很高&#xff0c;使用过程中出现问题也很好修改。 我很喜欢这样的代码&#xff0c;至少我看的懂&#xff0c;该有的都有。 //package main // //import ( // "context&q…

leetcode209_长度最小的子数组

要求某个连续的区间内的元素值总和>S . 思路&#xff1a;滑动窗口&#xff1a;本质上是一种双指针法。 &#xff08;1&#xff09;初始化left right 0&#xff1b; &#xff08;2&#xff09;left不动&#xff0c;right移动&#xff0c;扩大窗口&#xff0c;直至符合要…

selinux的安全策略可以影响ntp的方式

SELinux 是一个灵活而强大的模块化安全策略框架&#xff0c;它允许管理员定义和执行非常具体的访问控制策略。这些策略可以限制程序和进程对系统资源的访问&#xff0c;包括文件、网络端口、进程间通信等。 对于NTP&#xff0c;SELinux 策略可以影响以下几个方面&#xff1a; …

网络空间安全数学基础·整除与同余

主要内容&#xff1a; 整除的基本概念&#xff08;掌握&#xff09; 素数&#xff08;掌握&#xff09; 同余的概念&#xff08;掌握&#xff09; 1.1整除 定义&#xff1a;设a&#xff0c;b是任意两个整数&#xff0c;其中b≠0&#xff0c;如果存在一个整数q&#xff0c;使 …

12306技术内幕

公司内部做的一次技术分享 文章目录 12306的成就12306系统特点12306系统难点解决思路产品角度技术角度余票库存的表如何设计&#xff1f; 抢票软件推荐巨人的肩膀 对于未公开的技术部分&#xff0c;只能结合已公开的信息&#xff0c;去做大胆的猜想。 本文提到的一些解决方案&…

SpringBoot + Mybatis-Plus中乐观锁实现

悲观锁 悲观锁是一种悲观思想&#xff0c;它认为数据很可能会被别人所修改 所以总会对数据进行上锁&#xff0c;读操作和写操作都会上锁&#xff0c;性能较低&#xff0c;使用较少&#xff01; 乐观锁 乐观锁是一种乐观思想&#xff0c;它认为数据并不一定会被别人所修改 所以…

成为程序员后我都明白了什么?从入行到弃坑?

作为一个入行近10年的php程序员&#xff0c;真心感觉一切都才刚开始&#xff0c;对计算机&#xff0c;编程语言的理解也好&#xff0c;程序员中年危机也罢&#xff0c;之前都是听别人说的&#xff0c;真的自己到了这个水平&#xff0c;这个年龄才深刻体会到这其中的种种。 我一…

测试基础05:软件测试的分类

课程大纲 1、两种架构&#xff08;Architecture&#xff09; 1.1、B/S&#xff08;Browser/Server&#xff09; 浏览器服务器架构&#xff08;大体3步&#xff09;&#xff1a;用户通过浏览器向服务器发出请求&#xff0c;服务器处理请求&#xff0c;将结果通过网络返回到用户…

使用Webcam实现摄像头的开启和关闭,并保存和复制图片

实现思路 0&#xff0c;将webcam的jar文件传入项目中 1&#xff0c;显示摄像头的地方&#xff1a;创建一个画板&#xff0c;在画板上添加开启和关闭按钮 2&#xff0c;设置开启和关闭功能&#xff1a;创建一个类实现动作监听器&#xff0c;进而实现监听动作按钮 3&#xff…

【数据结构与算法篇】二叉树链式结构及实现

【数据结构与算法篇】二叉树链式结构及实现 &#x1f955;个人主页&#xff1a;开敲&#x1f349; &#x1f525;所属专栏&#xff1a;每日刷题&#x1f34d; &#x1f33c;文章目录&#x1f33c; 4. 二叉树链式结构的实现 4.1 前置说明 4.2 二叉树的遍历 4.2.1 前序、中序以及…

通过ssh在本地打开远程服务器的网页

用途 在远程服务器使用jupyter notebook或者tensorboard等时&#xff0c;在本地打开服务器端的网页的方式有很多比如可以使用MobaXterm工具等&#xff0c;此方法可参考https://blog.csdn.net/cc__cc__/article/details/108060618?spm1001.2014.3001.5502。 若直接使用ssh则可…

C++感受11-Hello Object 成员版

当一个C程序员在设计类型时&#xff0c;他在想什么&#xff1f; 这一类型的对象&#xff0c;需要拥有哪些属性数据&#xff1f;这一类型的对象&#xff0c;它将拥有哪些功能&#xff1f;这一类型的对象&#xff0c;它的各个属性和功能之间&#xff0c;有哪些关联关系&#xff1…

OceanBase的存储架构与传统LSM-Tree架构的异同|OceanBase数据转储合并技术解读(二)

前篇博文将OceanBase的存储架构巧妙地与自然界中的“水生态”进行了类比&#xff0c;今日我们转变视角&#xff0c;聚焦在与拥有相同LSM-Tree架构的其他产品的比较&#xff0c;深入探讨OceanBase相较于它们所展现出的独特性能。 众所周知&#xff0c;OceanBase数据库的存储引擎…

element-ui 前端ui框架用法开发指南(2024-05-22)

Element&#xff0c;一套为开发者、设计师和产品经理准备的基于 Vue 2.0 的桌面端组件库 1、npm安装 // npm安装&#xff1a;npm install element-ui --save 能更好地和 webpack 打包工具配合使用 2、cdn在线引入 访问最新版本的资源地址 - element-uiThe CDN for element-u…

RedHat9 | DNS剖析-配置主DNS服务器实例

一、实验环境 1、BIND软件包介绍 BIND软件是一款开放源码的DNS服务器软件&#xff0c;由美国加州大学Berkeley分校开发和维护&#xff0c;全称为Berkeley Internet Name Domain。该软件在DNS&#xff08;域名系统&#xff09;领域具有重要地位&#xff0c;是目前世界上使用最…

使用OpenCV dnn c++加载YOLOv8生成的onnx文件进行目标检测

在网上下载了60多幅包含西瓜和冬瓜的图像组成melon数据集&#xff0c;使用 LabelMe 工具进行标注&#xff0c;然后使用 labelme2yolov8 脚本将json文件转换成YOLOv8支持的.txt文件&#xff0c;并自动生成YOLOv8支持的目录结构&#xff0c;包括melon.yaml文件&#xff0c;其内容…

信息系统管理工程师问答题

信息系统管理工程师问答题 系统管理安全两方面 安全测试 入侵检测系统的功能 用户标识与验证常用的3种方法 (1) 要求用户输入一些保密信息&#xff0c;例如用户名称和密码&#xff1b; (2) 采用物理识别设备&#xff0c;例如访问卡、钥匙或令牌&#xff1b; (3) 采用生物统计学…