从零到一:如何用阿里云百炼和火山引擎搭建专属 AI 助手(DeepSeek)?
本文首发:从零到一:如何用阿里云百炼和火山引擎搭建专属 AI 助手(DeepSeek)?
阿里云百炼和火山引擎都推出了免费的 DeepSeek 模型体验额度,今天我和大家一起搭建一个本地的专属 AI 助手。
- 阿里云百炼为 DeepSeek-R1 与 DeepSeek-V3 模型分别提供 100 万 tokens 免费额度
🐳 https://www.aliyun.com/solution/tech-solution/deepseek-r1-for-platforms
- 火山引擎为 DeepSeek 在内的多种模型提供 50 万 tokens 免费额度
🐳 https://www.volcengine.com/product/ark
一、阿里云百炼部署 DeepSeek 模型
1、登录阿里云百炼
注册并登录阿里云百炼平台,进入模型广场即可查看 DeepSeek 模型。
2、创建 API Key
在阿里云百炼主页右上角的个人图标中,进入 API-KEY 页面并创建专属的 API Key。
3、调用 API 验证
参考《配置 API Key 到环境变量》文档,将 API Key 配置到环境变量中,并通过代码调用 API 进行验证。
🐳配置 API Key 到环境变量
https://help.aliyun.com/zh/model-studio/developer-reference/configure-api-key-through-environment-variables
以下是官方提供的代码示例,帮助您快速上手:
import os
from openai import OpenAIclient = OpenAI(# 若没有配置环境变量,请用百炼API Key将下行替换为:api_key="sk-xxx",api_key=os.getenv("DASHSCOPE_API_KEY"), # 如何获取API Key:https://help.aliyun.com/zh/model-studio/developer-reference/get-api-keybase_url="https://dashscope.aliyuncs.com/compatible-mode/v1"
)completion = client.chat.completions.create(model="deepseek-r1", # 此处以 deepseek-r1 为例,可按需更换模型名称。messages=[{'role': 'user', 'content': '9.9和9.11谁大'}]
)# 通过reasoning_content字段打印思考过程print("思考过程:")
print(completion.choices[0].message.reasoning_content)# 通过content字段打印最终答案print("最终答案:")
print(completion.choices[0].message.content)
二、火山引擎部署 DeepSeek 模型
1、登录火山方舟
🐵
注册并登录火山方舟平台,可使用我的邀请码 9Z52V71T 可免费获得每个模型 50 万 tokens 的推理额度。
# 登录后免费赠送每个模型50万tokens推理额度。
https://www.volcengine.com/experience/ark?utm_term=202502dsinvite&ac=DSASUQY5&rc=9Z52V71T
登录后就能体验 DeepSeek-R1 等各种模型
2、创建 API Key
在“在线推理”页面找到“API 接入”,按照提示创建 API Key。
3、创建自定义推理接入点
根据官方教程,在“在线推理”页面选择“创建推理接入点”。
创建过程比较简单,填写名称并选择模型(如 DeepSeek-R1),比如我选择 DeepSeek-R1 模型,为了方便我自己识别,所以接入点名称我填写成“DeepSeek-R1”
在模型选择页,可以根据自己需求去选择模型
创建完成就可以得到接入点名称。注意:后续用到的 model_name 是火山平台自动生成(以“ep-”开头)。
4、调用 API 验证
设置 API Key 作为环境变量,其中"YOUR_API_KEY"需要替换为火山方舟上创建的 API Key
export ARK_API_KEY="YOUR_API_KEY"
官方示例参考
import os
from openai import OpenAIclient = OpenAI(api_key = os.environ.get("ARK_API_KEY"),base_url = "https://ark.cn-beijing.volces.com/api/v3",
)# Non-streaming:
print("----- standard request -----")
completion = client.chat.completions.create(model = "ep-", # your model endpoint IDmessages = [{"role": "system", "content": "你是人工智能助手"},{"role": "user", "content": "常见的十字花科植物有哪些?"},],
)
print(completion.choices[0].message.content)# Streaming:
print("----- streaming request -----")
stream = client.chat.completions.create(model = "ep-", # your model endpoint IDmessages = [{"role": "system", "content": "你是人工智能助手"},{"role": "user", "content": "常见的十字花科植物有哪些?"},],stream=True
)for chunk in stream:if not chunk.choices:continueprint(chunk.choices[0].delta.content, end="")
print()
三、搭建专属 AI 助手
无论是开发者还是普通用户,都可以通过以下方式快速搭建专属的 AI 助手:
1、用 streamlit 编写个应用
对于程序员,可以使用 Streamlit 编写一个简单的网页应用,实现本地化交互。
我已经编写了一个基础版,日常用用就足够了,代码参考
import streamlit as st
import uuid
import os
import hashlib
from openai import OpenAI, AuthenticationError, APIError# 生成或获取用户特定的会话ID
if'user_session_id'notin st.session_state:st.session_state.user_session_id = str(uuid.uuid4())# 使用用户会话ID来获取或初始化用户特定的数据
defget_user_data():if'user_data'notin st.session_state:st.session_state.user_data = {}if st.session_state.user_session_id notin st.session_state.user_data:st.session_state.user_data[st.session_state.user_session_id] = {'messages': [{"role": "system", "content": "你是一个AI助手,请回答用户提出的问题。"}],'uploaded_files': [],'api_key': 'sk-','base_url': 'https://dashscope.aliyuncs.com/compatible-mode/v1','model_name': 'deepseek-r1','past_sessions': []}return st.session_state.user_data[st.session_state.user_session_id]# 更新用户数据的辅助函数
defupdate_user_data(key, value):user_data = get_user_data()user_data[key] = value# 保存当前会话
defsave_current_session():user_data = get_user_data()iflen(user_data['messages']) > 1: # 只有当有实际对话时才保存current_session = {'id': st.session_state.user_session_id,'messages': user_data['messages']}# 检查是否已存在相同ID的会话,如果存在则更新,不存在则插入existing_session = next((session for session in user_data['past_sessions'] if session['id'] == current_session['id']), None)if existing_session:existing_session.update(current_session)else:user_data['past_sessions'].insert(0, current_session)# 限制保存的会话数量,例如只保留最近的5个会话user_data['past_sessions'] = user_data['past_sessions'][:5]# 加载选定的会话
defload_session(session_id):user_data = get_user_data()for session in user_data['past_sessions']:if session['id'] == session_id:st.session_state.user_session_id = session_idst.session_state.user_data[session_id] = {'messages': session['messages'],'uploaded_files': [],'api_key': user_data['api_key'],'base_url': user_data['base_url'],'model_name': user_data['model_name'],'past_sessions': user_data['past_sessions']}breakdefsave_uploaded_files(upload_dir, uploaded_files):"""保存上传的 txt 和 markdown 文件到临时目录并返回文件信息"""user_data = get_user_data()saved_files = []current_files = [f["name"] for f in user_data['uploaded_files']]for file in uploaded_files:if file.name in current_files:continueifnot file.name.lower().endswith(('.txt', '.md', '.markdown')):st.warning(f"不支持的文件类型: {file.name}。请上传 .txt 或 .md 文件。")continueif file.size > 1 * 1024 * 1024: # 1MB限制st.error(f"文件 {file.name} 超过大小限制(1MB)")continuetry:# 保存文件到指定目录file_path = os.path.join(upload_dir, file.name)withopen(file_path, "wb") as f:f.write(file.getbuffer())# 读取文件内容withopen(file_path, "r", encoding='utf-8') as f:content = f.read()# 生成内容哈希值content_hash = hashlib.md5(content.encode()).hexdigest()# 检查重复内容ifany(f["hash"] == content_hash for f in user_data['uploaded_files']):st.info(f"文件 {file.name} 的内容与已上传的文件重复,已跳过。")continuesaved_files.append({"name": file.name,"content": content,"size": file.size,"hash": content_hash})st.success(f"成功上传文件: {file.name}")except Exception as e:st.error(f"处理文件 {file.name} 时出错: {str(e)}")continuereturn saved_filesdefformat_file_contents(files):return"\n".join([f"=== {f['name']} ===\n{f['content']}\n"for f in files])defget_active_api_config():user_data = get_user_data()return user_data['base_url'], user_data['api_key'], user_data['model_name']defprocess_stream(stream):"""合并处理思考阶段和响应阶段"""thinking_content = ""response_content = ""# 在状态块外部预先创建响应占位符response_placeholder = st.empty()with st.status("思考中...", expanded=True) as status:thinking_placeholder = st.empty()thinking_phase = True# 思考阶段标记for chunk in stream:# 解析数据块delta = chunk.choices[0].deltareasoning = delta.reasoning_content ifhasattr(delta, 'reasoning_content') else""content = delta.content ifhasattr(delta, 'content') else""role = delta.role ifhasattr(delta, 'role') else""# 处理思考阶段if thinking_phase:if reasoning:thinking_content += reasoningthinking_placeholder.markdown(f"思考过程:\n{thinking_content}")# 检测思考阶段结束if content:status.update(label="思考完成", state="complete", expanded=False)thinking_phase = Falseresponse_placeholder.markdown("回答:\n▌") # 初始化响应光标# 处理响应阶段(无论是否在思考阶段都收集内容)if content:response_content += contentifnot thinking_phase:response_placeholder.markdown(f"回答:\n{response_content}▌")# 流结束后移除光标response_placeholder.markdown(f"回答:\n{response_content}")returnf"{thinking_content}{response_content}"defdisplay_chat_history():user_data = get_user_data()for message in user_data['messages']:with st.chat_message(message["role"]):st.markdown(message["content"])defhandle_user_input():user_data = get_user_data()base_url, api_key, model_name = get_active_api_config()ifnot api_key or api_key == 'sk-':st.error("请在侧边栏输入有效的 API Key。")returntry:client = OpenAI(api_key=api_key, base_url=base_url)uploaded_files = st.file_uploader("上传文本文件(支持 .txt 和 .md)",type=["txt", "md", "markdown"],accept_multiple_files=True,key="file_uploader")if uploaded_files:new_files = save_uploaded_files(dirs, uploaded_files)user_data['uploaded_files'].extend(new_files)user_content = []if user_input := st.chat_input("请问我任何事!"):user_content.append(user_input)if user_data['uploaded_files']:file_content = format_file_contents(user_data['uploaded_files'])user_content.append("\n[上传文件内容]\n" + file_content)user_data['uploaded_files'] = [] # 清空已处理的文件列表full_content = "\n".join(user_content)user_data['messages'].append({"role": "user", "content": full_content})with st.chat_message("user"):st.markdown(user_input)with st.chat_message("assistant"):try:stream = client.chat.completions.create(model=model_name,messages=user_data['messages'],stream=True)response = process_stream(stream)user_data['messages'].append({"role": "assistant", "content": response})except AuthenticationError:st.error("API 认证失败。请检查您的 API Key 是否正确。")except APIError as e:st.error(f"API 错误: {str(e)}")except Exception as e:st.error(f"发生未知错误: {str(e)}")except Exception as e:st.error(f"设置 OpenAI 客户端时发生错误: {str(e)}")defmain_interface():st.title("AI 助手")user_data = get_user_data()with st.sidebar:api_key = st.text_input("API Key", user_data['api_key'], type="password")if api_key:update_user_data('api_key', api_key)else:st.warning("请输入有效的 API Key")# Base URL 选项base_url_options = {"DashScope": "https://dashscope.aliyuncs.com/compatible-mode/v1","ARK": "https://ark.cn-beijing.volces.com/api/v3","自定义": "custom"}selected_base_url = st.selectbox("选择 Base URL",options=list(base_url_options.keys()),index=list(base_url_options.keys()).index("DashScope") if user_data['base_url'] == base_url_options["DashScope"] else0)if selected_base_url == "自定义":custom_base_url = st.text_input("自定义 Base URL", user_data['base_url'])update_user_data('base_url', custom_base_url)else:update_user_data('base_url', base_url_options[selected_base_url])# Model Name 选项model_options = {"deepseek-r1": "deepseek-r1","deepseek-v3": "deepseek-v3","自定义": "custom"}selected_model = st.selectbox("选择 Model",options=list(model_options.keys()),index=list(model_options.keys()).index("deepseek-r1") if user_data['model_name'] == "deepseek-r1"else0)if selected_model == "自定义":custom_model = st.text_input("自定义 Model Name", user_data['model_name'])update_user_data('model_name', custom_model)else:update_user_data('model_name', model_options[selected_model])if st.button("🆕 新会话"):save_current_session() # 保存当前会话new_session_id = str(uuid.uuid4())st.session_state.user_data[new_session_id] = {'messages': [{"role": "system", "content": "你是一个AI助手,请回答用户提出的问题。"}],'uploaded_files': [],'api_key': user_data['api_key'], # 保留当前的 API Key'base_url': user_data['base_url'], # 保留当前的 Base URL'model_name': user_data['model_name'], # 保留当前的 Model Name'past_sessions': user_data['past_sessions'] # 保留过去的会话记录}st.session_state.user_session_id = new_session_idst.rerun()# 显示过去的会话st.write("过去的会话:")for past_session in user_data['past_sessions']:if st.button(f"加载会话 {past_session['id'][:8]}...", key=past_session['id']):load_session(past_session['id'])st.rerun()display_chat_history()handle_user_input()defmain():if'user_session_id'notin st.session_state:st.session_state.user_session_id = str(uuid.uuid4())main_interface()if __name__ == "__main__":dirs = 'uploads/'ifnot os.path.exists(dirs):os.makedirs(dirs)main()
以下是启动服务的命令:
streamlit run chat_ui.py
通过网页界面,可以轻松填写 API Key 并选择平台与模型,如阿里云百炼或火山方舟。
比如我用 阿里百炼 验证交互过程
2、使用 Cherry Studio
如果您希望更便捷地使用 AI 助手,可以直接下载并安装开源的 Cherry Studio。
🐳https://cherry-ai.com/
安装好 Cherry Studio 之后,可配置需要接入的大模型应用后就可以本地化使用了,教程可参考 Cherry 官方文档。
往期阅读
手把手教你用 DeepSeek 和 Kimi,轻松搞定 PPT!
用 PyMuPDF 和 Pillow 打造 PDF 超级工具
基于 DeepSeek+AutoGen 的智能体协作系统
清华大学:普通人如何抓住 DeepSeek 红利?(65 页 PDF)
AI 时代,如何用 Python 脚本轻松搞定 PDF 需求?
DeepSeek 与 Ollama:本地运行 AI 模型的完美组合
相关文章:

从零到一:如何用阿里云百炼和火山引擎搭建专属 AI 助手(DeepSeek)?
本文首发:从零到一:如何用阿里云百炼和火山引擎搭建专属 AI 助手(DeepSeek)? 阿里云百炼和火山引擎都推出了免费的 DeepSeek 模型体验额度,今天我和大家一起搭建一个本地的专属 AI 助手。 阿里云百炼为 …...

Open3D解决SceneWidget加入布局中消失的问题
Open3D解决SceneWidget加入布局中消失的问题 Open3D解决SceneWidget加入布局中消失的问题1. 问题2. 问题代码3. 解决 Open3D解决SceneWidget加入布局中消失的问题 1. 问题 把SceneWidget加到布局管理其中图形可以展示出来,但是鼠标点击就消失了。 stackoverflow上已…...

计算机毕业设计Python+DeepSeek-R1大模型游戏推荐系统 Steam游戏推荐系统 游戏可视化 游戏数据分析(源码+文档+PPT+讲解)
温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 作者简介:Java领…...

Linux笔记---缓冲区
1. 什么是缓冲区 在计算机系统中,缓冲区(Buffer) 是一种临时存储数据的区域,主要用于协调不同速度或不同时序的组件之间的数据传输,以提高效率并减少资源冲突。它是系统设计中的重要概念,尤其在I/O操作、网…...
如何流畅访问github
1.传输数据原理 本地计算机通过本地网接入运营骨干网,经过DNS域名解析,将输入的字符解析为要连接的真实IP地址,服务器返还一个数据包(github)给计算机 2.原因 DNS域名污染-DNS解析出现问题,导致访问一个不存在的服务器 3.解决…...

