Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Flutter 网络请求之Dio库

Flutter 网络请求之Dio库

作者头像
晨曦_LLW
发布于 2024-05-25 00:39:10
发布于 2024-05-25 00:39:10
59900
代码可运行
举报
运行总次数:0
代码可运行
Flutter 网络请求之Dio库

  • 前言
  • 正文
    • 一、配置项目
    • 二、网络请求
    • 三、封装
      • ① 单例模式
      • ② 网络拦截器
      • ③ 返回值封装
      • ④ 封装请求
    • 四、结合GetX使用
    • 五、源码

前言

  最近再写Flutter系列文章,在了解过状态管理之后,我们再来学习一下网络请求。

正文

  网络请求对于一个线上的App来说是必不可少的,那么Flutter中的网络请求同样也是官方的没有第三方的那么好用,这里我们使用Dio,目前来说比较好用简洁的网络库。

一、配置项目

  首先我们创建一个名为study_http的项目。

在这里插入图片描述
在这里插入图片描述

创建项目之后,我们配置一下依赖库,在项目的pubspec.yaml文件中,添加如下所示代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
dependencies:
  
  get:
  
  dio: ^5.4.0

添加位置如下图所示:

在这里插入图片描述
在这里插入图片描述

然后点击Pub get,获取并安装所添加的库,安装成功之后,项目配置完成。

二、网络请求

  下面我们来设计一个场景,页面上有一个图片和一个按钮,默认显示一个图片,点击按钮之后请求网络接口,返回一个图片,将这个请求返回的网络图片显示出来,首先我们在lib下新建一个https的目录,然后这个目录下新建一个https_page.dart文件 ,里面代码如下所示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:dio/dio.dart';
import 'package:get/get.dart';

class HttpsPage extends StatelessWidget {
  var imgPath =
      "https://img-s-msn-com.akamaized.net/tenant/amp/entityid/BB1h31Ip.img?w=768&h=1226&m=6&x=326&y=887&s=506&d=118"
          .obs;

  final dio = Dio();

  void request() async {
    var response = await dio.get('https://www.dmoe.cc/random.php?return=json');
    //转化为Json
    String jsonString = jsonEncode(response.data);
    print(jsonString);
    // 解析JSON字符串
    Map<String, dynamic> json = jsonDecode(jsonString);
    // 获取特定字段值
    imgPath.value = json['imgurl'];
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: Center(
      child: Container(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Obx(() => Image.network(
                  imgPath.value,
                  width: 200,
                )),
            SizedBox(height: 10),
            ElevatedButton(
              onPressed: () {
                request();
              },
              child: Text("请求网络"),
            )
          ],
        ),
      ),
    ));
  }
}

  说明一下这个代码,这里使用了Get库,不了解的可以看看我上一篇文章:Flutter 状态管理之GetX库,创建了一个可观察的变量,然后写了一个请求网络的方法,使用了Dio库的Get请求,请求一个API地址,你可以将这个地址在浏览器中测试,确保它可以返回值。这是我请求的结果,如下图所示:

在这里插入图片描述
在这里插入图片描述

  通过网络请求会返回一个response 对象,我们将对象转换为Json字符串,然后再获取字符串中的imgurl的值,也就是这个图片的网络地址链接,最后再更新这个imgPath的值,Obx()包裹的内容就会刷新,下面我们运行一下看看效果:

在这里插入图片描述
在这里插入图片描述

这是默认的图片,然后点击一下请求网络的按钮,经过短暂的网络延迟之后就会加载出网络请求返回后的图片,如下图所示:

这个请求返回的图片类似于每日一图,所以变化很大,因此你只要有加载出来就可以,不需要跟我一样。

三、封装

  在对Dio库进行进行使用的时候,我们通常会进行封装而不是直接使用。Flutter原生的网络请求是使用HttpClient,使用起来相当繁琐,因此Dio对于HttpClient进行了封装,那么我们为什么还需要对Dio进行封装呢?这就是考虑到实际中的业务处理了,封装都是针对于实际情况来的,下面我们看看怎么封装这个Dio库。

