此文参考自:https://www.toutiao.com/article/7506140643970826779/

引言:RAG 会成为 2025 年 AI 落地核心?

在2025年,检索增强生成(RAG)技术已成为企业级AI应用的标配。传统大模型受限于知识更新慢、业务适配性差,而 RAG 通过动态外接知识库,结合向量数据库与AI推理能力,显著提升回答的准确性与实时性。本文将基于 Solon AI 与 Redis Vector Search,从0到1搭建 RAG 服务,并结合电商客服场景,揭秘如何通过5步实现生产级落地。

一、项目初始化:Solon AI

核心依赖:

<dependency>
<groupId>org.noear</groupId>
<artifactId>solon-ai</artifactId>
</dependency> <dependency>
<groupId>org.noear</groupId>
<artifactId>solon-ai-repo-redis</artifactId>
</dependency> <dependency>
<groupId>org.noear</groupId>
<artifactId>solon-ai-load-pdf</artifactId>
</dependency>

配置参考:

solon.ai.chat:
ds3:
apiUrl: "http://127.0.0.1:11434/api/chat" # 使用完整地址(而不是 api_base)
provider: "ollama" # 使用 ollama 服务时,需要配置 provider
model: "llama3.2" solon.ai.embed:
bgem3:
apiUrl: "http://127.0.0.1:11434/api/embed" # 使用完整地址(而不是 api_base)
provider: "ollama" # 使用 ollama 服务时,需要配置 provider
model: "bge-m3:latest" solon.ai.repo:
redis:
server: localhost:6379

实例构建:

import org.noear.redisx.RedisClient;
import org.noear.solon.ai.chat.ChatModel;
import org.noear.solon.ai.embedding.EmbeddingModel;
import org.noear.solon.ai.rag.RepositoryStorable;
import org.noear.solon.ai.rag.repository.RedisRepository;
import org.noear.solon.ai.rag.repository.redis.MetadataField;
import org.noear.solon.annotation.Bean;
import org.noear.solon.annotation.Configuration;
import org.noear.solon.annotation.Inject; import java.util.ArrayList;
import java.util.List; @Configuration
public class RagConfig {
@Bean
public ChatModel chatModel(@Inject("${solon.ai.chat.ds3}") ChatModel chatModel) {
return chatModel;
} @Bean
public EmbeddingModel embeddingModel(@Inject("${solon.ai.embed.bgem3}") EmbeddingModel embeddingModel) {
return embeddingModel;
} @Bean
public RedisClient client(@Inject("${solon.ai.repo.redis}") RedisClient client) { //构建知识库的连接客户端
return client;
} @Bean
public RepositoryStorable repository(EmbeddingModel embeddingModel, RedisClient client) { //构建知识库
// 创建元数据索引字段列表(用于支持混合搜索)
List<MetadataField> metadataFields = new ArrayList<>();
metadataFields.add(MetadataField.tag("title"));
metadataFields.add(MetadataField.tag("category"));
metadataFields.add(MetadataField.numeric("price"));
metadataFields.add(MetadataField.numeric("stock")); return RedisRepository.builder(embeddingModel, client.jedis())
.metadataIndexFields(metadataFields)
.build();
}
}

技术选型优势:

  • Redis Vector Search(建议 Redis 8+):支持千亿级向量毫秒检索,实时数据更新秒级可见
  • Solon AI:统一接口支持各种主流向量数据库,内置流式输出与异步处理。

二、数据处理:文档分块与向量化

1. 文档加载与分块

@Component
public class RagService {
public void load(){
// 加载PDF/Word文档
List<Document> docs = new PdfLoader("product-manual.pdf").load(); // 智能分块(动态调整块大小)
docs = new TokenSizeTextSplitter(500, 64).split(docs);
}
}

分块策略:

  • 动态分块:根据语义边界(如段落、表格)自动调整块大小,避免信息割裂;
  • 重叠机制:设置64 Token的重叠区,确保上下文连贯性。

2. 向量嵌入与存储

在 RagService 的基础上,进一步补充

import org.noear.solon.ai.embedding.EmbeddingModel;
import org.noear.solon.ai.rag.Document;
import org.noear.solon.ai.rag.RepositoryStorable;
import org.noear.solon.ai.rag.splitter.TokenSizeTextSplitter;
import org.noear.solon.annotation.Component;
import org.noear.solon.annotation.Inject; import java.io.IOException;
import java.util.List; @Component
public class RagService {
@Inject
private RepositoryStorable repository;
@Inject
private EmbeddingModel embeddingModel; public void load() throws IOException {
// 加载PDF/Word文档
List<Document> docs = new PdfLoader("product-manual.pdf").load(); // 智能分块(动态调整块大小)
docs = new TokenSizeTextSplitter(500, 64).split(docs); // 存储(内部自动完成向量嵌入,内部支持分批入库)
repository.insert(docs);
}
}

