当前位置: 首页 > article >正文

SpringAI+DeepSeek大模型应用开发——2 大模型应用开发架构

目录

2.大模型开发

2.1 模型部署

2.1.1 云服务-开放大模型API

2.1.2 本地部署

搜索模型

运行大模型

2.2 调用大模型

接口说明

提示词角色

​编辑

会话记忆问题

2.3 大模型应用开发架构

2.3.1 技术架构

纯Prompt模式

FunctionCalling

RAG检索增强

Fine-tuning

2.3.2 技术选型

2.大模型开发

2.1 模型部署

首先大模型应用开发并不是在浏览器中跟AI聊天。而是通过访问模型对外暴露的API接口,实现与大模型的交互

因此,需要有一个可访问的大模型,通常有三种选择:

2.1.1 云服务-开放大模型API

部署在云服务器上,部署维护简单,部署方案简单,全球访问 ,缺点:数据隐私,网络依赖,长期成本问题

通常发布大模型的官方、大多数的云平台都会提供开放的、公共的大模型服务。以下是一些国内提供大模型服务的云平台

这些开放平台并不是免费,而是按照调用时消耗的token来付费,每百万token通常在几毛~几元钱,而且平台通常都会赠送新用户百万token的免费使用权;

以百炼大模型为例 大模型服务平台百炼_企业级大模型开发平台_百炼AI应用构建-阿里云

注册一个阿里云账号==>然后访问百炼平台,开通服务(首次开通应该会赠送百万token的使用权,包括DeepSeek-R1模型、qwen模型。)

==>申请API_KEY(百炼平台右上角个人中心)==>创建APIKEY==>进入模型广场

选择一个自己喜欢的模型,然后点击API调用示例,即可进入API文档页===>立即体验==>进入API调用大模型的试验台==>模拟调用大模型接口

2.1.2 本地部署

数据安全,不依赖网络,成本低,缺点:初期成本高,部署麻烦周期长

最简单的方案是使用ollama Download Ollama on macOS,当然这种方式不推荐,阉割版

访问官网下载查看对应模型的本地调用即可

OllamaSetup.exe所在目录打开cmd命令行,然后输入命令如下:

OllamaSetup.exe /DIR=你要安装的目录位置

安装完成后,还需要配置一个环境变量,更改Ollama下载和部署模型的位置。配置完成如图:

搜索模型
  • Ollama是一个模型管理工具和平台,它提供了很多国内外常见的模型,可以在其官网上搜索自己需要的模型:Ollama Search;

  • 搜索DeepSeek-R1后,进入DeepSeek-R1页面,会发现DeepSeek-R1也有很多版本:

运行大模型

选择自己电脑合适的模型后,Ollama会给出运行模型的命令: 打开cmd运行即可

ollama run deepseek-r1:7b  #运行大模型
/bye   #退出当前大模型
ollama ps #查看运行的大模型

Ollama是一个模型管理工具,有点像Docker,而且命令也很像,常见命令如下:

ollama serve      # Start ollama
ollama create     # Create a model from a Modelfile
ollama show       # Show information for a model
ollama run        # Run a model
ollama stop       # Stop a running model
ollama pull       # Pull a model from a registry
ollama push       # Push a model to a registry
ollama list       # List models
ollama ps         # List running models
ollama cp         # Copy a model
ollama rm         # Remove a model
ollama help       # Help about any command

2.2 调用大模型

调用大模型并不是在浏览器中跟AI聊天,而是通过访问模型对外暴露的API接口,实现与大模型的交互;所以要学习大模型应用开发,就必须掌握模型的API接口规范

目前大多数大模型都遵循OpenAI的接口规范,是基于Http协议的接口。因此请求路径、参数、返回值信息都是类似的,可能会有一些小的差别。具体需要查看大模型的官方API文档。

以DeepSeek官方给出的文档为例:

