从零到一:如何用阿里云百炼和火山引擎搭建专属 AI 助手(DeepSeek)?

news2025/2/27 4:40:16

本文首发:从零到一:如何用阿里云百炼和火山引擎搭建专属 AI 助手(DeepSeek)?

阿里云百炼和火山引擎都推出了免费的 DeepSeek 模型体验额度,今天我和大家一起搭建一个本地的专属 AI 助手。 

Image

  • 阿里云百炼为 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 模型

Image

1、登录阿里云百炼

注册并登录阿里云百炼平台,进入模型广场即可查看 DeepSeek 模型。 

Image

2、创建 API Key

在阿里云百炼主页右上角的个人图标中,进入 API-KEY 页面并创建专属的 API Key。 

Image

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 OpenAI

client = 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-key
    base_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 模型

Image

1、登录火山方舟

🐵

注册并登录火山方舟平台,可使用我的邀请码 9Z52V71T 可免费获得每个模型 50 万 tokens 的推理额度。 


 

# 登录后免费赠送每个模型50万tokens推理额度。
https://www.volcengine.com/experience/ark?utm_term=202502dsinvite&ac=DSASUQY5&rc=9Z52V71T

登录后就能体验 DeepSeek-R1 等各种模型 

Image

2、创建 API Key

在“在线推理”页面找到“API 接入”,按照提示创建 API Key。 

Image

3、创建自定义推理接入点

根据官方教程,在“在线推理”页面选择“创建推理接入点”。 

Image

创建过程比较简单,填写名称并选择模型(如 DeepSeek-R1),比如我选择 DeepSeek-R1 模型,为了方便我自己识别,所以接入点名称我填写成“DeepSeek-R1” 

Image

在模型选择页,可以根据自己需求去选择模型 

Image

创建完成就可以得到接入点名称。注意:后续用到的 model_name 是火山平台自动生成(以“ep-”开头)。 

Image

4、调用 API 验证

设置 API Key 作为环境变量,其中"YOUR_API_KEY"需要替换为火山方舟上创建的 API Key 


 

export ARK_API_KEY="YOUR_API_KEY"

官方示例参考 

import os
from openai import OpenAI

client = 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 ID
    messages = [
        {"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 ID
    messages = [
        {"role": "system", "content": "你是人工智能助手"},
        {"role": "user", "content": "常见的十字花科植物有哪些?"},
    ],
    stream=True
)

for chunk in stream:
    if not chunk.choices:
        continue
    print(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_id
            st.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']
            }
            break

defsave_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:
            continue

        ifnot file.name.lower().endswith(('.txt', '.md', '.markdown')):
            st.warning(f"不支持的文件类型: {file.name}。请上传 .txt 或 .md 文件。")
            continue

        if file.size > 1 * 1024 * 1024:  # 1MB限制
            st.error(f"文件 {file.name} 超过大小限制(1MB)")
            continue

        try:
            # 保存文件到指定目录
            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} 的内容与已上传的文件重复,已跳过。")
                continue

            saved_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)}")
            continue

    return saved_files

defformat_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].delta
            reasoning = 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 += reasoning
                    thinking_placeholder.markdown(f"思考过程:\n{thinking_content}")

                # 检测思考阶段结束
                if content:
                    status.update(label="思考完成", state="complete", expanded=False)
                    thinking_phase = False
                    response_placeholder.markdown("回答:\n▌")  # 初始化响应光标

            # 处理响应阶段(无论是否在思考阶段都收集内容)
            if content:
                response_content += content
                ifnot 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。")
        return

    try:
        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_id
            st.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 并选择平台与模型,如阿里云百炼或火山方舟。 

Image

比如我用 阿里百炼 验证交互过程 

Image

2、使用 Cherry Studio

如果您希望更便捷地使用 AI 助手,可以直接下载并安装开源的 Cherry Studio。 

🐳https://cherry-ai.com/ 

安装好 Cherry Studio 之后,可配置需要接入的大模型应用后就可以本地化使用了,教程可参考 Cherry 官方文档。 

Image


往期阅读

