【优化】AI 知识库: 从url下载文档资源

This commit is contained in:
xiaoxin 2024-08-29 10:12:47 +08:00
parent ed2296e4c7
commit 024109dac9
4 changed files with 19 additions and 11 deletions

View File

@ -10,5 +10,5 @@ import org.apache.ibatis.annotations.Mapper;
* @author xiaoxin
*/
@Mapper
public interface AiKnowledgeBaseMapper extends BaseMapperX<AiKnowledgeDO> {
public interface AiKnowledgeMapper extends BaseMapperX<AiKnowledgeDO> {
}

View File

@ -1,6 +1,7 @@
package cn.iocoder.yudao.module.ai.service.knowledge;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.http.HttpUtil;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
@ -17,7 +18,7 @@ import org.springframework.ai.reader.tika.TikaDocumentReader;
import org.springframework.ai.tokenizer.TokenCountEstimator;
import org.springframework.ai.transformer.splitter.TokenTextSplitter;
import org.springframework.ai.vectorstore.RedisVectorStore;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@ -46,17 +47,14 @@ public class AiKnowledgeDocumentServiceImpl implements AiKnowledgeDocumentServic
private RedisVectorStore vectorStore;
// TODO xiaoxin 临时测试用后续删
@Value("classpath:/webapp/test/Fel.pdf")
private org.springframework.core.io.Resource data;
// TODO 芋艿需要 review 代码格式
@Override
@Transactional(rollbackFor = Exception.class)
public Long createKnowledgeDocument(AiKnowledgeDocumentCreateReqVO createReqVO) {
// TODO xiaoxin 后续从 url 加载
TikaDocumentReader loader = new TikaDocumentReader(data);
// 1.1 加载文档
// 1.1 下载文档
String url = createReqVO.getUrl();
TikaDocumentReader loader = new TikaDocumentReader(downloadFile(url));
// 1.2 加载文档
List<Document> documents = loader.get();
Document document = CollUtil.getFirst(documents);
// TODO @xin是不是不存在就抛出异常呀厚泽 return
@ -86,4 +84,14 @@ public class AiKnowledgeDocumentServiceImpl implements AiKnowledgeDocumentServic
return documentId;
}
private org.springframework.core.io.Resource downloadFile(String url) {
try {
byte[] bytes = HttpUtil.downloadBytes(url);
return new ByteArrayResource(bytes);
} catch (Exception e) {
log.error("[downloadFile][url({}) 下载失败]", url, e);
throw new RuntimeException(e);
}
}
}

View File

