概述:本文使用阿里百炼平台,创建私有知识库,发布配置了知识库的RAG智能体应用,实现用户在小程序、网页端、wx公众号的智能问答。
一、基础知识
1. RAG是什么?
检索增强生成(Retrieval-Augmented Generation,RAG)是自然语言处理(NLP)领域的一种前沿技术,核心思想是通过结合检索(Retrieval)与生成(Generation),让模型在生成答案时动态参考外部知识库,从而提升生成内容的准确性、相关性和可解释性。
简单来说,RAG就像一个超级聪明的助手。它不仅靠自己的“知识储备”回答问题,还能从外部信息库中找到最相关的资料来辅助回答。想象一下,你问AI:“最近的大模型技术有哪些突破?”如果AI只凭过去的记忆回答,可能不够全面。但有了RAG,它会先去翻阅最新的文章和报告,找到相关内容,再结合这些信息给出答案。
2. RAG工作流程
RAG的具体工作流程可以拆成三个步骤:
- 存储信息:把大量的文档(比如文章、报告)转化成一种特殊的数学形式——向量,存起来备用。
- 匹配问题:当你提出问题时,AI会把问题也变成向量,然后在信息库中找到与之最匹配的内容。
- 生成答案:最后,AI把这些匹配的内容和你的问题一起交给大语言模型(LLM),生成一个更准确、更贴切的回答。
3. 什么是分块?
分块就像是给AI准备食材。如果切得不好,AI可能会抓不到重点,甚至理解错上下文。比如,一段关于技术的完整描述被硬生生切成两半,AI可能只看到一半,回答就跑偏了。相反,合理的分块能让AI快速找到最相关的“食材”,烹饪出一道美味的回答。
RAG的五种分块策略
- 固定大小分块:简单直接,但有风险
这是最基础的方法:按照固定的字数、词数或标记数(token)把文档切成小块。比如,每500字一块。为了避免句子被拦腰截断,通常会在相邻两块之间留点重叠(比如重叠100字)。
优点:操作简单,像切面包一样直截了当。每块大小一致,AI处理起来很方便。
缺点:可能会把一句话或一个完整的想法切成两半。关键信息分散在不同块中,AI检索时容易漏掉重点。
适合场景:文档内容比较零散、不太讲究上下文时可以用,但对复杂文档来说效果一般。 - 语义分块:按意思切,聪明又贴心
这种方法不再机械地按字数分,而是根据内容的“意思”来切。具体做法是:先把文档分成句子或段落等有意义的单元。为每个单元生成一个向量表示(嵌入)。比较相邻单元的相似度:如果很相似,就合并成一块;如果差异大了,就另起一块。
优点:保留了内容的自然流畅性和完整思路。每块内容更丰富,AI检索时能抓住更相关的部分,回答更靠谱。
缺点:需要设定一个相似度的标准(阈值),而这个标准可能因文档不同而变化,得试着调。
适合场景:当文档有清晰的主题或段落划分时,这种方法能让AI更好地理解内容。 - 递归分块:层层分解,灵活实用
递归分块有点像剥洋葱:先按文档的自然分隔(比如段落或章节)分成大块。如果某块太大(超过预设大小),就再细分,直到每块都合适为止。
优点:既保留了文档的自然结构,又能控制块的大小。适应性强,适合各种文档。
缺点:比固定大小分块复杂一点,计算量稍微多一些。
适合场景:文档有层次结构,又需要控制大小的时候,这种方法很实用。 - 基于文档结构的分块:跟着“骨架”走
这种方法直接利用文档的天然结构,比如按标题、章节或段落来分块。每块对应一个逻辑单元,比如一个章节或一个小标题下的内容。
优点:尊重文档的逻辑布局,AI理解起来更顺手。分块边界清晰,管理方便。
缺点:前提是文档得有明确的结构,如果乱七八糟就不好使。分块大小可能不均匀,有的块太大,AI处理不了。
适合场景:学术论文、技术文档等结构化强的文件用这个很合适。 - 基于LLM的分块:交给AI自己搞定
既然大语言模型(LLM)这么聪明,为什么不让它来分块呢?具体是给LLM一个任务,让它根据内容生成独立、有意义的小块。
优点:分得最聪明,语义准确性最高,因为LLM能理解深层含义。每块内容质量极佳,AI用起来得心应手。
缺点:计算量大,成本高,不是随便就能用。LLM的处理范围有限,太长的文档可能会卡住。
适合场景:预算充足、对质量要求极高时,可以试试这个“高端玩法”。
RAG技术为AI的回答能力打开了新世界的大门,而分块策略则是这扇门上的钥匙。选择合适的“钥匙”,AI就能更聪明、更准确地为你服务。
二、发布挂载知识库的智能体应用
1. 注册
阿里百炼平台注册后,模型广场-选择模型-查看详情,查看模型免费额度(100wToken)。
2.数据管理
支持结构化数据和非结构化数据
1.数据库导出一份机构化数据(excel),导出字段名称改为中文,例如:areaCode 行政区划代码。
2.数据管理-结构化数据-新建数据表-导入数据;
3.支持非结构数据(pdf,.doc,.docx,.txt,.md,.pptx,.ppt,.png,.jpg,.jpeg,.bmp,.gif,.xls,.xlsx 等格式),结构化数据支持RDS中的表,文章的最后进行补充说明;
3.数据应用
3.1 数据应用-创建知识库
3.2 对知识库进行命中测试
4.新增应用
我的应用-新增应用-创建TAG应用或直接创建-配置-提问测试-发布
应用ID:HTTP或SDK调用api参数
提问“成都周边有哪些优质产品?”,看是否是回答挂载excel知识库中内容。
三、api调用RAG智能体应用,实现智能回答
- 创建API KEY
- API调用
2.1 HTTP调用
http调用1.png
http调用2.png
PC演示效果图
小程序演示效果图
注意:http调用返回的格式是Markdown,需要引入插件转换格式。
2.2 Spring Boot 集成 DashScope SDK
查看文档
pom
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dashscope-sdk-java</artifactId>
<!-- 最新版本号:https://mvnrepository.com/artifact/com.alibaba/dashscope-sdk-java -->
<version>2.18.5</version>
<!--框架冲突-->
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- gson dashscope-sdk-java 中gson2.8.7版本有问题 -->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.10.1</version>
</dependency>
controller
@ApiOperation("百炼Stream")
@GetMapping("/streamText")
public void getStreamText(String prompt, String sessionId, HttpServletResponse response) {
// 设置字符编码为 UTF-8
response.setCharacterEncoding("UTF-8");
// 设置 Content-Type 并指定字符集
response.setContentType("text/html;charset=UTF-8");
Flowable<ApplicationResult> result = null;
try {
ApplicationParam param = ApplicationParam.builder()
.apiKey(apiKey)
.appId(appId)
.prompt(prompt)
.hasThoughts(true)
.sessionId(sessionId)
// 增量输出
.incrementalOutput(true)
.build();
Application application = new Application();
result = application.streamCall(param);
} catch (ApiException | NoApiKeyException | InputRequiredException e) {
System.err.println("message:" + e.getMessage());
e.printStackTrace(); // 打印堆栈信息,便于调试
}
result.blockingForEach(message -> {
handleGenerationResult(message, response);
});
}
private static void handleGenerationResult(ApplicationResult message, HttpServletResponse response) throws IOException {
ApplicationOutput.Thought thought = message.getOutput().getThoughts().get(1);
String content = message.getOutput().getText();
PrintWriter writer = response.getWriter();
if (ObjectUtil.isNotNull(thought) ) {
String reasoning = thought.getThought();
if (!StrUtil.isBlank(reasoning)){
if (isFirstPrint) {
writer.write("====================思考过程====================\n");
writer.write("====================sessionId====================\n");
writer.write(message.getOutput().getSessionId());
isFirstPrint = false;
}
writer.write(reasoning);
}
}
if (!content.isEmpty()) {
if (!isFirstPrint) {
writer.write("====================完整回复====================\n");
isFirstPrint = true;
}
writer.write(content);
}
writer.flush();
}
注意:DashScope Java SDK在安全性上更优,HTTP调用需额外安全措施,适合灵活但需谨慎,API Key 和 appId不暴露在代码或日志中。
3. wx公众号
准备工作:已认证的wx公众号开发者ID(AppID)
扫描使用
补充:
-
数据管理
非结构化数据:支持 .pdf,.doc,.docx,.txt,.md,.pptx,.ppt,.png,.jpg,.jpeg,.bmp,.gif,.xls,.xlsx 等格式
单文档最大限制100MB或1000页,单图片最大限制20MB,最多支持(0/ 200)个。
非结构化数据1.png
2.数据应用-知识索引-创建知识库-结构化数据支持直接关联到阿里RDS数据库表