手把手教你用 DeepSeek 和 Kimi,轻松搞定 PPT!

用 PyMuPDF 和 Pillow 打造 PDF 超级工具

基于 DeepSeek+AutoGen 的智能体协作系统

清华大学:普通人如何抓住 DeepSeek 红利?(65 页 PDF)

AI 时代,如何用 Python 脚本轻松搞定 PDF 需求?

DeepSeek 与 Ollama:本地运行 AI 模型的完美组合


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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

FFmpeg视频处理入门级教程

一、FFmpeg常规处理流程 #mermaid-svg-W8X1llNEyuYptV3I {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-W8X1llNEyuYptV3I .error-icon{fill:#552222;}#mermaid-svg-W8X1llNEyuYptV3I .error-text{fill:#552222;str…

C/C++ | 每日一练 (4)

💢欢迎来到张胤尘的技术站 💥技术如江河,汇聚众志成。代码似星辰,照亮行征程。开源精神长,传承永不忘。携手共前行,未来更辉煌💥 文章目录 C/C | 每日一练 (4)题目参考答案基础容器序列容器std:…

蓝桥杯备考:贪心算法之矩阵消除游戏

这道题是牛客上的一道题,它呢和我们之前的排座位游戏非常之相似,但是,排座位问题选择行和列是不会改变元素的值的,这道题呢每每选一行都会把这行或者这列清零,所以我们的策略就是先用二进制把选择所有行的情况全部枚举…

基于 CFD 预测的机器学习第 2 部分:在 Benchmark 应用程序上使用 Stochos 预测流场

了解机器学习和 Stochos 如何彻底改变制造业的 CFD 预测。 挑战 预测复杂流体动力学场景中的流场一直是工程师和科学家面临的重大挑战。传统的计算流体动力学 (CFD) 方法需要大量的计算资源和时间,因此难以处理实时预测和大规模模拟。 此外…

批量导出数据库表到Excel

这篇文章将介绍如何批量的将多个甚至成千上万的数据库表导出为Excel文件。 准备数据 如下图是数据库里的表,我们需要将它们全部导出为excel文件,这里以SQL Server数据库为例 新增导出 打开的卢导表工具,新建数据库连接,这里以S…

力扣提升第一天

力扣提升第一天 题目链接:https://leetcode.cn/problems/design-memory-allocator/?envTypedaily-question&envId2025-02-25 一开始解题思路 暴力解决法 我奔着先从简单的写法做起,之后再想办法进行改进,心里已经预料到会出现超出时间…

uni-app 开发 App 、 H5 横屏签名(基于lime-signature)

所用插件&#xff1a;lime-signature 使用到 CSS 特性 绝对定位transform 旋转transform-origin transform 原点 复习一下定位元素&#xff08;相对定位、绝对定位、粘性定位&#xff09; 代码# <template><view class"signature-page"><view clas…

【Python】Python顺序语句经典题(四)

Python顺序语句经典练习题例题&#xff08;四&#xff09;。题目来源&#xff1a;Acwing 前三期合集&#xff1a;【Python】Python顺序语句经典题合集-CSDN博客 目录 1.最大值 题目描述 解题思路 AC代码 2.距离 题目描述 AC代码 3.燃料消耗 题目描述 AC代码 4.钞票…

03_pyqt5 + vlc 实现视频播放器

1.功能需求如图 按钮: 播放/暂停, 前进/后退, 视频上一个/下一个, 打开视频进度条: 视频进度条显示, 进度条拖拽, 音量控制按键控制: 1,2,3,4缩放画面大小, 2.方案选择 开发语言: python UI界面: pyqt5 qt_designed 设计ui布局 视频编码: python-vlc 方案说明: 视频解码可…

prometheus+node_exporter+grafana监控K8S信息

prometheusnode_exportergrafana监控K8S 1.prometheus部署2.node_exporter部署3.修改prometheus配置文件4.grafana部署 1.prometheus部署 包下载地址&#xff1a;https://prometheus.io/download/ 将包传至/opt 解压 tar xf prometheus-2.53.3.linux-amd64.tar.gz 移动到…