① 单例模式

  在使用网络请求时,通常会有多个网络请求,我们可以写一个单例,将一些基本的内容写在单例里面,写几个方法供其他地方调用,下面我们首先来写一个单例在lib下新建一个net包,包下新建一个network_manager.dart文件,代码如下所示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import 'package:dio/dio.dart';

/// 网络管理
class NetworkManager {
  static NetworkManager? _instance = NetworkManager._internal();

  late Dio dio;

  static NetworkManager getInstance() {
    _instance ??= NetworkManager._internal();
    return _instance!;
  }

  NetworkManager._internal() {
    // 配置BaseOptions
    BaseOptions options = BaseOptions(
        baseUrl: "",
        //连接超时
        connectTimeout: const Duration(seconds: 15),
        //接收超时
        receiveTimeout: const Duration(seconds: 10),
        //内容类型
        contentType: 'application/json;Charset=UTF-8',
        //响应数据类型:Json
        responseType: ResponseType.json);
    dio = Dio(options);
  }

  get(String url, {option, params}) async {
    Response response;
    try {
      response =
          await dio.get(url, options: Options(responseType: ResponseType.json));
      print("response.data:${response.data}");
      print("response.data:${response.statusCode}");
      print("response.data:${response.statusMessage}");
      print("response.data:${response.headers}");
    } on Exception catch (e) {
      print("Get方法出错:${e.toString()}");
    }
  }
  
}

  下面说明一下上面代码,首先我们写了一个getInstance()方法,在这里面判断_instance 是否为空,为空则NetworkManager._internal(),对dio进行一些基本的配置,然后初始化dio 对象,不为空则,直接返回_instance 。然后写了一个get()方法,方法里面就是一个get请求,我们在之前已经页面中已经写好了,同时我们打印一下返回的数据,下面我们在前面的页面中改造一下。修改https_page.dart中的request()方法,代码如下所示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
  void request() async {
    NetworkManager.getInstance().get('https://www.dmoe.cc/random.php?return=json');
  }

这里就是直接使用单例中的方法,我们就不需要再当前页面创建dio对象了,运行一下,看控制台日志,如下图所示:

在这里插入图片描述
在这里插入图片描述

现在我们的方法在单例中有效果,我们继续往下走。

② 网络拦截器

  现在的这个日志确实不怎么好看,为了解决这个问题,也为了我们看日志的时候一目了然,我们可以自定义一个拦截器,在net包下新建一个interceptor包,该包下新建一个custom_interceptor.dart文件,里面的代码如下所示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import 'dart:convert';

import 'package:dio/dio.dart';
import 'package:flutter/foundation.dart';

///日志拦截器
class CustomInterceptor extends Interceptor {
  @override
  void onRequest(RequestOptions options, RequestInterceptorHandler handler) {
    StringBuffer buffer = StringBuffer();
    buffer.write('⌈‾‾ Request ヾ(•ω•`)o \n');
    buffer.write('| \n');
    buffer.write('| - Url:   ${options.baseUrl + options.path}\n');
    buffer.write('| - Method:${options.method}\n');
    buffer.write('| - Header:${options.headers.toString()}\n');
    final data = options.data;
    if (data != null) {
      if (data is Map) {
        buffer.write('| - Body:  ${options.data.toString()}\n');
      } else if (data is FormData) {
        final formDataMap = {}
          ..addEntries(data.fields)
          ..addEntries(data.files);
        buffer.write("| - Body:  ${formDataMap.toString()}\n");
      } else {
        buffer.write("| - Body:  ${data.toString()}\n");
      }
    }
    buffer.write(
        '⌊_____________________________________________________________________');
    printDebugLog(buffer);
    return handler.next(options);
  }

