AI agents系列之智能体框架介绍

1. 引言

智能体AI Agents框架通过赋予自主系统动态感知、推理和行动的能力,彻底改变了AI领域。本节将探讨智能体框架的核心概念,并重点介绍为什么开源解决方案对现代AI开发的创新和可扩展性至关重要。

1.1 什么是智能体框架?

智能体框架代表了人工智能系统设计范式的重大转变。与依赖静态、预定义工作流的传统AI应用不同,智能体框架引入了动态、自适应的系统,能够自主感知、推理和行动。这些框架将复杂任务分解为更小的子任务,由专门的智能体协作完成更广泛的目标。通过利用大语言模型(LLMs),智能体框架可以管理工作流、做出决策并无缝集成工具,使其成为动态决策和实时问题解决等高级应用的理想选择。

关键参考: LangGraph和CrewAI等智能体框架体现了这种动态方法,使开发者能够超越单智能体、线性工作流,进入多智能体协作系统的世界。

1.2 为什么它们很重要?

从零开始构建智能体绝非易事。像LangGraph、CrewAI和OpenAI Swarm这样的框架简化了这一过程,让开发者能够专注于应用逻辑,而不是重新发明状态管理、编排和工具集成的轮子。

智能体框架的核心功能包括:

  • 定义智能体和工具的简单方式
  • 编排机制
  • 状态管理
  • 支持更复杂应用的其他工具,例如持久层(记忆)、中断等

我们将在接下来的章节中逐一探讨这些功能。


2. 热门智能体框架与库

现在,让我们深入了解当前最突出的一些AI智能体框架和工具:

None

图片来源:analyticsvidhya

2.1 Langchain

**LangChain**是一个强大且灵活的框架,简化了基于大语言模型(LLMs)的应用程序开发。凭借其丰富的工具和抽象层,开发者可以设计出具备复杂推理能力、任务执行能力以及与外部数据源和API交互能力的AI智能体。

LangChain解决了开发者在与LLMs协作时面临的诸多挑战,例如在长对话中保持上下文、整合外部信息以及协调多步骤项目。其模块化架构使其能够轻松组合各种组件,适用于多种用途。

  • GitHub链接: LangChain GitHub
  • 文档链接: https://python.langchain.com/docs/introduction/
2.2 LangGraph

**LangGraph**是LangChain的扩展,支持创建有状态、多参与者的应用程序。它特别适用于构建涉及规划、反思和多智能体协调的复杂交互式AI系统。

  • GitHub链接: LangGraph
  • 文档链接: LangGraph
2.3 CrewAI

**CrewAI**是一个用于编排角色扮演AI智能体的框架。它允许开发者创建一组具有特定角色和职责的AI智能体,共同完成复杂任务。该框架特别适合构建协作式AI系统,解决需要多样化专业知识和协调努力的多方面问题。

  • GitHub链接: CrewAI GitHub
  • 文档: CrewAI
2.4 Microsoft Semantic Kernel

**Microsoft Semantic Kernel**旨在弥合传统软件开发与AI能力之间的鸿沟。它特别关注将大语言模型(LLMs)集成到现有应用中。该框架为开发者提供了在不完全重构现有代码库的情况下加入AI功能的工具。

其轻量级特性和对多种编程语言的支持使其能够适应各种开发环境。其编排器允许管理复杂的多步骤AI任务,使开发者能够在应用中创建复杂的AI驱动工作流。

  • GitHub链接: Microsoft Semantic Kernel
  • 文档链接: Microsoft Semantic Kernel
2.5 Microsoft AutoGen

**Microsoft AutoGen**是一个开源框架,用于构建高级AI智能体和多智能体系统。由微软研究院开发,AutoGen提供了一个灵活而强大的工具包,用于创建对话式和任务完成型AI应用。它强调模块化、可扩展性和易用性,使开发者能够高效构建复杂的AI系统。

  • 文档: https://microsoft.github.io/autogen/stable/user-guide/agentchat-user-guide/
  • GitHub链接: Microsoft AutoGen
2.6 Smolagents