# Please install OpenAI SDK first: `pip3 install openai`from openai import OpenAI# 1.初始化OpenAI客户端,要指定两个参数:api_key、base_url
client = OpenAI(api_key="<DeepSeek API Key>", base_url="https://api.deepseek.com")# 2.发送http请求到大模型,参数比较多
response = client.chat.completions.create(# 2.1.选择要访问的模型model="deepseek-chat",# 2.2.发送给大模型的消息messages=[{"role": "system", "content": "You are a helpful assistant"},{"role": "user", "content": "Hello"},],# 2.3.是否以流式返回结果stream=False
)
print(response.choices[0].message.content)
接口说明
  • 请求方式:通常是POST,因为要传递JSON风格的参数;

  • 请求路径:与平台有关

    • DeepSeek官方平台:https://api.deepseek.com;

    • 阿里云百炼平台:https://dashscope.aliyuncs.com/compatible-mode/v1;

    • 本地ollama部署的模型:http://localhost:11434;

  • 安全校验:开放平台都需要提供API_KEY来校验权限,本地Ollama则不需要;

  • 请求参数:参数很多,比较常见的有:

    • model:要访问的模型名称;

    • messages:发送给大模型的消息,是一个数组;

    • stream

      • true,代表响应结果流式返回;

      • false,代表响应结果一次性返回,但需要等待;

    • temperature:取值范围[0:2),代表大模型生成结果的随机性,越小随机性越低。DeepSeek-R1不支持;

  • 注意,这里请求参数中的messages是一个消息数组,而且其中的消息要包含两个属性:

    • role:消息对应的角色;

    • content:消息内容;也被称为提示词(Prompt),也就是发送给大模型的指令。

提示词角色

常用的消息的角色有三种:

其中System类型的消息非常重要!影响了后续AI会话的行为模式;

  • 比如,当我们询问AI对话产品(文心一言、DeepSeek等)“你是谁” 这个问题的时候,每一个AI的回答都不一样,这是怎么回事呢?

  • 这其实是因为AI对话产品并不是直接把用户的提问发送给LLM,通常都会在user提问的前面通过System消息给模型设定好背景

  • 所以,当你问问题时,AI就会遵循System的设定来回答了。因此,不同的大模型由于System设定不同,回答的答案也不一样;

## Role
System: 你是邓超
## Example
User: 你是谁
Assisant: 到!gogogo,黑咖啡品味有多浓!我只要汽水的轻松,大热天做个白日梦,梦见我变成了彩虹
我是邓超啊!哈哈,你没看错,就是那个又帅又幽默的邓超!怎么样,是不是被我的魅力惊到了?😎 
会话记忆问题

为什么要把历史消息都放入Messages中,形成一个数组呢?

这是因为大模型是没有记忆的,因此在调用API接口与大模型对话时,每一次对话信息都不会保留,但是可以发现AI对话产品却能够记住每一轮对话信息,根据这些信息进一步回答,这是怎么回事呢?

答案就是Messages数组;

只需要每一次发送请求时,都把历史对话中每一轮的User消息、Assistant消息都封装到Messages数组中,一起发送给大模型,这样大模型就会根据这些历史对话信息进一步回答,就像是拥有了记忆一样;

2.3 大模型应用开发架构

2.3.1 技术架构

目前,大模型应用开发的技术架构主要有四种

纯Prompt模式

不同的提示词能够让大模型给出差异巨大的答案;

不断雕琢提示词,使大模型能给出最理想的答案,这个过程就叫做提示词工程(Prompt Engineering);

很多简单的AI应用,仅仅靠一段足够好的提示词就能实现了,这就是纯Prompt模式;流程如图:

FunctionCalling