  @override
  void onResponse(Response response, ResponseInterceptorHandler handler) {
    StringBuffer buffer = StringBuffer();
    buffer.write('⌈‾‾ Response O(∩_∩)O \n');
    buffer.write('| \n');
    buffer.write('| - Code:   ${response.statusCode}\n');
    buffer.write('| - CodeMsg:${response.statusMessage}\n');
    buffer.write('| - Header:\n');
    response.headers.forEach((key, value) {
      buffer.write('|    $key  $value\n');
    });
    final data = response.data;
    if (data != null) {
      if (data is Map) {
        buffer.write('| - Data:  ${response.data.toString()}\n');
        String dataJson = jsonEncode(response.data);
        buffer.write('| - Json:  $dataJson\n');
      } else if (data is FormData) {
        final formDataMap = {}
          ..addEntries(data.fields)
          ..addEntries(data.files);
        buffer.write("| - Data:  ${formDataMap.toString()}\n");
      } else {
        buffer.write("| - Data:  ${data.toString()}\n");
      }
    }
    buffer.write(
        '⌊_____________________________________________________________________');
    printDebugLog(buffer);
    return handler.next(response);
  }

  @override
  void onError(DioException err, ErrorInterceptorHandler handler) {
    //处理错误信息
    handlerError(err);
    StringBuffer buffer = StringBuffer();
    buffer.write('⌈‾‾ Error (っ °Д °;)っ\n');
    buffer.write('| \n');
    buffer.write('| - ExceptionType:${err.type.name}\n');
    buffer.write('| - ErrorMsg:     ${err.message}\n');
    buffer.write('| - StatusCode:   ${err.response?.statusCode}\n');
    buffer.write('| - StatusMsg:    ${err.response?.statusMessage}\n');
    buffer.write(
        '⌊_____________________________________________________________________');
    printDebugLog(buffer);
    return handler.next(err);
  }

  ///处理错误信息 --自行去实现里面的功能代码
  void handlerError(DioException err) {
    switch (err.type) {
      //连接超时
      case DioExceptionType.connectionTimeout:
        break;
      //响应超时
      case DioExceptionType.receiveTimeout:
        break;
      //发送超时
      case DioExceptionType.sendTimeout:
        break;
      //请求取消
      case DioExceptionType.cancel:
        break;
      //错误响应 404 等
      case DioExceptionType.badResponse:
        break;
      //错误证书
      case DioExceptionType.badCertificate:
        break;
      //未知错误
      default:
        break;
    }
  }

  void printDebugLog(StringBuffer buffer) {
    if (kDebugMode) {
      print(buffer.toString());
    }
  }
}

  在这里面我们继承了创建CustomInterceptor 类,继承DioInterceptor ,重写里面onRequest(请求前)onResponse(响应前)onError(错误时)的拦截方法,在里面对于相关数据信息进行打印,同时只在debug模式下打印,下面我们回到NetworkManager中,使用这个自定义拦截器。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import 'interceptor/custom_interceptor.dart';

首先导包,然后在_internal()方法中增加如下代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    //添加日志拦截器
    dio.interceptors.add(CustomInterceptor());

添加位置如下图所示:

在这里插入图片描述
在这里插入图片描述

再将get方法中的打印注释掉

在这里插入图片描述
在这里插入图片描述

然后我们重新运行一下,请求网络接口,查看控制台日志,如下图所示:

在这里插入图片描述
在这里插入图片描述

这样看起来是否会清晰一些呢,可以自行调整,我们接着往下走。

③ 返回值封装

  对返回值的封装,我们可以分为两步,第一步就是在响应前封装,第二步在响应后转换。先来看第一步,在net包下新建一个response包,该包下新建一个base_response.dart,代码如下所示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
///自定义响应封装
class BaseResponse<T> {
  //状态码
  final int? code;
  //状态描述
  final String? msg;
  //数据
  final T data;

  BaseResponse({required this.code,required this.msg,required this.data});