Smolagents是一个前沿的开源框架,旨在彻底改变AI智能体的开发。它为开发者提供了一套全面的工具包,用于构建智能、协作的多智能体系统。该框架注重灵活性和模块化,支持创建能够在独立或人类监督下运作的复杂AI系统。

  • 文档: https://huggingface.co/docs/smolagents/en/index
  • GitHub链接: https://github.com/huggingface/smolagents
2.7 AutoGPT

**AutoGPT**基于强大的GPT-4语言模型,能够通过语言输入执行目标导向的活动,代表了自主AI智能体领域的重大进步。这一前沿AI助手将决策能力提升到了新的高度,超越了基本的反射式智能体,集成了复杂功能,使其成为各种应用中不可或缺的工具。

  • 文档: https://huggingface.co/docs/smolagents/en/index
  • GitHub链接: https://github.com/huggingface/smolagents
2.8 Agno (Phidata)

我们将讨论的最后一个AI智能体框架是**Phidata**。它是一个多模态智能体框架,可以开发协作执行的智能体系统。它还设计为与记忆和工具等组件配合使用,帮助智能体自主且一致地执行任务。

默认情况下,Phidata智能体支持文本、图像和音频等多模态数据,使其无需依赖外部工具即可发挥价值。该框架还提供了Agentic UI,供喜欢与智能体进行视觉交互的用户使用。他们也是Agentic RAG的先驱之一,智能体可以搜索知识库。

  • 文档: https://docs.phidata.com/introduction
  • GitHub链接: https://github.com/agno-agi/phidata

3. 智能体框架对比

下表提供了本文讨论的关键AI智能体框架的高层次对比。此对比旨在突出每个框架的独特优势和重点领域,帮助开发者和研究人员根据具体需求选择最合适的工具。
在这里插入图片描述


4. 深入LangGraph

LangGraph是由LangChain团队构建的一个库,旨在帮助开发者创建基于图的单智能体或多智能体AI应用。作为一个底层框架,LangGraph让你能够控制智能体之间的交互方式、使用的工具以及信息在应用中的流动方式。

4.1 什么是图?

想象一下,你有一堆数据可以表示为一个网络,其中每个数据或实体与其他数据或实体之间存在某种关系,这种关系可以是多种类型(一对一、一对多、多对多等)。图有两个主要组成部分:节点和边。

这种数据的例子包括交通数据或社交媒体网络,其中每个实体或用户与其他实体或用户存在关系,而图可以轻松可视化这种数据。

图有两种类型:

  • 有向图:在有向图中,边有方向,表示节点之间的流动或关系(例如,社交媒体上的关注)。
  • 无向图:在无向图中,边没有方向,表示对称关系(例如,LinkedIn上的连接)。

None

图片来源:ionio

4.2 核心概念
4.2.1 图结构

LangGraph设计的核心是基于图的应用工作流表示。该图由两个主要元素组成:

  • 节点:工作的构建块
    图中的每个节点代表应用中的一个独立工作单元或动作。这些节点本质上是封装特定任务的Python函数。这些任务可以包括多种操作,例如:

    • 直接与LLM通信以生成文本、摘要或其他基于语言的任务。
    • 与外部工具和API交互以获取数据或在现实世界中执行操作。
    • 通过格式化、过滤或转换等过程操作数据。
    • 与用户交互以获取输入或显示信息。
  • :引导信息和控制的流动
    边是LangGraph中的连接组织,建立信息流动的路径并决定操作序列。LangGraph支持多种边类型:

    • 简单边:表示从一个节点到另一个节点的直接无条件流动。第一个节点的输出作为后续节点的输入,形成线性进展。
    • 条件边:引入动态层,条件边使工作流能够根据特定节点操作的结果进行分支。例如,根据用户的响应,图可以决定终止交互或继续调用工具。这种决策能力对于创建能够适应不同情况的应用至关重要。

None

4.2.2 状态管理

管理多智能体系统的一个关键方面是确保所有智能体对任务的当前状态有共同的理解。LangGraph通过自动状态管理解决了这一问题。这意味着该库在智能体执行任务时自动跟踪和更新中央状态对象。

