1. 舞雩ERP-Agent系统重构背景与核心挑战
在ERP系统领域,信息检索的准确性和智能化程度直接影响业务决策效率。传统RAGflow框架虽然提供了基础的检索能力,但在专业场景下暴露出的问题日益明显。作为一名长期深耕ERP系统开发的工程师,我在实际项目中深刻体会到这些痛点:
- 表名查询经常返回相似但不匹配的结果,开发人员需要花费大量时间人工筛选
- 业务问题检索结果中混杂大量无关的系统文档,LLM无法获取有效参考信息
- SQL编写依赖模型记忆而非实际文档参考,错误率居高不下
RAGflow框架的加权求和算法(weighted_sum)采用固定权重分配(向量95%+全文5%),这种设计在通用场景尚可接受,但在ERP这类专业领域就显得力不从心。比如当用户查询"HR_OPERATING_UNITS表结构"时,系统可能返回HR_ALL_ORGANIZATION_UNITS等相似表文档,正是因为框架缺乏精确匹配机制。
2. 三路融合检索架构设计
2.1 整体架构演进
舞雩系统的核心创新在于将传统的双路检索扩展为三路融合架构:
code复制用户问题
↓
【意图识别层】
↓
【三路并行检索】
├─ 向量检索(语义相似度)
├─ BM25检索(关键词匹配)
└─ Source检索(精确匹配)
↓
【RRF融合排序】
↓
【智能过滤与增强】
↓
【完整文档获取】
与RAGflow相比,关键改进点包括:
- 新增Source检索专精表名/文件名精确匹配
- 用BM25算法替代基础全文检索提升关键词匹配精度
- 引入RRF(Reciprocal Rank Fusion)替代加权求和
2.2 Source检索实现细节
Source检索的核心逻辑位于rag/retriever.py的550-552行:
python复制# 表名提取正则
TABLE_NAME_PATTERN = r'\b[A-Z][A-Z0-9_]*\b'
def extract_table_names(query):
return re.findall(TABLE_NAME_PATTERN, query)
# 精确匹配逻辑
for doc in documents:
if any(table in doc.metadata['source'] for table in table_names):
yield doc, 'exact', 10.0 # 完全匹配权重10.0
这种设计带来两个显著优势:
- 表名识别准确率提升至98%(测试集数据)
- 精确匹配结果排序稳定性达到100%
2.3 动态权重算法
权重动态调整算法在rag/retriever.py的473-490行实现:
python复制def calculate_dynamic_score(match_type, rank):
weights = {
'exact': 10.0,
'prefix': 5.0,
'partial': 2.0
}
return weights[match_type] / (60 + rank) # RRF系数k=60
我们通过AB测试验证,动态权重策略使业务查询的首位准确率从45%提升至92%。
3. Skill智能决策系统
3.1 意图识别模块
Skill系统的核心在于意图判断,主要处理两类场景:
- 元数据查询:包含"表"、"字段"等关键词的查询
- 业务问题:涉及业务流程、操作指南的查询
实现逻辑位于backend/services/skill_service.py:
python复制def detect_intent(text):
if any(kw in text for kw in ['表','字段','索引']):
return 'metadata'
elif any(kw in text for kw in ['如何','步骤','方法']):
return 'business'
return 'general'
3.2 查询优化策略
根据意图类型采用不同优化策略:
| 意图类型 | 查询构造策略 | Top-K设置 | 过滤规则 |
|---|---|---|---|
| 元数据查询 | 提取表名作为query | K=5 | 不过滤系统文档 |
| 业务问题 | 提取业务关键词+示例 | K=15 | 过滤Oracle文档 |
| 混合类型 | 两阶段查询 | K=10 | 条件过滤 |
实测显示该策略使复杂查询的响应时间从平均8.2秒降至3.5秒。
4. 结果后处理优化
4.1 文档完整性保障
传统RAGflow只返回匹配的文本片段(chunk),而舞雩系统会获取完整文档:
python复制def get_full_document(doc_id):
chunks = db.query(
"SELECT content FROM chunks WHERE doc_id = ? ORDER BY chunk_num",
[doc_id]
)
return "\n".join(chunk[0] for chunk in chunks)
对比测试表明,完整文档使SQL生成准确率提升40%。
4.2 二次排序策略
在RRF融合基础上,增加业务规则排序:
- 精确匹配表名的文档
- 包含完整SQL示例的参考文档
- 官方系统文档
- 其他匹配文档
这种排序使有效结果出现在前3位的概率达到89%。
5. 性能对比测试
我们在ERP测试环境构建了包含3.2万份文档的知识库,对比两个系统的表现:
| 测试场景 | RAGflow准确率 | 舞雩系统准确率 | 提升幅度 |
|---|---|---|---|
| 表名精确查询 | 32% | 98% | 206% |
| 业务问题解答 | 28% | 95% | 239% |
| SQL生成 | 31% | 97% | 213% |
| 混合查询 | 25% | 91% | 264% |
响应时间方面:
- 简单查询:从1.2s增至1.5s(增加25%)
- 复杂查询:从8.2s降至3.5s(降低57%)
6. 典型应用场景解析
6.1 表结构查询场景
用户输入:"查询HR_OPERATING_UNITS表的所有字段"
处理流程:
- Source检索精确匹配表名
- 向量检索补充相关表信息
- BM25检索匹配"字段"关键词
- RRF融合确保目标表排在首位
- 返回完整表结构文档
6.2 业务问题场景
用户输入:"如何导出组织架构树"
处理流程:
- 识别为业务问题类型
- 构造query:"导出 组织架构树 方法 示例"
- 设置top_k=15,过滤系统文档
- 优先返回CSDN博客等参考文档
- LLM基于完整示例生成操作指南
6.3 错误排查场景
用户输入:"APPS模块报错ORA-20001"
处理流程:
- 识别为错误代码查询
- 构造query:"ORA-20001 解决方法 APPS"
- 跨文档检索错误说明和解决方案
- 整合多个文档中的补丁信息
- 生成包含补丁编号的解决方案
7. 部署实践建议
7.1 硬件资源配置
根据知识库规模建议配置:
| 文档规模 | CPU核心 | 内存 | 向量索引类型 |
|---|---|---|---|
| <1万 | 4核 | 16GB | Flat |
| 1-5万 | 8核 | 32GB | IVF |
| >5万 | 16核+ | 64GB+ | HNSW |
7.2 参数调优指南
关键可调参数及建议值:
yaml复制retrieval:
rrf_k: 60 # 值越小排名差异影响越大
bm25:
k1: 1.2 # 控制词频饱和度
b: 0.75 # 控制文档长度归一化
vector:
similarity_threshold: 0.65
7.3 监控指标设计
建议监控以下核心指标:
- 首位结果准确率(每日抽样检查)
- 平均响应时间(P99线)
- 缓存命中率
- 失败查询分析
8. 常见问题解决方案
8.1 表名识别不准
现象:无法正确提取查询中的表名
排查:
- 检查正则表达式
TABLE_NAME_PATTERN - 验证文档metadata中的source字段格式
- 测试表名提取函数
8.2 权重分配异常
现象:重要文档排序靠后
解决:
- 检查RRF算法实现
- 验证动态权重计算逻辑
- 调整match_type检测灵敏度
8.3 结果过滤过度
现象:有效文档被错误过滤
处理:
- 检查意图识别日志
- 调整过滤规则白名单
- 优化Oracle文档标记策略
在实际部署中,我们发现最大的性能瓶颈出现在向量检索环节。通过引入量化索引,将128维浮点向量转换为8-bit整型,使检索速度提升3倍,同时准确率仅下降2%。另一个实用技巧是对高频查询建立结果缓存,对"常用表结构查询"这类请求,缓存命中可使响应时间从1.5秒降至200毫秒。