【LangChain】理论及应用实战(5):Agent

文章目录

  • 一、基本介绍
    • 1.1 Agent介绍
    • 1.2 Agent示例
  • 二、几种主要的Agent类型
    • 2.1 ZERO_SHOT_REACT_DESCRIPTION
    • 2.2 CHAT_ZERO_SHOT_REACT_DESCRIPTION
    • 2.3 CONVERSATIONAL_REACT_DESCRIPTION
    • 2.4 CHAT_CONVERSATIONAL_REACT_DESCRIPTION
    • 2.5 OPENAI_FUNCTIONS
  • 三、给Agent增加Memory
  • 四、在Agent与Tool之间共享记忆
  • 参考资料

本文主要内容参考资料:AI Agent智能体开发,一步步教你搭建agent开发环境(需求分析、技术选型、技术分解)

一、基本介绍

大模型跟人脑一样存储了大量的知识,我们不仅希望用这些知识来做一些简单的问答,我们更希望它也可以像人一样做一些自主决策,这就意味着要求它能够在没有人参与的情况下独立完成一些具有一定复杂度的任务。这个完成任务的过程就包括将任务切分成一些具体的小任务,以及每一步完成后接下来要做什么等这样的推理过程。langchain中的agent就是基于这种目标的一项功能。

在这里插入图片描述

1.1 Agent介绍

在这里插入图片描述

Agent的能力主要分为以下四部分:

  • Memory(记忆)智能体用来存储和检索历史信息的组件。它允许智能体在多次交互中保持上下文,从而做出更连贯和相关的响应。记忆可以分为短期记忆和长期记忆:
    • 短期记忆:通常用于存储当前会话中的信息,如最近的对话历史。
    • 长期记忆:用于存储更持久的信息,如用户偏好或历史数据。
  • Plan(计划): 智能体用来决定如何执行任务的策略或步骤。它涉及对当前状态和目标的分析,以生成一系列行动步骤。计划可以是静态的(预定义的)或动态的(根据当前情况生成)。
    • 静态计划:预先定义好的步骤,适用于结构化的任务。
    • 动态计划:根据当前上下文和目标实时生成的步骤,适用于复杂和动态的任务。
  • Action(动作): 智能体执行的具体操作。每个行动都是实现计划中的一个步骤。行动可以是调用一个工具、生成一段文本或执行一个外部 API 调用。
    • 工具调用:智能体可以调用各种工具来执行特定任务,如搜索、计算或数据检索。
    • 文本生成:智能体可以生成自然语言响应,与用户进行交互。
  • Tools(工具): 智能体用来执行特定任务的函数或 API。工具可以包括搜索引擎、数据库查询、计算器、翻译服务等。智能体通过调用这些工具来获取信息或执行操作。
    • 内置工具:LangChain 提供了一些内置工具,如搜索工具、计算工具等。
    • 自定义工具:开发者可以根据需要创建自定义工具,并将其集成到智能体中。

主要流程:

  1. (用户)提出需求/问题
  2. 问题+Prompt组合
  3. ReAct Loop
  4. 查找Memory
  5. 查找可用工具
  6. 执行工具并观察结果
  7. 重复步骤2-7只到得到最终结果

1.2 Agent示例

一个最简单的Agent的示例,具备两个功能:

  1. 会做数学题
  2. 不知道答案的时候可以搜索

实现代码如下:

import os
from langchain.llms import OpenAI
from langchain.agents import load_tools
from langchain.agents import initialize_agent, AgentType# 定义LLM
1lm = OpenAI(temperature=0,model="gpt-3.5-turbo-instruct",
)# 搭建工具:serpai搜索引擎可以实现在线搜索
# pip install google-search-resultsos.environ["SERPAPI_API_KEY"] = "xxxxxxxxxxxxx"tools = load_tools(["serpapi", "llm-math"], llm=llm)agent = initialize_agent(tools=tools,llm=llm,agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION,  # agent的类型verbose=True
)
agent.run("请问上一任的美国总统是谁?他的年龄除以2的整数是多少?")

二、几种主要的Agent类型

langchain中内置的几种主要的Agent类型包括:

  1. OPENAI_FUNCTIONS:OPENAI函数调用型,遵循OPENAI风格的用法
  2. ZERO_SHOT_REACT_DESCRIPTION:零样本增强生成型(LLM)
  3. CHAT_ZERO_SHOT_REACT_DESCRIPTION:零样本增强生成型(Chat Model)
  4. CONVERSATIONAL_REACT_DESCRIPTION:对话增强生成型

