大模型应用:多轮对话(prompt工程)
概述
在与大型语言模型(如ChatGPT)交互的过程中,我们常常体验到与智能助手进行连贯多轮对话的便利性。那么,当我们开启一个新的聊天时,系统是如何管理聊天上下文的呢?
一、初始上下文的建立
1. 创建新会话
当用户开启一个新的聊天时,应用程序后端会为该对话创建一个独立的会话(session),并分配一个唯一的会话ID。这确保了每个对话都是独立的,防止不同对话之间的混淆。
2. 系统提示的引入
在新会话的开始,系统会向模型提供一段隐藏的系统提示(System Prompt)。这段提示用于设定模型在整个对话中的角色、语气和行为准则。例如:
- 角色设定:让模型扮演助理、教师、技术专家等特定身份。
- 语言风格:规定回复使用正式、友好、幽默等特定语气。
- 行为准则:避免生成不适当内容,遵守伦理规范。
系统提示对用户是不可见的,但对模型的回复有着深远影响,它确保了模型在整个对话过程中保持一致的行为。
二、上下文的积累与管理
1. 对话历史的记录
随着用户与模型的交互进行,系统会将每一次的用户输入和模型回复按照时间顺序累积,形成当前会话的消息队列。这使得模型在生成回复时,可以参考之前的对话内容,保持连贯性和一致性。
2. 上下文窗口的限制
大型语言模型在处理输入时,有一个固定的上下文窗口(Context Window),表示模型一次能处理的最大文本长度。例如,GPT-3的上下文窗口为4096个Token。
当对话长度超过上下文窗口时,系统需要对输入进行截断。为了确保模型继续遵循最初的系统提示,应用程序会:
- 优先保留系统提示:系统提示始终位于输入的开头,不被截断。
- 截断早期对话:从最早的用户和模型对话开始移除,保留最近的交互内容。
3. 上下文组装
在生成回复时,应用程序会将以下内容按顺序拼接,形成当前的输入上下文:
- 系统提示:设定模型行为的隐藏指令。
- 重要信息:用户提供的关键数据或参数(如果有)。
- 最近的对话历史:包括最近几轮的用户输入和模型回复。
通过这种方式,模型能够在一次交互中获得必要的上下文信息,生成符合预期的回复。
三、系统提示的重要作用
1. 保证模型行为一致性
由于模型在每次生成回复时,只能参考当前的输入文本,因此系统提示需要在每次输入中提供,确保模型始终按照设定的角色和风格进行回复。
2. 防止不当内容生成
系统提示中包含的行为准则和禁止事项,有助于模型避免生成不合规或不适当的内容,提升对话的安全性和可靠性。
3. 提高用户体验
通过精心设计的系统提示,模型能够更好地理解用户意图,提供高质量、个性化的回复,提升用户的交互体验。
四、技术实现细节
1. 会话管理
- 创建会话ID:为每个新对话分配唯一的会话ID,用于区分不同用户的会话。
- 状态跟踪:记录每个会话的状态信息,便于后续的上下文管理。
2. 消息队列维护
- 记录交互内容:保存当前会话中的所有用户输入和模型回复。
- 长度检查:在发送给模型之前,检查输入的总长度,确保不超过上下文窗口限制。
3. 上下文优化
- 截断策略:当超过上下文窗口限制时,从早期对话开始移除内容。
- 摘要处理:对于重要但较早的内容,通过生成摘要的方式保留关键信息。
五、模型与应用的职责划分
需要明确的是,大型语言模型本身并不具备会话管理、消息队列维护或上下文组装的能力。这些功能由应用程序在模型之上实现。具体来说:
- 模型的职责:根据输入生成下一段文本。
- 应用的职责:管理对话上下文、用户会话、内容过滤等。
通过合理的职责划分,应用程序能够充分发挥模型的能力,提供丰富多样的应用场景。
六、用户数据的安全与隐私
- 独立的会话:每个新对话都是独立的,模型不会记住之前会话中的信息,保护用户隐私。
- 数据限制:用户的输入和模型的回复都严格限定在当前会话内,不会跨会话传播。
七、总结
大型语言模型在新聊天中管理上下文,主要通过以下方式实现:
- 创建新会话,重置上下文:确保每个对话的独立性。
- 使用系统提示:设定模型的角色、风格和行为准则,确保模型行为一致。
- 维护消息队列:记录对话历史,供模型参考,提高回复的连贯性。
- 上下文管理:在上下文窗口限制内,优化输入内容,保证模型有效处理。
示例
使用多轮会话示例代码
下面的代码,演示如何在代码中实现与大型语言模型的多轮对话。我们将引入一个循环,允许用户多次输入,并维护会话的上下文,使模型的回复能够参考之前的对话内容。
代码
import torch
import logging
from transformers import Qwen2_5_VLForConditionalGeneration, AutoProcessor
from qwen_vl_utils import process_vision_info# 设置日志配置,包含Transformers库的日志
logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',level=logging.INFO # 设置全局日志级别为INFO,避免过多日志输出
)
# 获取Transformers库的logger并设置级别为INFO
transformers_logger = logging.getLogger('transformers')
transformers_logger.setLevel(logging.INFO)# 设置模型缓存目录
cache_dir = '/data/model/'# 加载模型,启用GPU加速
model = Qwen2_5_VLForConditionalGeneration.from_pretrained("Qwen/Qwen2.5-VL-3B-Instruct",torch_dtype=torch.bfloat16,attn_implementation="sdpa",device_map="auto",cache_dir=cache_dir
)
logging.info("模型已加载到设备:%s,使用attn_implementation='sdpa'", model.device)# 设置视觉令牌范围以平衡性能和成本
min_pixels = 256 * 28 * 28
max_pixels = 1280 * 28 * 28# 加载处理器
processor = AutoProcessor.from_pretrained("Qwen/Qwen2.5-VL-3B-Instruct",min_pixels=min_pixels,max_pixels=max_pixels,cache_dir=cache_dir
)
logging.info("处理器已加载,设置了自定义的视觉令牌范围。")# 初始化消息内容列表,包含系统提示(可选)
messages = [# 可以添加系统提示,设定模型的行为{"role": "system","content": [{"type": "text", "text": "你是一位友好的智能助手,乐于回答用户的问题并提供帮助。"},],}
]# 多轮会话循环
while True:user_input = input("用户:")if user_input.lower() in ['退出', 'exit', 'quit']:print("结束对话。")break# 将用户输入添加到消息列表messages.append({"role": "user","content": [{"type": "text", "text": user_input}]})# 准备推理输入logging.info("开始准备推理输入...")text = processor.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)image_inputs, video_inputs = process_vision_info(messages)inputs = processor(text=[text],images=image_inputs,videos=video_inputs,padding=True,return_tensors="pt",)inputs = inputs.to(model.device)logging.info("推理输入已准备完毕。")# 进行推理并生成输出logging.info("开始生成输出...")generated_ids = model.generate(**inputs, max_new_tokens=512)logging.info("输出生成完毕。")# 处理生成的输出generated_ids_trimmed = [out_ids[len(in_ids):] for in_ids, out_ids in zip(inputs.input_ids, generated_ids)]output_text = processor.batch_decode(generated_ids_trimmed, skip_special_tokens=True, clean_up_tokenization_spaces=False)[0] # 取第一个元素print("助手:" + output_text.strip())# 将模型的回复添加到消息列表messages.append({"role": "assistant","content": [{"type": "text", "text": output_text.strip()}]})# 为了防止超过上下文长度限制,可以在这里检查并截断消息列表# 例如,只保留最近的n轮对话max_history = 5 # 保留最近5轮对话(可根据需要调整)# 保留系统提示加上最近的max_history*2条消息(用户和助手各一条,所以乘以2)if len(messages) > max_history * 2 + 1: # +1是因为系统提示算一条messages = [messages[0]] + messages[-max_history*2:]logging.info("消息列表已截断,保留最近的 %d 轮对话。", max_history)
代码说明
-
引入多轮会话循环:使用
while True循环,不断读取用户输入,实现多轮对话。 -
管理消息列表:使用
messages列表维护对话历史,在每一轮中将用户和助手的消息添加到列表中。 -
处理用户退出指令:如果用户输入
退出、exit或quit,程序将结束对话循环。 -
准备推理输入:在每一轮对话中,使用
processor.apply_chat_template方法将messages列表转换为模型可接受的输入格式。 -
调用模型生成回复:使用
model.generate方法生成模型的回复,并将其解码为文本。 -
显示模型回复并添加到对话历史:将模型的回复打印出来,并添加到
messages列表中,以在后续对话中提供上下文。 -
管理上下文长度:为了防止超过模型的上下文窗口限制(即最大输入长度),在每轮对话后检查
messages列表的长度,并截断早期的对话内容,只保留最近的max_history轮对话。
示例运行
拖到最右侧,重点看输入给大模型的messages在不断的累积
2025-02-27 04:00:07,656 - root - INFO - 处理器已加载,设置了自定义的视觉令牌范围。
用户:你好!
2025-02-27 04:00:49,596 - root - INFO - 开始准备推理输入...
2025-02-27 04:00:49,596 - root - INFO - [{'role': 'system', 'content': [{'type': 'text', 'text': '你是一位友好的智能助手,乐于回答用户的问题并提供帮助。'}]}, {'role': 'user', 'content': [{'type': 'text', 'text': '你好!'}]}]
2025-02-27 04:00:49,609 - root - INFO - 推理输入已准备完毕。
2025-02-27 04:00:49,609 - root - INFO - 开始生成输出...
2025-02-27 04:00:59,579 - root - INFO - 输出生成完毕。
助手:你好!有什么可以帮助你的吗?
用户:你能给我讲个笑话吗?
2025-02-27 04:01:11,942 - root - INFO - 开始准备推理输入...
2025-02-27 04:01:11,942 - root - INFO - [{'role': 'system', 'content': [{'type': 'text', 'text': '你是一位友好的智能助手,乐于回答用户的问题并提供帮助。'}]}, {'role': 'user', 'content': [{'type': 'text', 'text': '你好!'}]}, {'role': 'assistant', 'content': [{'type': 'text', 'text': '你好!有什么可以帮助你的吗?'}]}, {'role': 'user', 'content': [{'type': 'text', 'text': '你能给我讲个笑话吗?'}]}]
2025-02-27 04:01:11,943 - root - INFO - 推理输入已准备完毕。
2025-02-27 04:01:11,943 - root - INFO - 开始生成输出...
2025-02-27 04:01:32,729 - root - INFO - 输出生成完毕。
助手:当然可以!这是一个经典的笑话:为什么电脑经常生病?因为它的窗户(Windows)总是开着!
用户:哈哈,很有趣。再讲一个脑筋急转弯?
2025-02-27 04:02:08,591 - root - INFO - 开始准备推理输入...
2025-02-27 04:02:08,591 - root - INFO - [{'role': 'system', 'content': [{'type': 'text', 'text': '你是一位友好的智能助手,乐于回答用户的问题并提供帮助。'}]}, {'role': 'user', 'content': [{'type': 'text', 'text': '你好!'}]}, {'role': 'assistant', 'content': [{'type': 'text', 'text': '你好!有什么可以帮助你的吗?'}]}, {'role': 'user', 'content': [{'type': 'text', 'text': '你能给我讲个笑话吗?'}]}, {'role': 'assistant', 'content': [{'type': 'text', 'text': '当然可以!这是一个经典的笑话:为什么电脑经常生病?因为它的窗户(Windows)总是开着!'}]}, {'role': 'user', 'content': [{'type': 'text', 'text': '哈哈,很有趣。再讲一个脑筋急转弯?'}]}]
2025-02-27 04:02:08,592 - root - INFO - 推理输入已准备完毕。
2025-02-27 04:02:08,593 - root - INFO - 开始生成输出...
2025-02-27 04:02:34,326 - root - INFO - 输出生成完毕。
助手:好的,这个脑筋急转弯挺有趣的:什么东西越洗越脏?答案是水。
用户:谢谢你的回答
2025-02-27 04:03:03,807 - root - INFO - 开始准备推理输入...
2025-02-27 04:03:03,807 - root - INFO - [{'role': 'system', 'content': [{'type': 'text', 'text': '你是一位友好的智能助手,乐于回答用户的问题并提供帮助。'}]}, {'role': 'user', 'content': [{'type': 'text', 'text': '你好!'}]}, {'role': 'assistant', 'content': [{'type': 'text', 'text': '你好!有什么可以帮助你的吗?'}]}, {'role': 'user', 'content': [{'type': 'text', 'text': '你能给我讲个笑话吗?'}]}, {'role': 'assistant', 'content': [{'type': 'text', 'text': '当然可以!这是一个经典的笑话:为什么电脑经常生病?因为它的窗户(Windows)总是开着!'}]}, {'role': 'user', 'content': [{'type': 'text', 'text': '哈哈,很有趣。再讲一个脑筋急转弯?'}]}, {'role': 'assistant', 'content': [{'type': 'text', 'text': '好的,这个脑筋急转弯挺有趣的:什么东西越洗越脏?答案是水。'}]}, {'role': 'user', 'content': [{'type': 'text', 'text': '谢谢你的回答'}]}]
2025-02-27 04:03:03,809 - root - INFO - 推理输入已准备完毕。
2025-02-27 04:03:03,809 - root - INFO - 开始生成输出...
2025-02-27 04:03:27,048 - root - INFO - 输出生成完毕。
助手:不客气,随时欢迎你来提问!
用户:退出
结束对话。
另外多模态大模型可以支持复杂的会话messages,单次输入给大模型的输入可以如下:
conversation = [{"role": "user","content": [{"type": "image"}, {"type": "text", "text": "Hello, how are you?"}],},{"role": "assistant","content": "I'm doing well, thank you for asking. How can I assist you today?",},{"role": "user","content": [{"type": "text", "text": "Can you describe these images and video?"},{"type": "image"},{"type": "image"},{"type": "video"},{"type": "text", "text": "These are from my vacation."},],},{"role": "assistant","content": "I'd be happy to describe the images and video for you. Could you please provide more context about your vacation?",},{"role": "user","content": "It was a trip to the mountains. Can you see the details in the images and video?",},
]# default:
prompt_without_id = processor.apply_chat_template(conversation, add_generation_prompt=True
)
# Excepted output: '<|im_start|>system\nYou are a helpful assistant.<|im_end|>\n<|im_start|>user\n<|vision_start|><|image_pad|><|vision_end|>Hello, how are you?<|im_end|>\n<|im_start|>assistant\nI'm doing well, thank you for asking. How can I assist you today?<|im_end|>\n<|im_start|>user\nCan you describe these images and video?<|vision_start|><|image_pad|><|vision_end|><|vision_start|><|image_pad|><|vision_end|><|vision_start|><|video_pad|><|vision_end|>These are from my vacation.<|im_end|>\n<|im_start|>assistant\nI'd be happy to describe the images and video for you. Could you please provide more context about your vacation?<|im_end|>\n<|im_start|>user\nIt was a trip to the mountains. Can you see the details in the images and video?<|im_end|>\n<|im_start|>assistant\n'# add ids
prompt_with_id = processor.apply_chat_template(conversation, add_generation_prompt=True, add_vision_id=True
)
# Excepted output: '<|im_start|>system\nYou are a helpful assistant.<|im_end|>\n<|im_start|>user\nPicture 1: <|vision_start|><|image_pad|><|vision_end|>Hello, how are you?<|im_end|>\n<|im_start|>assistant\nI'm doing well, thank you for asking. How can I assist you today?<|im_end|>\n<|im_start|>user\nCan you describe these images and video?Picture 2: <|vision_start|><|image_pad|><|vision_end|>Picture 3: <|vision_start|><|image_pad|><|vision_end|>Video 1: <|vision_start|><|video_pad|><|vision_end|>These are from my vacation.<|im_end|>\n<|im_start|>assistant\nI'd be happy to describe the images and video for you. Could you please provide more context about your vacation?<|im_end|>\n<|im_start|>user\nIt was a trip to the mountains. Can you see the details in the images and video?<|im_end|>\n<|im_start|>assistant\n'
注意事项
-
上下文长度限制:大型语言模型对输入文本的长度是有最大限制的(例如4096个Token)。在实际应用中,需要根据模型的实际限制,调整
max_history的值,或者采用更加复杂的截断和摘要策略。 -
视觉信息处理:示例代码中包含了对图像和视频输入的处理。如果当前对话不涉及图像或视频,可以简化相关处理,或者在需要时动态地添加图像或视频信息到
messages中。 -
系统提示的作用:在
messages列表中添加"role": "system"的消息,可以设定模型的整体行为和风格。系统提示通常只需在对话开始时添加一次,后续对话中无需重复。 -
日志级别设置:为了避免过多的日志输出,将全局日志级别从
DEBUG调整为INFO。根据需要,可以进一步调整日志级别。 -
模型性能与资源:运行此代码需要具备支持相应模型大小的计算资源(例如GPU内存)。在实际应用中,根据硬件条件选择合适的模型规模。
相关文章:
大模型应用:多轮对话(prompt工程)
概述 在与大型语言模型(如ChatGPT)交互的过程中,我们常常体验到与智能助手进行连贯多轮对话的便利性。那么,当我们开启一个新的聊天时,系统是如何管理聊天上下文的呢? 一、初始上下文的建立 1. 创建新会…...
WSDM24-因果推荐|因果去偏的可解释推荐系统
1 动机 可解释推荐系统(ERS)通过提供透明的推荐解释,提高用户信任度和系统的说服力,如下图所示,然而: 1:现有工作主要关注推荐算法的去偏(流行度偏差),但未显…...
VScode在Windows11中配置MSVC
因为MSVC编译器在vs当中,所以我们首先要安装vs的一部分组件。如果只是需要MSVC的话,工作负荷一个都不需要勾选,在单个组件里面搜索MSVC和windows11 SDK,其中一个是编译器,一个是头文件然后右下角安装即可。搜索Develop…...
数据库基础二(数据库安装配置)
打开MySQL官网进行安装包的下载 https://www.mysql.com/ 接着找到适用于windows的版本 下载版本 直接点击下载即可 接下来对应的内容分别是: 1:安装所有 MySQL 数据库需要的产品; 2:仅使用 MySQL 数据库的服务器; 3&a…...
cuda-12.4.0 devel docker 中源码安装 OpenAI triton
1,准备 docker 容器 下载docker image: $ sudo docker pull nvidia/cuda:12.6.2-devel-ubuntu20.04 创建容器: sudo docker run --gpus all -it --name cuda_LHL_01 -v /home/hongleili/ex_triton/tmp1:/root/ex_triton/tmp1 nvidia/cuda:12.6…...
doris: Hive Catalog
通过连接 Hive Metastore,或者兼容 Hive Metatore 的元数据服务,Doris 可以自动获取 Hive 的库表信息,并进行数据查询。 除了 Hive 外,很多其他系统也会使用 Hive Metastore 存储元数据。所以通过 Hive Catalog,我们不…...
【LeetCode】131.分割回文串
目录 题目描述输入输出示例及数据范围思路C 实现 题目描述 这道题目来自 LeetCode 131. 分割回文串。 题目描述如下: 给你一个字符串 s,请你将 s 分割成一些子串,使每个子串都是 回文串 。返回 s 所有可能的分割方案。 输入输出示例及数据…...
JeeWMS graphReportController.do SQL注入漏洞复现(CVE-2025-0392)
免责申明: 本文所描述的漏洞及其复现步骤仅供网络安全研究与教育目的使用。任何人不得将本文提供的信息用于非法目的或未经授权的系统测试。作者不对任何由于使用本文信息而导致的直接或间接损害承担责任。如涉及侵权,请及时与我们联系,我们将尽快处理并删除相关内容。 0x0…...
基于Python+django+mysql旅游数据爬虫采集可视化分析推荐系统
2024旅游推荐系统爬虫可视化(协同过滤算法) 基于Pythondjangomysql旅游数据爬虫采集可视化分析推荐系统 有文档说明 部署文档 视频讲解 ✅️基于用户的协同过滤推荐算法 卖价就是标价~ 项目技术栈 Python语言、Django框架、MySQL数据库、requests网络爬虫…...
我的工作经历
主要说一下毕业工作大半年了一些心得与想法。 首先是因为本科不好的原因,单2硕士找了一个国企(其实应该说是央企)。也幸好找的是央企,后续工作基本上没有强度,不然后期神经衰弱抑郁症家里乱七八糟催婚的事情能把人逼疯…...
筑牢安全防线:工商业场所燃气泄漏防护新方案
燃气安全是企业经营不可逾越的生命线。在餐饮后厨、化工车间、酒店锅炉房等场所,可燃气体一旦泄漏,极易引发严重事故。如何实现精准监测、快速响应,成为工业及商业领域安全管理的核心诉求。旭华智能深耕安全监测领域,推出的工业及…...
基于STM32的智能停车场管理系统
1. 引言 传统停车场管理存在车位利用率低、停车体验差等问题,难以满足现代城市停车需求。本文设计了一款基于STM32的智能停车场管理系统,通过车位状态实时监测、智能导航与无感支付技术,实现停车资源的高效利用与用户服务的全面升级。 2. 系…...
MacBook 终端中使用 vim命令
在 MacBook 终端中使用 vim 编辑器时,以下是一些常用命令和操作指南: 1. 基本操作 启动 vim vim 文件名 # 打开或创建文件退出 vim 保存并退出: 按 Esc,然后输入 :wq,按 Enter。 不保存退出: 按 Esc&am…...
VoIP之SBC(会话边界控制器)
SBC(Session Border Controller,会话边界控制器)是一种在VoIP通信网络中的重要设备,用于连接处理会话边界,核心功能包含信令代理/媒体代理、网络NAT穿越、防火墙、QoS等。 经典案例 关键说明 用于客户端和核心业务服务器的互联互通支持IP接入控…...
threejs:document.createElement创建标签后css设置失效
vue3threejs,做一个给模型批量CSS2D标签的案例,在导入模型的js文件里,跟着课程写的代码如下: import * as THREE from three; // 引入gltf模型加载库GLTFLoader.js import { GLTFLoader } from three/addons/loaders/GLTFLoader.…...
安装2018版本的petalinux曲折经历
具体操作步骤 1.安装VMware Workstation15.5的虚拟机2.安装Ubuntu16.04.43.配置Ubuntu的环境1.可以复制粘贴的指令2.安装vim 4.准备安装petalinux1.先配置petalinux的安装环境2.替换镜像源1.备份原始的软件源2.从以下镜像点找到合适自己系统版本的源3.执行替换镜像源1.打开源文…...
return和print
目录 1.print的用法 2.return的用法 3. print 和 return 的区别 4.总结 1.print的用法 print 是一个函数,用于将信息输出到控制台(终端)。它主要用于显示程序运行的结果,方便用户查看。print 的作用是输出内容,而不…...
springboot411-基于Java的自助客房服务系统(源码+数据库+纯前后端分离+部署讲解等)
💕💕作者: 爱笑学姐 💕💕个人简介:十年Java,Python美女程序员一枚,精通计算机专业前后端各类框架。 💕💕各类成品Java毕设 。javaweb,ssm…...
跨平台文件互传工具
一款高效便捷的文件互传工具,支持在线快速传输各种文件格式,无需注册,直接分享文件。适用于个人和团队间的文件共享,跨平台支持,轻松解决文件传输问题。免费的文件传输服务,让你的工作更高效。 gotool...
final 关键字在不同上下文中的用法及其名称
1. final 变量 名称:final 变量(常量)。 作用:一旦赋值后,值不能被修改。 分类: final 实例变量:必须在声明时或构造函数中初始化。 final 静态变量:必须在声明时或静态代码块中初…...
HTML 语义化
目录 HTML 语义化HTML5 新特性HTML 语义化的好处语义化标签的使用场景最佳实践 HTML 语义化 HTML5 新特性 标准答案: 语义化标签: <header>:页头<nav>:导航<main>:主要内容<article>&#x…...
深入剖析AI大模型:大模型时代的 Prompt 工程全解析
今天聊的内容,我认为是AI开发里面非常重要的内容。它在AI开发里无处不在,当你对 AI 助手说 "用李白的风格写一首关于人工智能的诗",或者让翻译模型 "将这段合同翻译成商务日语" 时,输入的这句话就是 Prompt。…...
云启出海,智联未来|阿里云网络「企业出海」系列客户沙龙上海站圆满落地
借阿里云中企出海大会的东风,以**「云启出海,智联未来|打造安全可靠的出海云网络引擎」为主题的阿里云企业出海客户沙龙云网络&安全专场于5.28日下午在上海顺利举办,现场吸引了来自携程、小红书、米哈游、哔哩哔哩、波克城市、…...
剑指offer20_链表中环的入口节点
链表中环的入口节点 给定一个链表,若其中包含环,则输出环的入口节点。 若其中不包含环,则输出null。 数据范围 节点 val 值取值范围 [ 1 , 1000 ] [1,1000] [1,1000]。 节点 val 值各不相同。 链表长度 [ 0 , 500 ] [0,500] [0,500]。 …...
如何将联系人从 iPhone 转移到 Android
从 iPhone 换到 Android 手机时,你可能需要保留重要的数据,例如通讯录。好在,将通讯录从 iPhone 转移到 Android 手机非常简单,你可以从本文中学习 6 种可靠的方法,确保随时保持连接,不错过任何信息。 第 1…...
【python异步多线程】异步多线程爬虫代码示例
claude生成的python多线程、异步代码示例,模拟20个网页的爬取,每个网页假设要0.5-2秒完成。 代码 Python多线程爬虫教程 核心概念 多线程:允许程序同时执行多个任务,提高IO密集型任务(如网络请求)的效率…...
DeepSeek 技术赋能无人农场协同作业:用 AI 重构农田管理 “神经网”
目录 一、引言二、DeepSeek 技术大揭秘2.1 核心架构解析2.2 关键技术剖析 三、智能农业无人农场协同作业现状3.1 发展现状概述3.2 协同作业模式介绍 四、DeepSeek 的 “农场奇妙游”4.1 数据处理与分析4.2 作物生长监测与预测4.3 病虫害防治4.4 农机协同作业调度 五、实际案例大…...
使用Matplotlib创建炫酷的3D散点图:数据可视化的新维度
文章目录 基础实现代码代码解析进阶技巧1. 自定义点的大小和颜色2. 添加图例和样式美化3. 真实数据应用示例实用技巧与注意事项完整示例(带样式)应用场景在数据科学和可视化领域,三维图形能为我们提供更丰富的数据洞察。本文将手把手教你如何使用Python的Matplotlib库创建引…...
Go 语言并发编程基础:无缓冲与有缓冲通道
在上一章节中,我们了解了 Channel 的基本用法。本章将重点分析 Go 中通道的两种类型 —— 无缓冲通道与有缓冲通道,它们在并发编程中各具特点和应用场景。 一、通道的基本分类 类型定义形式特点无缓冲通道make(chan T)发送和接收都必须准备好࿰…...
【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的“no matching...“系列算法协商失败问题
【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的"no matching..."系列算法协商失败问题 摘要: 近期,在使用较新版本的OpenSSH客户端连接老旧SSH服务器时,会遇到 "no matching key exchange method found", "n…...