IDEA关闭SpringBoot程序后仍然占用端口的排查与解决

IDEA关闭SpringBoot程序后仍然占用端口的排查与解决 问题描述 在使用 IntelliJ IDEA 开发 Spring Boot 应用时&#xff0c;有时即使关闭了应用&#xff0c;程序仍然占用端口&#xff08;例如&#xff1a;4001 端口&#xff09;。这会导致重新启动应用时出现端口被占用的错误&a…

山东大学软件学院nosql实验三

实验题目&#xff1a; 用Java做简单查询(2学时) 实验内容 用API方式&#xff0c;做简单查询。 实验要求 在以下要求中选择至少2个&#xff0c;使用Java语言实现数据查询&#xff0c;最终把数据输出到前端界面。 &#xff08;1&#xff09;找出年龄小于20岁的所有学生 &…

零样本学习 zero-shot

1 是什么 2 如何利用零样本学习进行跨模态迁移&#xff1f; demo代码 安装clip pip install ftfy regex tqdm pip install githttps://github.com/openai/CLIP.git import torch import clip from PIL import Image# 加载 CLIP 模型 device "cuda" if torch.cuda.i…

《深度学习实战》第3集:循环神经网络(RNN)与序列建模

第3集&#xff1a;循环神经网络&#xff08;RNN&#xff09;与序列建模 引言 在深度学习领域&#xff0c;处理序列数据&#xff08;如文本、语音、时间序列等&#xff09;是一个重要的研究方向。传统的全连接网络和卷积神经网络&#xff08;CNN&#xff09;难以直接捕捉序列中…

mac下载MAMP6.8.1

因为mac的小皮面板没有php7.4了 链接&#xff1a;c9cc270e6961c17c.dmg官方版下载丨最新版下载丨绿色版下载丨APP下载-123云盘 鹅选一 附上大佬写的教程&#xff1a;MAMP PRO教程 - 牛奔 - 博客园

BUU41 [GYCTF2020]FlaskApp1【SSTI】

题目&#xff1a; 加密处没啥事&#xff0c;但是解密的地方提交{{7*7}}就会返回报错界面&#xff0c;顺便把代码也爆出来了 text_decode base64.b64decode(text.encode()) 先将字符串 text编码为字节对象&#xff0c;然后使用 base64.b64decode 函数对这个字节对象进行 Base…

今日运维之-Mac笔记本python环境问题

1. 问题&#xff1a;MAC升级系统后git报错&#xff1f; Error: Cant create update lock in /usr/local/var/homebrew/locks! Fix permissions by running:sudo chown -R $(whoami) /usr/local/var/homebrew Traceback (most recent call last):11: from /usr/local/Homebrew/…

易基因:RNA甲基化修饰和R-loop的交叉调控:从分子机制到临床意义|深度综述

大家好&#xff0c;这里是专注表观组学十余年&#xff0c;领跑多组学科研服务的易基因。 R-loop&#xff08;RNA-DNA杂合结构&#xff09;是转录调控、DNA复制和修复等关键细胞过程的重要组成部分。但R-loop异常积累可能会破坏基因组完整性&#xff0c;从而导致多种疾病的发生…

NLP的预处理数据

处理文本数据的主要工具是Tokenizer。Tokenizer根据一组规则将文本拆分为tokens。然后将这些tokens转换为数字&#xff0c;然后转换为张量&#xff0c;成为模型的输入。模型所需的任何附加输入都由Tokenizer添加。 如果您计划使用预训练模型&#xff0c;重要的是使用与之关联的…

Linux相关知识(文件系统、目录树、权限管理)和Shell相关知识(字符串、数组)

仅供自学&#xff0c;请去支持javaGuide原版书籍。 1.Linux 1.1.概述 Linux是一种类Unix系统。 严格来讲&#xff0c;Linux 这个词本身只表示 Linux内核&#xff0c;单独的 Linux 内核并不能成为一个可以正常工作的操作系统。所以&#xff0c;就有了各种 Linux 发行版&#…