游乐游手机版
首页/AI热点日报/热点详情

Vasari:GitHub上的本地开源AI功能评估工具快速入门指南

类型:热点整理2026-07-13
Vasari是一款本地开源工具,用于评估AI功能。它支持加载trace、人工标注通过或失败、进行扎根理论错误分析,并构建和验证LLM法官,最终导出用于生产环境质量监控。所有操作在浏览器中完成,无需后端或账号,数据仅本地存储。

Vasari 是一个本地、开源的工具,专门用来评估AI功能。你可以从任何AI Agent、聊天机器人、RAG助手或LLM功能中加载trace,然后逐条查看对话,标记为“通过”或“失败”并附上评论。接下来,通过扎根理论错误分析,发现哪些类型的失败最常出现。最后,基于这些人工标注,构建并验证一个LLM作为法官,并将这个法官导出用于生产环境的质量监控。

所有操作都在你的浏览器中完成。没有后端,不需要账号,除非你主动调用LLM API,否则不会有任何数据离开你的机器。你可以把它部署成一个单独的网页,离线也能工作。

Vasari 是一个本地、开源的工具,用于评估 AI 功能

为什么存在这个工具:上线一个AI功能,然后随便看几个输出“感觉一下”,并不能说明它是否好用、在哪些地方失败、或者有没有在改进。真正的评估是一个循环:先看数据,然后标注,找到失败模式,进行量化,然后用一个经过验证的法官来自动化测量。Vasari 就是为运行这个循环而专门搭建的工具。

Credit and inspiration

这个工具深受Hamel Husain的AI评估方法论的启发。核心思想直接来自他的教学:查看数据,通过开放编码和轴向编码进行错误分析,只有在证明LLM法官与人类评审员一致(通过真正率和真负率衡量)时,才信任它。如果你想了解Vasari背后的理论,可以观看Hamel Husain的AI评估速成课程。

Vasari 是这些想法的独立实现。它与Hamel Husain没有关联,也未获得他的认可。

The evaluation loop