大模型虽然可以理解自然语言,更清晰地弄懂用户意图,但是确无法直接操作数据库、执行严格的业务规则。这个时候就可以整合传统应用与大模型的能力了;

  1. 把传统应用中的部分功能封装成一个个函数(Function);

  2. 在提示词中描述用户的需求,并且描述清楚每个函数的作用,要求AI理解用户意图,判断什么时候需要调用哪个函数,并且将任务拆解为多个步骤(Agent);

  3. 当AI执行到某一步,需要调用某个函数时,会返回要调用的函数名称、函数需要的参数信息;

  4. 传统应用接收到这些数据以后,就可以调用本地函数。再把函数执行结果封装为提示词,再次发送给AI;

  5. 以此类推,逐步执行,直到达成最终结果。

RAG检索增强

检索增强生成(Retrieval-Augmented Generation,简称RAG)已成为构建智能问答系统的关键技术。

模型从知识角度存在很多限制:

  • 时效性差:大模型训练比较耗时,其训练数据都是旧数据,无法实时更新;

  • 缺少专业领域知识:大模型训练数据都是采集的通用数据,缺少专业数据;

把最新的数据或者专业文档都拼接到提示词,一起发给大模型,不就可以了?

现在的大模型都是基于Transformer神经网络,Transformer的强项就是所谓的注意力机制。它可以根据上下文来分析文本含义

但是,上下文的大小是有限制的,GPT3刚刚出来的时候,仅支持2000个token的上下文。所以海量知识库数据是无法直接写入提示词的;

RAG原理

RAG 的核心原理是将检索技术与生成模型相结合,结合外部知识库或私有数据源来检索相关信息来指导和增强生成模型的输出,有效解决了传统大语言模型的知识更新滞后和"幻觉"问题。

其核心工作流程分为三个阶段:

  1. 接收请求: 首先,系统接收到用户的请求(例如提出一个问题)

  2. 信息检索(R): 系统从一个大型文档库中检索出与查询最相关的文档片段。这一步的目标是找到那些可能包含答案或相关信息的文档。这里不一定是从向量数据库中检索,但是向量数据库能反应相似度最高的几个文档(比如说法不同,意思相同),而不是精确查找

    • 文本拆分:将文本按照某种规则拆分为很多片段;

    • 文本嵌入(Embedding):根据文本片段内容,将文本片段归类存储;

    • 文本检索:根据用户提问的问题,找出最相关的文本片段;

  3. 生成增强(A): 将检索到的文档片段与原始查询一起输入到大模型(如chatGPT)中,注意使用合适的提示词,比如原始的问题是XXX,检索到的信息是YY,给大模型的输入应该类似于: 请基于YYY回答XXXX。

  4. 输出生成(G): 大模型LLM 基于输入的查询和检索到的文档片段生成最终的文本答案,并返回给用户

由于每次都是从向量库中找出与用户问题相关的数据,而不是整个知识库,所以上下文就不会超过大模型的限制,同时又保证了大模型回答问题是基于知识库中的内容;

Fine-tuning

模型微调,就是在预训练大模型(比如DeepSeek、Qwen)的基础上,通过企业自己的数据做进一步的训练,使大模型的回答更符合自己企业的业务需求。这个过程通常需要在模型的参数上进行细微的修改,以达到最佳的性能表现;

在进行微调时,通常会保留模型的大部分结构和参数,只对其中的一小部分进行调整。减少了训练时间和计算资源的消耗。

微调的过程包括以下几个关键步骤:

  1. 选择合适的预训练模型:根据任务的需求,选择一个已经在大量数据上进行过预训练的模型,如Qwen-2.5;

  2. 准备特定领域的数据集:收集和准备与任务相关的数据集,这些数据将用于微调模型;

  3. 设置超参数:调整学习率、批次大小、训练轮次等超参数,以确保模型能够有效学习新任务的特征;

  4. 训练和优化:使用特定任务的数据对模型进行训练,通过前向传播、损失计算、反向传播和权重更新等步骤,不断优化模型的性能;

2.3.2 技术选型
  • 从开发成本由低到高来看,四种方案的排序:Prompt < Function Calling < RAG < Fine-tuning

  • 所以在选择技术时通常也应该遵循"在达成目标效果的前提下,尽量降低开发成本"这一首要原则。然后可以参考以下流程来思考:

相关文章:

SpringAI+DeepSeek大模型应用开发——2 大模型应用开发架构

目录 2.大模型开发 2.1 模型部署 2.1.1 云服务-开放大模型API 2.1.2 本地部署 搜索模型 运行大模型 2.2 调用大模型 接口说明 提示词角色 ​编辑 会话记忆问题 2.3 大模型应用开发架构 2.3.1 技术架构 纯Prompt模式 FunctionCalling RAG检索增强 Fine-tuning …...

Transformer 架构 - 编码器 (Transformer Architecture - Encoder)

1.Transformer 编码器整体结构 Transformer 编码器的结构相对直观:它由 N 个完全相同的编码器层 (Encoder Layer) 堆叠而成。 图1: Transformer 编码器整体结构示意图 (简化) 输入序列(例如,通过 embedding 层转换后的词向量)首先会加上位置编码,然后传入第一个编码器层…...

2.2/Q2,Charls最新文章解读

文章题目&#xff1a;Association of uric acid to high-density lipoprotein cholesterol ratio with the presence or absence of hypertensive kidney function: results from the China Health and Retirement Longitudinal Study (CHARLS) DOI&#xff1a;10.1186/s12882-…...

下拉框select标签类型

在我们很多页面里有下拉框的选择&#xff0c;这种元素怎么定位呢&#xff1f;下拉框分为两种类型&#xff1a;我们分别针对这两种元素进行定位和操作 select标签 &#xff1a; 通过select类处理。 非select标签 1、针对下拉框元素&#xff0c;如果是Select标签类型&#xff0c;…...

CentOS 7 linux系统从无到有部署项目

环境部署操作手册 一、Maven安装与配置 1. 下载与解压 下载地址&#xff1a;https://maven.apache.org/download.cgi?spm5238cd80.38b417da.0.0.d54c32cbnOpQh2&filedownload.cgi上传并解压解压命令&#xff1a; tar -zxvf apache-maven-3.9.9-bin.tar.gz -C /usr/loc…...

李飞飞团队新作WorldScore:“世界生成”能力迎来统一评测,3D/4D/视频模型同台PK

从古老神话中对世界起源的幻想&#xff0c;到如今科学家们在实验室里对虚拟世界的构建&#xff0c;人类探索世界生成奥秘的脚步从未停歇。如今&#xff0c;随着人工智能和计算机图形学的深度融合&#xff0c;我们已站在一个全新的起点&#xff0c;能够以前所未有的精度和效率去…...

如何在米尔-STM32MP257开发板上部署环境监测系统

本文将介绍基于米尔电子MYD-LD25X开发板&#xff08;米尔基于STM35MP257开发板&#xff09;的环境监测系统方案测试。 摘自优秀创作者-lugl4313820 一、前言 环境监测是当前很多场景需要的项目&#xff0c;刚好我正在论坛参与的一个项目&#xff1a;Thingy:91X 蜂窝物联网原型…...

MySQL之SQL优化

目录 1.插入数据 2.大批量插入数据 3.order by优化 4.group by优化 5.limit优化 6.count优化 count用法 7.update优化 1.插入数据 如果我们需要一次性往数据库表中插入多条记录&#xff0c;可以从以下三个方面进行优化 第一个:批量插入数据 Insert into tb_test va…...

python_level1.2

目录 一、变量 例如&#xff1a;小正方形——>大正方形 【1】第一次使用这个变量&#xff0c;所以说&#xff1a;定义一个变量length&#xff1b; 【2】&#xff1a;是赋值符号&#xff0c;不是等于符号。&#xff08;只有赋值&#xff0c;该变量才会被创建&#xff09;…...

Linux、Kylin OS挂载磁盘,开机自动加载