我们可以看下官方关于 AgentType 的源代码:

class AgentType(str, Enum):"""An enum for agent types.See documentation: https://python.langchain.com/docs/modules/agents/agent_types/"""ZERO_SHOT_REACT_DESCRIPTION = "zero-shot-react-description""""A zero shot agent that does a reasoning step before acting."""REACT_DOCSTORE = "react-docstore""""A zero shot agent that does a reasoning step before acting.This agent has access to a document store that allows it to look up relevant information to answering the question."""SELF_ASK_WITH_SEARCH = "self-ask-with-search""""An agent that breaks down a complex question into a series of simpler questions.This agent uses a search tool to look up answers to the simpler questionsin order to answer the original complex question."""CONVERSATIONAL_REACT_DESCRIPTION = "conversational-react-description"CHAT_ZERO_SHOT_REACT_DESCRIPTION = "chat-zero-shot-react-description""""A zero shot agent that does a reasoning step before acting.This agent is designed to be used in conjunction """CHAT_CONVERSATIONAL_REACT_DESCRIPTION = "chat-conversational-react-description"STRUCTURED_CHAT_ZERO_SHOT_REACT_DESCRIPTION = ("structured-chat-zero-shot-react-description")"""An zero-shot react agent optimized for chat models.This agent is capable of invoking tools that have multiple inputs."""OPENAI_FUNCTIONS = "openai-functions""""An agent optimized for using open AI functions."""OPENAI_MULTI_FUNCTIONS = "openai-multi-functions"

实际上不同类型的Agent在处理任务时,对应着不同的Prompt模版(可以通过上面 AgentType 的定义或者打印Agent在解决问题的中间输出过程看到)。

下面我们结合代码示例的形式来具体讲解每种Agent。首先给出Agent的基础的可复用的代码,后面只需将LLM及Agent定义的代码替换即可:

# 几种主要的agent
import os
from langchain.agents import load_tools, initialize_agent, AgentType# 搭建工具:serpai 可以实现在线搜索
# pip install google-search-results
# pip install numexpr  # llm-math工具需要安装os.environ["SERPAPI_API_KEY"] = "xxxxxxxxxxxxx"
tools = load_tools(["serpapi", "llm-math"], llm=llm)"""
替换为LLM及Agent的定义代码
"""agent.run("请问上一任的美国总统是谁?他的年龄除以2的整数是多少?")

2.1 ZERO_SHOT_REACT_DESCRIPTION

ZERO_SHOT_REACT_DESCRIPTION 零样本增强生成型(LLM)Agent,即在没有示例的情况下可以自主地进行对话。

from langchain.llms import OpenAI# 定义LLM
1lm = OpenAI(temperature=0,model="gpt-3.5-turbo-instruct",
)# 定义Agent:ZERO_SHOT_REACT_DESCRIPTION
agent = initialize_agent(tools=tools,llm=llm,agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION,verbose=True
)

输出如下:

{'input''现在美国总统是谁?他的年龄除以2是多少?',
'output''Joe Biden is the current US president and his age divided by 2 is 39.0.'}

注意:不同类型的Agent在处理任务时,对应着不同的Prompt模版。ZERO_SHOT_REACT_DESCRIPTION 类型的Agent 对应的 Prompt 示例如下:

template='Answer the following questions as best you can. You have access to the following tools:\n\nCalculator(*args: Any, callbacks: Union[list[langchain_core.callbacks.base.BaseCallbackHandler], langchain_core.callbacks.base.BaseCallbackManager, NoneType] = None, tags: Optional[List[str]] = None, metadata: Optional[Dict[str, Any]] = None, **kwargs: Any) -> Any - Useful for when you need to answer questions about math.\n\nUse the following format:\n\nQuestion: the input question you must answer\nThought: you should always think about what to do\nAction: the action to take, should be one of [Calculator]\nAction Input: the input to the action\nObservation: the result of the action\n... (this Thought/Action/Action Input/Observation can repeat N times)\nThought: I now know the final answer\nFinal Answer: the final answer to the original input question\n\nBegin!\n\nQuestion: {input}\nThought:{agent_scratchpad}')

