构建LangChain应用程序的示例代码:55、如何实现多代理模拟,其中特权代理决定谁发言。这遵循与多代理分散发言者选择相反的选择方案
示例展示了如何实现一个多代理模拟,其中一个特权代理决定谁来发言。
这遵循与多代理分散式发言人选择相反的选择方案。
我们在一个虚构的新闻网络模拟环境中展示这种方法的一个例子。这个例子将展示我们如何实现能够:
- 在说话前思考
- 终止对话
的代理。
导入LangChain相关模块
import functools
import random
from collections import OrderedDict
from typing import Callable, Listimport tenacity
from langchain.output_parsers import RegexParser
from langchain.prompts import (PromptTemplate,
)
from langchain.schema import (HumanMessage,SystemMessage,
)
from langchain_openai import ChatOpenAI# 导入所需的Python模块和LangChain组件
# 包括功能性工具、随机数生成、有序字典、类型提示
# 以及LangChain的输出解析器、提示模板、消息模式和OpenAI聊天模型
DialogueAgent
和 DialogueSimulator
类
我们将使用在其他示例多人龙与地下城和分散式发言人选择中定义的相同 DialogueAgent
和 DialogueSimulator
类。
class DialogueAgent:def __init__(self,name: str,system_message: SystemMessage,model: ChatOpenAI,) -> None:self.name = nameself.system_message = system_messageself.model = modelself.prefix = f"{self.name}: "self.reset()def reset(self):self.message_history = ["Here is the conversation so far."]def send(self) -> str:"""应用聊天模型到消息历史并返回消息字符串"""message = self.model.invoke([self.system_message,HumanMessage(content="\n".join(self.message_history + [self.prefix])),])return message.contentdef receive(self, name: str, message: str) -> None:"""将{name}说的{message}连接到消息历史中"""self.message_history.append(f"{name}: {message}")class DialogueSimulator:def __init__(self,agents: List[DialogueAgent],selection_function: Callable[[int, List[DialogueAgent]], int],) -> None:self.agents = agentsself._step = 0self.select_next_speaker = selection_functiondef reset(self):for agent in self.agents:agent.reset()def inject(self, name: str, message: str):"""用{name}的{message}启动对话"""for agent in self.agents:agent.receive(name, message)# 增加时间步self._step += 1def step(self) -> tuple[str, str]:# 1. 选择下一个说话者speaker_idx = self.select_next_speaker(self._step, self.agents)speaker = self.agents[speaker_idx]# 2. 下一个说话者发送消息message = speaker.send()# 3. 每个人接收消息for receiver in self.agents:receiver.receive(speaker.name, message)# 4. 增加时间步self._step += 1return speaker.name, message# 定义对话代理类,包含初始化、重置、发送和接收消息的方法
# 定义对话模拟器类,包含初始化、重置、注入消息和执行一步模拟的方法
DirectorDialogueAgent
类
DirectorDialogueAgent
是一个特权代理,负责选择其他代理中的哪一个下一个发言。这个代理负责
- 通过选择何时让哪个代理发言来引导对话
- 终止对话。
为了实现这样一个代理,我们需要解决几个问题。
首先,为了引导对话,DirectorDialogueAgent
需要在一条消息中(1)反思已经说过的内容,(2)选择下一个代理,以及(3)提示下一个代理发言。虽然可能可以提示LLM在同一个调用中执行所有三个步骤,但这需要编写自定义代码来解析输出的消息以提取选择的下一个代理。这不太可靠,因为LLM可以用不同的方式表达它如何选择下一个代理。
相反,我们可以做的是将步骤(1-3)明确地分成三个单独的LLM调用。首先,我们会要求DirectorDialogueAgent
反思到目前为止的对话并生成一个响应。然后我们提示DirectorDialogueAgent
输出下一个代理的索引,这很容易解析。最后,我们将选定的下一个代理的名字传回DirectorDialogueAgent
,要求它提示下一个代理发言。
其次,简单地提示DirectorDialogueAgent
决定何时终止对话通常会导致DirectorDialogueAgent
立即终止对话。为了解决这个问题,我们随机抽样一个伯努利变量来决定对话是否应该终止。根据这个变量的值,我们将注入一个自定义提示,告诉DirectorDialogueAgent
继续对话或终止对话。
class IntegerOutputParser(RegexParser):def get_format_instructions(self) -> str:return "Your response should be an integer delimited by angled brackets, like this: <int>."# 定义整数输出解析器,用于解析输出中的整数class DirectorDialogueAgent(DialogueAgent):def __init__(self,name,system_message: SystemMessage,model: ChatOpenAI,speakers: List[DialogueAgent],stopping_probability: float,) -> None:super().__init__(name, system_message, model)self.speakers = speakersself.next_speaker = ""self.stop = Falseself.stopping_probability = stopping_probabilityself.termination_clause = "Finish the conversation by stating a concluding message and thanking everyone."self.continuation_clause = "Do not end the conversation. Keep the conversation going by adding your own ideas."# 1. 有一个用于生成对前一个说话者的响应的提示self.response_prompt_template = PromptTemplate(input_variables=["message_history", "termination_clause"],template=f"""{{message_history}}Follow up with an insightful comment.
{{termination_clause}}
{self.prefix}""",)# 2. 有一个用于决定下一个说话者的提示self.choice_parser = IntegerOutputParser(regex=r"<(\d+)>", output_keys=["choice"], default_output_key="choice")self.choose_next_speaker_prompt_template = PromptTemplate(input_variables=["message_history", "speaker_names"],template=f"""{{message_history}}Given the above conversation, select the next speaker by choosing index next to their name:
{{speaker_names}}{self.choice_parser.get_format_instructions()}Do nothing else.""",)# 3. 有一个用于提示下一个说话者发言的提示self.prompt_next_speaker_prompt_template = PromptTemplate(input_variables=["message_history", "next_speaker"],template=f"""{{message_history}}The next speaker is {{next_speaker}}.
Prompt the next speaker to speak with an insightful question.
{self.prefix}""",)def _generate_response(self):# 如果self.stop = True,那么我们将注入带有终止条款的提示sample = random.uniform(0, 1)self.stop = sample < self.stopping_probabilityprint(f"\tStop? {self.stop}\n")response_prompt = self.response_prompt_template.format(message_history="\n".join(self.message_history),termination_clause=self.termination_clause if self.stop else "",)self.response = self.model.invoke([self.system_message,HumanMessage(content=response_prompt),]).contentreturn self.response@tenacity.retry(stop=tenacity.stop_after_attempt(2),wait=tenacity.wait_none(), # 重试之间无等待时间retry=tenacity.retry_if_exception_type(ValueError),before_sleep=lambda retry_state: print(f"ValueError occurred: {retry_state.outcome.exception()}, retrying..."),retry_error_callback=lambda retry_state: 0,) # 当所有重试都用尽时的默认值def _choose_next_speaker(self) -> str:speaker_names = "\n".join([f"{idx}: {name}" for idx, name in enumerate(self.speakers)])choice_prompt = self.choose_next_speaker_prompt_template.format(message_history="\n".join(self.message_history + [self.prefix] + [self.response]),speaker_names=speaker_names,)choice_string = self.model.invoke([self.system_message,HumanMessage(content=choice_prompt),]).contentchoice = int(self.choice_parser.parse(choice_string)["choice"])return choicedef select_next_speaker(self):return self.chosen_speaker_iddef send(self) -> str:"""应用聊天模型到消息历史并返回消息字符串"""# 1. 生成并保存对前一个说话者的响应self.response = self._generate_response()if self.stop:message = self.responseelse:# 2. 决定下一个说话者self.chosen_speaker_id = self._choose_next_speaker()self.next_speaker = self.speakers[self.chosen_speaker_id]print(f"\tNext speaker: {self.next_speaker}\n")# 3. 提示下一个说话者发言next_prompt = self.prompt_next_speaker_prompt_template.format(message_history="\n".join(self.message_history + [self.prefix] + [self.response]),next_speaker=self.next_speaker,)message = self.model.invoke([self.system_message,HumanMessage(content=next_prompt),]).contentmessage = " ".join([self.response, message])return message# 定义导演对话代理类,继承自DialogueAgent
# 包含生成响应、选择下一个说话者和发送消息的方法
# 使用tenacity库进行重试处理
定义参与者和话题
topic = "The New Workout Trend: Competitive Sitting - How Laziness Became the Next Fitness Craze"
director_name = "Jon Stewart"
agent_summaries = OrderedDict({"Jon Stewart": ("Host of the Daily Show", "New York"),"Samantha Bee": ("Hollywood Correspondent", "Los Angeles"),"Aasif Mandvi": ("CIA Correspondent", "Washington D.C."),"Ronny Chieng": ("Average American Correspondent", "Cleveland, Ohio"),}
)
word_limit = 50# 定义讨论话题、主持人名称、参与者信息和字数限制
生成系统消息
agent_summary_string = "\n- ".join([""]+ [f"{name}: {role}, located in {location}"for name, (role, location) in agent_summaries.items()]
)conversation_description = f"""This is a Daily Show episode discussing the following topic: {topic}.The episode features {agent_summary_string}."""agent_descriptor_system_message = SystemMessage(content="You can add detail to the description of each person."
)def generate_agent_description(agent_name, agent_role, agent_location):agent_specifier_prompt = [agent_descriptor_system_message,HumanMessage(content=f"""{conversation_description}Please reply with a creative description of {agent_name}, who is a {agent_role} in {agent_location}, that emphasizes their particular role and location.Speak directly to {agent_name} in {word_limit} words or less.Do not add anything else."""),]agent_description = ChatOpenAI(temperature=1.0)(agent_specifier_prompt).contentreturn agent_descriptiondef generate_agent_header(agent_name, agent_role, agent_location, agent_description):return f"""{conversation_description}Your name is {agent_name}, your role is {agent_role}, and you are located in {agent_location}.Your description is as follows: {agent_description}You are discussing the topic: {topic}.Your goal is to provide the most informative, creative, and novel perspectives of the topic from the perspective of your role and your location.
"""def generate_agent_system_message(agent_name, agent_header):return SystemMessage(content=(f"""{agent_header}
You will speak in the style of {agent_name}, and exaggerate your personality.
Do not say the same things over and over again.
Speak in the first person from the perspective of {agent_name}
For describing your own body movements, wrap your description in '*'.
Do not change roles!
Do not speak from the perspective of anyone else.
Speak only from the perspective of {agent_name}.
Stop speaking the moment you finish speaking from your perspective.
Never forget to keep your response to {word_limit} words!
Do not add anything else."""))agent_descriptions = [generate_agent_description(name, role, location)for name, (role, location) in agent_summaries.items()
]
agent_headers = [generate_agent_header(name, role, location, description)for (name, (role, location)), description in zip(agent_summaries.items(), agent_descriptions)
]
agent_system_messages = [generate_agent_system_message(name, header)for name, header in zip(agent_summaries, agent_headers)
]# 生成代理描述、代理头部和系统消息
# 使用OpenAI聊天模型生成创意描述
# 组合生成每个代理的完整系统消息
for name, description, header, system_message in zip(agent_summaries, agent_descriptions, agent_headers, agent_system_messages
):print(f"\n\n{name} Description:")print(f"\n{description}")print(f"\nHeader:\n{header}")print(f"\nSystem Message:\n{system_message.content}")# 打印每个代理的描述、头部和系统消息
使用LLM详细阐述讨论话题
topic_specifier_prompt = [SystemMessage(content="You can make a task more specific."),HumanMessage(content=f"""{conversation_description}Please elaborate on the topic. Frame the topic as a single question to be answered.Be creative and imaginative.Please reply with the specified topic in {word_limit} words or less. Do not add anything else."""),
]
specified_topic = ChatOpenAI(temperature=1.0)(topic_specifier_prompt).contentprint(f"Original topic:\n{topic}\n")
print(f"Detailed topic:\n{specified_topic}\n")# 使用OpenAI聊天模型生成更详细的话题描述
# 将话题转化为一个需要回答的问题
定义说话者选择函数
最后我们将定义一个说话者选择函数 select_next_speaker
,它接受每个代理的出价并选择出价最高的代理(随机打破平局)。
我们将定义一个 ask_for_bid
函数,它使用我们之前定义的 bid_parser
来解析代理的出价。我们将使用 tenacity
来装饰 ask_for_bid
,以便在代理的出价无法正确解析时多次重试,并在最大尝试次数后产生默认出价0。
def select_next_speaker(step: int, agents: List[DialogueAgent], director: DirectorDialogueAgent
) -> int:"""如果步骤是偶数,则选择导演否则,由导演选择下一个说话者。"""# 导演在奇数步骤说话if step % 2 == 1:idx = 0else:# 这里导演选择下一个说话者idx = director.select_next_speaker() + 1 # +1 因为我们排除了导演return idx# 定义选择下一个说话者的函数
# 在奇数步骤选择导演,否则由导演选择
主循环
director = DirectorDialogueAgent(name=director_name,system_message=agent_system_messages[0],model=ChatOpenAI(temperature=0.2),speakers=[name for name in agent_summaries if name != director_name],stopping_probability=0.2,
)agents = [director]
for name, system_message in zip(list(agent_summaries.keys())[1:], agent_system_messages[1:]
):agents.append(DialogueAgent(name=name,system_message=system_message,model=ChatOpenAI(temperature=0.2),))# 创建导演代理和其他对话代理
simulator = DialogueSimulator(agents=agents,selection_function=functools.partial(select_next_speaker, director=director),
)
simulator.reset()
simulator.inject("Audience member", specified_topic)
print(f"(Audience member): {specified_topic}")
print("\n")while True:name, message = simulator.step()print(f"({name}): {message}")print("\n")if director.stop:break# 创建对话模拟器并运行模拟
# 注入指定话题并循环执行模拟步骤
# 直到导演决定停止对话
总结
本文介绍了如何实现一个多代理模拟系统,其中一个特权代理决定谁来发言。这与分散式发言人选择方案相反。文章以一个虚构的新闻网络模拟为例,展示了如何实现能够在说话前思考并终止对话的代理。
扩展知识
-
多代理系统:这是人工智能和自然语言处理领域的一个重要研究方向,涉及多个AI代理之间的交互和协作。这种系统可以模拟复杂的社会互动,用于各种应用,如虚拟助手、游戏AI和社会模拟。
-
对话管理:在这个示例中,导演代理负责管理对话流程。这反映了现实世界中的对话管理策略,如在会议或访谈中由主持人引导讨论。
-
自然语言生成(NLG):系统中的每个代理都使用NLG技术来生成响应。这涉及到根据上下文和角色生成连贯、相关和自然的语言输出。
-
角色扮演AI:每个代理都被赋予了特定的角色和个性。这种技术可以用于创建更真实和引人入胜的AI角色,用于娱乐、教育或训练目的。
-
概率决策:使用随机抽样来决定是否结束对话是一种简单但有效的方法,可以引入不可预测性和多样性。在更复杂的系统中,这可能涉及更高级的概率模型和决策理论。
相关文章:
构建LangChain应用程序的示例代码:55、如何实现多代理模拟,其中特权代理决定谁发言。这遵循与多代理分散发言者选择相反的选择方案
示例展示了如何实现一个多代理模拟,其中一个特权代理决定谁来发言。 这遵循与多代理分散式发言人选择相反的选择方案。 我们在一个虚构的新闻网络模拟环境中展示这种方法的一个例子。这个例子将展示我们如何实现能够: 在说话前思考终止对话 的代理。 导入LangChain相关模块…...

船舶雷达与导航系统选择7/8防水插座的原因分析
概述 船舶雷达与导航系统在现代航海中扮演着至关重要的角色,它们为船舶提供准确的导航信息,确保航行的安全和效率。在这些系统中,7/8防水插座的使用尤为重要,因为它们能够在恶劣的海上环境中提供稳定的电力和信号连接。接下来&am…...
墨烯的C语言技术栈-C语言基础-006
六.常量 C语言的常量为 字面常量 const修饰的常变量 #define定义的 枚举常量 int main() { // 四个都是字面常量 30; 3.14; "w"; // 字符常量 "abc"; // const修饰的常变量 const int a 10; // 在C语言中,const修饰的a,本质是变量,但不能直…...
常用SHELL命令
在 Unix/Linux 系统中,除了基本的文件和目录操作命令外,还有许多强大的工具命令,用于文本处理、系统监控、文件操作等。以下是一些常用的 Shell 命令,特别是类似 sed 和 awk 的文本处理工具: 文本处理命令 sed - 流编…...

Python脚本:将Word文档转换为Excel文件
引言 在文档处理中,我们经常需要将Word文档中的内容转换成其他格式,如Excel,以便更好地进行数据分析和报告。针对这一需求,我编写了一个Python脚本,能够批量处理指定目录下的Word文档,将其内容结构化并转换…...
【单链表】03 设L为带头结点的单链表,编写算法实现从尾到头反向输出每个结点的值。
🕺作者: 主页 我的专栏C语言从0到1探秘C数据结构从0到1探秘Linux算法题上机准备 😘欢迎 ❤️关注 👍点赞 🙌收藏 ✍️留言 题目 设L为带头结点的单链表,编写算法实现从尾到头反向输出每个结点的值。 算法…...

鸿蒙开发设备管理:【@ohos.vibrator (振动)】
振动 说明: 开发前请熟悉鸿蒙开发指导文档:gitee.com/li-shizhen-skin/harmony-os/blob/master/README.md点击或者复制转到。 本模块首批接口从API version 8开始支持。后续版本的新增接口,采用上角标单独标记接口的起始版本。 导入模块 imp…...

【信息学奥赛】CSP-J/S初赛07 排序算法及其他算法在初赛中的考察
本专栏👉CSP-J/S初赛内容主要讲解信息学奥赛的初赛内容,包含计算机基础、初赛常考的C程序和算法以及数据结构,并收集了近年真题以作参考。 如果你想参加信息学奥赛,但之前没有太多C基础,请点击👉专栏&#…...

第N7周:seq2seq翻译实战-pytorch复现-小白版
🍨 本文为🔗365天深度学习训练营 中的学习记录博客🍖 原作者:K同学啊 理论基础 seq2seq(Sequence-to-Sequence)模型是一种用于机器翻译、文本摘要等序列转换任务的框架。它由两个主要的递归神经网络&#…...

java集合(1)
目录 一.集合概述 二. 集合体系概述 1. Collection接口 1.1 List接口 1.2 Set接口 2. Map接口 三. ArrayList 1.ArrayList常用方法 2.ArrayList遍历 2.1 for循环 2.2 增强for循环 2.3 迭代器遍历 一.集合概述 我们经常需要存储一些数据类型相同的元素,之前我们学过…...

分布式数据库HBase:从零开始了解列式存储
在接触过大量的传统关系型数据库后你可能会有一些新的问题: 无法整理成表格的海量数据该如何储存? 在数据非常稀疏的情况下也必须将数据存储成关系型数据库吗? 除了关系型数据库我们是否还有别的选择以应对Web2.0时代的海量数据? 如果你也曾经想到过这些问题, 那么HBase将是…...

接口测试流程及测试点!
一、什么时候开展接口测试 1.项目处于开发阶段,前后端联调接口是否请求的通?(对应数据库增删改查)--开发自测 2.有接口需求文档,开发已完成联调(可以转测),功能测试展开之前 3.专…...

已经安装deveco-studio-4.1.3.500的基础上安装deveco-studio-3.1.0.501
目录标题 1、执行exe文件后安装即可2、双击devecostudio64_3.1.0.501.exe2.1、安装Note (注意和4.1的Note放不同目录)2.2、安装ohpm (注意和4.1版本的ohpm放不同目录)2.3、安装SDK (注意和4.1版本的SDK放不同目录) 1、执行exe文件后安装即可 2、双击devecostudio64_3.1.0.501.e…...

【C++】 解决 C++ 语言报错:Use of Uninitialized Variable
文章目录 引言 使用未初始化的变量(Use of Uninitialized Variable)是 C 编程中常见且危险的错误之一。它通常在程序试图使用尚未赋值的变量时发生,导致程序行为不可预测,可能引发运行时错误、数据损坏,甚至安全漏洞。…...

2024年7月6日 十二生肖 今日运势
小运播报:2024年7月6日,星期六,农历六月初一 (甲辰年庚午月辛未日),法定节假日。 红榜生肖:猪、马、兔 需要注意:狗、鼠、牛 喜神方位:西南方 财神方位:正…...

ubuntu丢失网络/网卡的一种原因解决方案
现象 开机进入ubuntu后发现没有网络,无论是在桌面顶部状态栏的快捷键 还是 系统设置中,都没有”有线网“和”无线网“的选项,”代理“的选项是有的使用数据线连接电脑和手机,手机开启”通过usb共享网络“,还是没有任何…...
第6篇 共识机制深度解析:PoW、PoS、DPoS和PBFT
在区块链的世界里,有一个非常重要的概念叫做“共识机制”。它就像是区块链的心脏,保证大家在这条链上的信息是可靠的、不可篡改的。今天,我们就来通俗易懂地聊聊区块链里的四大共识机制:工作量证明(PoW)、权益证明(PoS)、委托权益证明(DPoS)和拜占庭容错(PBFT)。为…...

Windows环境使用SpringBoot整合Minio平替OSS
目录 配置Minio环境 一、下载minio.exe mc.exe 二、设置用户名和密码 用管理员模式打开cmd 三、启动Minio服务器 四、访问WebUI给的地址 SpringBoot整合Minio 一、配置依赖,application.yml 二、代码部分 FileVO MinioConfig MinioUploadService MinioController 三…...

LeetCode 196, 73, 105
目录 196. 删除重复的电子邮箱题目链接表要求知识点思路代码 73. 矩阵置零题目链接标签简单版思路代码 优化版思路代码 105. 从前序与中序遍历序列构造二叉树题目链接标签思路代码 196. 删除重复的电子邮箱 题目链接 196. 删除重复的电子邮箱 表 表Person的字段为id和email…...

在Apache HTTP服务器上配置 TLS加密
安装mod_ssl软件包 [rootlocalhost conf.d]# dnf install mod_ssl -y此时查看监听端口多了一个443端口 自己构造证书 [rootlocalhost conf.d]# cd /etc/pki/tls/certs/ [rootlocalhost certs]# openssl genrsa > jiami.key [rootlocalhost certs]# openssl req -utf8 -n…...
在HarmonyOS ArkTS ArkUI-X 5.0及以上版本中,手势开发全攻略:
在 HarmonyOS 应用开发中,手势交互是连接用户与设备的核心纽带。ArkTS 框架提供了丰富的手势处理能力,既支持点击、长按、拖拽等基础单一手势的精细控制,也能通过多种绑定策略解决父子组件的手势竞争问题。本文将结合官方开发文档,…...

visual studio 2022更改主题为深色
visual studio 2022更改主题为深色 点击visual studio 上方的 工具-> 选项 在选项窗口中,选择 环境 -> 常规 ,将其中的颜色主题改成深色 点击确定,更改完成...
系统设计 --- MongoDB亿级数据查询优化策略
系统设计 --- MongoDB亿级数据查询分表策略 背景Solution --- 分表 背景 使用audit log实现Audi Trail功能 Audit Trail范围: 六个月数据量: 每秒5-7条audi log,共计7千万 – 1亿条数据需要实现全文检索按照时间倒序因为license问题,不能使用ELK只能使用…...

【SQL学习笔记1】增删改查+多表连接全解析(内附SQL免费在线练习工具)
可以使用Sqliteviz这个网站免费编写sql语句,它能够让用户直接在浏览器内练习SQL的语法,不需要安装任何软件。 链接如下: sqliteviz 注意: 在转写SQL语法时,关键字之间有一个特定的顺序,这个顺序会影响到…...
python爬虫:Newspaper3k 的详细使用(好用的新闻网站文章抓取和解析的Python库)
更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 一、Newspaper3k 概述1.1 Newspaper3k 介绍1.2 主要功能1.3 典型应用场景1.4 安装二、基本用法2.2 提取单篇文章的内容2.2 处理多篇文档三、高级选项3.1 自定义配置3.2 分析文章情感四、实战案例4.1 构建新闻摘要聚合器…...

2025盘古石杯决赛【手机取证】
前言 第三届盘古石杯国际电子数据取证大赛决赛 最后一题没有解出来,实在找不到,希望有大佬教一下我。 还有就会议时间,我感觉不是图片时间,因为在电脑看到是其他时间用老会议系统开的会。 手机取证 1、分析鸿蒙手机检材&#x…...
【碎碎念】宝可梦 Mesh GO : 基于MESH网络的口袋妖怪 宝可梦GO游戏自组网系统
目录 游戏说明《宝可梦 Mesh GO》 —— 局域宝可梦探索Pokmon GO 类游戏核心理念应用场景Mesh 特性 宝可梦玩法融合设计游戏构想要素1. 地图探索(基于物理空间 广播范围)2. 野生宝可梦生成与广播3. 对战系统4. 道具与通信5. 延伸玩法 安全性设计 技术选…...
DeepSeek 技术赋能无人农场协同作业:用 AI 重构农田管理 “神经网”
目录 一、引言二、DeepSeek 技术大揭秘2.1 核心架构解析2.2 关键技术剖析 三、智能农业无人农场协同作业现状3.1 发展现状概述3.2 协同作业模式介绍 四、DeepSeek 的 “农场奇妙游”4.1 数据处理与分析4.2 作物生长监测与预测4.3 病虫害防治4.4 农机协同作业调度 五、实际案例大…...
【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的“no matching...“系列算法协商失败问题
【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的"no matching..."系列算法协商失败问题 摘要: 近期,在使用较新版本的OpenSSH客户端连接老旧SSH服务器时,会遇到 "no matching key exchange method found", "n…...
腾讯云V3签名
想要接入腾讯云的Api,必然先按其文档计算出所要求的签名。 之前也调用过腾讯云的接口,但总是卡在签名这一步,最后放弃选择SDK,这次终于自己代码实现。 可能腾讯云翻新了接口文档,现在阅读起来,清晰了很多&…...