此状态对象充当存储关键信息的仓库,这些信息需要在工作流的不同点可访问。这可能包括:

  • 对话历史:在聊天机器人应用中,状态可以存储用户与机器人之间的持续对话,从而实现上下文感知的响应。
  • 上下文数据:与当前任务相关的信息,如用户偏好、过去行为或相关外部数据,可以存储在状态中供智能体在决策时使用。
  • 内部变量:智能体可以使用状态跟踪内部标志、计数器或其他指导其行为和决策的变量。

5. LangGraph实战

5.1 安装

要开始使用LangGraph,你需要先安装它。

在终端或命令提示符中运行以下命令以安装LangGraph:

pip install -U langgraph

此命令将下载并安装最新版本的LangGraph。-U标志确保你获取的是最新版本。

5.2 用LangGraph创建基础聊天机器人

这个例子是理解LangGraph基础概念的良好起点。

  1. 导入必要的库:首先从LangGraph和其他相关库中导入所需的类和模块。
from typing import Annotated
from typing_extensions import TypedDict
from langgraph.graph import StateGraph, START, END
from langgraph.graph.message import add_messages
  1. 定义状态结构:创建一个类来定义状态对象的结构,该对象将保存图中节点之间需要共享和更新的信息。
class State(TypedDict):# 'messages'将存储聊天机器人的对话历史。# 'add_messages'函数确保新消息被追加到列表中。messages: Annotated[list, add_messages]# 创建StateGraph的实例,传入State类
graph_builder = StateGraph(State)
  1. 初始化LLM:实例化你选择的LLM模型,提供必要的API密钥或配置参数。此LLM将用于驱动聊天机器人的响应。
#pip install -U langchain_anthropic
from langchain_anthropic import ChatAnthropicllm = ChatAnthropic(model="claude-3-5-sonnet-20240620")
  1. 创建聊天机器人节点:定义一个Python函数,封装聊天机器人节点的逻辑。此函数将当前状态作为输入,并根据LLM的输出生成响应。
def chatbot(state: State):# 使用LLM基于当前对话历史生成响应。response = llm.invoke(state["messages"])# 返回更新后的状态,新消息被追加return {"messages": [response]}# 将'chatbot'节点添加到图中
graph_builder.add_node("chatbot", chatbot)
  1. 定义入口和结束点:指定图中工作流的起点和终点。
# 对于这个基础聊天机器人,'chatbot'节点既是入口点也是结束点
graph_builder.add_edge(START, "chatbot")
graph_builder.add_edge("chatbot", END)
  1. 编译图:通过编译创建图的可运行实例。
graph = graph_builder.compile()
  1. 可视化图:通过运行简单的Python代码,你可以用节点和边可视化图。
from IPython.display import Image, displaytry:display(Image(graph.get_graph().draw_mermaid_png()))
except Exception:# 这需要一些额外的依赖项,是可选的pass
  1. 运行聊天机器人:实现一个循环与用户交互,将用户输入传递给图并显示聊天机器人的响应。
while True:user_input = input("用户: ")if user_input.lower() in ["quit", "exit", "q"]:print("再见!")break# 通过LangGraph处理用户输入for event in graph.stream({"messages": [("user", user_input)]}):for value in event.values():print("助手:", value["messages"][-1].content)

此代码片段提供了一个LangGraph聊天机器人的基础结构。你可以通过加入更复杂的状态管理、不同的LLM模型或连接外部工具和API来扩展它。关键在于为不同任务定义清晰的节点,并使用边在聊天机器人中建立所需的信息和控制流。

5.3 高级LangGraph技巧

工具集成:将工具集成到你的LangGraph聊天机器人中可以显著增强其能力,使其能够以你喜欢的方式访问和处理信息。

通过工具集成增强基础聊天机器人

让我们修改上一节创建的基础聊天机器人,加入一个可以搜索网络信息的工具。我们将使用langchain_community.tools.tavily_search中的TavilySearchResults工具。你需要Tavily API密钥来运行此示例。