性能优化:

  • 批量处理:数据批次插入,降低I/O开销;
  • 元数据附加:为每个向量附加来源、时间戳等字段,支持精准过滤。

三、检索增强:混合搜索

使用元信息字段 category 过滤(减少匹配范围),并使用向量检索

@Component
public class RagService {
@Inject
private RepositoryStorable repository;
@Inject
private EmbeddingModel embeddingModel; public void load() throws IOException {
// 加载PDF/Word文档
List<Document> docs = new PdfLoader("product-manual.pdf").load(); // 智能分块(动态调整块大小)
docs = new TokenSizeTextSplitter(500, 64).split(docs); // 存储(内部自动完成向量嵌入)
repository.insert(docs);
} public List<Document> find(String category, String query) throws IOException {
return repository.search(new QueryCondition(query)
.filterExpression("category == '" + category + "'"));
}
}

场景适配:

  • 元数据检索:处理明确实体(如商品目录);
  • 向量检索:应对复杂语义(如“性价比高的手机推荐”)。

四、生成优化:提示工程与流式输出

1. 动态Prompt设计

String promptTemplate = """
你是一名电商客服专家,请根据以下上下文回答问题:
${context}
问题:${question}
要求:回答需包含具体数据,若信息不足则回复“暂未收录”。
示例:库存查询 → “当前iPhone 20库存为500件,预计48小时发货。”
""";

关键技巧:

  • 指令约束:限制回答范围,减少幻觉;
  • 示例引导:提供标准回答格式,提升一致性。

2. 流式响应与溯源

写一个控制器,整合 ChatModel 和 RagService

import org.noear.solon.ai.chat.ChatModel;
import org.noear.solon.ai.chat.message.ChatMessage;
import org.noear.solon.ai.rag.Document;
import org.noear.solon.annotation.Controller;
import org.noear.solon.annotation.Inject;
import org.noear.solon.annotation.Mapping;
import reactor.core.publisher.Flux; import java.io.IOException;
import java.util.List; @Controller
public class RagController {
@Inject
RagService ragService; @Inject
ChatModel chatModel; static String promptTemplate = """
你是一名电商客服专家,请根据以下上下文回答问题:
#{context}
问题:#{question}
要求:回答需包含具体数据,若信息不足则回复“暂未收录”。
示例:库存查询 → “当前iPhone 20库存为500件,预计48小时发货。”
"""; @Mapping("/ask")
public Flux<String> streamAnswer(String question) throws IOException {
List<Document> context = ragService.find("商品", question); ChatMessage message = ChatMessage.ofUserTmpl(promptTemplate)
.paramAdd("question", question)
.paramAdd("context", context)
.generate(); return Flux.from(chatModel.prompt(message).stream())
.filter(resp -> resp.hasChoices())
.map(resp -> resp.getMessage().getContent());
}
}

用户体验优化:

  • 逐字输出:响应延迟降低至100ms以内(要看模型服务的性能);
  • 来源标记:返回答案关联的文档ID与置信度。

五、实战案例:电商客服RAG系统

场景:秒杀活动问答

需求:用户询问“iPhone 20秒杀库存和优惠规则”。

RAG处理流程:

检索:从商品手册中匹配“iPhone 20”的库存条款与促销规则;

生成:返回“当前库存2000件,限购1台,叠加满减券再降500元”。

