服务网格(ServiceMesh)号称是下一代微服务架构。
互联网公司,经常使用的是微服务分层架构。
画外音:
为什么要服务化,详见服务化解决了什么问题?
随着数据量不断增大,吞吐量不断增加,业务越来越复杂,服务的个数会越来越多,分层会越来越细,除了数据服务层,还会衍生出业务服务层,前后端分离等各种层次结构。
画外音:
分层的细节,详见《互联网分层架构演进》。
不断发现主要矛盾,抽离主要矛盾,解决主要矛盾,架构自然演进了,微服务架构,潜在的主要矛盾会是什么呢?
引入微服务架构,一般会引入一个RPC框架,来完成整个RPC的调用过程。
如上图粉色部分所示,RPC分为:
画外音:
《离不开的微服务架构,脱不开的RPC细节》。
不只是微服务,MQ也是类似的架构:
如上图粉色部分所示,MQ分为:
画外音:
《MQ,互联网架构解耦神器》。
框架只是第一步,越来越多和RPC,和微服务相关的功能,会被加入进来。
例如:负载均衡
如果要扩展多种负载均衡方案,例如:
RPC-client需要进行升级。
例如:数据收集
如果要对RPC接口处理时间进行收集,来实施统一监控与告警,也需要对RPC-client进行升级。
画外音,处理时间分为:
客户端视角处理时间
服务端视角处理时间
如果要收集后者,RPC-server也要修改与上报。
又例如:服务发现
服务新增一个实例,通知配置中心,配置中心通知已注册的RPC-client,将流量打到新启动的服务实例上去,迅猛完成扩容。
再例如:调用链跟踪
如果要做全链路调用链跟踪,RPC-client和RPC-server都需要进行升级。
下面这些功能:负载均衡数据收集服务发现调用链跟踪…其实都不是业务功能,所以互联网公司一般会有一个类似于“架构部”的技术部门去研发和升级相关功能,而业务线的技术部门直接使用相关框架、工具与平台,享受各种“黑科技”带来的便利。
完美!!!理想很丰满,现实却很骨感,由于:
往往会面临以下一些问题:
画外音:
兄弟,贵司推广一个技术新产品,周期要多长?
这些耦合,这些通用的痛点,有没有办法解决呢?
一个思路是,将服务拆分成两个进程,解耦。
画外音:
负载均衡、监控告警、服务发现与治理、调用链…等诸多基础设施,都放到这一层实现。
这样就实现了“业务的归业务,技术的归技术”,实现了充分解耦,如果所有节点都实现了解耦,整个架构会演变为:
整个服务集群变成了网格状,这就是ServiceMesh服务网格的由来。
要聊ServiceMesh,就不得不提Istio,它是ServiceMesh目前最流行的实践,今天说说Istio是干啥的。
画外音:不能落伍。
什么是Istio?
Istio是ServiceMesh的产品化落地,它的一些关键性描述是:
画外音:
Istiohelpsyoutoconnect,secure,control,andobservemicroservices。
画外音:
佩服,硬是凑齐了十条,其实SM还能提供更多基础服务功能。
画外音:
说的还是解耦。
Istio官网是怎么吹嘘自己的?
画外音:
这个问题的另一个问法是“为什么大家要来用Istio”。
Istio非常牛逼,如果要实施ServiceMesh,必须用Istio,因为:
画外音:
你信了么?
Istio的核心特性是什么?
Istio强调了它提供的五项关键特性:
画外音:
断路器(circuitbreakers)、超时、重试、高可用、多路由规则、AB测试、灰度发布、按照百分比分配流量等。
Istio的吹嘘与特性,对于国外很多通过RESTful提供内网服务的公司,很有吸引力,但相对于国内微服务架构,未必达到了很好的拉拢效果:
(1)国内基本都是TCP的RPC框架,多协议支持未必是必须的;
(2)RPC框架里,路由、重试、故障转移、负载均衡、高可用都是最基础的;
(3)流控、限速、配额管理,是服务治理的内容,在微服务架构初期是锦上添花;
(4)自动度量,系统入口出口数据收集,调用跟踪,可观察和可操控的后台确实是最吸引人的;
(5)服务到服务的身份认证,微服务基本是内网访问,在架构初期也只是锦上添花;
另外一个花边,为什么代理会叫sidecarproxy?
Istio这么牛逼,它的核心架构如何呢?
关于Istio的架构设计,官网用了这样一句话:
逻辑上,Istio分为:
这两个词,是Istio架构核心,但又是大家被误导最多的地方。
数据平面和控制平面,不是ServiceMesh和Istio第一次提出,它是计算机网络,报文路由转发里很成熟的概念:
画外音:上两图为路由器架构。
它的设计原则是:
画外音:
Istio的架构核心与路由器非常类似:
(1)高效转发;
(2)接收和实施来自mixer的策略;
(1)管理和配置边车代理;
(2)通过mixer实施策略与收集来自边车代理的数据;
画外音:
(1)sidecarproxy,原文使用的是envoy,后文envoy表示代理;
(2)mixer,不确定要怎么翻译了,有些文章叫“混音器”,后文直接叫mixer;
(3)pilot,galley,citadel,不敢翻译为飞行员,厨房,堡垒,后文直接用英文;
如架构图所示,该两层架构中,有五个核心组件。
Envoy的核心职责是高效转发,更具体的,它具备这样一些能力:
(1)服务发现
(2)负载均衡
(3)安全传输
(4)多协议支持,例如HTTP/2,gRPC。
(5)断路器(Circuitbreakers)。
(6)健康检查
(7)百分比分流路由
(8)故障注入(Faultinjection)。
(9)系统度量
大部分能力是RPC框架都具备,或者比较好理解的,这里面重点介绍下断路器和故障注入。
它是软件架构设计中,一个服务自我保护,或者说降级的设计思路。
举个例子:当系统检测出某个接口有大量超时时,断路器策略可以终止对这个接口的调用(断路器打开),经过一段时间后,再次尝试调用,如果接口不再超时,则慢慢恢复调用(断路器关闭)。
它是软件架构设计中,一种故意引入故障,以扩大测试覆盖范围,保障系统健壮性的方法,主要用于测试。
国内大部分互联网公司,架构设计中不太会考虑故障注入,在操作系统内核开发与调试,路由器开发与调试中经常使用,可以用来模拟内存分配失败、磁盘IO错误等一些非常难出现的异常,以确保测试覆盖度。
Mixer的一些核心能力是:
(1)跨平台,作为其他组件的adapter,实现Istio跨平台的能力;
(2)和Envoy通讯,实时各种策略
(3)和Envoy通讯,收集各种数据
Mixer的设计核心在于“插件化”,这种模型使得Istio能够适配各种复杂的主机环境,以及后端基础设施。
Pilot作为非常重要的控制平面组件,其核心能力是:
(1)为Envoy提供服务发现能力;
(2)为Envoy提供各种智能路由管理能力,例如A/B测试,灰度发布;
(3)为Envoy提供各种弹性管理能力,例如超时,重试,断路策略;
Pilot的设计核心在于“标准化”,它会将各种流控的控制命令转化为Envoy能够识别的配置,并在运行时,将这些指令扩散到所有的Envoy。
Pilot将这些能力抽象成通用配置的好处是,所有符合这种标准的Envoy都能够接入到Pilot来。
潜台词是,任何第三方可以实现自己的proxy,只要符合相关的API标准,都可以和Pilot集成。
Citadel组件,它提供终端用户身份认证,以及服务到服务的访问控制。总之,这是一个和安全相关的组件。
Gally组件,它是一个配置获取、校验、处理、分发的组件,它的设计核心在于“解耦”,它将“从底层平台(例如:K8S)获取用户配置”与Istio解耦开来。
Istio采用二层架构,五大模块,进行微服务ServiceMesh解耦:
数据平面,主要负责高效转发
(1)envoy模块:即proxy;
(2)mixer模块:支持跨平台,标准化API的adapter;
(3)pilot模块:控制与配置envoy的大部分策略;
(4)citadel模块:安全相关;
(5)galley模块:与底层平台(例如:K8S)配置解耦;
实施与控制分离,经典的架构设计方法,GOT?
思路比结论重要。
智能代理技术的例子有哪些方面
在提供答案前,大模型通过中间推理步骤(尤其是结合少样本提示)能实现复杂推理,获得更优结果,以完成更具挑战的任务。
然而,仅依靠思维链推理无法解决大模型固有问题:无法主动更新知识,导致事实幻觉。
也就是说,由于缺乏与外部世界的接触,大模型仅拥有训练时见过的知识和提示信息中提供的上下文知识。
如果你问的问题超出其知识范围,要么大模型会告诉你:“我的训练时间截至XXXX年XX月XX日”,要么它就会开始胡编乱造。
下面这张图就属于第二种情况,我制作的一个Prompt骗过了大模型,它会误以为我引述的很多虚构的东西是事实,并且它还会顺着这个思路继续胡编乱造。
遇到自己不懂的东西,大模型“一本正经地胡说八道”。
这个问题如何解决呢?也不难。
你可以让大模型先在本地知识库中进行搜索,检查提示信息的真实性,如果真实,再进行输出;如果不真实,则进行修正。
如果本地知识库找不到相应的信息,可以调用工具进行外部搜索,来检查提示信息的真实性。
上面所说的无论本地知识库还是搜索引擎,都不是封装在大模型内部的知识,我们把它们称为“外部工具”。
代理的作用
每当你遇到这种需要模型做自主判断、自行调用工具、自行决定下一步行动的时候,Agent(也就是代理)就出场了。
代理就像一个多功能的接口,它能够接触并使用一套工具。根据用户的输入,代理会决定调用哪些工具。它不仅可以同时使用多种工具,而且可以将一个工具的输出数据作为另一个工具的输入数据。
在LangChain中使用代理,我们只需要理解下面三个元素。
代理接收任务后,会自动调用工具,给出答案
上面的思路看似简单,其实很值得我们仔细琢磨。
这个过程有很多地方需要大模型自主判断下一步行为(也就是操作)要做什么,如果不加引导,那大模型本身是不具备这个能力的。比如下面这一系列的操作:
那么,LangChain中的代理是怎样自主计划、自行判断,并执行行动的呢?
这里我要请你思考一下:如果你接到一个新任务,你将如何做出决策并完成下一步的行动?
比如说,你在运营花店的过程中,经常会经历天气变化而导致的鲜花售价变化,那么,每天早上你会如何为你的鲜花定价?
也许你会告诉我,我会去Google上面查一查今天的鲜花成本价啊(行动),也就是我预计的进货的价格,然后我会根据这个价格的高低(观察),来确定我要加价多少(思考),最后计算出一个售价(行动)!。
定价过程
你看,在这个简单的例子中,你有观察、有思考,然后才会具体行动。这里的观察和思考,我们统称为“推理”(Reasoning)过程,“推理”指导着你的“行动”(Acting)。
我们今天要讲的ReAct框架的灵感正是来自“行动”和“推理”之间的协同作用,这种协同作用使得咱们人类能够学习新任务并做出决策或推理。
这个框架,也是大模型能够作为“智能代理”,自主、连续、交错地生成推理轨迹和任务特定操作的理论基础。
先和你说明一点,此“ReAct”并非指代流行的前端开发框架React,它在这里专指如何指导大语言模型推理和行动的一种思维框架。
这个思维框架是ShunyuYao等人在ICLR2023会议论文《ReAct:SynergizingReasoningandActinginLanguageModels》(ReAct:在语言模型中协同推理和行动)中提出的。
这篇文章的一个关键启发在于:大语言模型可以通过生成推理痕迹和任务特定行动来实现更大的协同作用。
具体来说,就是引导模型生成一个任务解决轨迹:观察环境-进行思考-采取行动,也就是观察-思考-行动。那么,再进一步进行简化,就变成了推理-行动,也就是Reasoning-Acting框架。
其中,Reasoning包括了对当前环境和状态的观察,并生成推理轨迹。
这使模型能够诱导、跟踪和更新操作计划,甚至处理异常情况。
Acting在于指导大模型采取下一步的行动,比如与外部源(如知识库或环境)进行交互并且收集信息,或者给出最终答案。
ReAct的每一个推理过程都会被详细记录在案,这也改善大模型解决问题时的可解释性和可信度,而且这个框架在各种语言和决策任务中都得到了很好的效果。
下面让我们用一个具体的示例来说明这一点。比如我给出大模型这样一个任务:在一个虚拟环境中找到一个胡椒瓶并将其放在一个抽屉里。
在这个任务中,没有推理能力的模型不能在房间的各个角落中进行寻找,或者在找到胡椒瓶之后不能判断下一步的行动,因而无法完成任务。如果使用ReAct,这一系列子目标将被具体地捕获在每一个思考过程中。
通过ReAct思维框架,大模型成功找到胡椒瓶。
现在,让我们回到开始的时候我们所面临的问题。
仅使用思维链(CoT)提示,LLMs能够执行推理轨迹,以完成算术和常识推理等问题,但这样的模型因为缺乏和外部世界的接触或无法更新自己的知识,会导致幻觉的出现。
从仅使用CoT,仅执行Action,到ReAct。
而将ReAct框架和思维链(CoT)结合使用,则能让大模型在推理过程同时使用内部知识和获取到的外部信息,从而给出更可靠和实际的回应,也提高了LLMs的可解释性和可信度。
LangChain正是通过Agent类,将ReAct框架进行了完美封装和实现,这一下子就赋予了大模型极大的自主性(Autonomy),你的大模型现在从一个仅仅可以通过自己内部知识进行对话聊天的Bot,飞升为了一个有手有脚能使用工具的智能代理。
ReAct框架会提示LLMs为任务生成推理轨迹和操作,这使得代理能系统地执行动态推理来创建、维护和调整操作计划,同时还支持与外部环境(例如Google搜索、Wikipedia)的交互,以将额外信息合并到推理中。
更多内容,请参考我的LangChain课程哈!!支持佳哥!!。
下面,就让我们用LangChain中最为常用的ZERO_SHOT_REACT_DESCRIPTION——这种常用代理类型,来剖析一下LLM是如何在ReAct框架的指导之下进行推理的。
此处,我们要给代理一个任务,这个任务是找到玫瑰的当前市场价格,然后计算出加价15%后的新价格。
在开始之前,有一个准备工作,就是你需要在serpapi.com注册一个账号,并且拿到你的SERPAPI_API_KEY,这个就是我们要为大模型提供的Google搜索工具。
先安装SerpAPI的包。
设置好OpenAI和SerpAPI的API密钥。
再导入所需的库。
然后加载将用于控制代理的语言模型。
接下来,加载一些要使用的工具,包括serpapi(这是调用Google搜索引擎的工具)以及llm-math(这是通过LLM进行数学计算的工具)。
最后,让我们使用工具、语言模型和代理类型来初始化代理。
好了,现在我们让代理来回答我刚才提出的问题了!目前市场上玫瑰花的平均价格是多少?如果我在此基础上加价15%卖出,应该如何定价?
大模型成功遵循了ReAct框架,它输出的思考与行动轨迹如下:
可以看到,ZERO_SHOT_REACT_DESCRIPTION类型的智能代理在LangChain中,自动形成了一个完善的思考与行动链条,并且给出了正确的答案。
你可以对照下面这个表格,再巩固一下这个链条中的每一个环节。
这个思维链条中,智能代理有思考、有观察、有行动,成功通过搜索和计算两个操作,完成了任务。在下一讲中,我们将继续深入剖析LangChain中的不同类型的代理,并利用它完成更为复杂的任务。
这节课我们介绍了什么是LangChain中的代理,更重要的是,我们介绍了代理自主行动的驱动力——ReAct框架。
通过ReAct框架,大模型将被引导生成一个任务解决轨迹,即观察环境-进行思考-采取行动。
观察和思考阶段被统称为“推理”(Reasoning),而实施下一步行动的阶段被称为“行动”(Acting)。
在每一步推理过程中,都会详细记录下来,这也改善了大模型解决问题时的可解释性和可信度。
ReAct框架的这些优点,使得它在未来的发展中具有巨大的潜力。
随着技术的进步,我们可以期待ReAct框架将能够处理更多、更复杂的任务。
特别是,随着具身智能的发展,ReAct框架将能够使智能代理在虚拟或实际环境中进行更复杂的交互。
例如,智能代理可能会在虚拟环境中进行导航,或者在实际环境中操作物理对象。
这将大大扩展AI的应用范围,使得它们能够更好地服务于我们的生活和工作。
更多内容,请参考我的LangChain课程哈!!支持佳哥!!
还没有评论,来说两句吧...