0.实验环境&#xff1a; 1.确定挂载目录&#xff0c;如果没有使用mkdir 进行创建&#xff1a; mkdir /data 2.查看磁盘 lsblk #列出所有可用的块设备df -T #查看磁盘文件系统类型 3.格式化成xfs文件系统 (这里以xfs为例&#xff0c;ext4类似) mkfs.xfs /dev/vdb 4.挂载到…...

FPGA-VGA

目录 前言 一、VGA是什么&#xff1f; 二、物理接口 三、VGA显示原理 四、VGA时序标准 五、VGA显示参数 六、模块设计 七、波形图设计 八、彩条波形数据 前言 VGA的FPGA驱动 一、VGA是什么&#xff1f; VGA&#xff08;Video Graphics Array&#xff09;是IBM于1987年推出的…...

java的lambda和stream流操作

Lambda 表达式 ≈ 匿名函数 &#xff08;Lambda接口&#xff09;函数式接口&#xff1a;传入Lambda表达作为函数式接口的参数 函数式接口 只能有一个抽象方法的接口 Lambda 表达式必须赋值给一个函数式接口&#xff0c;比如 Java 8 自带的&#xff1a; 接口名 作用 Functio…...

【嵌入式】【阿里云服务器】【树莓派】学习守护进程编程、gdb调试原理和内网穿透信息

目录 一. 守护进程的含义及编程实现的主要过程 1.1守护进程 1.2编程实现的主要过程 二、在树莓派中通过三种方式创建守护进程 2.1nohup命令创建 2.2fork()函数创建 2.3daemon()函数创建 三、在阿里云中通过三种方式创建守护进程 3.1nohup命令创建 3.2fork()函数创建 …...

数据结构学习笔记 :树与二叉树详解

目录 树的基本概念二叉树的定义与特性二叉树的存储结构 3.1 顺序存储 3.2 链式存储二叉树遍历特殊二叉树类型总结与应用场景 一、树的基本概念 核心定义 树&#xff1a;由根节点和若干子树构成的层次结构。叶子节点&#xff08;终端节点&#xff09;&#xff1a;没有子节点的…...

前沿篇|CAN XL 与 TSN 深度解读

引言 1. CAN XL 标准演进与设计目标 2. CAN XL 物理层与帧格式详解 3. 时间敏感网络 (TSN) 关键技术解析 4. CAN XL + TSN 在自动驾驶领域的典型应用...

七、LangChain Tool类参数对接机制解析:基于Pydantic的类型安全与流程实现

LangChain 的 Tool 类(包括 BaseTool 和 StructuredTool)通过 参数校验、输入解析、函数调用 的流程,将外部函数与 Agent 的逻辑对接。以下是其内部逻辑的详细解析: 1. 工具与函数对接的核心机制 (1) 工具的定义方式 LangChain 提供了两种主要方式定义工具: 继承 BaseTo…...

Spring-AI-alibaba 结构化输出

1、将模型响应转换为 ActorsFilms 对象实例&#xff1a; ActorsFilms package com.alibaba.cloud.ai.example.chat.openai.entity;import java.util.List;public record ActorsFilms(String actor, List<String> movies) { } GetMapping("/toBean")public Ac…...

AI大模型科普:从零开始理解AI的“超级大脑“,以及如何用好提示词?

大家好&#xff0c;小机又来分享AI了。 今天分享一些新奇的东西&#xff0c; 你有没有试过和ChatGPT聊天时&#xff0c;心里偷偷犯嘀咕&#xff1a;"这AI怎么跟真人一样对答如流&#xff1f;它真的会思考吗&#xff1f;" 或者刷到技术文章里满屏的"Token"…...

STM32单片机入门学习——第40节: [11-5] 硬件SPI读写W25Q64

写这个文章是用来学习的,记录一下我的学习过程。希望我能一直坚持下去,我只是一个小白,只是想好好学习,我知道这会很难&#xff0c;但我还是想去做&#xff01; 本文写于&#xff1a;2025.04.18 STM32开发板学习——第一节&#xff1a; [1-1]课程简介第40节: [11-5] 硬件SPI读…...

