引言
你已经发布了你的 AI 应用。用户正在与它互动。回复虽然没有出错,但也不算出色。反馈含糊不清,满意度得分平平,每一次新的提示词调整或模型更换都像是在黑暗中摸索。你尝试不同的工作流程,处理各种边缘情况,但仍然无法判断是否有任何实际改进。最终,你放弃了跟踪,开始凭感觉猜测,然后就发布了。
情况不必如此。读完这篇文章,你将拥有一个清晰的行动指南,通过评估来系统性地改进你的 AI 应用,从设置到建立稳健、自动化的评估循环,从而超越用户期望。这些见解提炼自我们在多家企业和数十家初创公司改进大语言模型(LLM)应用的经验,以及构建 Ragas 本身的经验教训。
摘要
改进 AI 应用不是艺术,而是科学。设定明确的指标,构建真实的测试集,收集人类反馈,并利用自动化的 LLM 评估进行扩展。本指南将带你走过整个评估循环,从创建测试数据集到分析错误和整合用户反馈,让你不再凭感觉猜测,而是开始系统性地改进你的 AI 应用。
什么是评估?
评估是衡量你的 AI 系统实现其预期目标的效果。
AI 应用中的评估常常与 AI 可观测性或护栏等相关概念混淆。评估专门用于量化系统在明确目标下的性能。
评估有三个关键步骤:
- 整理一个真实的测试集:收集或生成系统的预期输入。
- 明确定义成功:具体说明什么是“好”的结果,以及为什么好。
- 选择精确的指标:衡量每个结果(通过/失败、分数、排名)。
另一个常见的误解是关于评估和基准测试。
评估和基准测试是一回事吗?不,它们不是。LLM 基准测试侧重于在公开可用的数据集上,基于学术指标评估不同模型。这些模型被评估的数据或指标在大多数情况下与你的系统、数据或任务无关。这也是为什么公共基准或数据集无法帮助你评估和改进你的系统的原因。
为什么 AI 工程师应该花时间在这上面?
科学实验/评估是系统性改进 AI 应用的唯一可靠方法。你可能会想,为什么不直接目测检查回复并快速部署更改呢?
以下是为什么评估优于凭感觉检查的原因:
- 规模:你无法手动检查数百个边缘案例。现实世界的输入是杂乱的,模型会以随机检查无法发现的微妙方式失败。
- 客观性:你的“直觉”可能与队友的不同。评估将主观印象转化为一致、可重复的指标。
- 沟通:说“感觉更好了”并不能帮助团队达成一致。评估提供具体数字:“新的提示词将任务完成率从 50% 提高到了 70%。”
评估不仅仅是好的实践——它是必不可少的基础设施。
从哪里开始?
对于基于 LLM 的系统,迭代速度快,但衡量影响却很慢。与传统的机器学习工作流程中训练和数据准备耗费大部分时间不同,AI 应用开发通常归结为更改提示词、工具或路由逻辑。这些更改只需几分钟即可实现,但评估这些更改对结果的影响需要更多时间,因为通常需要人工审查一组样本回复并对其进行评分/感觉检查。
事实上,我们看到评估占据了团队迭代周期的约 30%,尤其是在需要在许多边缘案例中测试提示词调整或检索更改时。我们并非个例:像 GitHub Copilot、Casetext 和 Notion 这样的团队也写过关于评估在其工作流程中日益重要的作用。[3]
那么,你该从哪里开始呢?
首先决定评估什么。
- 端到端评估:就像集成测试或端到端测试。它们告诉你整个流程组合在一起后,是否真正交付了用户关心的结果。
- 组件评估:就像单元测试。它们帮助你调试流程的特定部分,如检索器或重排器,以确保每个部分都能独立工作。
从端到端开始。这是用户看到的东西。一旦你对输出有信心,再深入研究那些不太可能被替换的最重要组件或单元。
数据集整理
如果你已经读到这里,说明你对改进 AI 系统是认真的。第一步:构建一个好的测试数据集。
- 生产前
还没有用户?没问题。从编写 10-30 个真实的 AI 系统输入开始,这些输入代表了你在生产中期望看到的内容。你的目标是设计意图的多样性,而不是数量。
合成数据在这里可以大有作为,一旦你有了初始的输入集,你就可以使用合成数据生成流程来推断并生成更多变体。下面描述了需要牢记的原则细节。
- 生产后
已经有用户了?太好了。从真实系统输入中抽样 30-50 个。手动审查它们——寻找质量、多样性和边缘案例。你的目标是得到一组代表你在生产中看到的各种场景的输入。
尽管这是一个好的开始,但它可能无法代表具有足够多样性的系统输入。这里有一个最简单的技术可以用来改进你的测试数据:
- 从生产中抽样 x% 的系统输入。理想情况下是 1000 个或更多样本。
- 根据系统输入进行去重。
- 使用嵌入模型对这些系统输入进行嵌入。
- 使用 KNN 或 DBSCAN 对嵌入进行聚类。
- 从每个簇中抽样一个或多个。检查它们,并将其添加到你的测试数据中。
在这两种情况下,都从小处着手,使其真实,并根据需要逐步扩展。你不想做的是陷入“技术难题陷阱”——在你运行第一次评估之前,就陷入设计完美测试集的漩涡中。
生成高质量合成测试数据的技术
如果你缺少真实输入或想要现有输入的变化形式,LLM 可以提供帮助。
通过在几个关键变量上对 LLM 进行条件设置,来生成高质量的合成数据。这些变量对于不同的应用可能有所不同,这里的原则是找到可以用来条件化 LLM 的变量,以便它能产生具有足够多样性的输入。
以下是针对常见 AI 聊天机器人应用的一个例子:
- 角色:谁在提问?(例如,“一位研究癌症治疗的初级研究员”)
- 主题:关于什么?(例如,“基因组学和个性化医疗”)
- 查询复杂性:短 vs. 长,模糊 vs. 具体
提示词结构 + 示例 + 少量真实查询 → 优秀的合成数据。
用 LLM 进行推断,用人类进行验证。永远不要跳过审查步骤。
你可以通过从向量数据库中检索过去的真实查询,并将其用作生成提示词中的示例,来进一步提高质量。
# Define some representative personas personas = [ "A PhD student early in their research journey, seeking help with literature reviews and forming hypotheses.", "An experienced academic looking for synthesis across papers and advanced insights.", "A specialist doctor (e.g. oncologist) using the assistant for rare case support and new treatment options." ] # Define query complexities and topics query_complexities = [ "long_form_summary", "comparative_analysis", "query_with_ambiguity" ] topics = [ "cancer_treatment", "clinical_trials", "genomics_and_personalized_medicine" ] # Prompt template to generate synthetic test queries prompt_template = """ You are helping build a test dataset for a healthcare AI assistant. Generate a user query based on: - Persona: {persona} - Query Complexity: {complexity} - Topic: {topic} Instructions: - Write a **realistic query** this persona might ask. - Reflect the specified complexity and keep it grounded in the topic. - Output only the query. No explanations or metadata. """ # Example usage (you would loop through combinations in practice) print(prompt_template.format( persona=personas[0], complexity=query_complexities[1], topic=topics[2] ))
我们曾使用电子表格或 CSV 文件来组织和维护这类数据集,但逐渐转向了 Notion 数据库,它为从代码中读写数据集提供了更好的用户体验和 API。
人工审查和标注
这是许多团队出错的地方。
他们低估了人工审查的重要性,并高估了建立审查流程所需的工作量。明确一点:如果你的目标是让你的 AI 系统与人类期望保持一致,你必须首先清楚地定义那些期望。LLM 无法读懂你的心思。如果你不向它们展示什么是“好”和“坏”,它可能永远也学不会。
第一步:定义要衡量的内容
问:在你的用例中,一个好的回复什么最重要?
为每个输入-回复对选择 1-3 个维度。常见例子:
- 对于 RAG 系统:关注回复的正确性和引用的准确性。
- 对于编码代理(SWE 代理):关注语法正确性、运行时成功和代码风格。
第二步:选择指标类型
为每个维度选择一个既易于应用又具可操作性的指标。通常有三种类型:
- 二元(通过/失败):当可接受和不可接受之间有明确界限时使用。例如:代理是否完成了任务?是或否。
- 数值(例如 0-1):当部分给分合理且你能清楚定义分数含义时使用。例如:引用准确度为 0.5 = 一半的引用不正确。
- 排名:当输出是主观的,且比较比绝对判断更容易时使用。例如:摘要 A 优于摘要 B。
无论你使用哪种指标,都要同时收集理由。
没有理由的“失败”是没有帮助的。添加上下文,如“回复中出现了事实幻觉”或“遗漏了关键点”。这些理由将成为你之后训练 LLM 作为评判者的重要数据。
提示:定制 UI 使标注/人工审查过程更顺畅
查看数据可能很乏味,但通过这个简单的技巧,你可以让它变得不那么乏味且更高效。最好的方法是为用例定制数据查看器。
你的数据查看器应该是:
- 为你的用例量身定制(RAG、摘要、代理等)
- 标注速度快
- 结构化到足以一致地存储数据和反馈
我们使用 Claude Sonnet 构建的轻量级 Web UI——它在快速生成自定义界面方面表现惊人。一旦建成,每当你需要从领域专家那里获得新的标注时,都可以重复使用这个 UI。
使用 LLM 作为评判者进行扩展
一旦你建立了一个带有人机标注的坚实测试集,下一个挑战就是扩展你的评估。每次你更改提示词、检索器或重排器时,手动重新标注所有内容都是痛苦的。这使得人工审查成为瓶颈——并减慢了迭代速度。
这就是LLM 作为评判者发挥作用的地方。
目标很简单:用自动评估取代重复的手动审查,这种评估由被提示扮演你领域专家的 LLM 驱动。理想情况下,你的 LLM 评判者应该与你的专家标签至少有 80% 的一致性。
第一步:设置
你已经定义了要衡量的内容(例如,正确性、引用准确性)。现在,编写提示词,指示 LLM 在这些维度上对回复进行评分或分类。
第二步:与人类判断对齐
在已标注的测试集上运行你的 LLM 评判者。将其输出与专家标签进行比较。迭代提示词质量和少量示例,直到你持续看到高一致性。
实践中效果最好的方法:
- 使用高质量示例的少样本提示
- 基于检索的提示:从你的数据集中获取相似的已审查样本,并将其提供给评判者
- 包括你在标注期间写的口头反馈——这有助于评判者更好地推理
通过强大的反馈循环,你的 LLM 作为评判者会随着时间的推移而改进。你可以使用斯皮尔曼等级相关性或科恩 kappa 等相关性分析方法来衡量 LLM 作为评判者的输出与人类评估者评分之间的一致性。
def judge_response(input, response): # Embed the input + response to find similar, labeled examples embedding = embedding_model.embed(f"{input} - {response}") examples = get_similar(embedding, labeled_index) # Construct a few-shot prompt prompt = f""" Check if the response is relevant to the input. Output: Pass or Fail. ### Examples {examples} ### Input {input} ### Response {response} """ return llm.generate(prompt)
如果你愿意,也可以尝试 Dspy 类的优化或微调评估者模型。话虽如此,在大多数情况下,这并非必需。手工制作的示例 + 基于检索的提示通常就足够了。
如果你有一个好的系统来审查 LLM 作为评判者的结果,随着时间的推移,你的 LLM 作为评判者会变得更好——更接近人类判断——而无需持续的人工监督。
错误分析
评估告诉你系统在哪里失败。错误分析帮助你理解为什么失败以及接下来该做什么。
评估 = 测量
错误分析 = 诊断
假设你的测试集显示 30% 的样本失败了。现在怎么办?
在修复任何问题之前,你需要可见性。这意味着检查输入、中间输出和组件日志数据、检索器、重排器、LLM 调用、代码逻辑、外部工具等。
错误分析从根本上涉及两个步骤:
- 第一步:错误假设
手动检查每个表现不佳样本的日志,然后问:我认为这里出了什么问题?用简单的语言写下一行假设。
- 第二步:错误分类
将这些假设分组归类,以便你可以优先处理和修复它们。你可以手动操作,也可以提示 LLM 为你进行聚类。
error_hypothesis = [ "document was not retrieved", "document had paywall", "retrieved doc had a paywall", "doc not retrieved", "paywall in document" ] prompt = f""" Given the following error hypotheses, generate a set of error categories. Then classify each hypothesis under one of these categories. {error_hypothesis} """ # Expected output: { "retrieval_issues": ["document was not retrieved", "doc not retrieved"], "paywall_issues": ["document had paywall", "retrieved doc had a paywall", "paywall in document"] }
现在,按频率对你的类别进行排序。首先处理最常见的类别。这为你提供了一个清晰的调试和迭代路线图。
现在你已经确定了故障点,是时候进行实验了——做出改变,运行评估,并衡量哪些真正改进了你的流程。这就是我们接下来要讨论的内容。
实验
既然你已经确定了导致系统表现不佳的错误模式,你可能会有很多改进的想法。这就是实验的用武之地。
什么是实验?
一个实验是对你的 AI 系统进行的结构化更改,目的是观察其对一个或多个评估指标的影响。
一个好的实验是这样的:
- 更改:调整你的流程中的单个组件(例如,提示词调整、更换检索器、添加重排器)。
- 评估:使用你现有的测试数据运行它,并记录新的响应和指标。
- 比较:将其与你的基线进行基准测试。手动审查和比较更改。
- 决定:如果指标和响应有显著改善,就发布它,或者尝试不同的解决方案。
假设你有五个改进系统的想法。逐一尝试,记录结果,评估并比较。这个过程消除了迭代中的猜测,让你有信心发布最佳版本。
但这就结束了吗?如果你在生产中部署了一个 AI 应用,你肯定会知道,无论你怎么尝试,每周都会有新的边缘案例出现,影响客户体验。这就引出了我们的下一节。
机器学习反馈循环
你已经进行了实验,发布了改进,并部署了你的 AI 系统。这就是循环的终点吗?不完全是。
AI 问题是长尾的。真正的挑战不是前 80%——而是最后的 20%。
在生产中,新的边缘案例会定期出现。这是因为你的系统现在会遇到各种各样罕见、不可预测的场景。而最好的 AI 系统是那些能从中学习的系统——并且学得很快。
想象一个只处理常见问题的客户支持机器人。那是基本要求。真正的差异化在于处理那奇怪、意外、非结构化的 20%。
第一步:从生产中捕获信号
为了在实际应用中捕捉失败,你需要一个信号管道。这些可以是:
- 显式反馈 – 来自用户的直接输入(例如,点踩、1 星评级)
- 隐式反馈 – 行为信号(例如,用户不复制输出、重试相同输入、放弃会话)
例如:在一个文本到 SQL 的系统中,用户没有复制结果。这是一个隐式的信号,表明出了问题——即使他们没有点踩。
第二步:仔细解读反馈
并非所有反馈都意味着你所想的那样。
- 一个“踩”可能是因为延迟,而不是质量问题。
- 用户可能不复制输出,因为他们只是在复核自己的 SQL。
所以:不要把原始反馈当真。建立一个轻量级的审查流程,可以是手动的,也可以是使用 LLM 作为评判者,来从真实信号中过滤掉噪音。
第三步:闭合循环
当你识别出一个真正的失败时:
- 将其添加到你的测试数据集中
- 专门针对该场景进行实验
- 发布一个改进版本
结论
最好的 AI 产品——那些用户真正喜爱的产品——是由那些深度关注实验、评估和迭代的团队构建的,以提高其可靠性。这就是它们与竞争对手的区别所在。
在 Ragas,我们正在构建基础设施,用评估循环取代凭感觉检查。我们正在将所有这些经验教训转化为构建下一代 Ragas。如果你有兴趣与我们合作解决这个问题,我们很乐意与你交谈。
🔗 预定一个时间段与我们交流。
资源
- 来自顶尖 AI 产品构建者的故事