#pip install -U tavily-python langchain_community
from typing import Annotated
from langchain_anthropic import ChatAnthropic
from langchain_community.tools.tavily_search import TavilySearchResults
from langchain_core.messages import BaseMessage
from typing_extensions import TypedDictfrom langgraph.graph import StateGraph
from langgraph.graph.message import add_messages
from langgraph.prebuilt import ToolNode, tools_conditionclass State(TypedDict):messages: Annotated[list, add_messages]graph_builder = StateGraph(State)tool = TavilySearchResults(max_results=2)
tools = [tool]
llm = ChatAnthropic(model="claude-3-5-sonnet-20240620")
llm_with_tools = llm.bind_tools(tools)def chatbot(state: State):return {"messages": [llm_with_tools.invoke(state["messages"])]}graph_builder.add_node("chatbot", chatbot)tool_node = ToolNode(tools=[tool])
graph_builder.add_node("tools", tool_node)graph_builder.add_conditional_edges("chatbot",tools_condition,
)
# 每当调用工具时,我们返回到聊天机器人以决定下一步
graph_builder.add_edge("tools", "chatbot")
graph_builder.set_entry_point("chatbot")
graph = graph_builder.compile()

解释:

  1. 导入工具:导入必要的工具类,这里是TavilySearchResults
  2. 定义并绑定工具:创建工具的实例,并使用llm.bind_tools()将其绑定到LLM。这通知LLM可用的工具及其用法。
  3. 创建工具节点:实例化一个ToolNode,传入可用工具列表。
  4. 将工具节点添加到图中:使用graph_builder.add_node()ToolNode加入LangGraph。
  5. 条件路由:使用graph_builder.add_conditional_edges()设置基于LLM是否决定调用工具的路由逻辑。tools_condition函数检查LLM的响应是否包含工具调用指令。
  6. 循环返回:执行工具后,使用graph_builder.add_edge()将流导向chatbot节点,使对话能够继续。

现在,当你运行聊天机器人并询问需要外部信息的问题时,LLM可以选择调用网络搜索工具,检索相关数据并将其整合到响应中。


6. 为聊天机器人添加记忆

记忆对于创建能够通过记住过去互动进行有意义对话的聊天机器人至关重要。

LangGraph的检查点系统

  1. 检查点器:当你编译LangGraph时,可以提供一个checkpointer对象。此对象负责在不同时间点保存图的状态。
  2. 线程ID:每次调用图时,你提供一个thread_id。此ID由checkpointer用于跟踪不同的对话线程。
  3. 自动保存和加载:LangGraph在图的每一步执行后自动保存给定thread_id的状态。当你再次用相同的thread_id调用图时,它会自动加载保存的状态,使聊天机器人能够从上次中断的地方继续对话。

通过检查点实现记忆

基于之前的代码,以下是如何使用LangGraph的检查点功能添加记忆:

# ... (之前的代码定义State、graph_builder、节点和边)from langgraph.checkpoint.memory import MemorySaver# 创建一个MemorySaver对象作为检查点器
memory = MemorySaver()# 编译图,传入'memory'对象作为检查点器
graph = graph_builder.compile(checkpointer=memory)# ... (运行聊天机器人的其余代码)

解释:

  1. 导入MemorySaver:从langgraph.checkpoint.memory导入MemorySaver类。
  2. 创建MemorySaver对象:实例化一个MemorySaver对象,它将处理图的保存和加载状态。
  3. 传递给compile():编译图时,将memory对象作为checkpointer参数传递。

现在,当你运行聊天机器人时,首先使用一个thread_id作为此对话的键:

config = {"configurable": {"thread_id": "1"}}

每个唯一的thread_id将有其对话历史存储。

然后开始对话:

while True:user_input = input("用户: ")if user_input.lower() in ["quit", "exit", "q"]:print("再见!")break# 通过LangGraph处理用户输入for event in graph.stream({"messages": [("user", user_input)]}, config):for value in event.values():print("助手:", value["messages"][-1].content)

注意:调用图时,config作为第二个位置参数提供。


7. 人机交互(HIL)

人机交互(HIL)的工作流对于需要在AI应用中引入人类监督、验证或决策的场景至关重要。

