news 2026/9/13 2:44:04

Label Studio 构建 RAG 人工反馈评估界面:检索相关性、回答相关性与忠实度标注实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Label Studio 构建 RAG 人工反馈评估界面:检索相关性、回答相关性与忠实度标注实战

Label Studio 构建 RAG 人工反馈评估界面:检索相关性、回答相关性与忠实度标注实战

【免费下载链接】label-studioLabel Studio is a multi-type data labeling and annotation tool with standardized output format项目地址: https://gitcode.com/GitHub_Trending/la/label-studio

本文以 Label Studio 官方模板 llm_rag_human_feedback 为核心,讲解如何用标签配置(Labeling Config)搭建一套面向 RAG(Retrieval-Augmented Generation,检索增强生成)流水线的人工评估界面。你将掌握三类核心评估维度(检索文档的上下文相关性、回答相关性、回答忠实度)的标注界面设计,学会使用ListRankerCollapseChoices等标签组合完成可视化评估,并通过 Label Studio SDK 与 LlamaIndex 对接,把真实检索结果自动构造成可导入的标注任务。

RAG 评估为什么需要人工反馈

在 RAG 流水线中,最终输出的质量不只取决于大语言模型(LLM)的生成能力,还取决于检索阶段返回的文档质量。官方模板文档明确指出,评估目标不应局限于单条 LLM 回答,还应纳入对检索文档的多维度评价,主要包括:

  • Contextual relevancy(上下文相关性):被检索回来的文档与当前问题是否相关;
  • Answer relevancy(回答相关性):LLM 基于这些文档生成的回答是否与问题相关;
  • Answer faithfulness(回答忠实度):回答是否在事实上忠于检索到的上下文、是否存在幻觉(hallucination)或编造内容。

借助 Label Studio,你可以把上述三类评估以可视化的形式呈现给人工标注员,让他们把检索文档拖入“相关/不相关”桶中,并对回答给出二元打分,从而沉淀可用于 RAG 效果分析、检索器调优乃至 RLHF 对齐的高质量人工反馈数据。

配置标注界面:完整标签配置解析

按文档指引,创建项目 后将下面的 XML 配置粘贴到 Labeling Config 中即可生成评估界面:

<View> <Style> .htx-text {white - space: pre-wrap;} .question { font - size: 120%; width: 800px; margin-bottom: 0.5em; border: 1px solid #eee; padding: 0 1em 1em 1em; background: #fefefe; } .answer { font - size: 120%; width: 800px; margin-top: 0.5em; border: 1px solid #eee; padding: 0 1em 1em 1em; background: #fefefe; } .doc-body { white - space: pre-wrap; overflow-wrap: break-word; word-break: keep-all; } .doc-footer { font - size: 85%; overflow-wrap: break-word; word-break: keep-all; } h3 + p + p {font - size: 85%;} /* doc id */ </Style> <View className="question"> <Header value="Question"/> <Text name="question" value="$question"/> </View> <View style="margin-top: 2em"> <Header value="Context"/> <List name="results" value="$similar_docs" title="Retrieved Documents"/> <Ranker name="rank" toName="results"> <Bucket name="relevant" title="Relevant"/> <Bucket name="non_relevant" title="Non Relevant"/> </Ranker> </View> <View className="answer"> <Header value="Answer"/> <Text name="answer" value="$answer"/> </View> <Collapse> <Panel value="How relevant is the answer to the provided context?"> <Choices name="answer_relevancy" toName="question" showInline="true"> <Choice value="Relevant" html="&lt;div class=&quot;thumb-container&quot; style=&quot;display: flex; gap: 20px;&quot;&gt; &lt;div class=&quot;thumb-box&quot; id=&quot;thumb-up&quot; style=&quot;width: 100px; height: 100px; display: flex; align-items: center; justify-content: center; border: 1px solid #ccc; border-radius: 5px; cursor: pointer; transition: background-color 0.3s;&quot;&gt; &lt;span class=&quot;thumb-icon&quot; style=&quot;font-size: 48px;&quot;&gt;&amp;#128077;&lt;/span&gt; &lt;!-- Thumbs Up Emoji --&gt; &lt;/div&gt;&lt;/div&gt;"/> <Choice value="Non Relevant" html="&lt;div class=&quot;thumb-container&quot; style=&quot;display: flex; gap: 20px;&quot;&gt; &lt;div class=&quot;thumb-box&quot; id=&quot;thumb-down&quot; style=&quot;width: 100px; height: 100px; display: flex; align-items: center; justify-content: center; border: 1px solid #ccc; border-radius: 5px; cursor: pointer; transition: background-color 0.3s;&quot;&gt; &lt;span class=&quot;thumb-icon&quot; style=&quot;font-size: 48px;&quot;&gt;&amp;#128078;&lt;/span&gt; &lt;!-- Thumbs Down Emoji --&gt; &lt;/div&gt; &lt;/div&gt;"/> </Choices> </Panel> </Collapse> <Collapse> <Panel value="If the answer factually aligns with the retrieved context?"> <Choices name="faithfulness" toName="question" showInline="true"> <Choice value="Relevant" html="&lt;div class=&quot;thumb-container&quot; style=&quot;display: flex; gap: 20px;&quot;&gt; &lt;div class=&quot;thumb-box&quot; id=&quot;thumb-up&quot; style=&quot;width: 100px; height: 100px; display: flex; align-items: center; justify-content: center; border: 1px solid #ccc; border-radius: 5px; cursor: pointer; transition: background-color 0.3s;&quot;&gt; &lt;span class=&quot;thumb-icon&quot; style=&quot;font-size: 48px;&quot;&gt;&amp;#128077;&lt;/span&gt; &lt;!-- Thumbs Up Emoji --&gt; &lt;/div&gt;&lt;/div&gt;"/> <Choice value="Non Relevant" html="&lt;div class=&quot;thumb-container&quot; style=&quot;display: flex; gap: 20px;&quot;&gt; &lt;div class=&quot;thumb-box&quot; id=&quot;thumb-down&quot; style=&quot;width: 100px; height: 100px; display: flex; align-items: center; justify-content: center; border: 1px solid #ccc; border-radius: 5px; cursor: pointer; transition: background-color 0.3s;&quot;&gt; &lt;span class=&quot;thumb-icon&quot; style=&quot;font-size: 48px;&quot;&gt;&amp;#128078;&lt;/span&gt; &lt;!-- Thumbs Down Emoji --&gt; &lt;/div&gt; &lt;/div&gt;"/> </Choices> </Panel> </Collapse> </View>

各标签在评估界面中的作用

  • <View>:所有标签配置都必须包含的基础容器标签。本配置中它类似 HTML 的div,用于组织界面区块布局(例如className="question"className="answer"以及内联style="margin-top: 2em"的分组)。
  • <Style>:定义作用于View内元素的 CSS 样式,为问题区、回答区、文档正文等区块统一排版(如pre-wrap保留换行、固定宽度与背景边框)。
  • <Header>:通过value参数显示界面标题,本配置用于标注“Question”“Context”“Answer”等区块名。
  • <Text>:展示输入数据提供的文本。以示例数据为准,该标签分别渲染源 JSON 中的questionanswer键,你需要根据自己 JSON 数据的键名调整value="$question"value="$answer"
  • <List>:展示检索回来的文档列表。以示例数据为准,列表数据来自源 JSON 的similar_docs字段。其value参数指向一个对象数组(含idtitlebody等字段),参见 List 标签文档。
  • <Ranker>:为列表项创建可拖拽排序的 UI 元素,将列表项拖入不同Bucket完成分类。其nametoName参数中,toName必须指向所连接的List标签名,参见 Ranker 标签文档。
  • <Bucket>:在Ranker内定义一个分类容器。本配置定义了relevant(相关)与non_relevant(不相关)两个桶,标注员把每条检索文档拖入其一,即可完成上下文相关性评估。
  • <Collapse>/<Panel>:创建可折叠/展开的区域。Collapse提供折叠容器(支持accordionborderedopen等参数),Panelvalue定义折叠面板标题,用于收纳两个评分问题,保持界面简洁,参见 Collapse 标签文档。
  • <Choices>/<Choice>Choices通过nametoName参数呈现一组选项,Choice定义单个选项。本配置中两个Choicesanswer_relevancyfaithfulness)均设置了showInline="true"让选项同行显示,并借助html参数将选项渲染为可点击的 👍/👎 图标按钮。

关于 html 参数与导出值

两个评分选项的html参数中包含了内联样式的大拇指图标 HTML(Thumbs Up/Down Emoji),这正是标注界面呈现“点赞/点踩”视觉效果的关键。根据 Choice 标签参数说明,html用于展示富内容、优先级高于value,但导出结果中使用的仍是value(且需正确转义 HTML 实体)。因此标注后落库的是Relevant/Non Relevant这样的稳定枚举值,便于后续统计与训练,图标仅承担视觉表达。你可以替换其中的 emoji(&#128077;&#128078;)、尺寸或颜色来定制视觉风格,而无需改动分析逻辑。

输入数据格式

本模板的任务数据需包含提示词(prompt/question)、回答(answer)以及用于上下文的检索文档(similar_docs),如下所示:

[ { "data": { "question": "Can I use Label Studio for LLM evaluation?", "answer": "Yes, you can use Label Studio for LLM evaluation.", "similar_docs": [ {"id": 0, "body": "Label Studio is a data labeling tool."}, {"id": 1, "body": "Label Studio is a data labeling tool for AI projects."} ] } } ]

要点说明:

  • 每条任务是一个包含data键的对象,data下的字段名必须与标签配置中的$question$answer$similar_docs一一对应。
  • similar_docs是对象数组,每个对象至少应包含idbodyList标签还支持titlehtml字段用于富展示,参见 List 标签文档)。
  • 实际项目中,这三个字段均可由 RAG 管线直接产出:question为用户查询,answer为 LLM 生成回答,similar_docs为检索器返回的 Top-K 文档。