Solon AI 五步构建 RAG 服务:2025 最新 AI + 向量数据库实战的更多相关文章

  1. Jenkins教程(五)构建Java服务Docker镜像

    本文主旨 主要记录下如何使用Jenkins构建Java服务的Docker镜像,以及手动部署测试下 前期准备 已安装Jenkins 为jenkins用户添加到docker组内 本地装有maven,配置或 ...

  2. 高级运维(五):构建memcached服务、LNMP+memcached、使用Tomcat设置Session、Tomcat实现session共享

    一.构建memcached服务 目标: 本案例要求先快速搭建好一台memcached服务器,并对memcached进行简单的添.删.改.查操作: 1> 安装memcached软件,并启动服务d ...

  3. Springboot & Mybatis 构建restful 服务五

    Springboot & Mybatis 构建restful 服务五 1 前置条件 成功执行完Springboot & Mybatis 构建restful 服务四 2 restful ...

  4. Spring Cloud构建微服务架构(五)服务网关

    通过之前几篇Spring Cloud中几个核心组件的介绍,我们已经可以构建一个简略的(不够完善)微服务架构了.比如下图所示: 我们使用Spring Cloud Netflix中的Eureka实现了服务 ...

  5. 玩转Windows服务系列——使用Boost.Application快速构建Windows服务

    玩转Windows服务系列——创建Windows服务一文中,介绍了如何快速使用VS构建一个Windows服务.Debug.Release版本的注册和卸载,及其原理和服务运行.停止流程浅析分别介绍了Wi ...

  6. 为AI提供数据:构建2017数据创新的总结

    本周在微软年度大会上,我们正在讨论组织如何依靠开发人员创造突破性的经验.随着大数据,云和人工智能的融合,创新与破坏正在加速,从未见过.数据是这一融合核心的关键战略资产.当结合云的无限计算能力和机器学习 ...

  7. Spring Security构建Rest服务-1202-Spring Security OAuth开发APP认证框架之重构3种登录方式

    SpringSecurityOAuth核心源码解析 蓝色表示接口,绿色表示类 1,TokenEndpoint 整个入口点,相当于一个controller,不同的授权模式获取token的地址都是 /oa ...

  8. Spring Security构建Rest服务-0102-Spring Social开发第三方登录之qq登录

    图一 基于SpringSocial实现qq登录,要走一个OAuth流程,拿到服务提供商qq返回的用户信息. 由上篇介绍的可知,用户信息被封装在了Connection里,所以最终要拿到Connectio ...

  9. 一步一步构建手机WebApp开发——页面布局篇

    继上一篇:一步一步构建手机WebApp开发——环境搭建篇过后,我相信很多朋友都想看看实战案例,这一次的教程是页面布局篇,先上图: 如上图所示,此篇教程便是教初学者如何快速布局这样的页面.废话少说,直接 ...

  10. 【高并发】高并发环境下构建缓存服务需要注意哪些问题?我和阿里P9聊了很久!

    写在前面 周末,跟阿里的一个朋友(去年晋升为P9了)聊了很久,聊的内容几乎全是技术,当然了,两个技术男聊得最多的话题当然就是技术了.从基础到架构,从算法到AI,无所不谈.中间又穿插着不少天马行空的想象 ...

随机推荐

  1. StarRocks 升级注意事项

    前段时间升级了生产环境的 StarRocks,从 3.3.3 升级到了 3.3.9,期间还是踩了不少坑所以在这里记录下. 因为我们的集群使用的是存算分离的版本,也是使用官方提供的 operator 部 ...

  2. Cython二进制逆向系列(三)运算符

    Cython二进制逆向系列(三)运算符 在开始前,先给出本文用到的py源代码 def test1(x, y): # 数学运算符 a = x + y b = x - y c = x * y d = x ...

  3. Joker 智能开发平台再推重磅新品,引领开发新潮流

    自 Joker 智能开发平台的前端可视化版本惊艳亮相后,便迅速在行业内掀起热潮,其创新的理念与出色的性能,为开发者和企业打造了高效.便捷的开发新路径,备受瞩目与好评.如今,Joker 智能开发平台即将 ...

  4. 查看docker容器占用内存

    ps -ef|grep 容器Id 1 2 3 [root@wentao-2 order]# ps -ef|grep 3a61cb3fd4f6 root      7358 12956  0 09:14 ...

  5. c-primer-plus深入解读系列-从二进制到误差:逐行拆解C语言浮点运算中的4008175468544之谜

    前言 小提示:阅读本篇内容,至少需要了解double和float的二进制表示规则. 书中的代码示例如下: #include <stdio.h> int main(void) { float ...

  6. 【JDBC】总结

    JDBC核心技术 第1章:JDBC概述 1.1 数据的持久化 持久化(persistence):把数据保存到可掉电式存储设备中以供之后使用.大多数情况下,特别是企业级应用,数据持久化意味着将内存中的数 ...

  7. 【数据结构与算法】Java链表与递归:移除链表元素

    Java链表与递归:移除链表元素 Java https://leetcode-cn.com/problems/remove-linked-list-elements/solution/javalian ...

  8. C中输入输出

    引入一个概念,对于计算机来说,外来数据都是输入,经过计算机处理的结果并进行显示的就是输出.在linux里面,一切都是文件,就连输入输出,都可以划归到"文件"一类,而为了管理这些文件 ...

  9. PHP传递参数(跨文件)的8种常见方法

    以下是 PHP 中跨文件传递参数的 8 种常见方法,按场景和安全性分类整理,附详细说明和示例代码: 一.超全局变量(适合请求间数据共享) 1. $_GET / $_POST 用途:通过 URL 或表单 ...

  10. Python科学计算系列7—微分方程

    1.可分离变量方程 例1:求下列微分方程法通解 先化简此方程如下: 代码如下: from sympy import * x = symbols('x') f = symbols('f', cls=Fu ...