  @override
  String toString() {
    StringBuffer buffer = StringBuffer();
    buffer.write('{');
    buffer.write('"code":$code');
    buffer.write('"msg":"$msg"');
    buffer.write('"data":"$data"');
    buffer.write('}');
    return super.toString();
  }
}

  这里就是对默认的Response进行一次封装,然后这里的data就是我们接口所拿到的返回值, 下面我们改动一下之前的自定义拦截器custom_interceptor.dart中的代码,主要就是修改onResponse()方法,代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
  @override
  void onResponse(Response response, ResponseInterceptorHandler handler) {
    //返回自定义的Base
    final baseResponse = BaseResponse(code: response.statusCode, msg: response.statusMessage, data: response.data);
    response.data = baseResponse;

    StringBuffer buffer = StringBuffer();
    buffer.write('⌈‾‾ Response O(∩_∩)O \n');
    buffer.write('| \n');
    buffer.write('| - Code:   ${response.statusCode}\n');
    buffer.write('| - CodeMsg:${response.statusMessage}\n');
    buffer.write('| - Header:\n');
    response.headers.forEach((key, value) {
      buffer.write('|    $key  $value\n');
    });
    final data = response.data;
    if (data != null) {
      if (data is Map) {
        buffer.write('| - Data:  ${response.data.toString()}\n');
        String dataJson = jsonEncode(response.data);
        buffer.write('| - Json:  $dataJson\n');
      } else if (data is FormData) {
        final formDataMap = {}
          ..addEntries(data.fields)
          ..addEntries(data.files);
        buffer.write("| - Data:  ${formDataMap.toString()}\n");
      } else {
        buffer.write("| - Data:  ${baseResponse.data.toString()}\n");
      }
    }
    buffer.write(
        '⌊_____________________________________________________________________');
    printDebugLog(buffer);
    return handler.next(response);
  }

核心代码就是这一段

在这里插入图片描述
在这里插入图片描述

  将response.data封装到BaseResponse中,然后再赋值返回。然后我们再对返回值进行一个JSON转Bean的操作,AS中提供了一个插件,FlutterJsonBeanFactory,安装。

在这里插入图片描述
在这里插入图片描述

  安装好之后,我们可以重启一下AS,然后就来根据JSON返回值构建Dart的Bean。在lib包下新建一个model包,然后鼠标右键model包,点击New → JsonToDartBeanAction,如下图所示:

在这里插入图片描述
在这里插入图片描述

输入文件名称,然后将接口返回的JOSN:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
{
    "code": "200",
    "imgurl": "https://image.baidu.com/search/down?url=https://tvax3.sinaimg.cn//large/a15b4afegy1fmvk16yis3j21hc0u0tpx.jpg",
    "width": "1920",
    "height": "1080"
}

赋值进去,如下图所示:

在这里插入图片描述
在这里插入图片描述

点击Make,完成构建。

在这里插入图片描述
在这里插入图片描述

  构建之后会在model包下生成一个img_entity.dart,我刚才输入的是img,_entity是这个插件自己添加的,然后会生成一个generated文件夹,里面可以看到一个img_entity.g.dart文件,里面的内容就是对你JSON和Bean之间的转化代码的生成,我们不需要关心。先不急着使用这个返回值,我们继续往下走。

④ 封装请求

  接着我们封装请求方法,针对网络请求有get、post、put等等方式,在dio库中,最终实际上调用的都是request请求,在net包下新建一个method包,该包下新建一个bese_method.dart,代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
enum BaseMethod {
  get,
  post,
  put,
  delete,
  patch,
  head
}

  这里代码很简单,就是列举了dio的网络请求方式,然后我们回到network_manager.dart中,在里面新增一个request()方法,其他的代码也做了修改,整体代码如下所示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
  class NetworkManager {

  factory NetworkManager() => _getInstance();
  static NetworkManager? _instance = NetworkManager._initialize();

  late Dio _dio;

  static NetworkManager _getInstance() {
    _instance ??= NetworkManager._initialize();
    return _instance!;
  }

  NetworkManager._initialize() {
    // 配置BaseOptions
    BaseOptions options = BaseOptions(
        baseUrl: "",
        //连接超时
        connectTimeout: const Duration(seconds: 15),
        //接收超时
        receiveTimeout: const Duration(seconds: 10),
        //内容类型
        contentType: 'application/json;Charset=UTF-8',
        //响应数据类型:Json
        responseType: ResponseType.json);
    _dio = Dio(options);
    //添加日志拦截器
    _dio.interceptors.add(CustomInterceptor());
  }

  ///网络请求
  Future<T> request<T>(String path,
      {BaseMethod method = BaseMethod.get, Map<String, dynamic>? params,
      data, Options? options}) async {
    const methodValues = {
      BaseMethod.get: 'get',
      BaseMethod.post: 'post',
      BaseMethod.put: 'put',
      BaseMethod.delete: 'delete',
      BaseMethod.patch: 'patch',
      BaseMethod.head: 'head',
    };

    options ??= Options(method: methodValues[method]);
    try {
      Response response;
      response = await _dio.request(path,
          data: data, queryParameters: params, options: options);
      return response.data;
    } on DioException catch (e) {
      throw e;
    }
  }
}