用 LlamaIndex 采集评估数据

模板文档提供了基于 LlamaIndex 的数据采集示例。首先安装:

pip install llama-index

然后可用如下脚本构建 RAG 流水线,针对 GitHub issues 回答问题,并从中提取检索到的文档:

import os from llama_index.readers.github import GitHubRepositoryIssuesReader, GitHubIssuesClient from llama_index.core import VectorStoreIndex, StorageContext, load_index_from_storage from llama_index.core.callbacks import CallbackManager, LlamaDebugHandler, CBEventType reader = GitHubRepositoryIssuesReader( github_client=GitHubIssuesClient(), owner="HumanSignal", repo="label-studio", ) llama_debug = LlamaDebugHandler() callback_manager = CallbackManager([llama_debug]) # check if storage already exists PERSIST_DIR = "./llama-index-storage" if not os.path.exists(PERSIST_DIR): # load the documents and create the index documents = reader.load_data(state=GitHubRepositoryIssuesReader.IssueState.CLOSED) index = VectorStoreIndex.from_documents(documents, callback_manager=callback_manager) # store it for later index.storage_context.persist(persist_dir=PERSIST_DIR) else: # load the existing index storage_context = StorageContext.from_defaults(persist_dir=PERSIST_DIR) index = load_index_from_storage(storage_context, callback_manager=callback_manager) query_engine = index.as_query_engine() question = "Can I use Label Studio for LLM evaluation?" answer = query_engine.query(query) # accessing the list of top retrieved documents from callback event_pairs = llama_debug.get_event_pairs(CBEventType.RETRIEVE) retrieved_nodes = list(event_pairs[0][1].payload.values())[0] retrieved_documents = [node.text for node in retrieved_nodes]

脚本的关键链路:

  1. GitHubRepositoryIssuesReader读取 GitHub 仓库的 issue 数据(示例读取 HumanSignal/label-studio 仓库已关闭的 issue);
  2. 通过VectorStoreIndex建立向量索引,并借助CallbackManager+LlamaDebugHandler监听检索(CBEventType.RETRIEVE)事件;
  3. 首次运行时把索引持久化到./llama-index-storage,后续直接load_index_from_storage加载,避免重复建库;
  4. LlamaDebugHandler的回调事件中提取 Top 检索节点文本,得到retrieved_documents列表。

随后即可用 Label Studio SDK 把结果构造成可直接导入上文标签配置的任务:

task = { "question": question, "answer": answer, "similar_docs": [{"id": i, "body": text} for i, text in enumerate(retrieved_documents)] }

这里similar_docsenumerate生成自增id,保证List/Ranker中每个列表项有稳定标识(最终拖拽排序的结果也会以这些id序列化,详见下文结果格式说明)。SDK 导入后即可在 Label Studio 中逐条人工评估。

仓库内的同类实现参考

本模板在仓库中不是孤例,label_studio/annotation_templates/generative-ai/目录下汇集了多个同族模板:

  • llm-ranker/config.yml:官方内置的 “LLM Ranker” 模板,将多个 LLM 回答以List+Ranker展示并拖入relevant_results/biased_results桶,用于模型对比与偏好收集;
  • 同一目录下的chatbot-assessmenthuman-feedback-collectionresponse-gradingsupervised-llmvisual-ranker等模板,覆盖了对话评估、反馈收集、回答打分等 LLM 评估场景。

上述内置模板与本文介绍的 RAG 评估模板在 UI 架构上同源:都用List承载动态条目、用Ranker+Bucket做分类/排序、用Choices做二元或多选评分,体现了 Label Studio 在 LLM 评估模板家族中的一致设计模式。从 gallery_llm_evals.ejs 的模板画廊可以看到,本模板与 “LLM Response Grading”“Side-by-Side LLM Output Comparison”“Evaluate RAG with Ragas” 等共同组成 LLM 评估模板体系,开发者可按需选用或组合。