通过中断实现人机交互(HIL)

以下代码展示了如何使用LangGraph的interrupt_beforeinterrupt_after功能实现人机交互(HIL)。以下是详细说明:

from typing import Annotatedfrom langchain_anthropic import ChatAnthropic
from langchain_community.tools.tavily_search import TavilySearchResults
from langchain_core.messages import BaseMessage
from typing_extensions import TypedDictfrom langgraph.checkpoint.memory import MemorySaver
from langgraph.graph import StateGraph
from langgraph.graph.message import add_messages
from langgraph.prebuilt import ToolNode, tools_conditionclass State(TypedDict):messages: Annotated[list, add_messages]graph_builder = StateGraph(State)tool = TavilySearchResults(max_results=2)
tools = [tool]
llm = ChatAnthropic(model="claude-3-5-sonnet-20240620")
llm_with_tools = llm.bind_tools(tools)def chatbot(state: State):return {"messages": [llm_with_tools.invoke(state["messages"])]}graph_builder.add_node("chatbot", chatbot)tool_node = ToolNode(tools=[tool])
graph_builder.add_node("tools", tool_node)graph_builder.add_conditional_edges("chatbot",tools_condition,
)
graph_builder.add_edge("tools", "chatbot")
graph_builder.set_entry_point("chatbot")memory = MemorySaver()
graph = graph_builder.compile(checkpointer=memory,# 这是新增的!interrupt_before=["tools"],# 注意:如果需要,也可以在动作之后中断。# interrupt_after=["tools"]
)

解释:

在这个特定例子中,图将在执行tools节点之前暂停。此tools节点负责运行LLM在其回合中可能请求的任何工具。通过在此点中断,你可以允许人类执行以下操作:

  • 批准工具调用:人类可以审查LLM想要调用的工具及其输入。如果他们认为合适,可以简单地让图继续执行,工具将被调用。
  • 修改工具调用:如果人类认为需要调整LLM的工具调用(例如,优化搜索查询),他们可以修改图的状态,然后恢复执行。
  • 绕过工具调用:人类可能决定不需要工具。也许他们已经知道LLM试图查找的答案。在这种情况下,他们可以用适当的信息更新图状态,LLM将收到这些信息,就像工具返回了这些信息一样。 在这里插入图片描述

资源: 这里是关于人机交互(HIL)的更详细理解的笔记本:https://github.com/langchain-ai/langgraph/blob/main/docs/docs/how-tos/human_in_the_loop/review-tool-calls.ipynb


8. LangGraph的实际应用

LangGraph让你能够构建比简单问答机器人更复杂和交互性更强的AI系统,通过管理状态、协调多个智能体并允许人类反馈。以下是LangGraph的一些可能用途:

  • 更智能的客户服务:想象一个用于在线购物的聊天机器人,它可以记住你过去的订单和偏好。它可以回答产品问题、跟踪你的货物,甚至在需要时为你连接人工客服。
  • AI研究助手:需要研究项目的帮助吗?一个由LangGraph驱动的助手可以搜索大量学术论文和文章,总结关键发现,甚至帮助你整理笔记。
  • 个性化学习:LangGraph可以驱动下一代教育平台。想象一个系统能够适应你的学习风格,识别你需要额外帮助的领域,并推荐个性化资源。
  • 简化业务流程:许多业务流程涉及多个步骤和人员。LangGraph可以自动化这些工作流的部分内容,例如路由文档以获取批准、分析数据或管理项目。

这些例子突出了LangGraph如何帮助弥合AI能力与现实世界复杂性之间的差距。


9. 总结

智能体框架正在彻底改变AI系统的运作方式,使其能够动态推理、规划和交互。在本博客中,我们探讨了智能体框架的重要性,调查了一些最流行的库,并对比了它们的优势。然后我们深入研究了LangGraph,理解了其基于图的架构、状态管理和实际应用。实战部分展示了如何使用LangGraph构建具有记忆、人在回路能力和可扩展工作流的AI智能体。

