从零到一:如何用阿里云百炼和火山引擎搭建专属 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 宏控制日志…...
XCTF-web-easyupload
试了试php,php7,pht,phtml等,都没有用 尝试.user.ini 抓包修改将.user.ini修改为jpg图片 在上传一个123.jpg 用蚁剑连接,得到flag...
基于FPGA的PID算法学习———实现PID比例控制算法
基于FPGA的PID算法学习 前言一、PID算法分析二、PID仿真分析1. PID代码2.PI代码3.P代码4.顶层5.测试文件6.仿真波形 总结 前言 学习内容:参考网站: PID算法控制 PID即:Proportional(比例)、Integral(积分&…...
QMC5883L的驱动
简介 本篇文章的代码已经上传到了github上面,开源代码 作为一个电子罗盘模块,我们可以通过I2C从中获取偏航角yaw,相对于六轴陀螺仪的yaw,qmc5883l几乎不会零飘并且成本较低。 参考资料 QMC5883L磁场传感器驱动 QMC5883L磁力计…...
C++中string流知识详解和示例
一、概览与类体系 C 提供三种基于内存字符串的流,定义在 <sstream> 中: std::istringstream:输入流,从已有字符串中读取并解析。std::ostringstream:输出流,向内部缓冲区写入内容,最终取…...
2023赣州旅游投资集团
单选题 1.“不登高山,不知天之高也;不临深溪,不知地之厚也。”这句话说明_____。 A、人的意识具有创造性 B、人的认识是独立于实践之外的 C、实践在认识过程中具有决定作用 D、人的一切知识都是从直接经验中获得的 参考答案: C 本题解…...
【Go语言基础【13】】函数、闭包、方法
文章目录 零、概述一、函数基础1、函数基础概念2、参数传递机制3、返回值特性3.1. 多返回值3.2. 命名返回值3.3. 错误处理 二、函数类型与高阶函数1. 函数类型定义2. 高阶函数(函数作为参数、返回值) 三、匿名函数与闭包1. 匿名函数(Lambda函…...
QT3D学习笔记——圆台、圆锥
类名作用Qt3DWindow3D渲染窗口容器QEntity场景中的实体(对象或容器)QCamera控制观察视角QPointLight点光源QConeMesh圆锥几何网格QTransform控制实体的位置/旋转/缩放QPhongMaterialPhong光照材质(定义颜色、反光等)QFirstPersonC…...
排序算法总结(C++)
目录 一、稳定性二、排序算法选择、冒泡、插入排序归并排序随机快速排序堆排序基数排序计数排序 三、总结 一、稳定性 排序算法的稳定性是指:同样大小的样本 **(同样大小的数据)**在排序之后不会改变原始的相对次序。 稳定性对基础类型对象…...
虚拟电厂发展三大趋势:市场化、技术主导、车网互联
市场化:从政策驱动到多元盈利 政策全面赋能 2025年4月,国家发改委、能源局发布《关于加快推进虚拟电厂发展的指导意见》,首次明确虚拟电厂为“独立市场主体”,提出硬性目标:2027年全国调节能力≥2000万千瓦࿰…...
代码规范和架构【立芯理论一】(2025.06.08)
1、代码规范的目标 代码简洁精炼、美观,可持续性好高效率高复用,可移植性好高内聚,低耦合没有冗余规范性,代码有规可循,可以看出自己当时的思考过程特殊排版,特殊语法,特殊指令,必须…...