【Java学习笔记】关键字汇总

Java 关键字汇总 用于定义数据类型的关键字&#xff1a; classinterfaceenumbyteshortintlongfloatdoublecharbooleanvoid 用于定义数据值的关键字&#xff1a; truefalsenull 用于定义流程控制的关键字&#xff1a; ifelseswitchcasedefaultwhiledoforbreakcontinueretu…...

langgraph框架之初识

1.什么是langgraph&#xff1f; LangGraph 是一个用于构建可控代理的底层编排框架。在AI中&#xff0c;代理也就是执行动作的智能体&#xff0c;也就是agent。使用这个框架可以构建一个可以自由控制的智能执行体&#xff0c;它可以帮我们做许多事情&#xff0c;如下&#xff1…...

如何将 .txt 文件转换成 .md 文件

一、因为有些软件上传文件的时候需要 .md 文件&#xff0c;首先在文件所在的目录中&#xff0c;点击“查看”&#xff0c;然后勾选上“文件扩展名”&#xff0c;这个时候该目录下的所有文件都会显示其文件类型了。 二、这时直接对目标的 .txt 文件进行重命名&#xff0c;把后缀…...

pdfjs库使用记录1

import React, { useEffect, useState, useRef } from react; import * as pdfjsLib from pdfjs-dist; // 设置 worker 路径 pdfjsLib.GlobalWorkerOptions.workerSrc /pdf.worker.min.js; const PDFViewer ({ url }) > { const [pdf, setPdf] useState(null); const […...

Qt 创建QWidget的界面库(DLL)

【1】新建一个qt库项目 【2】在项目目录图标上右击&#xff0c;选择Add New... 【3】选择模版&#xff1a;Qt->Qt设计师界面类&#xff0c;选择Widget&#xff0c;填写界面类的名称、.h .cpp .ui名称 【4】创建C调用接口&#xff08;默认是创建C调用接口&#xff09; #ifnd…...

Django REST framework 并结合 `mixin` 的示例

下面为你提供一个使用 Django REST framework 并结合 mixin 的示例,该示例将实现一个简单的图书管理 API。 项目需求 我们要创建一个图书管理系统的 API,支持对图书信息的创建、读取、更新和删除操作。 实现步骤 1. 项目初始化 首先,确保你已经安装了 Django 和 Django…...

linux查看及修改用户过期时间

修改用户有效期 密码到期时间 sudo chage -E 2025-12-31 username sudo chage -M 180 username sudo chage -d $(date %F) username 查询用户密码到期时间 for user in $(cat /etc/passwd |cut -d: -f1); do echo $user; chage -l $user | grep "Password expires"; …...

Vue.directive自定义v-指令

翻阅文章有感&#xff0c;记录学习 vue前端菜单权限控制_vue权限管理菜单思路-CSDN博客 一、定义&#xff1a;Vue.directive是Vue框架中给开发者用于注册自定义指令和返回已注册指令的API 二、基本语法&#xff1a; // 注册 Vue.directive(my-directive, {bind: function () …...

AI Agent 元年,于 2025 开启

私人博客传送门 AI Agent 元年&#xff0c;于 2025 开启 | 魔筝炼药师...

Django 自带开发服务器

$ python manage.py runserver $ python manage.py runserver 666 # 用 666 端口 $ python manage.py runserver 0.0.0.0:8000 # 让局域网内其他客户端也可访问 $ python manage.py runserver --skip-checks # 跳过检查自动检查 $ python manage.py runserver --…...

Spring 数据库编程

Spring JDBC 传统的JDBC在操作数据库时&#xff0c;需要先打开数据库连接&#xff0c;执行SQL语句&#xff0c;然后封装结果&#xff0c;最后关闭数据库连接等资源。频繁的数据库操作会产生大量的重复代码&#xff0c;造成代码冗余&#xff0c;Spring的JDBC模块负责数据库资源…...