标注结果格式与后续利用

Ranker标签保存的结果格式可参考 Ranker 标签文档:当存在多个Bucket时,结果是一个字典,每个键为桶名、值为落入该桶的列表项id数组。对本模板而言,标注一次会产出类似下面的 annotation result:

{ "value": { "ranker": { "_": [], "relevant": ["0"], "non_relevant": ["1"] } }, "from_name": "rank", "to_name": "results", "type": "ranker", "origin": "manual" }

其中_键存放未被拖入任何桶的列表项(如果列表使用List且存在未分类项);若在<Bucket>上添加default="true",则未分类项会直接落入默认桶且原“未分类”列会被隐藏。answer_relevancyfaithfulness两个Choices则各自产出一条二元分类结果(值为Relevant/Non Relevant)。

由此你可以得到三类结构化标注结果:

  • 检索文档 × 相关性relevant/non_relevant桶中的文档id列表,可直接换算成每个查询的上下文相关性命中情况;
  • 回答相关性answer_relevancy的二元标签;
  • 回答忠实度faithfulness的二元标签。

这些结果可以通过 Label Studio 的导出功能或 API 批量取回,用于计算 RAG 评估指标(如检索命中率、回答相关率、忠实率),也可作为偏好数据参与模型微调或 RLHF 流程,形成“人工评估 → 指标分析 → 系统优化”的闭环。

小结

本文围绕 Label Studio 的 RAG 人工反馈评估模板,从界面配置、输入数据、LlamaIndex 数据采集到结果序列化给出了完整方案。核心要点可归纳为:用List+Ranker+Bucket完成检索文档的上下文相关性评估;用Collapse+Panel+Choices完成回答相关性与忠实度的二元评估;用 LlamaIndex 的检索回调自动组装任务并通过 SDK 导入。结合仓库内置的 LLM 评估模板家族与 Ranker、List、Collapse、Choices、Choice 等标签文档,你可以快速扩展出符合自身 RAG 系统的评估界面。

【免费下载链接】label-studioLabel Studio is a multi-type data labeling and annotation tool with standardized output format项目地址: https://gitcode.com/GitHub_Trending/la/label-studio

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/13 2:43:24

Wi-Fi Mesh排障不再靠猜:R-Mesh Gravitation拓扑与信号可视化实战

小区里一户别墅客户装了三套 Mesh&#xff0c;调试了整整一个周末&#xff0c;最后发现只是子节点摆放位置的墙体里有新风管道。这种经历多了之后&#xff0c;我越来越确信一件事&#xff1a;Wi-Fi Mesh 的安装调试&#xff0c;真正难的从来不是硬件本身&#xff0c;而是排障。…

作者头像 李华
网站建设 2026/9/13 2:42:55

Python脚本化数据库备份、导出与迁移的完整实践

做系统运维和数据开发的朋友&#xff0c;应该都遇到过这种尴尬&#xff1a;半夜收到磁盘告警&#xff0c;登上去一看&#xff0c;备份文件把空间塞满了&#xff1b;或者业务方要一份上个月的订单明细&#xff0c;你下意识写了一条select * from orders扔给 pandas&#xff0c;结…

作者头像 李华
网站建设 2026/9/13 2:42:46

Linux课程设计实战:从zip解压到源码阅读与实验报告对齐

简介&#xff1a;一套Linux课程设计资料包&#xff0c;面向计算机专业学生及需要完成Shell脚本数据库备份作业的开发者&#xff0c;重点展示如何用Shell与mysqldump实现MySQL数据库的即时备份、cron定时备份、增量备份及旧备份自动清理。资源共3个文件&#xff0c;包含两个Shel…

作者头像 李华
网站建设 2026/9/13 2:42:41

AD7745电容传感器驱动开发:从I2C寄存器到Linux IIO全攻略

简介&#xff1a;AD7745官方驱动程序压缩包面向需要快速上手高精度24位Σ-Δ ADC的嵌入式开发者&#xff0c;以及工业与医疗领域的数据采集、传感器接口和精密测量场景工程师&#xff0c;用于解决芯片初始化配置、转换结果读取和主机通信对接等问题。包内共5个文件&#xff0c;…

作者头像 李华
网站建设 2026/9/13 2:42:27

OpenCV红绿灯识别与动态配时控制系统设计

简介&#xff1a;本资源是一套基于Python与OpenCV实现的交通路口红绿灯智能控制系统高分毕业设计源码&#xff0c;面向计算机、自动化及智能交通方向的本科生&#xff0c;解决真实路口信号识别与状态联动控制问题&#xff0c;适用于毕业设计、课程设计及期末大作业场景。压缩包…

作者头像 李华