java基础+面向对象
Java基础语法 CMD命令 cls 清屏 cd 目录进入文件 cd… 退回 dir 查看当前目录所有文件 E:进入E盘 exit 退出 环境变量就是不用去专门的盘符去找,直接去环境变量里找到文件 语言优势 编译型语言c: 整体翻译 解释型语言python&#x…...
Linux 检测内存泄漏方法总结
文章目录 strace检测asan内存检测linux下gperf工具(tcmalloc)检查C/C代码内存泄露问题参考 strace检测 (1)启动程序 (2) strace -f -p <PID> -tt -e brk,mmap,mmap2,munmapbrk 变大 → 说明堆增长…...

本地部署deepseek大模型后使用c# winform调用(可离线)
介于最近deepseek的大火,我就在想能不能用winform也玩一玩本地部署,于是经过查阅资料,然后了解到ollama部署deepseek,最后用ollama sharp NUGet包来实现winform调用ollama 部署的deepseek。 本项目使用Vs2022和.net 8.0开发,ollam…...

Python----数据分析(Numpy:安装,数组创建,切片和索引,数组的属性,数据类型,数组形状,数组的运算,基本函数)
一、 Numpy库简介 1.1、概念 NumPy(Numerical Python)是一个开源的Python科学计算库,旨在为Python提供 高性能的多维数组对象和一系列工具。NumPy数组是Python数据分析的基础,许多 其他的数据处理库(如Pandas、SciPy)都依赖于Num…...