这个评估循环包括七个步骤:

  1. 观察:阅读AI功能的真实trace。
  2. 标记:将每个对话标记为通过或失败,并写简短评论。
  3. 编码:用简短的自由文本编码标记每个失败的原因(开放编码)。
  4. 聚类:将这些编码分组为失败类别(轴向编码)。
  5. 法官:为每个失败类别构建一个LLM法官。
  6. 验证:证明法官与人类一致(混淆矩阵、TPR、TNR、Cohen's kappa)。
  7. 部署:将经过验证的法官导出,用于生产环境,监控没有人类阅读的对话。

步骤1到4是人工工作,Vasari 让它们变得更快。步骤5到7让你能够将这种判断扩展到人类不会阅读的对话,但前提是法官已经证明与评审员一致。

What Vasari does

  • 读取任何trace:格式无关的输入:OpenTelemetry (OTLP) 导出、OpenInference 和 gen_ai 和 OpenLLMetry 跨度、Langfuse 导出、纯 [{role, content}] 对话、NDJSON,以及一个后备方案,将任何其他JSON渲染为可分级的时间线。
  • 渲染对话,而不是原始JSON:清晰的聊天时间线,显示用户和助手消息以及工具调用(可折叠的输入和输出),并且每个步骤都有一个“显示原始”开关。
  • 快速人工审查:具有进度和过滤器的队列,通过或失败加评论,以及为快速浏览数百个对话而设计的键盘快捷键。自动保存到浏览器。
  • 扎根理论错误分析:向失败添加自由文本开放编码,然后让LLM将它们聚类成失败分类,并显示每个类别的计数。
  • LLM作为法官,经过验证:每个失败类别一个二进制法官,每个法官都有一个可调、带版本的提示和模型。使用训练和测试分割以及完整的混淆矩阵(TPR、TNR、精度、F1、准确率、Cohen's kappa)进行验证。导出法官及其提示、模型和指标,用于生产环境。
  • 匿名化:在时间线、导出以及发送给LLM的所有内容中,脱敏PII(电子邮件、电话、IP、URL、卡、IBAN,以及名称和公司启发式算法和您自己的术语列表)。
  • 本地和私有:所有操作都在浏览器中完成。反馈存储在本地存储中,并导出为CSV或JSON。唯一的网络调用是您触发的可选LLM API请求。

Quick start

直接使用在线演示,或者下载构建好的 dist/index.html 文件,在任何浏览器中打开即可。它只有一个文件,离线也能工作。

从源码运行:

npm install
npm run dev  # 开发服务器,带热重载
npm run build  # 生成 dist/index.html,一个自包含文件
npm test  # 单元和DOM测试
npm run typecheck

使用内置的示例数据立即尝试(参见示例数据)。

How the LLM judge is evaluated (the important part)

LLM法官的核心目标是用自动化判断替代人工审查。但只有在你能证明法官的标注几乎和人类一样好时,这样做才安全。Vasari通过将人类标注视为真相,让法官标注相同的对话,然后比较两者来实现这一点。这就像任何分类器的评估:混淆矩阵、TPR、TNR、精度、F1等。特别需要注意的是Cohen's kappa,它修正了随机一致性的影响,是判断法官是否足够好的关键指标。

Ground truth

平台上的每个对话都由人类标注。对于给定的失败类别X,如果评审员的编码映射到类别X,则对话是正例,否则是负例。“完全编码”复选框允许您将失败标记为完全编码,这样其其他类别的负例就是可信的。

The confusion matrix

对于一个类别,将每个对话的人类标签与法官标签进行比较。每个对话落入四个单元格之一:

法官说YES 法官说NO
人类YES TP FN
人类NO FP TN
  • TP(真正例):两者都认为失败存在。
  • TN(真负例):两者都认为失败不存在。
  • FP(假正例):法官标记了,人类没有标记。法官过度标记。
  • FN(假负例):法官错过了人类发现的一个。法官标记不足。

The metrics

TPR (recall, sensitivity) = TP / (TP + FN)
TNR (specificity) = TN / (TN + FP)
Precision = TP / (TP + FP)
F1 = 2 * Precision * TPR / (Precision + TPR)
Accuracy = (TP + TN) / (TP + FP + FN + TN)
  • TPR 是法官捕获的真实失败的比例。TPR低意味着它错过了失败。
  • TNR 是法官正确放过的干净对话的比例。TNR低意味着它会误报。
  • Precision 是法官说YES时正确的频率。
  • F1 是一个平衡精度和召回率的单一数字。
  • Accuracy 是整体正确的比例。当失败很少时,它可能具有误导性,因为一个总是说NO的法官也能获得高分。不要仅依赖准确率。

Cohen's kappa (the headline number)

两个标注者可能因为偶然因素而大量一致,尤其是在一个类别很少时。Cohen's kappa 修正了随机一致性,因此它是判断“法官是否足够好”的最佳单一指标。

po (observed agreement) = Accuracy
pe (chance agreement) = ( (TP + FN) * (TP + FP) + (FN + TN) * (FP + TN) ) / N^2
kappa = (po - pe) / (1 - pe)

粗略解读:低于0.4为弱,0.4到0.6为中等,0.6到0.8为显著,高于0.8为近乎完美。目标是高kappa和高TPR。

Why a train and test split

如果在调整法官提示的同时用同一批对话进行评估,就会过拟合,数字也会失真。Vasari 将标注集分为训练集和保留的测试集(分层抽样,确保两者的正例比例相同)。在训练集上调整,然后信任测试集上的数字。Vasari 会同时报告两者,并且在编辑提示或模型后立即清除旧版本的指标,因此过时的数字不会误导你。

The decision

当法官在保留的测试集上达到强一致性(高kappa、高TPR、可接受的FP)时,它就可以作为该类别的人类替代者。导出它,然后用于未标注的生产环境流量。如果未达到标准,继续改进提示或模型,或者对该类别保持人工审核。

Tutorial for product managers

你不需要很技术就能运行真正的评估。这个教程使用内置的100个对话Demo,你可以在20分钟内完成整个流程,然后在自己的AI功能trace上重复。

0. 获取一些trace。 AI功能(Agent、聊天机器人、RAG助手、分类器)会产生对话。你的工程师通常可以从可观测性工具(OpenTelemetry、Langfuse、Arize Phoenix、LangSmith或普通日志)中导出JSON。Vasari 支持所有这些格式。没有导出?使用 test-files/ 中的Demo文件。

1. 查看数据。 这是最重要的一步。打开Vasari,点击“Load export”,然后选择 demo-100-conversations.json。从头到尾阅读几个对话。你会立即注意到模式:Agent 捏造事实、忽略指令、错误使用工具。

2. 标记通过或失败,加评论。 为每个对话决定:AI是否完成了它的工作?按“Pass”或“Fail”,并写简短评论说明原因。保持二元判断。“足够好发给用户”比1到5分制更好,后者会掩盖分歧。快捷键:jk 移动,pf 评分,/ 跳转到评论框。

3. 开放编码失败。 将队列筛选器设置为“Fail”。在每个失败上,在反馈栏中添加一个或多个简短的错误编码,例如 hallucinated figureignored constraintignored tool error。发明适合的词语。之前使用过的编码会自动补全,从而保持措辞一致。一旦捕获了该对话中的所有问题,勾选“fully coded”。

4. 轴向编码成失败分类。 点击“Analyze fails”。你会看到每个不同编码及其频率。将它们聚类成更高级别的失败类别。如果有API密钥,点击“Run with API”。没有密钥,点击“Copy prompt”,粘贴到ChatGPT或Claude中,然后将JSON粘贴回来。Vasari 会显示带有计数的类别。点击某个类别上的“filter queue”可以只查看那些失败。

5. 构建并验证每个类别的法官。 点击“Judges”。每个失败类别有一个选项卡。选择模型,查看或编辑法官提示,然后点击“Validate on labeled set”。阅读混淆矩阵和指标(面板中有“如何阅读这些数字”的指南)。关键指标是测试集上的Cohen's kappa。高FP意味着过度标记,因此收紧提示。高FN意味着错过案例,因此放宽提示。保存新版本,重新验证,观察数字变化。

6. 部署法官到生产环境。 一旦法官足够好,点击“Export judge”(或“Export all judges”)。你会得到一个包含精确提示、模型和测量指标的工件。交给工程团队,用于运行人类不会阅读的数千个生产环境对话,并跟踪每个类别随时间变化的失败率。

Tips distilled from Hamel Husain's approach

  • 在看仪表盘之前先看数据。阅读30到100个真实trace,比任何指标都更能让你学到东西。
  • 使用二元通过/失败判断。它迫使做出真正的决定,并使分歧变得可见。
  • 每个失败模式构建一个法官,而不是一个庞大的法官。狭窄的法官更容易验证和修复。
  • 法官的可靠性取决于它与人类的一致性。报告TPR、TNR和kappa,而不是感觉。
  • 警惕罕见类别的陷阱。如果某个失败很少见,高准确率可能掩盖法官从未捕获它的事实。关注TPR和kappa。
  • 每当更改提示或模型时,重新验证。

Sample data

以下所有内容都位于此仓库中,以便任何人都可以在没有自己的数据的情况下试用该工具。

test-files/ 中有每个输入格式的一个密集型、可直接拖拽的样本(相同对话的不同形状,以便你可以确认它们都能被相同地解析):

File Format
01-otlp-genai.json 具有 gen_ai 属性的 OTLP 导出
02-openinference-spans.json 扁平的 OpenInference 跨度数组
03-langfuse-export.json Langfuse trace 和 observation
04-plain-conversation.json 一个单一的 [{role, content}] 对话
05-array-of-conversations.json 一个普通对话数组
06-ndjson-spans.ndjson NDJSON,每行一个跨度
07-custom-fallback.json 一个自定义形状,通过可读的后备方案显示

test-files/demo-100-*.json 是包含100个对话的教程数据集:

  • demo-100-conversations.json: 100个Agent trace。
  • demo-100-feedback.json: 匹配的人类标注(45个失败,55个通过),已经使用大约5个失败类别的12个编码进行了开放编码。

要在Demo上运行完整流程,点击“Load export”并选择 demo-100-conversations.json,然后点击“Import feedback”并选择 demo-100-feedback.json。现在你已有编码的失败,可以直接进入“Analyze fails”和“Judges”。要跳过轴向编码的API,在“Analyze fails”的第3步中粘贴以下内容:

{"categories":[
{"name":"Fabrication","description":"捏造事实、数据、来源或工具结果。","codes":["hallucinated figure","fake citation","invented tool result"]},
{"name":"Tool misuse","description":"使用了错误的工具,或忽略了工具失败。","codes":["ignored tool error","wrong tool used"]},
{"name":"Reasoning error","description":"错误的算术或错误的结论。","codes":["math error","wrong conclusion"]},
{"name":"Instruction following","description":"忽略了约束、格式或问题。","codes":["ignored constraint","answered wrong question","ignored format"]},
{"name":"Safety and refusal","description":"过度拒绝无害请求或给出不安全建议。","codes":["over-refusal","unsafe advice"]}
]}

使用 npm run gen:testfilesnode scripts/generate-demo.mjs 重新生成这些文件。

Supported trace formats

OTLP (resourceSpans)、OpenInference 和 gen_ai 和 OpenLLMetry 跨度、Langfuse 导出、纯 [{role, content}](带 tool_calls)、对话数组、NDJSON,以及一个后备方案,将任何其他JSON渲染为可读、可分级的数据记录。这包括当前的OpenTelemetry GenAI约定(gen_ai.input.messagesgen_ai.output.messages,带有类型化的 parts,由 Vercel AI SDK v7 发出),以及较旧的 gen_ai.promptgen_ai.completion 风格。加载后会显示一个横幅,指示检测到的格式,并且每个步骤都有一个“显示原始”开关。如果遗漏了某个字段,可以扩展 src/parser.ts 顶部的属性键字典。

Keyboard shortcuts

Key Action
j / k 下一个或上一个对话
p / f 通过或失败(并跳转到下一个未审查的)
/ 聚焦评论框
c 聚焦错误编码框(在失败上)
Cmd/Ctrl + Enter 保存评论并跳转到下一个未审查的

API key, anonymization, and judges (details)

  • 设置,LLM连接。 选择一个提供商(默认使用最新Claude的Anthropic,OpenAI,或任何兼容OpenAI的基本URL,包括网关或本地模型),一个模型,一个密钥,以及一个最大输出令牌数。

    你的密钥在在线演示中安全吗? 是的,Vasari没有后端。你的密钥保存在浏览器中,并且仅通过HTTPS直接发送到你配置的提供商。此项目或我们运行的任何服务器都不会收集任何数据。默认情况下,密钥仅保留在当前会话中。如果你勾选“在此浏览器中记住密钥”,它将被保存到此源的本地存储中,这样你就不必重新输入。本地存储未加密,因此在共享计算机上取消勾选该框,并且永远不要托管带有内置共享密钥的此应用副本。如果你希望完全隔离,请下载 dist/index.html 并离线运行,而不是使用在线演示。

  • 匿名化。 在所有地方使用一致的占位符令牌脱敏PII,包括LLM负载。离线规则,加上一个基于字典的大写单词名称和公司启发式算法,以及你自己的术语列表和允许列表,并带有“扫描数据集以查找名称”的帮助程序。

  • 法官。 每个类别一个经过验证的法官。请参阅上面的教程和评估部分。导出会携带提示、模型和指标,以便法官在此工具之外可重现。

Exports

CSV列:conversation_id, verdict, comment, codes, axial_category, reviewed_at, model, agent, num_steps。JSON:{ feedback: [...], axial },可以重新导入以恢复,从而恢复编码和分类。

Project structure

index.html – 应用外壳(标记)
src/
  app.ts – 状态、渲染、DOM 连接
  parser.ts – 格式无关的 trace 解析器,纯函数,无 DOM(单元测试)
  coding.ts – 开放和轴向编码逻辑,纯函数(单元测试)
  judge.ts – 法官提示、裁决、运行、导出(单元测试)
  metrics.ts – 混淆矩阵、TPR、TNR、精度、F1、kappa、分割(单元测试)
  anonymize.ts – PII 检测和脱敏,纯函数(单元测试)
  llm.ts – 可配置的浏览器 LLM 客户端(单元测试,模拟 fetch)
  dict.ts – 用于名称启发式算法的常见单词字典
  types.ts – 共享类型
  styles.css – 主题和设计
test/ – Vitest 套件和一个 jsdom 应用冒烟测试
scripts/ – 样本数据生成器
fixtures/
  test-files/ – 样本导出(见上文)

使用 Vite 和 TypeScript 构建。风险逻辑(解析、编码、指标、判断)是纯函数并且完全经过单元测试,并且 npm run build 将所有内容内联到一个离线 dist/index.html 中。

Deploying

.github/workflows/deploy.yml 在每次推送到 main 时将 dist/ 发布到 GitHub Pages。在仓库设置中启用带有 GitHub Actions 源的 Pages。.github/workflows/ci.yml 在每次推送和拉取请求时运行类型检查、测试和构建。

Contributing

欢迎提交问题和拉取请求。保持解析、编码、指标和法官逻辑为纯函数(无DOM)以便可测试,将DOM和渲染放在 app.ts 中,并为任何新格式或行为添加测试。保持CI绿色:npm run typecheck && npm test && npm run build

License

MIT,请参阅 LICENSE。受 Hamel Husain 的 AI 评估方法启发。未与他关联,也未获得他的认可。

来源:https://www.bestblogs.dev/article/aaa57ee4cc?utm_source=rss&utm_medium=feed&utm_campaign=resources&entry=rss_article_item

相关热点

继续查看同栏目近期热点。

延伸阅读

补充最近整理过的热点入口。