下面我们再回到https_page.darat中去使用,修改request()方法,代码如下所示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
  void request() async {
    BaseResponse response = await NetworkManager().request('https://www.dmoe.cc/random.php?return=json');
    ImgEntity imgEntity = ImgEntity.fromJson(response.data);
    imgPath.value = imgEntity.imgurl;
  }

如果有报错注意一下导包

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import '../model/img_entity.dart';

运行一下,效果和之前是一样的,然后我们再来改动一下,针对于这个API地址:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
https://www.dmoe.cc/random.php?return=json

我们可以分为两部分。

基础地址

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
https://www.dmoe.cc/

功能地址

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
random.php?return=json

  一般的项目中,基础地址不会经常变,也就是ip地址,而不同的功能会根据实际情况去改变接口,因此这一部分我们需要和实际方法进行绑定,下面我们在NetworkManager中增加一行代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
final _mBaseUrl = "https://www.dmoe.cc/";

然后修改baseUrl的值,之前是空字符串,如下图所示:

在这里插入图片描述
在这里插入图片描述

再去修改实际调用的地方,如下图所示:

在这里插入图片描述
在这里插入图片描述

  这样就对一个API地址进行了分离,这在实际开发中是很常见的做法。对于dio的封装就到这里了,肯定不是完善了,因为还有很多东西没有考虑到,我们可以根据实际中的需要再去添加,我这里就不赘述了,下面我们结合GetX去使用。

四、结合GetX使用

在https包下新建一个https_controller.dart,代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import 'package:get/get.dart';

import '../model/img_entity.dart';
import '../net/network_manager.dart';
import '../net/response/base_response.dart';

class HttpsController extends GetxController {

  var imgPath =
      "https://img-s-msn-com.akamaized.net/tenant/amp/entityid/BB1h31Ip.img?w=768&h=1226&m=6&x=326&y=887&s=506&d=118"
          .obs;

  void request() async {
    BaseResponse response = await NetworkManager().request('random.php?return=json');
    ImgEntity imgEntity = ImgEntity.fromJson(response.data);
    imgPath.value = imgEntity.imgurl;
  }

}

这里就是将网络请求相关的变量和方法都放到HttpsController 中,然后我们再回到HttpsPage,修改代码如下所示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'https_controller.dart';

class HttpsPage extends StatelessWidget {
  final httpsController = Get.put(HttpsController());

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: Center(
      child: Container(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Obx(() => Image.network(
                  httpsController.imgPath.value,
                  width: 200,
                )),
            SizedBox(height: 10),
            ElevatedButton(
              onPressed: () => httpsController.request(),
              child: Text("请求网络"),
            )
          ],
        ),
      ),
    ));
  }
}

主要改动地方如下图所示:

在这里插入图片描述
在这里插入图片描述

这样基本上就符合现在的开发理念了,数据和UI进行分离,再次运行,效果依然一样,好了,本篇文章就到这里。

五、源码

