CCF第七届AIOps挑战赛季军:EasyRAG简洁RAG框架
基于llama-index构建的EasyRAG框架,面向网络运维私域知识问答,在不微调模型前提下集成查询改写、稀疏与密集检索、重排、排序融合及图像信息抽取等模块。通过分块优化、知识路径检索和答案迭代提升准确性,并采用bm25s加速、层早退重排和上下文压缩提高效率,最终夺得CCFAIOps国际挑战赛季军。
历时四个月,从初赛赛道第一,到复赛赛道第二,最终在决赛拿下季军——这个成绩背后,是一支团队在RAG(检索增强生成)方向上的深度实践。受组委会邀请,他们将本次比赛的方案整理成文,分享了关键思路和实验结论,非常值得参考。
先交代一下背景。本次比赛的主题是面向网络运维领域的私域知识问答,按大语言模型的类型分成两个赛道:赛道一允许微调Qwen2-7B,赛道二则调用GLM-4 API。我们选择的是赛道二,模拟那些无法微调大模型的真实场景。因此核心目标非常明确——在不微调任何模型的前提下,搭建一套尽可能简洁、准确、高效且实用的RAG系统。
为了实现这个目标,我们基于llama-index构建了一套完整的RAG框架,涵盖查询改写、图像数据处理、分块策略、元数据利用、密集检索、稀疏检索、重排、排序融合、提示词优化、上下文压缩以及部署等环节。这套框架可以灵活配置,方便直接迁移到私有领域知识问答场景中。
初赛阶段的RAG流程是:块调优 → 两路稀疏/密集检索粗排 → 重排 → RRF排序融合。到了复赛,流程演变为:块优化(加入了图像信息和路径知识的利用)→ 两路稀疏检索粗排 → 重排 → 答案迭代优化。
1. 准确性
数据处理流程
数据处理是整个系统的基础,主要涉及zedx文件的解析、文本分块和图像信息抽取三个环节。
zedx文件处理:解压后先做路径解析和文档抽取,再保存。这里有两个关键点:一是路径解析时提取了xml文件中的知识路径(比如“emsplus-安装与调测-软件安装-安装准备-版本文件准备”)和文件路径(比如“./emsplus/documents/软件安装/topics/版本文件准备.html”),为后续结合路径的检索打下了基础。二是在文档抽取中,用bs4提取了html文本,同时保留了图像标题和图像路径的对应关系,方便后续利用多模态信息。
文本分块:使用llama-index的Sentence Splitter,先用中文分隔符切句子,再按设定的块大小合并。分块时,chunk_size和chunk_overlap这两个参数需要仔细调优。一个细节是:节点的node.metadata中file_path默认是绝对路径,而句子分割类会计算元数据长度,原始数据放在不同的绝对路径下会导致结果差异很大,进而造成结果不稳定。所以我们重新实现了分块类,在存储元数据时将file_path改为相对路径,彻底消除了这个不稳定因素。代码如下:
# 原代码:https://github.com/run-llama/llama_index/blob/8f7cd3e1043da26514ac82fc732cd21bbb4bbe9c/llama-index-core/llama_index/core/node_parser/text/sentence.py#L155C5-L157C62
def split_text_metadata_aware(self, text: str, metadata_str: str) -> List[str]:
metadata_len = len(self._tokenizer(metadata_str))
effective_chunk_size = self.chunk_size - metadata_len
# 我们的实现:https://github.com/BUAADreamer/EasyRAG/blob/893b3c272b2ce0d8c6cee80f02a171cccded9f96/src/easyrag/custom/splitter.py#L149
def split_text_metadata_aware(self, text: str, metadata_str: str) -> List[str]:
metadata_len = len(self._tokenizer(metadata_str))
effective_chunk_size = self.chunk_size
# 分块实现:https://github.com/BUAADreamer/EasyRAG/blob/893b3c272b2ce0d8c6cee80f02a171cccded9f96/src/easyrag/custom/transformation.py#L67C1-L71C51
for node in nodes:
node.metadata["file_abs_path"] = node.metadata['file_path']
file_path = node.metadata["file_path"].replace(self.data_path + "/", "")
node.metadata["dir"] = file_path.split("/")[0]
node.metadata["file_path"] = file_path
图像信息抽取:先提取图像内容,再做过滤。举个例子,有道题问的是流程图里POD和VRU的比例,这种问题不解析图像内容是答不出来的。我们使用glm4v-9b对图像生成caption,提示词就是“简要描述图像”。我们也尝试了internvl2、gpt4o、claude等模型,glm4v的效果相对最好。图像过滤采用了多种规则:纯英文过滤(用paddleocr提取文字,过滤不含中文的图像,因为纯英文图像的信息可能和文本重复或过于复杂)、关键词过滤(标题含有“组网图”“架构”的复杂图像对问答帮助不大)、引用过滤(过滤掉那些在文中以“配置如图x所示”“文件如图x所示”等特定方式被引用的图像,这些图像的信息通常文本已经涵盖)。
RAG流程
查询改写:我们尝试过关键词扩展和HyDE两种思路,但发现直接用GLM4做查询扩展,新生成的查询词和私域文档的偏差比较大,所以最终提交的方案里没有采用。
两路稀疏检索粗排:基于BM25做了两路检索,除了常规的文档检索,还加入了知识路径检索。比如问“VNF弹性分几类?”,VNF和弹性这两个词都能在知识路径里直接找到,但在文档正文里可能找不到,这时路径检索的优势就体现出来了。BM25的分词方面,llama-index对中文的支持不太理想,所以我们基于jieba实现了中文分词,效果有明显提升。我们也尝试了清华的IT词库,但没有带来额外收益。文档检索时,把文本块和文件路径拼接在一起处理。停用词表用的是经典的哈工大停用词表。
密集检索粗排:基于大模型的embedding模型效果更好。我们选用了阿里的GTE-Qwen2-7B-instruct,在不微调的情况下,这个模型的表现优于bge-v1.5和bce。向量数据库用的是qdrant,官网的docker示例就能快速部署,简单高效。粗排时取topk=288。索引阶段同样把文本块和文件路径拼接后输入模型。
LLM Reranker重排:基于大模型的重排器效果更好。我们选用的是智源的bge-reranker-v2-minicpm-layerwise,不微调的情况下,效果领先其他bge系列的重排器。精排取topk=6。重排推理时,将文本块和知识路径拼接。
多路排序融合:主要尝试了naive(去重合并)和RRF(倒数排序融合)两种方式。实验发现,重排融合比粗排融合更有价值。融合策略分两种:生成前融合——把多组文档集合排序融合成一组,再输给大模型;生成后融合——每组文档集合分别输给大模型,再把多个答案融合,我们尝试过直接拼接和取最长两种。复赛阶段,直接对两路做了naive融合。重排融合则是多路分别做粗排+重排,得到多组文档集合后再融合。
LLM回答:我们测试了一圈提示词后发现,简单问答提示词效果最好。包括CoT提示、结构化的markdown提示词、CoSTAR提示词,都没有超过官方最初提供的那个。不过API本身有波动,这个方向还有探索空间。
LLM答案迭代优化:一个有意思的观察是,大模型对每个文本块都会分配一定的注意力,这可能导致top1文本块里的有效信息没有被充分利用。于是我们设计了两轮迭代:第一轮基于6个文本块得到answer1,第二轮把answer1和top1文本块一起输给模型,得到answer2作为最终答案。
初赛实验结果
初赛的提分过程大致分三个阶段:
- 单路粗排(0→2):官方Baseline跑通(0→57)、bge-v1.5实验(57→68)、bm25实验(68→69)
- 单路粗排+精排(3→16):增加基于BERT的重排(69→73)、改为基于LLM的重排(73→77)、优化数据处理(77→78)、粗排换用bm25或gte-qwen2-7B(78→81)、修改分块参数(81→83)
- 多路融合(17→21):重排融合(83→83.5+)
复赛实验结果
复赛的评价指标变了,更看重事实正确性,因此稀疏检索粗排整体上更有效。提分路径分五个阶段:
- 流程探索(0→4):改为单路稀疏检索粗排+重排(90→91.5)
- 路径知识利用(5→10):粗排利用文件路径(91.5→92.7)、重排利用知识路径(92.7→93.1)
- 图像信息利用(11→12):图像信息抽取+筛选(93.1→94.2)
- 知识路径检索(13):加上知识路径稀疏检索(94.2→94.5)
- 答案迭代优化(14→15):答案整合(94.5→96+)
2. 高效性
实际场景中速度很重要,所以我们也做了不少降低推理时延的尝试。整体来看:无加速时,粗排0.2s,重排6s,LLM推理10s;加速后,粗排接近瞬时,重排不到4s,LLM推理降到8.5s以内。
高效稀疏检索
引入bm25s库后,稀疏检索的时延降到了可以忽略的程度,问答效果几乎没有变化。它的原理是:用主动索引技术,以空间换时间,在索引阶段就把每个token相对每个文档的TF用矩阵存下来,推理时直接把对应词所在的行取出来,再配合高效的scipy矩阵运算,速度自然就上来了。
高效重排
我们设计了一个层早退算法,把重排时间降低了2秒以上。动机是:使用的bge-reranker-v2-minicpm-layerwise模型支持可选层模式,可以选择较小的层来提升速度。28层效果最好,普遍优于其他层。思路很简单:简单的query早退,复杂的query晚退。参考了DeeBERT和FastBERT的思路,设计了动态层早退方法,尽量接近原始排序效果的同时降低了推理时延。结论是:最大相似度阈值选择算法优于熵阈值选择算法;阈值越大越慢但越准,可以根据实际场景选择。还有一个有趣的现象:“比较大小”这个操作本身的开销不可忽视,所以只在28层之前选了三个断点做阈值判断,尽量做好tradeoff,避免“虚假”优化。
高效LLM推理
我们设计了上下文压缩方法,把LLM推理时间降低了1.5秒以上。最初尝试了llmlingua,但用大模型做压缩会带来额外开销,token省了,时间反而增加了。所以我们换了个思路:基于BM25相似度做抽取式压缩。先分句,再挑出相似度最高的若干句子,按原顺序拼接成压缩后的上下文。相比llmlingua,效果更好,节省的token和时间也更多。同样,阈值越大越慢但越准,可以根据场景灵活选择。
3. 实用性
扩展性:在单张A800上测试了8并发,平均推理时延从串行的16s降到了7.5s,初步验证了框架的可扩展性。
部署难度:支持简单的命令行部署和docker批量运行,几行命令就能启动一个Web应用。
网络运维问答案例