2.2 CHAT_ZERO_SHOT_REACT_DESCRIPTION

Agent的 CHAT_ZERO_SHOT_REACT_DESCRIPTION 类型 与 ZERO_SHOT_REACT_DESCRIPTION 类似,主要区别在于其大模型需要使用Chat Model。

from langchain.chat_models import ChatOpenAI# 定义Chat Model
1lm = ChatOpenAI(temperature=0,model="gpt-3.5-turbo",
)# 定义Agent:CHAT_ZERO_SHOT_REACT_DESCRIPTION
agent = initialize_agent(tools=tools,llm=llm,agent=AgentType.CHAT_ZERO_SHOT_REACT_DESCRIPTION,verbose=True
)

输出如下:

{'input''现在美国总统是谁?他的年龄除以2是多少?',
'output''Joe Biden, 40.5.'}

2.3 CONVERSATIONAL_REACT_DESCRIPTION

CONVERSATIONAL_REACT_DESCRIPTION 是一个对话型Agent,其使用的大模型是LLM模型,且需要和 memory 一起使用。

from langchain.llms import OpenAI
from langchain.memory import ConversationBufferMemory# 定义LLM
1lm = OpenAI(temperature=0,model="gpt-3.5-turbo-instruct",
)# 定义Memory
memory = ConversationBufferMemory(memory_key="chat_history"
)# 定义Agent:CONVERSATIONAL_REACT_DESCRIPTION
agent = initialize_agent(tools=tools,llm=llm,agent=AgentType.CONVERSATIONAL_REACT_DESCRIPTION,memory=memory, verbose=True
)

2.4 CHAT_CONVERSATIONAL_REACT_DESCRIPTION

CHAT_CONVERSATIONAL_REACT_DESCRIPTIONCONVERSATIONAL_REACT_DESCRIPTION类似,主要区别在于其使用Chat Model。

from langchain.chat_models import ChatOpenAI
from langchain.memory import ConversationBufferMemory# 定义LLM
1lm = ChatOpenAI(temperature=0,model="gpt-3.5-turbo",
)# 定义Memory
memory = ConversationBufferMemory(memory_key="chat_history"
)# 定义Agent:CHAT_CONVERSATIONAL_REACT_DESCRIPTION
agent = initialize_agent(tools=tools,llm=llm,agent=AgentType.CONVERSATIONAL_REACT_DESCRIPTION,memory=memory, verbose=True
)

2.5 OPENAI_FUNCTIONS

OPENAI_FUNCTIONS 使用OpenAI的函数调用(function_call)实现,只支持OpenAI的模型

from langchain.llms import OpenAI# 定义LLM
1lm = OpenAI(temperature=0,model="gpt-3.5-turbo-instruct",
)# 定义Agent:OPENAI_FUNCTIONS
agent = initialize_agent(tools=tools,llm=llm,agent=AgentType.OPENAI_FUNCTIONS,verbose=True
)

三、给Agent增加Memory

在这里插入图片描述
给Agent增加Memory的本质在于将Memory插入Agent的Prompt模板中。
代码示例如下:

from langchain.agents import (load_tools,AgentType,initialize_agent
)
from langchain.memory import ConversationBufferMemory
from langchain_ollama import OllamaLLM
from langchain.prompts import MessagesPlaceholder# 定义LLM
llm = OllamaLLM(model="llama3.1:8b")# 定义tools
tools = load_tools(["llm-math"], llm=llm)# 定义Memory
memory = ConversationBufferMemory(memory_key="Memory",return_messages=True
)# 定义Agent
agent = initialize_agent(tools=tools,llm=llm,agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION,agent_kwargs={  # 基于agent_kwargs传递参数,将memory_key传入提示词中"extra_prom_messages":[MessagesPlaceholder(variable_name="Memory"),MessagesPlaceholder(variable_name="agent_scratchpad")]},memory=memory,verbose=True
)# agent.run("你好,我是Mary。")
print(agent)

输出如下:

 memory=ConversationBufferMemory(chat_memory=InMemoryChatMessageHistory(messages=[]), return_messages=True, memory_key='Memory') verbose=True tags=['zero-shot-react-description'] agent=ZeroShotAgent(llm_chain=LLMChain(verbose=False, prompt=PromptTemplate(input_variables=['agent_scratchpad', 'input'], input_types={}, partial_variables={}, template='Answer the following questions as best you can. You have access to the following tools:\n\nCalculator(*args: Any, callbacks: Union[list[langchain_core.callbacks.base.BaseCallbackHandler], langchain_core.callbacks.base.BaseCallbackManager, NoneType] = None, tags: Optional[List[str]] = None, metadata: Optional[Dict[str, Any]] = None, **kwargs: Any) -> Any - Useful for when you need to answer questions about math.\n\nUse the following format:\n\nQuestion: the input question you must answer\nThought: you should always think about what to do\nAction: the action to take, should be one of [Calculator]\nAction Input: the input to the action\nObservation: the result of the action\n... (this Thought/Action/Action Input/Observation can repeat N times)\nThought: I now know the final answer\nFinal Answer: the final answer to the original input question\n\nBegin!\n\nQuestion: {input}\nThought:{agent_scratchpad}'), llm=OllamaLLM(model='llama3.1:8b'), output_parser=StrOutputParser(), llm_kwargs={}), output_parser=MRKLOutputParser(), allowed_tools=['Calculator']) tools=[Tool(name='Calculator', description='Useful for when you need to answer questions about math.', func=<bound method Chain.run of LLMMathChain(verbose=False, llm_chain=LLMChain(verbose=False, prompt=PromptTemplate(input_variables=['question'], input_types={}, partial_variables={}, template='Translate a math problem into a expression that can be executed using Python\'s numexpr library. Use the output of running this code to answer the question.\n\nQuestion: ${{Question with math problem.}}\n```text\n${{single line mathematical expression that solves the problem}}\n```\n...numexpr.evaluate(text)...\n```output\n${{Output of running the code}}\n```\nAnswer: ${{Answer}}\n\nBegin.\n\nQuestion: What is 37593 * 67?\n```text\n37593 * 67\n```\n...numexpr.evaluate("37593 * 67")...\n```output\n2518731\n```\nAnswer: 2518731\n\nQuestion: 37593^(1/5)\n```text\n37593**(1/5)\n```\n...numexpr.evaluate("37593**(1/5)")...\n```output\n8.222831614237718\n```\nAnswer: 8.222831614237718\n\nQuestion: {question}\n'), llm=OllamaLLM(model='llama3.1:8b'), output_parser=StrOutputParser(), llm_kwargs={}))>, coroutine=<bound method Chain.arun of LLMMathChain(verbose=False, llm_chain=LLMChain(verbose=False, prompt=PromptTemplate(input_variables=['question'], input_types={}, partial_variables={}, template='Translate a math problem into a expression that can be executed using Python\'s numexpr library. Use the output of running this code to answer the question.\n\nQuestion: ${{Question with math problem.}}\n```text\n${{single line mathematical expression that solves the problem}}\n```\n...numexpr.evaluate(text)...\n```output\n${{Output of running the code}}\n```\nAnswer: ${{Answer}}\n\nBegin.\n\nQuestion: What is 37593 * 67?\n```text\n37593 * 67\n```\n...numexpr.evaluate("37593 * 67")...\n```output\n2518731\n```\nAnswer: 2518731\n\nQuestion: 37593^(1/5)\n```text\n37593**(1/5)\n```\n...numexpr.evaluate("37593**(1/5)")...\n```output\n8.222831614237718\n```\nAnswer: 8.222831614237718\n\nQuestion: {question}\n'), llm=OllamaLLM(model='llama3.1:8b'), output_parser=StrOutputParser(), llm_kwargs={}))>)]

注意给Agent增加 Memory 的关键在于 基于agent_kwargs传递参数,将memory_key传入提示词中。

四、在Agent与Tool之间共享记忆

Tool 可以基于“只读”的形式读取Agent的Memory(不能写入),这主要是通过 langchain.memory 模块下的 ReadOnlySharedMemory 来实现的。
在这里插入图片描述

这里我们使用一个“总结文本链”,并基于 ReadOnlySharedMemory 来实现Tool 与 Agent 共享Memory。(注意:这里只给出了核心代码)

from langchain.chains import LLMChain
from langchain.memory import ConversationBufferMemory, ReadOnlySharedMemory# 定义Memory
memory = ConversationBufferMemory(memory_key="Memory",return_messages=True
)# 只读Memory
readonMemory = ReadOnlySharedMemory(memory=memory)# 定义Tool: 总结Chain
summary_chain = LLMChain(llm=llm,prompt=prompt,memory=readonMemory,verbose=True
)# 定义Agent
agent_chain = initialize_agent(tools,ltm,agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION,verbose=True,handle_parsing_errors=True,memory=memory,
)注意:这里只给出了核心代码

参考资料

  • AI Agent智能体开发,一步步教你搭建agent开发环境(需求分析、技术选型、技术分解)

  • LangChain学习记录(四)Agent

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

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

相关文章

口袋书签系统:AI 智能生成分类描述,省时又高效

口袋书签一键触达&#xff0c;免费使用&#xff1a;https://navfinder.cn/ 口袋书签系统新增了“根据收藏站点&#xff0c;AI自动生成分类描述”的功能&#xff0c;简要说明如下&#xff1a; 自动分析站点信息 系统会根据用户当前分类中的站点标题、标签等信息&#xff0c;结合…

AtCoder Beginner Contest 397 A - D题解

Tasks - OMRON Corporation Programming Contest 2025 (AtCoder Beginner Contest 397) 本文为 AtCoder Beginner Contest 397 A - D题解 题目A: 代码(C): #include <bits/stdc.h>int main() {double n;std::cin >> n;if (n > 38.0) {std::cout << 1;}…

linux按照nginx

第一步先按照依赖gcc 一键安装上面四个依赖 Nginx的编译安装需要一些依赖库&#xff0c;如gcc、make、zlib、openssl等。可以使用yum命令安装这些依赖&#xff1a; yum -y install gcc zlib zlib-devel pcre-devel openssl openssl-devel 创建目录 mkdir /usr/nginx 切换…

Muon: An optimizer for hidden layers in neural networks

引言 在深度学习领域&#xff0c;优化算法对模型训练效率和性能起着关键作用。从经典的随机梯度下降 (SGD) 及其动量法&#xff0c;到自适应优化方法 Adam/AdamW 等&#xff0c;一系列优化器大大加速了神经网络的收敛。然而&#xff0c;随着模型规模和数据量的爆炸式增长&…

数据结构与算法-图论-拓扑排序

前置芝士 概念 拓扑排序&#xff08;Topological Sorting&#xff09;是对有向无环图&#xff08;DAG&#xff0c;Directed Acyclic Graph&#xff09;的顶点进行排序的一种算法。它将图中的所有顶点排成一个线性序列&#xff0c;使得对于图中的任意一条有向边 (u, v)&#x…

市长海报/ Mayor‘s posters

AB 省 Bytetown 的市民无法忍受市长竞选活动的候选人随心所欲地将他们的选举海报贴在各个地方。市议会最终决定建造一面选举墙来放置海报&#xff0c;并引入以下规则&#xff1a; 每个候选人都可以在墙上放置一张海报。所有海报的高度都与墙壁的高度相同;海报的宽度可以是任意整…

LeetCode hot 100—验证二叉搜索树

题目 给你一个二叉树的根节点 root &#xff0c;判断其是否是一个有效的二叉搜索树。 有效 二叉搜索树定义如下&#xff1a; 节点的左子树只包含 小于 当前节点的数。节点的右子树只包含 大于 当前节点的数。所有左子树和右子树自身必须也是二叉搜索树。 示例 示例 1&#…

ccfcsp3402矩阵重塑(其二)

//矩阵重塑&#xff08;其二&#xff09; #include<iostream> using namespace std; int main(){int n,m,t;cin>>n>>m>>t;int c[10000][10000];int s0,sum0;int d[10000],k[100000];for(int i0;i<n;i){for(int j0;j<m;j){cin>>c[i][j];d[s…

MCP和Function Calling的区别

文章目录 1、什么是MCP1.1、定义和特点1.2、架构和工作原理3.3、MCP 的主要优势 2、什么是Function Calling3、MCP和Function Calling的区别4、总结 &#x1f343;作者介绍&#xff1a;双非本科大四网络工程专业在读&#xff0c;阿里云专家博主&#xff0c;前三年专注于Java领域…

裂缝识别系统 Matlab GUI设计

使用说明 裂缝识别系统 Matlab GUI设计 &#xff0c;运行环境Matlab2023b及以上&#xff1b; 一种基于MATLAB图形用户界面&#xff08;GUI&#xff09;的裂缝自动识别系统&#xff0c;该系统利用数字图像处理技术实现裂缝图像的预处理&#xff0c;集成均衡化、噪声滤波、对比…

【源码分析】Nacos实例注册流程分析-事件驱动框架

【踩坑记录】 本人下载的Nacos 服务端版本是2.3.2&#xff0c;在开始进行源码编译便遇到问题&#xff0c;下面是各个问题记录 源码大量爆红 在最开始用Idea加载Maven项目的时候&#xff0c;发现项目中大量的代码爆红&#xff0c;提示其类或者包不存在&#xff0c;后来结果查…

51单片机指令系统入门

目录 基本概念讲解 一、机器指令​ 二、汇编指令​ &#xff08;一&#xff09;汇编指令的一般格式 &#xff08;二&#xff09;按字节数分类的指令 三、高级指令 总结​ 基本概念讲解 指令是计算机&#xff08;或单片机&#xff09;中 CPU 能够识别并执行的基本操作命令…

mysql5.x和mysql8.x查看和设置隔离级别

MySQL的隔离级别 级别标志值描述读未提交READ-UNCOMMITTED0存在脏读、不可重复读、幻读的问题读已提交READ-COMMITTED1解决脏读的问题&#xff0c;存在不可重复读、幻读的问题可重复读REPEATABLE-READ2mysql 默认级别&#xff0c;解决脏读、不可重复读的问题&#xff0c;存在幻…

【函数式编程】【C#/F#】第四讲:单子与函子 - 抽象的编程模式

在第二讲中我们探讨了一个诚实的函数应该要做到什么事&#xff0c;并运用了一种方法&#xff0c;让我们可以去准确的描述数据。 不过有一种情况让我们始料未及&#xff0c;例如网站需要收集一些信息&#xff0c;但有些信息不是必须的&#xff0c;是可有可无的。如果我们要去准…

【vue2 + Cesium】使用Cesium、添加第三方地图、去掉商标、Cesium基础配置、地图放大缩小事件、获取可视区域、层级、高度

参考文章&#xff1a; vue2 使用 cesium 篇【第一篇】 vue2 使用 cesium 【第二篇-相机视角移动添加模型】 vue2 项目模版&#xff1a; vue2-common 安装 cesium npm install cesium --save这个就很简单&#xff0c;只需要一句简简单单的命令就可以实现在 vue 项目中安装 ce…

vllm-openai多服务器集群部署AI模型

服务器配置是两台ubantu系统电脑,每台电脑安装两张4090-48G显存的显卡,共计192G显存。 服务器1 服务器2 准备工作: 1.两台电脑都已经安装了docker 2.两台电脑都已经安装了nvidia驱动 参考vllm官方资料 https://docs.vllm.ai/en/latest/serving/distributed_serving.html…

【电源】斩波电路

文章目录 前言定义概念 缩写降压斩波电路使用步骤总结参考文献 前言 进行大创项目开发的学习 bilibili 定义概念 缩写 斩波电路&#xff1a;分为降压&#xff0c;电荷泵&#xff0c;升压&#xff0c;升降压&#xff0c;Cuk&#xff0c;Speic&#xff0c;Zeta 等等 降压斩…

Hadoop集群组成

&#xff08;一&#xff09;Hadoop的组成 对普通用户来说&#xff0c; Hadoop就是一个东西&#xff0c;一个整体&#xff0c;它能给我们提供无限的磁盘用来保存文件&#xff0c;可以使用提供强大的计算能力。 在Hadoop3.X中&#xff0c;hadoop一共有三个组成部…

c++基础知识-图论进阶

一、拓扑排序 1、基础知识 1&#xff09;什么是拓扑排序 对一个有向无环图G进行拓扑排序&#xff0c;是将G中所有顶点排成一个线性序列&#xff0c;使得图中任意一对顶点u和v&#xff0c;若&#xff0c;则u在线性序列中出现在v之前。 2&#xff09;拓扑排序的操作方法 重复执行…

从Scaling Laws中解析大模型训练的边际递减临界点

前言 当我们拆解GPT-4到DeepSeek的演进路径&#xff0c;会发现一个反直觉的真相&#xff1a;​AI的智能跃迁不依赖参数堆砌&#xff0c;而取决于对"结构-能量-信息"三元关系的精准把控。就像人类大脑在进化中通过皮层折叠而非单纯增大体积来实现智能突破&#xff0c…