Leetcode-最大矩形(单调栈)
一、题目描述 给定一个仅包含 0 和 1 、大小为 rows x cols 的二维二进制矩阵,找出只包含 1 的最大矩形,并返回其面积。 输入:matrix [["1","0","1","0","0"],["1","0&…...

域内委派维权
为某个服务账户配置 krbtgt 用户的非约束性委派或基于资源的约束性委派。这里我的 krbtgt 的基于资源约束性委派我利用不了,所以使用的是域控的机器账户 dc01$ 进行维权。 抓取所有 hash。 mimikatz.exe "privilege::debug" "lsadump::dcsync /doma…...

leetcode---LCR 140.训练计划
给定一个头节点为 head 的链表用于记录一系列核心肌群训练项目编号,请查找并返回倒数第 cnt 个训练项目编号。 示例 1: 输入:head [2,4,7,8], cnt 1 输出:8 提示: 1 < head.length < 1000 < head[i] <…...
Linux基础 -- ARM 32位常用机器码(指令)整理
ARM 32位常用机器码(指令)整理 1. 数据处理指令(运算、逻辑、比较) 指令含义示例备注MOV赋值(寄存器传输)MOV R0, R1直接将 R1 复制到 R0MVN取反MVN R0, R1R0 ~R1ADD加法ADD R0, R1, R2R0 R1 R2ADC带进…...
内存中的缓存区
在 Java 的 I/O 流设计中,BufferedInputStream 和 BufferedOutputStream 的“缓冲区”是 内存中的缓存区(具体是 JVM 堆内存的一部分),但它们的作用是优化数据的传输效率,并不是直接操作硬盘和内存之间的缓存。以下是详…...

基于 Spring Boot 的 +Vue“宠物咖啡馆平台” 系统的设计与实现
大家好,今天要和大家聊的是一款基于 Spring Boot 的 “宠物咖啡馆平台” 系统的设计与实现。项目源码以及部署相关事宜请联系我,文末附上联系方式。 项目简介 基于 Spring Boot 的 “宠物咖啡馆平台” 系统设计与实现的主要使用者分为 管理员、用户 和…...

LeetCode 解题思路 7(Hot 100)
解题思路: 初始化窗口元素: 遍历前 k 个元素,构建初始单调队列。若当前索引对应值大于等于队尾索引对应值,移除队尾索引,将当前索引加入队尾。遍历结束时当前队头索引即为当前窗口最大值,将其存入结果数组…...
linux-Dockerfile及docker-compose.yml相关字段用途
文章目录 计算机系统5G云计算LINUX Dockerfile及docker-conpose.yml相关字段用途一、Dockerfile1、基础指令2、.高级指令3、多阶段构建指令 二、Docker-Compose.yml1、服务定义(services)2、高级服务配置3、网络配置 (networks)4、卷配置 (volumes)5、扩…...
deepseek部署:ELK + Filebeat + Zookeeper + Kafka
## 1. 概述 本文档旨在指导如何在7台机器上部署ELK(Elasticsearch, Logstash, Kibana)堆栈、Filebeat、Zookeeper和Kafka。该部署方案适用于日志收集、处理和可视化场景。 ## 2. 环境准备 ### 2.1 机器分配 | 机器编号 | 主机名 | IP地址 | 部署组件 |-…...

微软Office 2016-2024 x86直装版 v16.0.18324 32位
微软 Office 是一款由微软公司开发的办公软件套装,能满足各种办公需求。包含 Word、Excel、PowerPoint、Outlook 和 OneNote 等软件。Word 有强大文档编辑功能和多人协作;Excel 可处理分析大量数据及支持宏编程;PowerPoint 用于制作演示文稿且…...
CMake宏定义管理:如何优雅处理第三方库的宏冲突
在C/C项目开发中,我们常常会遇到这样的困境: 当引入一个功能强大的第三方库时,却发现它定义的某个宏与我们的项目产生冲突。比如: 库定义了 BUFFER_SIZE 1024,而我们需要 BUFFER_SIZE 2048库内部使用 DEBUG 宏控制日志…...

Qt/C++开发监控GB28181系统/取流协议/同时支持udp/tcp被动/tcp主动
一、前言说明 在2011版本的gb28181协议中,拉取视频流只要求udp方式,从2016开始要求新增支持tcp被动和tcp主动两种方式,udp理论上会丢包的,所以实际使用过程可能会出现画面花屏的情况,而tcp肯定不丢包,起码…...
可靠性+灵活性:电力载波技术在楼宇自控中的核心价值
可靠性灵活性:电力载波技术在楼宇自控中的核心价值 在智能楼宇的自动化控制中,电力载波技术(PLC)凭借其独特的优势,正成为构建高效、稳定、灵活系统的核心解决方案。它利用现有电力线路传输数据,无需额外布…...
python爬虫:Newspaper3k 的详细使用(好用的新闻网站文章抓取和解析的Python库)
更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 一、Newspaper3k 概述1.1 Newspaper3k 介绍1.2 主要功能1.3 典型应用场景1.4 安装二、基本用法2.2 提取单篇文章的内容2.2 处理多篇文档三、高级选项3.1 自定义配置3.2 分析文章情感四、实战案例4.1 构建新闻摘要聚合器…...
Swagger和OpenApi的前世今生
Swagger与OpenAPI的关系演进是API标准化进程中的重要篇章,二者共同塑造了现代RESTful API的开发范式。 本期就扒一扒其技术演进的关键节点与核心逻辑: 🔄 一、起源与初创期:Swagger的诞生(2010-2014) 核心…...
A2A JS SDK 完整教程:快速入门指南
目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库ÿ…...

一些实用的chrome扩展0x01
简介 浏览器扩展程序有助于自动化任务、查找隐藏的漏洞、隐藏自身痕迹。以下列出了一些必备扩展程序,无论是测试应用程序、搜寻漏洞还是收集情报,它们都能提升工作流程。 FoxyProxy 代理管理工具,此扩展简化了使用代理(如 Burp…...
LangChain【6】之输出解析器:结构化LLM响应的关键工具
文章目录 一 LangChain输出解析器概述1.1 什么是输出解析器?1.2 主要功能与工作原理1.3 常用解析器类型 二 主要输出解析器类型2.1 Pydantic/Json输出解析器2.2 结构化输出解析器2.3 列表解析器2.4 日期解析器2.5 Json输出解析器2.6 xml输出解析器 三 高级使用技巧3…...
基于Java项目的Karate API测试
Karate 实现了可以只编写Feature 文件进行测试,但是对于熟悉Java语言的开发或是测试人员,可以通过编程方式集成 Karate 丰富的自动化和数据断言功能。 本篇快速介绍在Java Maven项目中编写和运行测试的示例。 创建Maven项目 最简单的创建项目的方式就是创建一个目录,里面…...
Oracle实用参考(13)——Oracle for Linux物理DG环境搭建(2)
13.2. Oracle for Linux物理DG环境搭建 Oracle 数据库的DataGuard技术方案,业界也称为DG,其在数据库高可用、容灾及负载分离等方面,都有着非常广泛的应用,对此,前面相关章节已做过较为详尽的讲解,此处不再赘述。 需要说明的是, DG方案又分为物理DG和逻辑DG,两者的搭建…...
WEB3全栈开发——面试专业技能点P8DevOps / 区块链部署
一、Hardhat / Foundry 进行合约部署 概念介绍 Hardhat 和 Foundry 都是以太坊智能合约开发的工具套件,支持合约的编译、测试和部署。 它们允许开发者在本地或测试网络快速开发智能合约,并部署到链上(测试网或主网)。 部署过程…...