四大名著问答案例
我们还用四大名著语料测试了框架能否支持通用语料问答。
4. 总结
本次比赛我们始终坚持“不微调任何模型”这个前提,利用各种先进模型搭建pipeline,做了充分的消融实验,达到了比赛中领先的准确度,同时也在高效性和实用性方面做了大量尝试。初步结论是:对于垂直领域的RAG,精心设计流程 + 挑选SOTA模型 + 流程调优,在初期带来的收益可能大于微调模型本身。当然,微调后的模型确实能让pipeline效果更好,这也值得继续探索。这个工作如果能对RAG社区有所贡献,那就再好不过了。
感谢组委会在比赛中的细致组织和耐心投入,本次比赛的讨论氛围和参赛体验都非常不错。也感谢张老师和学长们对比赛的大力支持。
```你是一名 AI 行业编辑,请围绕下面这条热点输出一份资讯解读:
热点:CCF第七届AIOps挑战赛季军:EasyRAG简洁RAG框架要求:
1. 先用一句话解释这条热点在讲什么
2. 再总结它为什么重要
3. 说明会影响哪些 AI 产品或内容方向
4. 最后给出 3 个适合资讯站使用的标题
游乐网为非赢利性网站,所展示的游戏/软件/文章内容均来自于互联网或第三方用户上传分享,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系youleyoucom@outlook.com。
相关热点利用Kimi撰写商务邮件时,先粘贴含收件人、事项及动作请求的初稿,再输入角色、场景、语气等明确指令,最后校验称谓、“请”字使用频率及时间金额等硬信息,经人工比对后发送,可提升邮件质量和效率。
AIGC技术正在席卷全球,金融行业自然也不能例外。从智能投顾到自动化报告,从个性化营销到风险控制,这波浪潮已经深入金融业务的各个关键环节。不少人觉得AIGC无非就是个效率工具,但更准确地说,它正在重新定义金融服务的创新逻辑与客户体验。不过,理想很丰满,现实却很骨感——很多从业者仍在困惑:这项技术到底
QoderWake脚本可在Windows、macOS、Linux间自动识别系统、处理路径差异并跳过临时文件,实现10秒内双向同步。编写时需确认环境,用绝对路径且避免全角字符或未转义空格。通过内置变量或动态拼接路径实现跨平台适配,并配置文件监控、30秒超时重试及冲突保留更新版本或生成副本的机制。
本地部署Qwen3-1 7B月成本约¥530,QoderCNPro+版API月费$99(6000Credits)。月调用≤2100次时本地更省钱;日均超80次深度诊断时API因节省人工审计成本更具优势。
- 日榜
- 周榜
- 月榜
热点快看