源码地址:study_http

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-05-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
大模型微调与RAG检索增强有何区别?从基础原理到案例分析全面详解
如果你一直在跟着Fanstuck博主的脚步探索AI大模型的相关内容,从最初的大模型Prompt工程解析,DeepSeek全面解析,到实际的私有化大模型开发部署,再到深入NL2SQL、知识图谱大模型和ChatBI等更高阶应用.我是Fanstuck,致力于将复杂的技术知识以易懂的方式传递给读者,热衷于分享最新的行业动向和技术趋势。如果你对大模型的创新应用、AI技术发展以及实际落地实践感兴趣,那么请关注Fanstuck。
fanstuck
2025/03/04
7756
大模型微调与RAG检索增强有何区别?从基础原理到案例分析全面详解
【RAG】001.1-RAG相关核心概念
RAG(Retrieval-Augmented Generation,检索增强生成)是一种结合信息检索与生成模型的混合架构,旨在提升生成的准确性和可信度。其核心概念可归纳为以下六个方面:
訾博ZiBo
2025/03/26
2470
2024!深入了解 大语言模型(LLM)微调方法(总结)
众所周知,大语言模型(LLM)正在飞速发展,各行业都有了自己的大模型。其中,大模型微调技术在此过程中起到了非常关键的作用,它提升了模型的生成效率和适应性,使其能够在多样化的应用场景中发挥更大的价值。
ShuYini
2024/02/23
7.8K0
2024!深入了解 大语言模型(LLM)微调方法(总结)
Fine-Tuning Vs RAG ,该如何选择?
随着技术的不断进步,LLM 带来了前所未有的机遇,吸引了开发者和组织纷纷尝试利用其强大的能力构建应用程序。然而,当预训练的 LLM 在实际应用中无法达到预期的性能水平时,人们将不由自主地开始思考:我们到底应该使用哪种技术来改善这些模型在特定场景下的表现?
Luga Lee
2024/11/01
1490
Fine-Tuning Vs RAG ,该如何选择?
2024年大语言模型的微调
一个LLM的生命周期包含多个步骤,下面将讨论这个周期中最活跃、最密集的部分之一 -- fine-tuning(微调)过程。
charlieroro
2024/03/08
4410
2024年大语言模型的微调
OpenAI放开ChatGPT微调接口!国内厂商压力山大!|附详细微调操作指南
“ OpenAI 于近日放开 ChatGPT 微调接口,这对于开发者来说无疑是一个利好消息。微调可以帮助开发者根据自己的特定需求对 ChatGPT 进行个性化定制,从而提升模型的性能。
技术人生黄勇
2024/07/19
4630
OpenAI放开ChatGPT微调接口!国内厂商压力山大!|附详细微调操作指南
RAG VS Fine-Tuning模型微调详解
这里先给大家推荐一篇实用的好文章:《一文彻底弄懂 Spring Boot 自动装配的过程!深入探索与案例解析》 来自作者:bug菌
小马哥学JAVA
2024/11/22
1580
【RAG】001-RAG概述
检索增强生成(Retrieval-Augmented Generation,RAG)技术能够有效解决上述问题:
訾博ZiBo
2025/03/25
1690
【RAG】001-RAG概述
微调LLMs:概述、方法和最佳实践(附天工Skywork-13B微调)
从总体上看,大模型的训练可以分为四个关键阶段:预训练、有监督微调、奖励建模和强化学习。
AI进修生
2024/12/02
3620
微调LLMs:概述、方法和最佳实践(附天工Skywork-13B微调)
AI大模型进阶系列(01)看懂AI大模型的主流技术 | AI对普通人的本质影响是什么?
2010年至今,我们见证了移动互联网时代、大数据时代、短视频时代,以及炙手可热的通用AI时代。科技技术迭代之快,让15年时间短得仿若一梦。而强大的AI智能,到底会给我们的现实世界产生哪些影响,尤其是全社会对超级AI能力的无限期许,让AI技术的每一个进展都会成为时下社会关注和讨论的热点。
拉丁解牛说技术
2025/04/03
5420
RAG 技术综述
检索增强生成(Retrieval Augmented Generation,简称 RAG)向 LLM 提供了从特定数据源检索的信息,以此作为生成答案的基础。简而言之,RAG 结合了搜索和 LLM 的提示功能,在此基础上,模型根据搜索算法提供的信息,作为上下文来回答问题。这些查询和检索到的上下文会一并被注入到发送给 LLM 的提示中。
科技之歌
2024/02/01
1.6K0
RAG 技术综述
带你全面了解 RAG,深入探讨其核心范式、关键技术及未来趋势!
大型语言模型(LLMs)已经成为我们生活和工作的一部分,它们以惊人的多功能性和智能化改变了我们与信息的互动方式。
ShuYini
2024/01/11
4.8K0
带你全面了解 RAG,深入探讨其核心范式、关键技术及未来趋势!
大模型+RAG,全面介绍!
大型语言模型(LLMs)在处理特定领域或高度专业化的查询时存在局限性,如生成不正确信息或“幻觉”。缓解这些限制的一种有前途的方法是检索增强生成(RAG),RAG就像是一个外挂,将外部数据检索集成到生成过程中,增强模型提供准确和相关响应的能力。
算法进阶
2024/05/31
8390
大模型+RAG,全面介绍!
从理论到实践:使用JAVA实现RAG、Agent、微调等六种常见大模型定制策略
大语言模型(LLM)在过去几年中彻底改变了自然语言处理领域,展现了在理解和生成类人文本方面的卓越能力。然而,通用LLM的开箱即用性能并不总能满足特定的业务需求或领域要求。为了将LLM更好地应用于实际场景,开发出了多种LLM定制策略。本文将深入探讨RAG(Retrieval Augmented Generation)、Agent、微调(Fine-Tuning)等六种常见的大模型定制策略,并使用JAVA进行demo处理,以期为AI资深架构师提供实践指导。
小马哥学JAVA
2025/03/18
5330
一文读懂大型语言模型微调技术挑战与优化策略
LLMs (Large Language Models )正在引领人工智能技术的新浪潮。这种先进的 AI 通过利用统计模型分析海量数据,学习单词和词组之间的复杂模式,从而模拟人类认知和语言能力。LLMs 的强大功能已引起了众多头部企业以及科技爱好者的浓厚兴趣,他们纷纷竞相采用这些由人工智能驱动的创新解决方案,旨在提高运营效率、减轻工作负担、降低成本支出,并最终激发出更多创造业务价值的创新想法。
Luga Lee
2024/11/01
1650
一文读懂大型语言模型微调技术挑战与优化策略
Prompt、RAG、微调还是重新训练?选择正确的生成式 AI 的方法指南
这篇博客试图根据一些常见的可量化指标,为您选择适合您用例的生成式人工智能方法提供指导。
叶庭云
2023/08/18
3.8K0
Prompt、RAG、微调还是重新训练?选择正确的生成式 AI 的方法指南
对于大模型,到底微调还是不微调?
调整开源大语言模型(LLM)的系列博客的第二篇文章。本文讨论:“什么时候应该进行微调,什么时候应该考虑其他技术?”
JavaEdge
2024/09/16
4270
对于大模型,到底微调还是不微调?
大模型训练全解析:预训练、微调、强化学习,一步到位!
2025年初,随着DeepSeek的迅速走红,公众对LLM(大语言模型)的兴趣急剧上升。许多人被LLM展现出的近乎魔法的能力所吸引。然而,这些看似神奇的模型背后究竟隐藏着什么秘密?接下来,我们将深入探讨LLM的构建、训练和微调过程,揭示它们如何从基础模型演变为我们今天所使用的强大AI系统。
福大大架构师每日一题
2025/03/18
5160
大模型训练全解析:预训练、微调、强化学习,一步到位!
身处AI浪潮中,你get到了什么
最近几年,大模型和AI毫无疑问是最热的话题和方向。最初的OpenAI作为大语言模型技术的重要推动者,引领了本次技术变革。后期ChatGPT的发布引爆全球,影响力度大到国家战略层面,小到改变了个体的工作模式。而在近两年,为了追赶业界最先进的大模型,国内在大模型行业也在不断突破,这才有了我们比较熟知的腾讯元宝、文心一言、通义千问、豆包等等。当然,最火爆的还得是今年的
六月的雨在Tencent
2025/03/22
4010
通过结合RAG和微调来改进LLM输出
在设计一个特定于领域的企业级会话式问答系统来回答客户问题时,Conviva 发现要么/要么的方法是不够的。
云云众生s
2024/05/02
4320
通过结合RAG和微调来改进LLM输出
推荐阅读
相关推荐
大模型微调与RAG检索增强有何区别?从基础原理到案例分析全面详解
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验