随着AI的不断发展,像LangGraph、LangChain、CrewAI等智能体框架将在塑造下一代智能应用中发挥关键作用。无论你是开发聊天机器人、自动化工具还是研究智能体,这些框架都提供了创建更适应和高效AI系统的构建块。

AI的未来是自主的、结构化的和交互式的——而智能体框架正引领这一潮流。现在是开始实验、构建和创新它们的完美时机。

祝你编码愉快!🎉

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

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

相关文章

【数据资产入表】数据确权

#数据要素[话题]# #数据资源盘点[话题]# #数据资产盘点[话题]# #数据资产[话题]# #数据资产入表[话题]# #数据盘点[话题]#&…

关于vxe-select得filter-method 自定义方法得使用,忽略大小写匹配

vxe-select使用模糊匹配时&#xff0c;filter-method自定义匹配方法&#xff0c;模糊忽略大小写进行匹配数据 <vxe-select v-model"marketingId":options"marketingOptions"transfer clearable placeholder"市场"filterable :filter-method&…

AIDL 中如何传递 Parcelable 对象

目录 1. 直接在 AIDL 中定义 Parcelable 对象2. 自定义 Parcelable 对象的传递3. 以 Rect 类为例的 Parcelable 实现4. 注意安全性5. 小结1. 直接在 AIDL 中定义 Parcelable 对象 背景说明 从 Android 10(API 级别 29)开始,AIDL 允许直接在 .aidl 文件中定义 Parcelable 对…

【LangChain核心组件】Retrieval(检索)模块

在AI技术日新月异的今天&#xff0c;大型语言模型&#xff08;LLM&#xff09;的局限性也逐渐显现——它们无法有效处理特定领域知识和用户私有数据。这正是检索增强生成&#xff08;Retrieval-Augmented Generation&#xff0c;RAG&#xff09;技术崛起的根本原因。作为当前最…

