en: # Introduction
zh: # 开始
请注意,您提供的源文本仅包含一个英文的Markdown标题,没有实际内容需要翻译。如果您希望翻译的内容包括实际文本,请提供完整内容。根据您给出的指令,仅翻译标题部分如下:
en: # Introduction
zh: # 开始
但是为什么我们要回到对状态和状态转换的控制上呢?我以为有了自主AI,我们已经不再局限于状态控制和转换的概念了?
其实,如果你看一下自主智能体的输出,你会注意到智能体是如何动态生成一系列行动然后遵循这些行动的。
LangGraph的目标是在使用自主AI代理时达到一定的控制水平。
很抱歉这篇文章比较长,但我想要真正了解图(图是一种数据结构)的这些基本原理。
现状考虑下面的图片,这就是大多数人都熟悉的用来创建对话和流程的用户界面的设计和开发界面。
设计可以分为两大类:节点和边。
节点在这里指的是块,有时也被称为资产。比如说,在下面这张图中,这张设计画布上有五个节点。每个节点之间都有链接,也就是所说的边。边表示可能的目的节点。
随着大型语言模型的出现,提示链技术也逐渐崭露头角。
提示链可以描述为在使用语言模型技术时采用的一种技术,其中多个提示节点被顺序连接(通过边)来引导生成应用完成一系列相关的任务和步骤。
这种方法用来通过把大型任务分解为更小且易于管理的部分,来实现更复杂和细腻的结果。
下面是一个简单的解释,说明链式提示是如何工作的。
- 分解任务(节点):一个复杂任务被分解成一系列较小的、按顺序执行的小步骤。每个小步骤旨在完成整体目标的一部分。
- 为每一步创建指令(边):为每个步骤设计一个特定指令,以指导语言模型生成所需的输出。这些指令被设计得清晰且专注于各自的子任务目标。
- 顺序执行:语言模型处理第一个指令并生成输出。这个输出会被用作后续指令的输入。
但需要注意的是,提示链是基于聊天机器人流程构建的原则。因此,我们依旧遇到了同样的问题,即僵硬的状态机。
确实,提示链式中的一些方面引入了一定程度的灵活性,并且输出也具有动态变化的特性。但总的来说,序列仍然固定且僵硬。
挑战这种方法要求每一个流程都要精心设计,并且每个决策点都必须明确;因此,本质上,这可以被视为一个状态机,对话树由不同的状态(节点)和路径定义,决定对话走向的具体决策点(路径)定义了这些路径。
也可以把边缘视为对话回合可以移动到的选项。
这引出了对话设计中的一个挑战;状态和流程管理。
这种方法过于僵硬的挑战也就显现出来了,人们普遍希望减少僵化,增加灵活性。
我们所熟知的传统聊天机器人存在一个问题,就是结构过于固定,不够灵活,
进入代理:自主代理是最近才被引入的,它们的自主程度令人惊讶不已。代理具有相当的自主性,可以实时创建一系列事件,并按照它创建的临时链执行,直到得出答案为止。代理可以执行一系列实时操作,以实现最终答案。
你可以把它当成是一种一次性链条。
zh: 原文:
考虑下面的例子,实际上会有人被问到非常模糊的问题,例如:「谁被认为发明了 iPhone,以及他的出生年份的平方根是什么?」
or
被普遍认为是iPhone之父的那个人,他出生那年的平方根是多少?
如下所示,代理会实时地创建一个链条,思考问题,并经历采取行动、观察情况、思考问题……直到得出最终答案为止。
> 开始新的AgentExecutor链...
我需要找出谁被认为是iPhone之父以及他的出生年。
行动:搜索
行动输入:iPhone之父的出生年份
观察:乔布斯出生于1955年2月24日,出生在加利福尼亚州旧金山,他的父母是乔安妮·卡罗尔·施皮布勒和阿卜杜勒法塔赫“约翰”简拉利(阿拉伯语:عبدالف...
思考:我找到了,史蒂夫·乔布斯被认为是iPhone之父,他出生于1955年。现在我将计算他的出生年份的平方根。
行动:计算器
行动输入:sqrt(1955)
观察:答案:44.21538193886829
思考:我现在得到了最终答案。
最终答案:史蒂夫·乔布斯被认为是iPhone之父,1955年是他的出生年,其平方根大约为44.22。
> 完成链。
面临的挑战(让我们一起来看看有哪些挑战吧!)
我最常听到的一个批评点是,代理拥有很大的自主权,这也成为了它们面临的一个挑战。
创作者希望对代理人有一定的控制程度.
因此,引入代理使我们从过度的控制和僵化转变为更灵活,但失去了控制。
进入LangGraph(从LangChain)
不过首先,什么是图作为一种数据类型呢? 什么是图(一种抽象数据类型)图数据的概念初听起来可能有点难懂,但我会试着把它拆解开来说清楚。
图确实是一种抽象的数据结构。
一个抽象数据类型(ADT)是从使用该数据的用户的视角定义的一种数学模型,通过其行为(即语义)来定义。
抽象数据类型与数据结构形成鲜明对比,因为后者是数据的具体表现形式,且是开发者而非用户的角度。这种特定的数据结构相对来说比较透明,易于理解和解释。
有向图(每个节点都指向另一个节点的图形)有向图(或称digraph)是由一组节点通过有向边连接组成的。
在一个无向图中,图的数据结构由有限的顶点及其无序成对的连接组成。
如下的图示显示了节点、边及其选项。
再次看看下面这张图片,左边展示了一段 LangGraph 的 Python 代码,右边画出了相应的图。你可以看到代码中节点是如何定义的,即 builder.add_node
并带有 ReturnNodeValue
参数。对于每个有定义边的节点,使用 builder.add_edge
定义边。
你也看到 a
是入口点,d
是终点。
LangGraph 是一个建立在 LangChain 之上的模块,更好地支持创建循环图,这些循环图通常在代理运行期间需要用到。
LangChain 的一个主要优势是能够轻松创建自定义链,也称为流程设计。结合 LangGraph 和 LangChain 代理,代理既可以是有方向的,也可以形成循环。
一个有向无环图(DAG,Directed Acyclic Graph)是计算机科学和数学中使用的一种图。下面是一些简单的解释:
定向的: 每个连接(或边)都有方向,就像在节点(或顶点)之间。它表明你可以从一个节点单向到达另一个节点。
没有循环: 它不含任何环路。也就是说,如果你从一个节点开始并沿着路径前进,你永远回不到同一个节点。你绝不会陷入死循环。
想象它就像家谱或分支图,你只能往前走,不能回头,永远无法回到原来的起点。
在开发更复杂的LLM应用程序时,常见的做法是在运行时引入循环。这些循环经常利用LLM来决定下一步做什么。
大型语言模型的一个显著优势在于它们可以执行这些推理任务,基本上就像在循环中不断运行的语言模型一样。采用这种方法的系统通常被称为智能代理。
代理与控制然而,不同阶段往往需要对代理程序进行精细控制。
开发者可能需要确保代理总是优先调用特定工具,或寻求更多工具使用的控制权。
他们可能想根据程序当前的状态使用不同的提示。
暴露狭窄的接口本质上,LangGraph 是基于 LangChain 构建的简洁界面。
韩国为什么使用LangGraph?LangGraph 是与框架无关的,每个节点都像一个普通的 Python 函数。
它扩展了核心的 Runnable 接口(用于流、异步和批处理调用的共享接口),以便。
- 在多个对话轮次或工具使用过程中实现无缝状态管理。
- 根据动态标准在节点间灵活路由。
- 实现LLM与人工干预之间的流畅转换。
- 为长期运行的多会话应用提供持久性支持。
下面是一个运行正常的LangChain聊天机器人,基于Anthropic的模型。基础代码是从LangChain的示例代码库中复制的。
%%capture --no-stderr
%pip install -U langgraph langsmith
# 用于本教程,但不是 LangGraph 的必需项
%pip install -U langchain_anthropic
#################################
导入 getpass
导入 os
def _set_env(var: str):
if not os.environ.get(var):
os.environ[var] = getpass.getpass(f"{var}: ")
# 如果环境变量不存在,则从用户处获取并设置环境变量
_set_env("ANTHROPIC_API_KEY")
#################################
from typing import Annotated
from typing_extensions import TypedDict
from langgraph.graph import StateGraph
from langgraph.graph.message import add_messages
class State(TypedDict):
# 定义了如何更新此状态键(在这种情况下,它会将消息添加到列表中,而不是覆盖它们)
messages: Annotated[list, add_messages]
graph_builder = StateGraph(State)
#################################
from langchain_anthropic import ChatAnthropic
llm = ChatAnthropic(model="claude-3-haiku-20240307")
def chatbot(state: State):
return {"messages": [llm.invoke(state["messages"])]}
# 调用 LLM 并返回包含新消息的字典
# 第一个参数是唯一的节点名
# 第二个参数是当节点被使用时将调用的函数或对象。
graph_builder.add_node("chatbot", chatbot)
#################################
graph_builder.set_entry_point("chatbot")
#################################
graph_builder.set_finish_point("chatbot")
#################################
graph = graph_builder.compile()
#################################
from IPython.display import Image, display
try:
display(Image(graph.get_graph().draw_mermaid_png()))
except Exception:
# 这需要一些额外的依赖,但不是强制的
pass
#################################
while True:
user_input = input("用户:")
if user_input.lower() in ["quit", "exit", "q"]:
print("再见!")
break
for event in graph.stream({"messages": ("用户", user_input)}):
for value in event.values():
print("助手:", value["messages"][-1].content)
#################################
下面这个代码片段展示了图形渲染的流程。
图数据类型(Graph Data Type)是一种强大的工具,可以展示数据的可视化。而不仅仅是视觉表示,节点之间的关系非常适合用来构建数据节点的空间布局。
从数据使用者的角度来看,图数据类型也非常适合其语义表现。
_⭐️ 在 LinkedIn 上关注我,获取关于大型语言模型的最新消息 ⭐️
我是 Kore AI 的 首席布道师。我探索并撰写关于人工智能与语言交汇处的所有内容;包括 LLMs、聊天机器人、语音助手、开发框架、数据驱动的潜在空间 等内容。
我研究并撰写有关AI与语言交叉领域的所有内容;大规模语言模型,NLP/NLU,聊天机器人,CCAI,……substack.com](https://substack.com/@cobusgreyling?source=post_page-----f7cd0c12cdbf--------------------------------)
科布斯·格雷林在AI与语言的交叉点上 | NLP/NLU/LLM、聊天机器人/语音助手、CCAI(计算机生成的创意智能) 我探索并撰写关于所有与……有关的事物 www.cobusgreyling.com(Note: The phrase "我探索并撰写关于所有与……有关的事物" has been retained as per the source format, despite the expert suggestion to remove it for conciseness.)
图(抽象数据类型)- 维基百科在计算机科学中,图是一种抽象数据类型,用于表示无向图和有向图……en.wikipedia.org 抽象数据类型 - 维基百科在计算机科学领域里,抽象数据类型(ADT)是一种描述数据类型的数学模型(… 数据结构 - 维基百科(Wikipedia)在计算机科学里,数据结构是指数据的组织方式和存储方式,通常为了高效…en.wikipedia.org LangGraph 简介: LangGraph 是一个构建在 LangChain 之上的模块,旨在更好地支持创建循环图,这种图常常用于在博客中……blog.langchain.dev LangGraph 入门 - 将语言代理构建为图形 - langchain-ai.github.io共同學習,寫下你的評論
評論加載中...
作者其他優質文章