@ -7,7 +7,7 @@ import cn.iocoder.yudao.module.ai.controller.admin.knowledge.vo.AiKnowledgeCreat
import cn.iocoder.yudao.module.ai.controller.admin.knowledge.vo.AiKnowledgeUpdateMyReqVO;
import cn.iocoder.yudao.module.ai.dal.dataobject.knowledge.AiKnowledgeDO;
import cn.iocoder.yudao.module.ai.dal.dataobject.model.AiChatModelDO;
import cn.iocoder.yudao.module.ai.dal.mysql.knowledge.AiKnowledgeBaseMapper;
import cn.iocoder.yudao.module.ai.dal.mysql.knowledge.AiKnowledgeMapper;
import cn.iocoder.yudao.module.ai.service.model.AiChatModelService;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
@ -29,7 +29,7 @@ public class AiKnowledgeServiceImpl implements AiKnowledgeService {
private AiChatModelService chatModalService;
@Resource
private AiKnowledgeBaseMapper knowledgeBaseMapper;
private AiKnowledgeMapper knowledgeBaseMapper;
@Override
public Long createKnowledgeMy(AiKnowledgeCreateMyReqVO createReqVO, Long userId) {

View File

@ -1,310 +0,0 @@
Fel 表达式引擎
一、名词解释
Fel全称是 Fast Expression Language一种开源表达式引擎。
EL表达式语言用于求表达式的值。
Ast抽象语法树一般由语法分析工具生成。1+2*3 会解析结果如下所示:
二、简介
FelFast Expression Language)在源自于企业项目,设计目标是为了满足不断变化的功能需
求和性能需求。
Fel 是开放的引擎执行中的多个模块都可以扩展或替换。Fel 的执行主要是通过函数实现,
运算符(+、-等都是 Fel 函数),所有这些函数都是可以替换的,扩展函数也非常简单。
Fel 有双引擎,同时支持解释执行和编译执行。可以根据性能要求选择执行方式。编译执行
就是将表达式编译成字节码(生成 java 代码和编译模块都是可以扩展和替换的)
Fel 基于 Java1.5开发,适用于 Java1.5及以上版本。
1. 特点
易用性API 使用简单,语法简洁,和 java 语法很相似。
轻量级整个包只有200多 KB。
高 效:目前没有发现有开源的表达式引擎比 Fel 快。
扩展性:采用模块化设计,可灵活控制表达式的执行过程。
根函数Fel 支持根函数,“$('Math')”在 Fel 中是常用的使用函数的方式。
$函数:通过$函数Fel 可以方便的调用工具类或对象的方法(并不需要任何附加代码),
2. 不足
支持脚本:否。
3. 适应场景
Fel 适合处理海量数据Fel 良好的扩展性可以更好的帮助用户处理数据。
Fel 同样适用于其他需要使用表达式引擎的地方(如果工作流、公式计算、数据有效性校验
等等)
三、安装
1. 获取 Fel
项目主页http://code.google.com/p/fast-el/
下载地址http://code.google.com/p/fast-el/downloads/list
2. Jdk1.6 环境
使用:将 fel.jar 加入 classpath 即可。
构建 Fel下载 fel-all.tar.gz解压后将 src 作为源码文件夹,并且将 lib/antlr-min.jar 加入
classpath 即可。
3. Jdk1.5 环境:
与 jdk1.6 环境下的区别在于,需要添加 jdk 内置的 tools.jar 到 classpath。
四、功能
1. 算术表达式:
FelEngine fel= new FelEngineImpl();
Object result= fel.eval("5000*12+7500");
System.out.println(result);
输出结果67500
2. 变量
使用变量,其代码如下所示:
FelContext ctx= fel.getContext();
ctx.set("单价", 5000);
ctx.set("数量", 12);
ctx.set("运费", 7500);
Object result= fel.eval("单价*数量+运费");
System.out.println(result);
输出结果67500
3. 调用 JAVA 方法
FelEngine fel= new FelEngineImpl();
FelContext ctx= fel.getContext();
ctx.set("out", System.out);
fel.eval("out.println('Hello Everybody'.substring(6))");
输出结果Everybody
4. 自定义上下文环境
//负责提供气象服务的上下文环境
FelContext ctx= new AbstractConetxt() {
public Object get(Object name) {
if("天气".equals(name)){
return "晴";
}
if("温度".equals(name)){
return 25;
}
return null;
}
};
FelEngine fel= new FelEngineImpl(ctx);
Object eval = fel.eval("'天气:'+天气+';温度:'+温度");
System.out.println(eval);
输出结果:天气:晴;温度:25
5. 多层上下文环境(命名空间)
FelEngine fel= new FelEngineImpl();
String costStr= "成本";
String priceStr="价格";
FelContext baseCtx= fel.getContext();
//父级上下文中设置成本和价格
baseCtx.set(costStr, 50);
baseCtx.set(priceStr,100);
String exp= priceStr+"-"+costStr;
Object baseCost= fel.eval(exp);
System.out.println("期望利润:" + baseCost);
FelContext ctx= new ContextChain(baseCtx, new MapContext());
//通货膨胀导致成本增加(子级上下文 中设置成本,会覆盖父级上下文中的成本)
ctx.set(costStr,50+20 );
Object allCost= fel.eval(exp, ctx);
System.out.println("实际利润:" + allCost);
输出结果:
期望利润50
实际利润30
6. 编译执行
FelEngine fel= new FelEngineImpl();
FelContext ctx= fel.getContext();
ctx.set("单价", 5000);
ctx.set("数量", 12);
ctx.set("运费", 7500);
Expression exp= fel.compile("单价*数量+运费",ctx);
Object result= exp.eval(ctx);
System.out.println(result);
执行结果67500
备注:适合处理海量数据,编译执行的速度基本与 Java 字节码执行速度一样快。
7. 自定义函数
//定义 hello 函数
Function fun= new CommonFunction() {
public String getName() {
return "hello";
}
/*
* 调用 hello("xxx")时执行的代码
*/
@Override
public Object call(Object[] arguments) {
Object msg= null;
if(arguments!= null && arguments.length>0){
msg= arguments[0];
}
return ObjectUtils.toString(msg);
}
};
FelEngine e= new FelEngineImpl();
//添加函数到引擎中。
e.addFun(fun);
String exp= "hello('fel')";
//解释执行
Object eval = e.eval(exp);
System.out.println("hello "+eval);
//编译执行
Expression compile= e.compile(exp, null);
eval = compile.eval(null);
System.out.println("hello "+eval);
执行结果:
hello fel hello fel
8. 调用静态方法
如果你觉得上面的自定义函数也麻烦Fel 提供的$函数可以方便的调用工具类的方法 熟悉
jQuery 的朋友肯定知道"$"函数的威力。Fel 东施效颦,也实现了一个"$"函数,其作用是获取 class
和创建对象。结合点操作符,可以轻易的调用工具类或对象的方法。
//调用 Math.min(1,2)
FelEngine.instance.eval("$('Math').min(1,2)");
//调用 new Foo().toString();
FelEngine.instance.eval("$('com.greenpineyu.test.Foo.new').toString()");
通过"$('class').method"形式的语法就可以调用任何等三方类包commons lang 等)及自
定义工具类的方法,也可以创建对象,调用对象的方法。如果有需要,还可以直接注册 Java
Method 到函数管理器中。
五、安全(始于 0.8 版本)
为了防止出现“${'System'}.exit(1)”这样的表达式导致系统崩溃。Fel 加入了安全管理器,主
要是对方法访问进行控制。安全管理器中通过允许访问的方法列表(黑名单)和禁止访问的方
法列表(白名单)来控制方法访问。将 "java.lang.System. *"加入到黑名单,表示 System 类的
所以方法都不能访问。将"java.lang.Math. *"加入白名单,表示只能访问 Math 类中的方法。如
果你不喜欢这个安全管理器,可以自己开发一个,非常简单,只需要实现一个方法就可以了。
六、语法
1. 简介
Fel 的语法非常简单,基本和 Java 语法没没有区别。Fel 语法是 Java 语法的一个子集,支
持的运算符有限。如果熟悉语法的话,只需要关注一下 Fel 支持的运算即可。
Fel 表达式由常量、变量、函数、运算符组成。详见下文。
2. 常量
常量 说明
Number 1,1.0 等
Boolean true,false
String 'abc',"abc"
3. 变量
变量命名规则与 java 变量相同。变量名由字母、数字、下划线、$组成。
变量 说明
abc 以字母开头
abc 以下划线开头
$abc 以$开头
变量 中文变量名也可以
4. 函数
函数名的语法规则与变量相同
函数 说明
$('Math') $是变量名,'Math'是参数
5. 运算符
运算符 类型 优先级 说明
条件 三元操作符
|| 逻辑 优 或操作
&& 先 与操作
==、!= 关系 级 等于、不等于
>、<、<=、>= 从 大于、小于、大于等于、小于等于
+、- 算术 低 加减
*、/、% 逻辑 到 乘、除、取模
! 高 取反操作
七、结构
1. 主要组成部分
引擎由四部分组成,每个组成部分都可以被替换。组成部分如下所示:
组件 说明
解析器 将表达式解析成 Ast 节点
解释执行 负责执行节点
执行上下文 负责提供变量
编译器 负责生成代码并编译
2. 主要流程
执行表达式的流程如下所示:
组件 说明
解析表达式 默认 Antlr 解析表达式,生成 Ast 节点。
Ast 节点 由解析器生成的抽象语法树节点
节点解释器 每一个节点都有一个解释器,负责解释节点。
编译器 负责生成表达式对应 Java 类并编译,生成 Expression 对象
3. 引擎上下文
引擎上下文负责存取变量,它是脚本引擎与 Java 对象之间的桥梁。其结构如下所示:
组件 说明
FelContext 负责存储和保存变量
MapContext 使用 Map 来保存变量
ContextChain 上下文链,保存两个上下文的引用。存取变量委托引用的上下文处理。
4. 表达式解析
解析表达式的过程就是将表达式解析成 Ast 节点的过程,目前 Fel 由 Antlr 负责解析表达式,
生成 Ast 节点FelNode),流程如下所示:
5. 解释执行
FelNode(Ast 节点)中都包含一个解释器,不同的节点有不同的解释器,解释器负责求节点
值,流程如下所示:
6. 编译执行
FelNode(Ast 节点)中都包含一个代码生成器,负责将 Fel 表达式转换成 java 表达式。编译
模块负责将 java 表达式封装成 Java 类、编译、创建 Expression。再通过调用 Expression.eval 求
表达式的值。其过程如下所示:
7. 小结
在上文介绍的 Fel 组件中,绝大多数组件都是可能被替换的。通过在运行时替换一些小粒
度的组件,就可以灵活控制 Fel 的执行过程,很有实用价值。有些变化较少的组件(Antlr 解析器)
的替换过程还不是挺方便,随着 Fel 的发展,会慢慢重构,努力使 Fel 转变成让人满意的模块
化结构。