Java使用WebSocket视频拆帧进度处理与拆帧图片推送,结合Apipost进行调试

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId></dependency>Configuration public class WebSocketConfig {/*** 启动 WebSocket 服务器*/Beanpublic ServerEndpointE…

XSS攻击(反射型、存储型、dom型、PDF、SWF、SVG)

一、XSS攻击是什么 XSS是恶意攻击者往 Web 页面里插入恶意可执行网页脚本代码&#xff0c;当用户浏览该页之时&#xff0c;嵌入其中 Web 里面的脚本代码会被执行&#xff0c;从而可以达到攻击者盗取用户信息或其他侵犯用户安全隐私的目的。 二、XSS分类 反射型XSS 常见情况是…

vue + element-plus自定义表单验证(修改密码业务)

写一个vue组件Password.vue 没有表单验证只有3个表单项 <template><div><el-form><el-form-item label"旧密码"><el-input></el-input></el-form-item><el-form-item label"新密码"><el-input>&l…

Linux下使用MTK的SP_Flash_tool刷机工具

MTK的SP_Flash_tool刷机工具安装流程如下&#xff1a; 1、解压SP_Flash_Tool_Linux_v5.1336.00.100_Customer.zip unzip SP_Flash_Tool_exe_Linux_64Bit_v5.1520.00.100.zip 2、首先安装 libusb-dev 这个包&#xff1a; sudo apt-get install libusb-dev 3、安装成功之后…

基于 PyGetWindow 获取窗口信息和控制窗口

PyGetWindow 是基于Python的一款简单、跨平台的模块&#xff0c;用来获取窗口信息和控制窗口。可以实现的功能有&#xff1a; 获取当前系统中所有打开窗口的列表。 根据窗口标题、窗口句柄等属性获取特定的窗口对象。 激活、最小化、最大化和关闭窗口。 获取和设置窗口的位置、…

STM32硬件IIC+DMA驱动OLED显示——释放CPU资源,提升实时性

目录 前言 一、软件IIC与硬件IIC 1、软件IIC 2、硬件IIC 二、STM32CubeMX配置KEIL配置 三、OLED驱动示例 1、0.96寸OLED 2、OLED驱动程序 3、运用示例 4、效果展示 总结 前言 0.96寸OLED屏是一个很常见的显示模块&#xff0c;其驱动方式在用采IIC通讯时&#xff0c;常用软件IIC…

【ozone工具使用指南】基于keil使用ozone创建一个调试工程

前言&#xff1a;一般调试嵌入式工程代码最常见的方式是基于keil上面DEBUG&#xff0c;使用这种最古老的方式虽然也很方便&#xff0c;但是一些功能并没有办法体现&#xff0c;比如变量的变化曲线或者波形并无法直观的显示出来&#xff0c;ozone这个工具就结合了上面提到的比ke…

【ROS2】行为树 BehaviorTree(五):详细学习端口和黑板

1、构造函数 之前使用的行为树创建节点时,默认的构造函数形如: CalculateGoal(const std::string& name, const NodeConfig& config):SyncActionNode(name,config) {

架构思维:缓存层场景实战_读缓存(下)

文章目录 Pre业务场景缓存存储数据的时机与常见问题解决方案1. 缓存读取与存储逻辑2. 高并发下的缓存问题及解决方案3. 缓存预热&#xff08;减少冷启动问题&#xff09; 缓存更新策略&#xff08;双写问题&#xff09;1. 先更新缓存&#xff0c;再更新数据库&#xff08;不推荐…

Odrive源码分析(七) 逆park变换

Odrive源码分析(七) Park逆变换 Odrive中FOC部分代码分散在各个对象中&#xff0c;并不是集中在某一块&#xff0c;所以试图在某一段代码就能得到FOC全貌是不现实的。 先看下FOC的整个流程&#xff1a; 控制变量到三相电流输出的关键部分分为Park逆变换和SVPWM。本文主要讨论…

Flink Hive Catalog最佳实践

Flink Hive Catalog 最佳实践 一、配置与初始化 依赖管理 Hive Connector 版本对齐&#xff1a;需确保 flink-sql-connector-hive 版本与 Hive 版本严格匹配&#xff08;如 Hive 3.1.3 对应 flink-sql-connector-hive-3.1.3_2.12&#xff09;&#xff0c;同时添加 Hadoop 遮蔽…

通过人类和机器人演示进行联合逆向和正向动力学的机器人训练

25年3月来自哥伦比亚大学的论文“Train Robots in a JIF: Joint Inverse and Forward Dynamics with Human and Robot Demonstrations”。 在大型机器人演示数据集上进行预训练是学习各种操作技能的强大技术&#xff0c;但通常受到收集以机器人为中心数据的高成本和复杂性限制…

金融简单介绍及金融诈骗防范

在当今社会&#xff0c;金融学如同一股无形却强大的力量&#xff0c;深刻影响着我们生活的方方面面。无论是个人的日常收支、投资理财&#xff0c;还是国家的宏观经济调控&#xff0c;都与金融学紧密相连。​ 一、金融学的概念​ 金融学&#xff0c;简单来说&#xff0c;是研…

JavaScript `new Date()` 方法移动端 `兼容 ios`,ios环境new Date()返回NaN

在 iOS 环境下&#xff0c;new Date() 方法会返回 NaN&#xff0c;这通常是由于时间字符串的格式问题。iOS 的 Date 构造函数对时间字符串的格式要求比其他平台更严格。 原因&#xff1a;ios端不兼容“-”为连接符的时间。 解决办法&#xff1a; 替换时间格式 IOS 不支持某…

【网络编程】网络编程基础和Socket套接字

目录 一. 网络编程的概念 二. 网络编程基础知识 1&#xff09;网卡 2&#xff09;接收端和发送端 3&#xff09;客户端和服务器 4&#xff09;请求和响应 5&#xff09;客户端和服务器的交互模式 三. Socket 套接字模型 一. 网络编程的概念 网络编程 是通过编程实现不同…

盛水最多的容器问题详解:双指针法与暴力法的对比与实现

文章目录 问题描述方法探讨方法一&#xff1a;暴力法&#xff08;Brute Force&#xff09;思路代码实现复杂度分析 方法二&#xff1a;双指针法&#xff08;Two Pointers&#xff09;思路正确性证明代码实现复杂度分析 方法对比总结 摘要 盛水最多的容器&#xff08;Container …